Files
fn_registry/frontend/functions/ui/select.tsx
T
egutierrez 145a6fce8f refactor: migrar Select y SimpleSelect a native HTML select
Select reescrito de @base-ui/react primitives a <select> nativo con wrapper
para mantener la misma API visual (ChevronDown, estilos tema). SimpleSelect
actualizado para usar <select>/<optgroup> directamente sin intermediarios.
Checkbox corregido: import CheckboxIndicator separado reemplazado por
CheckboxPrimitive.Indicator para consistencia.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 15:02:24 +02:00

92 lines
2.8 KiB
TypeScript

"use client"
import * as React from "react"
import { cn } from "../core/cn"
import { ChevronDown } from "lucide-react"
// ── Native select wrapper ─────────────────────────────────────────────────
interface SelectProps extends React.ComponentPropsWithoutRef<"select"> {
placeholder?: string
}
const Select = React.forwardRef<HTMLSelectElement, SelectProps>(
({ className, children, placeholder, ...props }, ref) => {
return (
<div className="relative">
<select
ref={ref}
data-slot="select"
className={cn(
"flex h-8 w-full appearance-none items-center rounded-lg border border-input bg-transparent px-2.5 pr-8 py-1 text-sm transition-colors outline-none",
"focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50",
"disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50",
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
className,
)}
{...props}
>
{placeholder && (
<option value="" disabled>
{placeholder}
</option>
)}
{children}
</select>
<ChevronDown className="pointer-events-none absolute right-2 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" />
</div>
)
},
)
Select.displayName = "Select"
// ── Sub-components (thin wrappers for API compatibility) ──────────────────
function SelectItem({
className,
...props
}: React.ComponentPropsWithoutRef<"option">) {
return <option className={className} {...props} />
}
function SelectGroup({
className,
...props
}: React.ComponentPropsWithoutRef<"optgroup">) {
return <optgroup className={className} {...props} />
}
function SelectGroupLabel(_props: { children?: React.ReactNode }) {
// optgroup uses `label` attr, this is a no-op for compatibility
return null
}
// Stubs for barrel export compatibility — these are no-ops with native select
function SelectContent({ children }: { children?: React.ReactNode; className?: string }) {
return <>{children}</>
}
function SelectTrigger({ children }: { children?: React.ReactNode; className?: string }) {
return <>{children}</>
}
function SelectValue(_props: { placeholder?: string }) {
return null
}
function SelectPortal({ children }: { children?: React.ReactNode }) {
return <>{children}</>
}
function SelectSeparator({ className, ...props }: React.ComponentProps<"div">) {
return <div className={cn("-mx-1 my-1 h-px bg-muted", className)} {...props} />
}
export {
Select,
SelectContent,
SelectGroup,
SelectGroupLabel,
SelectItem,
SelectPortal,
SelectSeparator,
SelectTrigger,
SelectValue,
}