diff --git a/apps/storybook/stories/typeahead.stories.tsx b/apps/storybook/stories/typeahead.stories.tsx index defffbf4..d8ca877a 100644 --- a/apps/storybook/stories/typeahead.stories.tsx +++ b/apps/storybook/stories/typeahead.stories.tsx @@ -1,8 +1,13 @@ import React, { useState } from 'react'; import type { ComponentMeta } from '@storybook/react'; -import type { TypeaheadOption } from '@tih/ui'; +import type { TypeaheadOption, TypeaheadTextSize } from '@tih/ui'; import { Typeahead } from '@tih/ui'; +const typeaheadTextSizes: ReadonlyArray = [ + 'default', + 'inherit', +]; + export default { argTypes: { disabled: { @@ -23,6 +28,10 @@ export default { required: { control: 'boolean', }, + textSize: { + control: { type: 'select' }, + options: typeaheadTextSizes, + }, }, component: Typeahead, parameters: { diff --git a/packages/ui/src/Typeahead/Typeahead.tsx b/packages/ui/src/Typeahead/Typeahead.tsx index 76cb71af..b15aa859 100644 --- a/packages/ui/src/Typeahead/Typeahead.tsx +++ b/packages/ui/src/Typeahead/Typeahead.tsx @@ -10,6 +10,7 @@ export type TypeaheadOption = Readonly<{ label: string; value: string; }>; +export type TypeaheadTextSize = 'default' | 'inherit'; type Attributes = Pick< InputHTMLAttributes, @@ -33,10 +34,16 @@ type Props = Readonly<{ ) => void; onSelect: (option: TypeaheadOption) => void; options: ReadonlyArray; + textSize?: TypeaheadTextSize; value?: TypeaheadOption; }> & Readonly; +const textSizes: Record = { + default: 'text-sm', + inherit: '', +}; + export default function Typeahead({ disabled = false, isLabelHidden, @@ -46,108 +53,123 @@ export default function Typeahead({ options, onQueryChange, required, + textSize = 'default', value, onSelect, ...props }: Props) { const [query, setQuery] = useState(''); return ( - { - if (newValue == null) { - return; - } - +
+ - - {label} - {required && ( - - )} - -
-
- { + if (newValue == null) { + return; + } + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + onSelect(newValue as TypeaheadOption); + }}> + + {label} + {required && ( + + )} + +
+
- (option as unknown as TypeaheadOption)?.label - } - required={required} - onChange={(event) => { - setQuery(event.target.value); - onQueryChange(event.target.value, event); - }} - {...props} - /> - - + + +
+ setQuery('')} + as={Fragment} + leave="transition ease-in duration-100" + leaveFrom="opacity-100" + leaveTo="opacity-0"> + + {options.length === 0 && query !== '' ? ( +
+ {noResultsMessage} +
+ ) : ( + options.map((option) => ( + + clsx( + 'relative cursor-default select-none py-2 px-4 text-slate-500', + active && 'bg-slate-100', + ) + } + value={option}> + {({ selected }) => ( + + {option.label} + + )} + + )) + )} +
+
- setQuery('')} - as={Fragment} - leave="transition ease-in duration-100" - leaveFrom="opacity-100" - leaveTo="opacity-0"> - - {options.length === 0 && query !== '' ? ( -
- {noResultsMessage} -
- ) : ( - options.map((option) => ( - - clsx( - 'relative cursor-default select-none py-2 px-4 text-slate-500', - active && 'bg-slate-100', - ) - } - value={option}> - {({ selected }) => ( - - {option.label} - - )} - - )) - )} -
-
-
- + +
); }