Skip to content

Commit

Permalink
feat: add chip input
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger committed Feb 17, 2025
1 parent d2e5ded commit d128b3b
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 0 deletions.
78 changes: 78 additions & 0 deletions src/components/chip-input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { type ComponentProps, createSignal, splitProps } from 'solid-js';
import { IconX } from '@tabler/icons-solidjs';

import type { WithOverride } from '~/utils';
import {
FORM_INPUT_PROP_NAMES,
makeFieldComponent,
type FormInputProps,
} from './forms';
import { TextInput } from './text-input';
import { Badge } from './badge';

export type ChipFieldProps = ComponentProps<typeof ChipField>;

export const ChipField = makeFieldComponent({
inputComponent: ChipInput,
inputPropNames: [...FORM_INPUT_PROP_NAMES, 'placeholder'],
});

export interface ChipInputOptions
extends FormInputProps<HTMLInputElement, string[]> {
placeholder?: string;
}

export type ChipInputProps = WithOverride<
ComponentProps<'div'>,
ChipInputOptions
>;

export function ChipInput(props: ChipInputProps) {
const [_, rest] = splitProps(props, [
...FORM_INPUT_PROP_NAMES,
'placeholder',
]);

const [inputValue, setInputValue] = createSignal('');

function onKeyDown(event: KeyboardEvent) {
if (event.key === 'Enter' && inputValue() !== '') {
event.preventDefault();
addChip(inputValue());
setInputValue('');
}
}

function addChip(chip: string) {
props.onChange?.([...(props.value ?? []), chip]);
}

function removeChip(chip: string) {
props.onChange?.(props.value?.filter(t => t !== chip) ?? []);
}

return (
<div {...rest}>
<TextInput
onBlur={() => props.onBlur?.()}
onKeyDown={onKeyDown}
onChange={setInputValue}
placeholder={props.placeholder}
value={inputValue()}
/>

<div class="flex flex-wrap gap-2">
{props.value?.map(chip => (
<Badge
variant="secondary"
class="cursor-pointer"
onClick={() => removeChip(chip)}
>
{chip}
<IconX class="ml-1 h-3 w-3" />
</Badge>
))}
</div>
</div>
);
}
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './breadcrumb';
export * from './card';
export * from './carousel';
export * from './checkbox-input';
export * from './chip-input';
export * from './collapsible';
export * from './combobox';
export * from './context-menu';
Expand Down

0 comments on commit d128b3b

Please sign in to comment.