From c116ac21671b0b9e0ce2be0968529f5429eaef50 Mon Sep 17 00:00:00 2001 From: dongmucat <1127093059@qq.com> Date: Fri, 20 Mar 2026 11:17:06 +0800 Subject: [PATCH] fix(web): keep shared select native wrapper --- web/src/shared/ui/select.test.ts | 12 +++++++++--- web/src/shared/ui/select.tsx | 28 +++++++++++++++++++++++----- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/web/src/shared/ui/select.test.ts b/web/src/shared/ui/select.test.ts index 341fc3bd..66992f6e 100644 --- a/web/src/shared/ui/select.test.ts +++ b/web/src/shared/ui/select.test.ts @@ -10,8 +10,12 @@ describe('shared select contract', () => { it('keeps the trigger aligned with the existing input styling language', () => { expect(SELECT_TRIGGER_CLASS_NAME).toContain('h-11') expect(SELECT_TRIGGER_CLASS_NAME).toContain('rounded-lg') - expect(SELECT_TRIGGER_CLASS_NAME).toContain('border-border') - expect(SELECT_TRIGGER_CLASS_NAME).toContain('focus:ring-primary/40') + expect(SELECT_TRIGGER_CLASS_NAME).toContain('border-border/60') + expect(SELECT_TRIGGER_CLASS_NAME).toContain('bg-secondary/50') + expect(SELECT_TRIGGER_CLASS_NAME).toContain('focus-visible:outline-none') + expect(SELECT_TRIGGER_CLASS_NAME).toContain('focus-visible:ring-2') + expect(SELECT_TRIGGER_CLASS_NAME).toContain('focus-visible:ring-primary/40') + expect(SELECT_TRIGGER_CLASS_NAME).toContain('focus-visible:border-primary/50') }) it('uses themed panel and item classes for the floating listbox', () => { @@ -21,8 +25,10 @@ describe('shared select contract', () => { expect(SELECT_ITEM_CLASS_NAME).toContain('data-[disabled]:opacity-50') }) - it('maps empty string form state to an undefined Radix value', () => { + it('maps empty and nullish form state to an undefined Radix value', () => { expect(normalizeSelectValue('')).toBeUndefined() + expect(normalizeSelectValue(null)).toBeUndefined() + expect(normalizeSelectValue(undefined)).toBeUndefined() expect(normalizeSelectValue('PUBLIC')).toBe('PUBLIC') }) }) diff --git a/web/src/shared/ui/select.tsx b/web/src/shared/ui/select.tsx index 6eaf2ffd..f2726e01 100644 --- a/web/src/shared/ui/select.tsx +++ b/web/src/shared/ui/select.tsx @@ -1,10 +1,10 @@ -import * as SelectPrimitive from '@radix-ui/react-select' +import * as React from 'react' import { cn } from '@/shared/lib/utils' export const SELECT_TRIGGER_CLASS_NAME = cn( - 'flex h-11 w-full items-center justify-between rounded-lg border border-border bg-white px-4 py-2 text-sm text-foreground', + 'flex h-11 w-full rounded-lg border border-border/60 bg-secondary/50 px-4 py-2 text-sm text-foreground', 'ring-offset-background transition-all duration-200', - 'placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/40 focus:border-primary/50', + 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:border-primary/50', 'disabled:cursor-not-allowed disabled:opacity-50' ) @@ -18,7 +18,25 @@ export const SELECT_ITEM_CLASS_NAME = cn( ) export function normalizeSelectValue(value?: string | null) { - return value && value.length > 0 ? value : undefined + return typeof value === 'string' && value.length > 0 ? value : undefined } -export const Select = SelectPrimitive.Root +interface SelectProps extends React.SelectHTMLAttributes {} + +const Select = React.forwardRef( + ({ className, children, ...props }, ref) => { + return ( + + ) + } +) + +Select.displayName = 'Select' + +export { Select }