Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tag component + InputField story using it #28

Merged
merged 21 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
}
}

.bk-input-field__tags-and-input {
.bk-input-field__container {
display: flex;
flex-direction: row;
gap: bk.$spacing-2;
Expand Down
22 changes: 6 additions & 16 deletions src/components/forms/fields/InputField/InputField.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,30 +60,20 @@ export const InputWithTags: Story = {
const [tags, setTags] = React.useState<Array<string>>(['Tag Title', 'Tag Title 2']);
const [inputText, setInputText] = React.useState<string>('Example');

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setInputText(e.target.value);
const handleUpdate = (newInputText: string) => {
setInputText(newInputText);
};
const onKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === 'Backspace' && inputText === '') {
setTags(tags.slice(0,-1));
}
if (e.key === 'Enter' && inputText !== '') {
setTags([...tags, inputText]);
setInputText('');
}
};
const onRemove = (index: number) => {
setTags(tags.filter((_, idx) => idx !== index));
const handleUpdateTags = (newTags: string[]) => {
setTags(newTags);
};

return (
<InputField
tags={tags}
value={inputText}
onKeyUp={onKeyUp}
onChange={onChange}
onUpdate={handleUpdate}
onUpdateTags={handleUpdateTags}
placeholder=""
tagRemoveCallback={onRemove}
/>
);
}
Expand Down
51 changes: 46 additions & 5 deletions src/components/forms/fields/InputField/InputField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ export type InputFieldProps = ComponentProps<'input'> & {
/** Tags to be displayed inside the input field */
tags?: undefined | string[],

/** Callback to remove a specific Tag, passed down to Tag component. */
tagRemoveCallback?: (index: number) => void,
/** Callback to update the input value. Internally hooks to onChange */
onUpdate?: undefined | ((arg0: string) => void),

/** Callback to update the tags. Internally hooks to onKeyUp */
onUpdateTags?: undefined | ((arg0: string[]) => void),
nighto marked this conversation as resolved.
Show resolved Hide resolved
};
/**
* Input field.
Expand All @@ -43,7 +46,8 @@ export const InputField = (props: InputFieldProps) => {
labelProps = {},
wrapperProps = {},
tags = [],
tagRemoveCallback,
onUpdate = null,
onUpdateTags = null,
nighto marked this conversation as resolved.
Show resolved Hide resolved
...inputProps
} = props;

Expand All @@ -55,6 +59,41 @@ export const InputField = (props: InputFieldProps) => {
unstyled: tags && tags.length > 0,
};

const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// first handle supplied onChange, if exists
if (inputProps.onChange) {
inputProps.onChange(e);
}
// then return value to onUpdate
if (onUpdate) {
onUpdate(e.target.value);
}
};

const onKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
// first handle supplied onKeyUp, if exists
if (inputProps.onKeyUp) {
inputProps.onKeyUp(e);
}
// then return value to onUpdateTags
if (onUpdateTags && onUpdate) {
const { value } = inputProps;
if (e.key === 'Backspace' && value === '') {
onUpdateTags(tags.slice(0,-1));
}
if (e.key === 'Enter' && value !== '') {
nighto marked this conversation as resolved.
Show resolved Hide resolved
onUpdateTags([...tags as string[], value as string]);
nighto marked this conversation as resolved.
Show resolved Hide resolved
onUpdate('');
}
}
};

const onRemoveTag = (index: number) => {
if (onUpdateTags) {
onUpdateTags(tags.filter((_, idx) => idx !== index));
}
};

return (
<div
{...wrapperProps}
Expand All @@ -74,15 +113,17 @@ export const InputField = (props: InputFieldProps) => {
{label}
</label>
}
<div className={cl['bk-input-field__tags-and-input']}>
<div className={cl['bk-input-field__container']}>
{tags && (
tags.map((tag, idx) => <Tag key={idx} content={tag} onRemove={() => tagRemoveCallback?.(idx)}/>)
tags.map((tag, idx) => <Tag key={idx} content={tag} onRemove={() => onRemoveTag(idx)}/>)
)}
<Input
{...injectedInputProps}
id={controlId}
form={formContext.formId}
className={cx(cl['bk-input-field__control'], inputProps.className)}
onChange={onChange}
onKeyUp={onKeyUp}
/>
</div>
</div>
Expand Down