{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "native-select",
  "type": "registry:component",
  "title": "Native select",
  "description": "Presents browser-native options inside a 1px control border.",
  "registryDependencies": [
    "https://vlak.dev/r/vlak-base.json",
    "https://vlak.dev/r/inter.json",
    "https://vlak.dev/r/icons.json",
    "https://vlak.dev/r/vlak-lib.json",
    "https://vlak.dev/r/field.json"
  ],
  "dependencies": [
    "@stylexjs/stylex"
  ],
  "devDependencies": [
    "@stylexjs/babel-plugin"
  ],
  "docs": "Vlak leaves are StyleX. Compile them with @stylexjs/babel-plugin (Vite: @stylexjs/unplugin, Next: @stylexjs/nextjs-plugin). If you would rather not run a compiler, import @noorddev/vlak-react instead: it ships precompiled with one stylesheet.",
  "files": [
    {
      "path": "vlak/native-select.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport { vlak, mq } from \"./tokens.stylex\";\nimport { rs } from \"./rs\";\nimport { useFieldControl } from \"./field\";\nimport { Icon } from \"./icons\";\n\nexport interface NativeSelectProps extends React.SelectHTMLAttributes<HTMLSelectElement> {\n  label?: React.ReactNode;\n}\n\nconst styles = stylex.create({\n  control: {\n    position: \"relative\",\n    width: \"100%\",\n  },\n  icon: {\n    position: \"absolute\",\n    insetInlineEnd: \"0.75rem\",\n    top: \"50%\",\n    marginTop: \"-0.5rem\",\n    color: vlak.ink,\n    pointerEvents: \"none\",\n  },\n  field: {\n    width: \"100%\",\n    display: \"flex\",\n    flexDirection: \"column\",\n    gap: \"0.5rem\",\n  },\n  label: {\n    fontSize: {\n      default: \"0.75rem\",\n      [mq.phone]: vlak.controlLabel,\n    },\n    fontWeight: 600,\n    color: vlak.gray,\n    letterSpacing: \"-0.01em\",\n    lineHeight: \"16px\",\n  },\n  select: {\n    appearance: \"none\",\n    WebkitAppearance: \"none\",\n    boxSizing: \"border-box\",\n    height: vlak.controlH,\n    minHeight: {\n      default: null,\n      [mq.phone]: vlak.hit,\n    },\n    fontFamily: \"inherit\",\n    fontSize: {\n      default: \"0.875rem\",\n      [mq.phone]: \"1rem\",\n    },\n    fontWeight: 500,\n    letterSpacing: \"-0.01em\",\n    lineHeight: `calc(${vlak.controlH} - 2px)`,\n    color: \"var(--text)\",\n    caretColor: \"var(--text)\",\n    backgroundColor: \"var(--bg)\",\n    borderWidth: vlak.hairline,\n    borderStyle: \"solid\",\n    borderColor: {\n      default: vlak.controlBorder,\n      \":focus\": vlak.accent,\n    },\n    borderRadius: {\n      default: vlak.radiusSm,\n      [mq.phone]: vlak.radiusSm,\n    },\n    paddingBlock: 0,\n    paddingInlineStart: {\n      default: \"0.625rem\",\n      [mq.phone]: \"0.875rem\",\n    },\n    paddingInlineEnd: {\n      default: \"2rem\",\n      [mq.phone]: \"2.25rem\",\n    },\n    outlineWidth: {\n      default: 0,\n      \":focus-visible\": 2,\n    },\n    outlineStyle: {\n      default: \"none\",\n      \":focus-visible\": \"solid\",\n    },\n    outlineColor: vlak.ink,\n    outlineOffset: 2,\n    width: \"100%\",\n  },\n  invalid: {\n    borderColor: vlak.ink,\n  },\n});\n\n/** The platform list. Vlak chrome. */\nexport const NativeSelect = React.forwardRef<HTMLSelectElement, NativeSelectProps>(\n  function NativeSelect({ label, className, style, id, children, ...props }, ref) {\n    const autoId = React.useId();\n    const selectId = id ?? autoId;\n    const field = useFieldControl(props);\n    const invalid = field.invalid;\n    const sx = rs([\"rs-native-select\", invalid && \"rs-native-select-invalid\", className], styles.select, invalid && styles.invalid);\n    const wrap = rs([\"rs-native-select-control\"], styles.control);\n    const icon = rs([\"rs-native-select-icon\"], styles.icon);\n    const control = (\n      <div className={wrap.className} style={wrap.style}>\n      <select\n        ref={ref}\n        id={selectId}\n        {...props}\n        aria-describedby={field[\"aria-describedby\"]}\n        aria-invalid={field[\"aria-invalid\"]}\n        className={sx.className}\n        style={{ ...sx.style, ...style }}\n      >\n        {children}\n      </select>\n      <Icon name=\"chevron-right\" rotate={90} className={icon.className} style={icon.style} />\n      </div>\n    );\n    if (label == null) return control;\n    const stack = rs([\"rs-field\", \"rs-native-select-field\"], styles.field);\n    const lab = rs([\"rs-field-label\", \"rs-native-select-label\"], styles.label);\n    return (\n      <div className={stack.className} style={stack.style}>\n        <label className={lab.className} style={lab.style} htmlFor={selectId}>\n          {label}\n        </label>\n        {control}\n      </div>\n    );\n  },\n);\n",
      "type": "registry:component",
      "target": "components/vlak/native-select.tsx"
    },
    {
      "path": "vlak/styles/native-select.css",
      "content": "/* ── native-select: generated from packages/react/src/components/native-select.tsx ── */\n.rs-native-select-control{position:relative;width:100%}\n.rs-native-select-icon{position:absolute;inset-inline-end:0.75rem;top:50%;margin-top:-0.5rem;color:var(--text);pointer-events:none}\n.rs-field.rs-native-select-field{width:100%;display:flex;flex-direction:column;gap:0.5rem}\n.rs-field-label.rs-native-select-label{font-size:0.75rem;font-weight:600;color:var(--text-secondary);letter-spacing:-0.01em;line-height:16px}\n@media (max-width: 640px){.rs-field-label.rs-native-select-label{font-size:var(--control-label)}}\n.rs-native-select{appearance:none;-webkit-appearance:none;box-sizing:border-box;height:var(--control-h);font-family:inherit;font-size:0.875rem;font-weight:500;letter-spacing:-0.01em;line-height:calc(var(--control-h) - 2px);color:var(--text);caret-color:var(--text);background-color:var(--bg);border-width:1px;border-style:solid;border-color:var(--control-border);border-radius:var(--radius-sm);padding-block:0;padding-inline-start:0.625rem;padding-inline-end:2rem;outline-width:0;outline-style:none;outline-color:var(--text);outline-offset:2px;width:100%}\n.rs-native-select:focus{border-color:var(--accent)}\n.rs-native-select:focus-visible{outline-width:2px;outline-style:solid}\n@media (max-width: 640px){.rs-native-select{min-height:var(--hit);font-size:1rem;border-radius:var(--radius-sm);padding-inline-start:0.875rem;padding-inline-end:2.25rem}}\n.rs-native-select-invalid{border-color:var(--text)}\n",
      "type": "registry:file",
      "target": "styles/vlak/native-select.css"
    }
  ],
  "meta": {
    "vlak": {
      "category": "forms",
      "classes": [
        "rs-native-select",
        "rs-native-select-invalid",
        "rs-native-select-field",
        "rs-native-select-label",
        "rs-native-select-control",
        "rs-native-select-icon"
      ],
      "snippet": "<div class=\"rs-native-select-control\"><select class=\"rs-native-select\" aria-label=\"City\"><option>Alkmaar</option><option>Amsterdam</option><option>Rotterdam</option></select><svg class=\"rs-native-select-icon rs-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" aria-hidden=\"true\"><path d=\"M5.5 3.75 L10.5 8.25 L5.5 12.75\" transform=\"rotate(90 8 8)\" vector-effect=\"non-scaling-stroke\" /></svg></div>",
      "cssOnly": false,
      "registryDependencies": [
        "icons",
        "vlak-lib",
        "field"
      ],
      "aliases": [
        "Native select",
        "Select element",
        "Dropdown",
        "HTML select"
      ],
      "example": "import { NativeSelect } from \"@noorddev/vlak-react\";\n\n<NativeSelect label=\"City\" defaultValue=\"alkmaar\">\n  <option value=\"alkmaar\">Alkmaar</option>\n  <option value=\"amsterdam\">Amsterdam</option>\n  <option value=\"rotterdam\">Rotterdam</option>\n</NativeSelect>",
      "usage": {
        "use": [
          "A short fixed list where the platform picker is fine, especially on phones.",
          "Forms that post natively; the value travels with the form."
        ],
        "avoid": [
          "Rich option labels or type-ahead over long lists; use Select or Combobox.",
          "Fewer than three options; use Radio."
        ]
      },
      "keyboard": [
        {
          "keys": "Space, Alt + Arrow down",
          "does": "Opens the platform list"
        },
        {
          "keys": "Arrow up, Arrow down",
          "does": "Changes the value"
        },
        {
          "keys": "Type a letter",
          "does": "Jumps to a matching option"
        }
      ],
      "a11y": [
        "Renders a native <select> with a generated id; label renders a <label> pointing at it.",
        "Inside Field, hint and error reach it through aria-describedby and aria-invalid."
      ]
    }
  }
}
