Skip to content

Commit 5588387

Browse files
authored
Merge pull request #157 from lambda-curry/codegen-bot/recreate-pr-135-generic-select-patch-bae1bf
2 parents 01eb068 + 78b6c81 commit 5588387

File tree

2 files changed

+16
-15
lines changed

2 files changed

+16
-15
lines changed

packages/components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@lambdacurry/forms",
3-
"version": "0.22.2",
3+
"version": "0.22.3",
44
"type": "module",
55
"main": "./dist/index.js",
66
"types": "./dist/index.d.ts",

packages/components/src/ui/select.tsx

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ import {
1717
useId,
1818
useRef,
1919
} from 'react';
20-
export interface SelectOption {
20+
export interface SelectOption<T extends React.Key = string> {
2121
label: string;
22-
value: string;
22+
value: T;
2323
}
2424

2525
export interface SelectUIComponents {
@@ -34,10 +34,11 @@ export interface SelectUIComponents {
3434

3535
export type SelectContentProps = Pick<ComponentProps<typeof PopoverPrimitive.Content>, 'align' | 'side' | 'sideOffset'>;
3636

37-
export interface SelectProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onChange'> {
38-
options: SelectOption[];
39-
value?: string;
40-
onValueChange?: (value: string) => void;
37+
export interface SelectProps<T extends React.Key = string>
38+
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'value' | 'onChange'> {
39+
options: SelectOption<T>[];
40+
value?: T;
41+
onValueChange?: (value: T) => void;
4142
placeholder?: string;
4243
disabled?: boolean;
4344
className?: string;
@@ -50,7 +51,7 @@ export interface SelectProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonE
5051
searchInputProps?: React.ComponentPropsWithoutRef<typeof CommandInput>;
5152
// Creatable behavior
5253
creatable?: boolean;
53-
onCreateOption?: (input: string) => SelectOption | Promise<SelectOption>;
54+
onCreateOption?: (input: string) => SelectOption<T> | Promise<SelectOption<T>>;
5455
createOptionLabel?: (input: string) => string;
5556
}
5657

@@ -60,7 +61,7 @@ const DefaultSearchInput = forwardRef<HTMLInputElement, React.ComponentPropsWith
6061
);
6162
DefaultSearchInput.displayName = 'SelectSearchInput';
6263

63-
export function Select({
64+
export function Select<T extends React.Key = string>({
6465
options,
6566
value,
6667
onValueChange,
@@ -77,7 +78,7 @@ export function Select({
7778
onCreateOption,
7879
createOptionLabel,
7980
...buttonProps
80-
}: SelectProps) {
81+
}: SelectProps<T>) {
8182
const popoverState = useOverlayTriggerState({});
8283
const listboxId = useId();
8384
const triggerRef = useRef<HTMLButtonElement>(null);
@@ -132,7 +133,7 @@ export function Select({
132133
aria-controls={listboxId}
133134
{...buttonProps}
134135
>
135-
{value !== '' ? (selectedOption?.label ?? value) : placeholder}
136+
{value != null && value !== '' ? (selectedOption?.label ?? String(value)) : placeholder}
136137
<ChevronIcon className="w-4 h-4 opacity-50" />
137138
</Trigger>
138139
</PopoverTrigger>
@@ -175,8 +176,8 @@ export function Select({
175176
const isSelected = option.value === value;
176177
const commonProps = {
177178
'data-selected': isSelected ? 'true' : 'false',
178-
'data-value': option.value,
179-
'data-testid': `select-option-${option.value}`,
179+
'data-value': String(option.value),
180+
'data-testid': `select-option-${String(option.value)}`,
180181
} as const;
181182

182183
// When a custom Item is provided, use asChild to let it render as the actual item element
@@ -240,7 +241,7 @@ export function Select({
240241
const lower = q.toLowerCase();
241242
const hasExactMatch =
242243
q.length > 0 &&
243-
options.some((o) => o.label.toLowerCase() === lower || o.value.toLowerCase() === lower);
244+
options.some((o) => o.label.toLowerCase() === lower || String(o.value).toLowerCase() === lower);
244245
if (!creatable || !q || hasExactMatch) return null;
245246
const label = createOptionLabel?.(q) ?? `Select "${q}"`;
246247
return (
@@ -252,7 +253,7 @@ export function Select({
252253
onSelect={async () => {
253254
if (!onCreateOption) return;
254255
const created = await onCreateOption(q);
255-
if (created?.value) onValueChange?.(created.value);
256+
onValueChange?.(created.value);
256257
popoverState.close();
257258
}}
258259
className={cn(

0 commit comments

Comments
 (0)