From d128b3bf516a41823af50b3515b0561398026daf Mon Sep 17 00:00:00 2001 From: lars-berger Date: Mon, 17 Feb 2025 21:35:14 +0800 Subject: [PATCH] feat: add chip input --- src/components/chip-input.tsx | 78 +++++++++++++++++++++++++++++++++++ src/components/index.ts | 1 + 2 files changed, 79 insertions(+) create mode 100644 src/components/chip-input.tsx diff --git a/src/components/chip-input.tsx b/src/components/chip-input.tsx new file mode 100644 index 0000000..1023de9 --- /dev/null +++ b/src/components/chip-input.tsx @@ -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; + +export const ChipField = makeFieldComponent({ + inputComponent: ChipInput, + inputPropNames: [...FORM_INPUT_PROP_NAMES, 'placeholder'], +}); + +export interface ChipInputOptions + extends FormInputProps { + 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 ( +
+ props.onBlur?.()} + onKeyDown={onKeyDown} + onChange={setInputValue} + placeholder={props.placeholder} + value={inputValue()} + /> + +
+ {props.value?.map(chip => ( + removeChip(chip)} + > + {chip} + + + ))} +
+
+ ); +} diff --git a/src/components/index.ts b/src/components/index.ts index fd0419d..7684ae7 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -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';