桌面应用(Tauri+React+SQLite):时间线/记录/学年学科成绩梯度/统计/类型与字段模板/附件内容寻址/详情视图/PWA 同步服务端(sync-server):多用户+邀请码/LWW推拉/seq游标/附件去重/Docker部署 多端同步地基:uuid v7/HLC混合逻辑时钟/软删除墓碑/sync_oplog,Node与Rust双端一致并通过自动化测试
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
import { forwardRef, type SelectHTMLAttributes } from 'react';
|
|
import { ChevronDown } from 'lucide-react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
export interface Option { value: string; label: string; }
|
|
|
|
export const Select = forwardRef<HTMLSelectElement, SelectHTMLAttributes<HTMLSelectElement> & { options?: Option[] }>(
|
|
function Select({ className, options, children, ...props }, ref) {
|
|
return (
|
|
<div className={cn('relative', className ? className.split(' ').filter(c => /^w-|^min-w|^flex-/.test(c)).join(' ') : '')}>
|
|
<select
|
|
ref={ref}
|
|
className={cn(
|
|
'w-full h-8 appearance-none rounded-md border border-line bg-surface pl-2.5 pr-7 text-[13px] text-ink-1',
|
|
'transition-colors hover:border-line-strong focus:border-brand focus:outline-none disabled:opacity-50',
|
|
className
|
|
)}
|
|
{...props}
|
|
>
|
|
{options
|
|
? options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)
|
|
: children}
|
|
</select>
|
|
<ChevronDown size={14} className="pointer-events-none absolute right-2 top-1/2 -translate-y-1/2 text-ink-3" />
|
|
</div>
|
|
);
|
|
}
|
|
);
|