Primitives
Native select
Native select control styled to match the Control UI control family.
Composition
Native options
- <NativeSelect>
- <optgroup>
- <option />
- <optgroup>
Installation
First install and activate one skin. Core deliberately contains no visual token defaults.
The Control UI source installs this primitive from src/registry/sources/control-ui/ui/native-select.tsx.
npx shadcn@latest add https://control-ui.dev/r/native-select.jsonDependencies
Control variants
src/registry/sources/control-ui/control-variants.tsSupportRaw code
Primary installed source
"use client";import { Input as InputPrimitive } from "@base-ui/react/input";import type { ComponentProps, CSSProperties } from "react";import type { ControlSize } from "@/components/control-ui/control-variants";import type { FieldKnobStyle } from "@/components/control-ui/knob-contracts/field-knobs";import { cn } from "@/components/control-ui/lib/cn";export type NativeSelectProps = Omit<Omit<ComponentProps<"select">, "size">, "style"> & { style?: CSSProperties & FieldKnobStyle } & { size?: ControlSize;};export function NativeSelect({ ref, id, name, value, defaultValue, disabled, autoFocus, size = "md", className, children, ...props}: NativeSelectProps) { return ( <div data-control-family="field" data-field-kind="native-select" className="relative inline-flex w-full items-center"> <InputPrimitive ref={ref} id={id} name={name} value={value} defaultValue={defaultValue} disabled={disabled} autoFocus={autoFocus} render={ <select {...props} data-control-ui="native-select" data-field-kind="native-select" data-slot="root" data-size={size} data-control-family="field" data-control="true" className={cn("w-full min-w-0 cursor-pointer", className)} > {children} </select> } /> <span aria-hidden="true" data-control-ui="native-select" data-control-family="field" data-field-kind="native-select" data-slot="icon" className="pointer-events-none absolute" > <svg viewBox="0 0 12 12" className="size-3" aria-hidden="true" fill="none"> <path d="M3 4.5 6 7.5 9 4.5" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round" strokeLinejoin="round" /> </svg> </span> </div> );}Knobs
Typed custom properties the recipe paints with. Set one on the root — style, a utility class, or a skin — and every slot inherits it.
--cui-field-* · 15 knobsHow the cascade resolves--cui-field-radius<length-percentage>var(--nest-radius, var(--radius-control))--cui-field-background<color>var(--control-fill)--cui-field-hover-background<color>var(--hover-fill)--cui-field-affordance-background<color>transparent--cui-field-affordance-shadow*0 0 transparent--cui-field-affordance-foreground<color>var(--muted-foreground)--cui-field-affordance-hover-background<color>var(--hover-fill)--cui-field-foreground<color>var(--foreground)--cui-field-border-color<color>var(--control-rim)--cui-field-border-width<length>var(--control-rim-width)--cui-field-shadow*var(--shadow-inset)--cui-field-backdrop-filter*blur(0px)--cui-field-height<length-percentage>var(--control-h-md)--cui-field-padding-inline<length-percentage>var(--padding-x)--cui-field-font-size<length-percentage>var(--text-body)