@cloudflare/kumo 1.13.1 → 1.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/ai/component-registry.json +57 -30
- package/ai/component-registry.md +247 -19
- package/ai/schemas.ts +3 -2
- package/dist/.build-complete +1 -1
- package/dist/ai/schemas.d.ts +10 -2
- package/dist/ai/schemas.d.ts.map +1 -1
- package/dist/ai/schemas.js +175 -173
- package/dist/ai/schemas.js.map +1 -1
- package/dist/chunks/Legend-mkh1v83sz972e29d.js +407 -0
- package/dist/chunks/Legend-mkh1v83sz972e29d.js.map +1 -0
- package/dist/chunks/{breadcrumbs-e564gabk59go37cg.js → breadcrumbs-gr907zcoo65rpn90.js} +2 -2
- package/dist/chunks/{breadcrumbs-e564gabk59go37cg.js.map → breadcrumbs-gr907zcoo65rpn90.js.map} +1 -1
- package/dist/chunks/{button-b1yp3lbrhjr9eg07.js → button-d82sexqgnd834eaa.js} +2 -2
- package/dist/chunks/{button-b1yp3lbrhjr9eg07.js.map → button-d82sexqgnd834eaa.js.map} +1 -1
- package/dist/chunks/{checkbox-khvh0efmlzvlo6qi.js → checkbox-f4qsbq6xycaji7qw.js} +3 -3
- package/dist/chunks/{checkbox-khvh0efmlzvlo6qi.js.map → checkbox-f4qsbq6xycaji7qw.js.map} +1 -1
- package/dist/chunks/{clipboard-text-jvrlvyz5ulm49h5b.js → clipboard-text-fvggzgqrza82t5om.js} +4 -4
- package/dist/chunks/{clipboard-text-jvrlvyz5ulm49h5b.js.map → clipboard-text-fvggzgqrza82t5om.js.map} +1 -1
- package/dist/chunks/{combobox-i3mdp6f01dvpoc5j.js → combobox-om4zw74o076sa00p.js} +61 -50
- package/dist/chunks/combobox-om4zw74o076sa00p.js.map +1 -0
- package/dist/chunks/{command-palette-l8dym46a74o7j8ci.js → command-palette-ejoszjfivybu9yi5.js} +3 -3
- package/dist/chunks/{command-palette-l8dym46a74o7j8ci.js.map → command-palette-ejoszjfivybu9yi5.js.map} +1 -1
- package/dist/chunks/{dialog-emk68n0piw8u7hkb.js → dialog-gkmecnx48ge38jrr.js} +11 -11
- package/dist/chunks/dialog-gkmecnx48ge38jrr.js.map +1 -0
- package/dist/chunks/{dropdown-ejgjnn9gq3daua1h.js → dropdown-i8n7nv3cvkvb1x3e.js} +2 -2
- package/dist/chunks/{dropdown-ejgjnn9gq3daua1h.js.map → dropdown-i8n7nv3cvkvb1x3e.js.map} +1 -1
- package/dist/chunks/{empty-crbntv0dhud7besh.js → empty-h3qhwtx0z8arupc9.js} +2 -2
- package/dist/chunks/{empty-crbntv0dhud7besh.js.map → empty-h3qhwtx0z8arupc9.js.map} +1 -1
- package/dist/chunks/{field-ftrgblg9mbmz9eo3.js → field-lc4gr226y5aqlctf.js} +3 -3
- package/dist/chunks/{field-ftrgblg9mbmz9eo3.js.map → field-lc4gr226y5aqlctf.js.map} +1 -1
- package/dist/chunks/input-area-ce3bf8m8wvot44kg.js +74 -0
- package/dist/chunks/input-area-ce3bf8m8wvot44kg.js.map +1 -0
- package/dist/chunks/{input-group-g6qyhe5jvpe02hee.js → input-group-kttdor9mr32k289o.js} +3 -3
- package/dist/chunks/{input-group-g6qyhe5jvpe02hee.js.map → input-group-kttdor9mr32k289o.js.map} +1 -1
- package/dist/chunks/{input-me56hug8sl0u650q.js → input-nvne68upfj8b2bk6.js} +20 -20
- package/dist/chunks/input-nvne68upfj8b2bk6.js.map +1 -0
- package/dist/chunks/{label-eooot7dhtfvw7n3x.js → label-e42o95ab0dxmchxb.js} +3 -3
- package/dist/chunks/{label-eooot7dhtfvw7n3x.js.map → label-e42o95ab0dxmchxb.js.map} +1 -1
- package/dist/chunks/{layer-card-8azgeai6zsrdbeoj.js → layer-card-mu2w82x6ko1nhhtr.js} +7 -7
- package/dist/chunks/{layer-card-8azgeai6zsrdbeoj.js.map → layer-card-mu2w82x6ko1nhhtr.js.map} +1 -1
- package/dist/chunks/{link-moetfdbgxda0yhwg.js → link-lpzl5s47pmobk361.js} +2 -2
- package/dist/chunks/{link-moetfdbgxda0yhwg.js.map → link-lpzl5s47pmobk361.js.map} +1 -1
- package/dist/chunks/{menubar-c2zwv4mbo3xqq7is.js → menubar-ifxxdoa35zz79z1q.js} +2 -2
- package/dist/chunks/{menubar-c2zwv4mbo3xqq7is.js.map → menubar-ifxxdoa35zz79z1q.js.map} +1 -1
- package/dist/chunks/{meter-em2hfu8j2rhmf5ae.js → meter-fbtqfg0okpwmaiju.js} +2 -2
- package/dist/chunks/{meter-em2hfu8j2rhmf5ae.js.map → meter-fbtqfg0okpwmaiju.js.map} +1 -1
- package/dist/chunks/{pagination-xt93wvwvow4z44lc.js → pagination-owm6h66jjgv1tjoe.js} +3 -3
- package/dist/chunks/{pagination-xt93wvwvow4z44lc.js.map → pagination-owm6h66jjgv1tjoe.js.map} +1 -1
- package/dist/chunks/{popover-irccwetx73p8pnua.js → popover-dd7hi5ajeoq9od1i.js} +2 -2
- package/dist/chunks/{popover-irccwetx73p8pnua.js.map → popover-dd7hi5ajeoq9od1i.js.map} +1 -1
- package/dist/chunks/radio-ff1csb328f12smd4.js +200 -0
- package/dist/chunks/radio-ff1csb328f12smd4.js.map +1 -0
- package/dist/chunks/{select-jxxef2rf76pgdrf8.js → select-go7a0z3evkh9cfxq.js} +41 -34
- package/dist/chunks/select-go7a0z3evkh9cfxq.js.map +1 -0
- package/dist/chunks/{sensitive-input-i7ey1w0ky7nco012.js → sensitive-input-gtzk3vit4i35n95g.js} +34 -34
- package/dist/chunks/sensitive-input-gtzk3vit4i35n95g.js.map +1 -0
- package/dist/chunks/switch-cpbp0i75jnazkani.js +241 -0
- package/dist/chunks/switch-cpbp0i75jnazkani.js.map +1 -0
- package/dist/chunks/{table-d4ql7fjvok30xs1f.js → table-g41yb7ruredizqr8.js} +3 -3
- package/dist/chunks/table-g41yb7ruredizqr8.js.map +1 -0
- package/dist/chunks/{tabs-n3rcvuzx0gbslyy6.js → tabs-hy6oa7xtf96d9mxt.js} +27 -27
- package/dist/chunks/{tabs-n3rcvuzx0gbslyy6.js.map → tabs-hy6oa7xtf96d9mxt.js.map} +1 -1
- package/dist/chunks/{toast-j05qj3vk688ht1i1.js → toast-j5gtfc50xpzzd0hc.js} +3 -3
- package/dist/chunks/{toast-j05qj3vk688ht1i1.js.map → toast-j5gtfc50xpzzd0hc.js.map} +1 -1
- package/dist/chunks/{tooltip-es2dwwbhftg4k2jy.js → tooltip-k68wcv9mrigb7rcb.js} +2 -2
- package/dist/chunks/{tooltip-es2dwwbhftg4k2jy.js.map → tooltip-k68wcv9mrigb7rcb.js.map} +1 -1
- package/dist/chunks/{vendor-base-ui-kxxocm122zr4pipe.js → vendor-base-ui-cpvkrhz4zgw9nw2b.js} +18 -18
- package/dist/chunks/{vendor-base-ui-kxxocm122zr4pipe.js.map → vendor-base-ui-cpvkrhz4zgw9nw2b.js.map} +1 -1
- package/dist/code.js +1 -1
- package/dist/code.js.map +1 -1
- package/dist/components/breadcrumbs.js +1 -1
- package/dist/components/button.js +1 -1
- package/dist/components/chart.js +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/clipboard-text.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/command-palette.js +1 -1
- package/dist/components/dialog.js +1 -1
- package/dist/components/dropdown.js +1 -1
- package/dist/components/empty.js +1 -1
- package/dist/components/field.js +1 -1
- package/dist/components/flow.js +1435 -1431
- package/dist/components/flow.js.map +1 -1
- package/dist/components/input.js +3 -3
- package/dist/components/label.js +1 -1
- package/dist/components/layer-card.js +1 -1
- package/dist/components/link.js +1 -1
- package/dist/components/menubar.js +1 -1
- package/dist/components/meter.js +1 -1
- package/dist/components/pagination.js +1 -1
- package/dist/components/popover.js +1 -1
- package/dist/components/radio.js +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/sensitive-input.js +1 -1
- package/dist/components/switch.js +1 -1
- package/dist/components/table.js +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/toast.js +2 -2
- package/dist/components/tooltip.js +1 -1
- package/dist/index.js +70 -69
- package/dist/primitives/accordion.js +1 -1
- package/dist/primitives/alert-dialog.js +1 -1
- package/dist/primitives/autocomplete.js +1 -1
- package/dist/primitives/avatar.js +1 -1
- package/dist/primitives/button.js +1 -1
- package/dist/primitives/checkbox-group.js +1 -1
- package/dist/primitives/checkbox.js +1 -1
- package/dist/primitives/collapsible.js +1 -1
- package/dist/primitives/combobox.js +1 -1
- package/dist/primitives/context-menu.js +1 -1
- package/dist/primitives/csp-provider.js +1 -1
- package/dist/primitives/dialog.js +1 -1
- package/dist/primitives/direction-provider.js +1 -1
- package/dist/primitives/drawer.js +1 -1
- package/dist/primitives/field.js +1 -1
- package/dist/primitives/fieldset.js +1 -1
- package/dist/primitives/form.js +1 -1
- package/dist/primitives/input.js +1 -1
- package/dist/primitives/menu.js +1 -1
- package/dist/primitives/menubar.js +1 -1
- package/dist/primitives/meter.js +1 -1
- package/dist/primitives/navigation-menu.js +1 -1
- package/dist/primitives/number-field.js +1 -1
- package/dist/primitives/popover.js +1 -1
- package/dist/primitives/preview-card.js +1 -1
- package/dist/primitives/progress.js +1 -1
- package/dist/primitives/radio-group.js +1 -1
- package/dist/primitives/radio.js +1 -1
- package/dist/primitives/scroll-area.js +1 -1
- package/dist/primitives/select.js +1 -1
- package/dist/primitives/separator.js +1 -1
- package/dist/primitives/slider.js +1 -1
- package/dist/primitives/switch.js +1 -1
- package/dist/primitives/tabs.js +1 -1
- package/dist/primitives/toast.js +1 -1
- package/dist/primitives/toggle-group.js +1 -1
- package/dist/primitives/toggle.js +1 -1
- package/dist/primitives/toolbar.js +1 -1
- package/dist/primitives/tooltip.js +1 -1
- package/dist/primitives.js +1 -1
- package/dist/scripts/theme-generator/config.d.ts.map +1 -1
- package/dist/scripts/theme-generator/config.js +12 -3
- package/dist/scripts/theme-generator/config.js.map +1 -1
- package/dist/src/code/code-highlighted.d.ts +2 -2
- package/dist/src/code/code-highlighted.d.ts.map +1 -1
- package/dist/src/code/provider.d.ts +2 -2
- package/dist/src/code/provider.d.ts.map +1 -1
- package/dist/src/components/chart/EChart.d.ts +7 -2
- package/dist/src/components/chart/EChart.d.ts.map +1 -1
- package/dist/src/components/combobox/combobox.d.ts.map +1 -1
- package/dist/src/components/flow/diagram.d.ts.map +1 -1
- package/dist/src/components/input/input-area.d.ts.map +1 -1
- package/dist/src/components/radio/index.d.ts +1 -1
- package/dist/src/components/radio/index.d.ts.map +1 -1
- package/dist/src/components/radio/radio.d.ts +43 -4
- package/dist/src/components/radio/radio.d.ts.map +1 -1
- package/dist/src/components/select/select.d.ts.map +1 -1
- package/dist/src/components/switch/switch.d.ts +8 -8
- package/dist/src/components/switch/switch.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/styles/kumo-binding.css +5 -0
- package/dist/styles/kumo-standalone.css +1 -1
- package/dist/styles/theme-kumo.css +7 -0
- package/package.json +3 -6
- package/scripts/theme-generator/config.ts +12 -3
- package/dist/chunks/Legend-fu32ev5ph2ehbfzy.js +0 -402
- package/dist/chunks/Legend-fu32ev5ph2ehbfzy.js.map +0 -1
- package/dist/chunks/combobox-i3mdp6f01dvpoc5j.js.map +0 -1
- package/dist/chunks/dialog-emk68n0piw8u7hkb.js.map +0 -1
- package/dist/chunks/input-area-hxtyrqpp44m18j72.js +0 -59
- package/dist/chunks/input-area-hxtyrqpp44m18j72.js.map +0 -1
- package/dist/chunks/input-me56hug8sl0u650q.js.map +0 -1
- package/dist/chunks/radio-394mfs3au5m8cgd8.js +0 -125
- package/dist/chunks/radio-394mfs3au5m8cgd8.js.map +0 -1
- package/dist/chunks/select-jxxef2rf76pgdrf8.js.map +0 -1
- package/dist/chunks/sensitive-input-i7ey1w0ky7nco012.js.map +0 -1
- package/dist/chunks/switch-b0xo8fxsfzv87krj.js +0 -257
- package/dist/chunks/switch-b0xo8fxsfzv87krj.js.map +0 -1
- package/dist/chunks/table-d4ql7fjvok30xs1f.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-go7a0z3evkh9cfxq.js","sources":["../../src/components/select/select.tsx"],"sourcesContent":["import { Select as SelectBase } from \"@base-ui/react/select\";\nimport { CaretUpDownIcon, CheckIcon } from \"@phosphor-icons/react\";\nimport { useId } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { buttonVariants } from \"../button\";\nimport { SkeletonLine } from \"../loader\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\n/** Select variant definitions (currently empty, reserved for future additions). */\nexport const KUMO_SELECT_VARIANTS = {\n // Select currently has no variant options but structure is ready for future additions\n} as const;\n\nexport const KUMO_SELECT_DEFAULT_VARIANTS = {} as const;\n\n/**\n * Select component styling metadata for Figma plugin code generation\n * Extracted from select.tsx implementation (source of truth)\n */\nexport const KUMO_SELECT_STYLING = {\n trigger: {\n height: 36, // h-9\n paddingX: 12, // px-3\n borderRadius: 8, // rounded-lg\n background: \"color-secondary\",\n text: \"text-color-surface\",\n ring: \"color-border\",\n fontSize: 16, // text-base\n fontWeight: 400, // font-normal\n },\n stateTokens: {\n focus: { ring: \"color-active\" },\n disabled: { opacity: 0.5 },\n },\n icons: {\n caret: { name: \"ph-caret-up-down\", size: 20 },\n check: { name: \"ph-check\", size: 20 },\n },\n popup: {\n background: \"color-secondary\",\n ring: \"color-border\",\n borderRadius: 8, // rounded-lg\n padding: 6, // p-1.5\n },\n option: {\n paddingX: 8, // px-2\n paddingY: 6, // py-1.5\n borderRadius: 4, // rounded\n fontSize: 16, // text-base\n highlightBackground: \"color-surface-secondary\",\n },\n} as const;\n\n// Derived types from KUMO_SELECT_VARIANTS\nexport interface KumoSelectVariantsProps {}\n\nexport function selectVariants(_props: KumoSelectVariantsProps = {}) {\n return cn(\n buttonVariants(),\n \"justify-between font-normal\",\n \"focus:opacity-100 focus-visible:ring-1 focus-visible:ring-kumo-ring *:in-focus:opacity-100\",\n );\n}\n\n/**\n * Normalizes items to array format for Base UI.\n * Object maps are converted to array format so Base UI can properly\n * handle value matching and placeholder display.\n */\nfunction normalizeItems<T>(\n items:\n | Record<string, ReactNode>\n | ReadonlyArray<{ label: ReactNode; value: T }>,\n): ReadonlyArray<{ label: ReactNode; value: T }> {\n if (Array.isArray(items)) {\n return items;\n }\n // Convert object map to array format\n return Object.entries(items).map(([key, label]) => ({\n value: key as T,\n label,\n }));\n}\n\n/**\n * Auto-generates Select.Option elements from items prop.\n * Only used when children are not explicitly provided.\n * Filters out null values (typically used for placeholders).\n */\nfunction renderOptionsFromItems<T>(\n items:\n | Record<string, ReactNode>\n | ReadonlyArray<{ label: ReactNode; value: T }>,\n): ReactNode {\n const normalizedItems = normalizeItems(items);\n\n // Filter out null values and render options\n return normalizedItems\n .filter((item) => item.value !== null)\n .map((item, index) => (\n <Option\n key={typeof item.value === \"string\" ? item.value : `option-${index}`}\n value={item.value}\n >\n {item.label}\n </Option>\n ));\n}\n\ntype SelectPropsGeneric<\n T,\n Multiple extends boolean | undefined = false,\n> = SelectBase.Root.Props<T, Multiple> &\n KumoSelectVariantsProps & {\n multiple?: Multiple;\n renderValue?: (value: Multiple extends true ? T[] : T) => ReactNode;\n className?: string;\n /**\n * Label content for the select.\n * When provided, enables the Field wrapper with a visible label.\n * For accessibility without a visible label, use `aria-label` instead.\n */\n label?: ReactNode;\n /**\n * @deprecated Use `aria-label` for hidden labels instead of `label` + `hideLabel={true}`.\n * When `label` is provided without `hideLabel`, the label is now visible by default (matching Input behavior).\n * This prop will be removed in a future version.\n */\n hideLabel?: boolean;\n placeholder?: string;\n loading?: boolean;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the select */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n };\n\n/**\n * Select component props.\n *\n * **Accessible Name Required:** Select should have one of:\n * 1. `label` prop (recommended) - enables Field wrapper with visible label\n * 2. `aria-label` - for selects without visible label (accessibility-only)\n * 3. `aria-labelledby` - for custom label association\n *\n * @example\n * ```tsx\n * // With visible label (recommended)\n * <Select label=\"Country\" onValueChange={setValue}>\n * <Select.Option value=\"us\">United States</Select.Option>\n * <Select.Option value=\"uk\">United Kingdom</Select.Option>\n * </Select>\n *\n * // Without visible label (use aria-label for accessibility)\n * <Select aria-label=\"Select a country\" onValueChange={setValue}>\n * <Select.Option value=\"us\">United States</Select.Option>\n * </Select>\n * ```\n */\nexport interface SelectProps {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /**\n * Label content for the select.\n * When provided, enables the Field wrapper with a visible label above the select.\n * For accessibility without a visible label, use `aria-label` instead.\n */\n label?: ReactNode;\n /**\n * @deprecated Use `aria-label` for hidden labels instead of `label` + `hideLabel={true}`.\n * When `label` is provided without `hideLabel`, the label is now visible by default (matching Input behavior).\n * This prop will be removed in a future version.\n */\n hideLabel?: boolean;\n /** Placeholder text shown when no value is selected. */\n placeholder?: string;\n /** When `true`, shows a skeleton loader in place of the selected value. */\n loading?: boolean;\n /** Whether the select is disabled. */\n disabled?: boolean;\n /** Whether the select is required. When `false`, shows \"(optional)\" text. */\n required?: boolean;\n /** Tooltip content displayed next to the label via an info icon. */\n labelTooltip?: ReactNode;\n /** Currently selected value (controlled mode). */\n value?: unknown;\n /** Initial value for uncontrolled mode. */\n defaultValue?: unknown;\n /** Callback fired when the selected value changes. */\n onValueChange?: (value: unknown) => void;\n /** Enable multi-select mode. */\n multiple?: boolean;\n /** `Select.Option` elements to render in the dropdown. */\n children?: ReactNode;\n /** Helper text displayed below the select. */\n description?: ReactNode;\n /** Error message string or validation error object with `match` key. */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}\n\n/**\n * Dropdown for selecting a value from a list of options.\n * Wraps Base UI Select with Kumo styling and optional Field integration.\n *\n * @example\n * ```tsx\n * <Select label=\"Fruit\" onValueChange={setFruit}>\n * <Select.Option value=\"apple\">Apple</Select.Option>\n * <Select.Option value=\"banana\">Banana</Select.Option>\n * </Select>\n * ```\n */\nexport function Select<T, Multiple extends boolean | undefined = false>({\n children,\n className,\n renderValue,\n label,\n hideLabel,\n placeholder,\n loading,\n labelTooltip,\n description,\n error,\n required,\n ...props\n}: SelectPropsGeneric<T, Multiple> & { required?: boolean }) {\n const labelId = useId();\n const propLookup = props as Record<string, unknown>;\n const ariaLabel = propLookup[\"aria-label\"] as string | undefined;\n const ariaLabelledby = propLookup[\"aria-labelledby\"] as string | undefined;\n // For aria-label, use string label or placeholder (ReactNode labels can't be used for aria-label)\n const fallbackLabel = typeof label === \"string\" ? label : placeholder;\n\n // Deprecation warning for hideLabel\n if (process.env.NODE_ENV !== \"production\" && hideLabel !== undefined) {\n console.warn(\n \"[Kumo Select]: `hideLabel` is deprecated. For hidden labels, use `aria-label` instead of `label` + `hideLabel={true}`.\\n\" +\n \" Migration:\\n\" +\n ' - For visible labels: <Select label=\"Country\" /> (hideLabel no longer needed)\\n' +\n ' - For hidden labels: <Select aria-label=\"Select a country\" /> (remove label and hideLabel)',\n );\n }\n\n // New behavior: label presence determines Field wrapper visibility (like Input)\n // hideLabel is only respected for backward compatibility when explicitly set to true\n const useFieldWrapper = label && hideLabel !== true;\n const triggerLabelledBy = useFieldWrapper\n ? undefined\n : (ariaLabelledby ?? (label ? labelId : undefined));\n const triggerAriaLabel =\n ariaLabel ?? (!triggerLabelledBy ? fallbackLabel : undefined);\n\n // Normalize items to array format for Base UI compatibility\n // This fixes placeholder not showing with object map items\n const normalizedItems = props.items ? normalizeItems(props.items) : undefined;\n\n // Auto-render children from items if children not provided\n const renderedChildren =\n children ?? (props.items ? renderOptionsFromItems(props.items) : null);\n\n const selectControl = (\n <SelectBase.Root\n {...props}\n items={normalizedItems}\n disabled={loading || props.disabled}\n >\n <SelectBase.Trigger\n className={cn(\n buttonVariants(),\n \"justify-between font-normal\",\n \"focus:opacity-100 focus-visible:ring-1 focus-visible:ring-kumo-ring *:in-focus:opacity-100\",\n props.disabled && \"cursor-not-allowed opacity-50\",\n className,\n )}\n aria-label={triggerAriaLabel}\n aria-labelledby={triggerLabelledBy}\n >\n {loading ? (\n <SkeletonLine className=\"w-32\" />\n ) : (\n <SelectBase.Value\n placeholder={placeholder}\n className=\"min-w-0 truncate\"\n >\n {renderValue}\n </SelectBase.Value>\n )}\n <SelectBase.Icon className=\"flex shrink-0 items-center\">\n <CaretUpDownIcon />\n </SelectBase.Icon>\n </SelectBase.Trigger>\n <SelectBase.Portal>\n <SelectBase.Positioner>\n <SelectBase.Popup\n className={cn(\n \"overflow-hidden bg-kumo-base text-kumo-default\", // background\n \"rounded-lg shadow-lg ring ring-kumo-ring\", // border part\n // 3px adjustment to account for padding + border differences\n \"min-w-[calc(var(--anchor-width)+3px)] p-1.5\", // spacing\n )}\n >\n {renderedChildren}\n </SelectBase.Popup>\n </SelectBase.Positioner>\n </SelectBase.Portal>\n </SelectBase.Root>\n );\n\n // Use Field wrapper when label is provided and not hidden\n if (useFieldWrapper) {\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n description={description}\n error={\n error\n ? typeof error === \"string\"\n ? { message: error, match: true }\n : error\n : undefined\n }\n >\n {selectControl}\n </Field>\n );\n }\n\n // Render with standalone label when label is hidden (sr-only)\n // Still show description/error for accessibility and UX\n const normalizedError = error\n ? typeof error === \"string\"\n ? { message: error, match: true as const }\n : error\n : undefined;\n\n return (\n <div className=\"grid gap-2\">\n {label && (\n <span id={labelId} className=\"sr-only\">\n {label}\n </span>\n )}\n {selectControl}\n {normalizedError ? (\n <span className=\"text-sm text-kumo-danger\">\n {normalizedError.message}\n </span>\n ) : (\n description && (\n <span className=\"text-sm leading-snug text-kumo-subtle\">\n {description}\n </span>\n )\n )}\n </div>\n );\n}\n\ntype OptionProps<T> = {\n children: ReactNode;\n value: T;\n};\n\nfunction Option<T>({ children, value }: OptionProps<T>) {\n return (\n <SelectBase.Item\n value={value}\n className=\"group flex cursor-pointer items-center justify-between gap-2 rounded px-2 py-1.5 text-base data-highlighted:bg-kumo-tint\"\n >\n <SelectBase.ItemText>{children}</SelectBase.ItemText>\n <SelectBase.ItemIndicator>\n <CheckIcon />\n </SelectBase.ItemIndicator>\n </SelectBase.Item>\n );\n}\n\nSelect.Option = Option;\n"],"names":["normalizeItems","items","key","label","renderOptionsFromItems","item","index","jsx","Option","Select","children","className","renderValue","hideLabel","placeholder","loading","labelTooltip","description","error","required","props","labelId","useId","propLookup","ariaLabel","ariaLabelledby","fallbackLabel","useFieldWrapper","triggerLabelledBy","triggerAriaLabel","normalizedItems","renderedChildren","selectControl","jsxs","SelectBase.Root","SelectBase.Trigger","cn","buttonVariants","SkeletonLine","SelectBase.Value","SelectBase.Icon","CaretUpDownIcon","SelectBase.Portal","SelectBase.Positioner","SelectBase.Popup","Field","normalizedError","value","SelectBase.Item","SelectBase.ItemText","SelectBase.ItemIndicator","CheckIcon"],"mappings":";;;;;;;;;AAsEA,SAASA,EACPC,GAG+C;AAC/C,SAAI,MAAM,QAAQA,CAAK,IACdA,IAGF,OAAO,QAAQA,CAAK,EAAE,IAAI,CAAC,CAACC,GAAKC,CAAK,OAAO;AAAA,IAClD,OAAOD;AAAA,IACP,OAAAC;AAAA,EAAA,EACA;AACJ;AAOA,SAASC,EACPH,GAGW;AAIX,SAHwBD,EAAeC,CAAK,EAIzC,OAAO,CAACI,MAASA,EAAK,UAAU,IAAI,EACpC,IAAI,CAACA,GAAMC,MACV,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MAEC,OAAOH,EAAK;AAAA,MAEX,UAAAA,EAAK;AAAA,IAAA;AAAA,IAHD,OAAOA,EAAK,SAAU,WAAWA,EAAK,QAAQ,UAAUC,CAAK;AAAA,EAAA,CAKrE;AACL;AA2GO,SAASG,EAAwD;AAAA,EACtE,UAAAC;AAAA,EACA,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,OAAAT;AAAA,EACA,WAAAU;AAAA,EACA,aAAAC;AAAA,EACA,SAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA,OAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GAA6D;AAC3D,QAAMC,IAAUC,EAAA,GACVC,IAAaH,GACbI,IAAYD,EAAW,YAAY,GACnCE,IAAiBF,EAAW,iBAAiB,GAE7CG,IAAgB,OAAOvB,KAAU,WAAWA,IAAQW;AAG1D,EAAI,QAAQ,IAAI,aAAa,gBAAgBD,MAAc,UACzD,QAAQ;AAAA,IACN;AAAA,EAAA;AASJ,QAAMc,IAAkBxB,KAASU,MAAc,IACzCe,IAAoBD,IACtB,SACCF,MAAmBtB,IAAQkB,IAAU,SACpCQ,IACJL,MAAeI,IAAoC,SAAhBF,IAI/BI,IAAkBV,EAAM,QAAQpB,EAAeoB,EAAM,KAAK,IAAI,QAG9DW,IACJrB,MAAaU,EAAM,QAAQhB,EAAuBgB,EAAM,KAAK,IAAI,OAE7DY,IACJ,gBAAAC;AAAA,IAACC;AAAAA,IAAA;AAAA,MACE,GAAGd;AAAA,MACJ,OAAOU;AAAA,MACP,UAAUf,KAAWK,EAAM;AAAA,MAE3B,UAAA;AAAA,QAAA,gBAAAa;AAAA,UAACE;AAAAA,UAAA;AAAA,YACC,WAAWC;AAAA,cACTC,EAAA;AAAA,cACA;AAAA,cACA;AAAA,cACAjB,EAAM,YAAY;AAAA,cAClBT;AAAA,YAAA;AAAA,YAEF,cAAYkB;AAAA,YACZ,mBAAiBD;AAAA,YAEhB,UAAA;AAAA,cAAAb,IACC,gBAAAR,EAAC+B,GAAA,EAAa,WAAU,OAAA,CAAO,IAE/B,gBAAA/B;AAAA,gBAACgC;AAAAA,gBAAA;AAAA,kBACC,aAAAzB;AAAA,kBACA,WAAU;AAAA,kBAET,UAAAF;AAAA,gBAAA;AAAA,cAAA;AAAA,cAGL,gBAAAL,EAACiC,GAAA,EAAgB,WAAU,8BACzB,UAAA,gBAAAjC,EAACkC,KAAgB,EAAA,CACnB;AAAA,YAAA;AAAA,UAAA;AAAA,QAAA;AAAA,0BAEDC,GAAA,EACC,UAAA,gBAAAnC,EAACoC,GAAA,EACC,UAAA,gBAAApC;AAAA,UAACqC;AAAAA,UAAA;AAAA,YACC,WAAWR;AAAA,cACT;AAAA;AAAA,cACA;AAAA;AAAA;AAAA,cAEA;AAAA;AAAA,YAAA;AAAA,YAGD,UAAAL;AAAA,UAAA;AAAA,QAAA,GAEL,EAAA,CACF;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAKJ,MAAIJ;AACF,WACE,gBAAApB;AAAA,MAACsC;AAAA,MAAA;AAAA,QACC,OAAA1C;AAAA,QACA,UAAAgB;AAAA,QACA,cAAAH;AAAA,QACA,aAAAC;AAAA,QACA,OACEC,IACI,OAAOA,KAAU,WACf,EAAE,SAASA,GAAO,OAAO,GAAA,IACzBA,IACF;AAAA,QAGL,UAAAc;AAAA,MAAA;AAAA,IAAA;AAOP,QAAMc,IAAkB5B,IACpB,OAAOA,KAAU,WACf,EAAE,SAASA,EAA4B,IACvCA,IACF;AAEJ,SACE,gBAAAe,EAAC,OAAA,EAAI,WAAU,cACZ,UAAA;AAAA,IAAA9B,uBACE,QAAA,EAAK,IAAIkB,GAAS,WAAU,WAC1B,UAAAlB,GACH;AAAA,IAED6B;AAAA,IACAc,IACC,gBAAAvC,EAAC,QAAA,EAAK,WAAU,4BACb,UAAAuC,EAAgB,QAAA,CACnB,IAEA7B,KACE,gBAAAV,EAAC,QAAA,EAAK,WAAU,yCACb,UAAAU,EAAA,CACH;AAAA,EAAA,GAGN;AAEJ;AAOA,SAAST,EAAU,EAAE,UAAAE,GAAU,OAAAqC,KAAyB;AACtD,SACE,gBAAAd;AAAA,IAACe;AAAAA,IAAA;AAAA,MACC,OAAAD;AAAA,MACA,WAAU;AAAA,MAEV,UAAA;AAAA,QAAA,gBAAAxC,EAAC0C,GAAA,EAAqB,UAAAvC,GAAS;AAAA,0BAC9BwC,GAAA,EACC,UAAA,gBAAA3C,EAAC4C,KAAU,EAAA,CACb;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGN;AAEA1C,EAAO,SAASD;"}
|
package/dist/chunks/{sensitive-input-i7ey1w0ky7nco012.js → sensitive-input-gtzk3vit4i35n95g.js}
RENAMED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsxs as b, Fragment as ce, jsx as
|
|
2
|
+
import { jsxs as b, Fragment as ce, jsx as r } from "react/jsx-runtime";
|
|
3
3
|
import { EyeSlash as ue, Eye as pe } from "@phosphor-icons/react";
|
|
4
4
|
import { forwardRef as de, useState as w, useRef as N, useId as T, useCallback as l, useEffect as fe } from "react";
|
|
5
5
|
import { c as p } from "./cn-ct4n7r74mh8y0f48.js";
|
|
6
|
-
import { K as me, i as ve } from "./input-
|
|
7
|
-
import { F as ge } from "./field-
|
|
8
|
-
import { I as he } from "./vendor-base-ui-
|
|
6
|
+
import { K as me, i as ve } from "./input-nvne68upfj8b2bk6.js";
|
|
7
|
+
import { F as ge } from "./field-lc4gr226y5aqlctf.js";
|
|
8
|
+
import { I as he } from "./vendor-base-ui-cpvkrhz4zgw9nw2b.js";
|
|
9
9
|
const Te = me, M = {
|
|
10
10
|
size: "base",
|
|
11
11
|
variant: "default"
|
|
@@ -18,7 +18,7 @@ const Te = me, M = {
|
|
|
18
18
|
onCopy: k,
|
|
19
19
|
size: t = M.size,
|
|
20
20
|
variant: $ = M.variant,
|
|
21
|
-
disabled:
|
|
21
|
+
disabled: i = !1,
|
|
22
22
|
readOnly: d = !1,
|
|
23
23
|
id: j,
|
|
24
24
|
autoComplete: H = "off",
|
|
@@ -73,7 +73,7 @@ const Te = me, M = {
|
|
|
73
73
|
A.current !== n && (A.current = n, !n && o === "masked" && c("empty"));
|
|
74
74
|
const te = l(
|
|
75
75
|
(e) => {
|
|
76
|
-
if (!
|
|
76
|
+
if (!i) {
|
|
77
77
|
if (u.current) {
|
|
78
78
|
const a = u.current.getBoundingClientRect();
|
|
79
79
|
if (!(e.clientX >= a.left && e.clientX <= a.right && e.clientY >= a.top && e.clientY <= a.bottom)) return;
|
|
@@ -81,7 +81,7 @@ const Te = me, M = {
|
|
|
81
81
|
o === "masked" && n && (c("revealed"), d || setTimeout(() => C.current?.focus(), 0));
|
|
82
82
|
}
|
|
83
83
|
},
|
|
84
|
-
[o, n,
|
|
84
|
+
[o, n, i, d]
|
|
85
85
|
), ne = l(
|
|
86
86
|
(e) => {
|
|
87
87
|
e.stopPropagation(), o === "revealed" ? c("masked") : o === "empty" && n && c("revealed");
|
|
@@ -98,24 +98,24 @@ const Te = me, M = {
|
|
|
98
98
|
u.current && e.relatedTarget instanceof Node && u.current.contains(e.relatedTarget) || n && c("masked");
|
|
99
99
|
},
|
|
100
100
|
[n]
|
|
101
|
-
),
|
|
101
|
+
), ie = l(
|
|
102
102
|
(e) => {
|
|
103
|
-
|
|
103
|
+
i || o === "masked" && n && (e.key === "Enter" || e.key === " ") && (e.preventDefault(), c("revealed"), d || setTimeout(() => C.current?.focus(), 0));
|
|
104
104
|
},
|
|
105
|
-
[o, n,
|
|
106
|
-
),
|
|
105
|
+
[o, n, i, d]
|
|
106
|
+
), re = l(
|
|
107
107
|
(e) => {
|
|
108
108
|
o === "revealed" && e.key === "Escape" && (c("masked"), setTimeout(() => u.current?.focus(), 0));
|
|
109
109
|
},
|
|
110
110
|
[o]
|
|
111
|
-
), s = o === "masked" && n, _ = !
|
|
111
|
+
), s = o === "masked" && n, _ = !i && (o === "revealed" || o === "empty" && n), se = t === "xs" || t === "sm" ? "size-3" : "size-4", D = p(
|
|
112
112
|
ve({ size: t, variant: $, parentFocusIndicator: !0 }),
|
|
113
113
|
"group/container relative flex w-full items-center",
|
|
114
|
-
s && !
|
|
115
|
-
|
|
114
|
+
s && !i && "cursor-pointer",
|
|
115
|
+
i && "cursor-not-allowed",
|
|
116
116
|
L
|
|
117
117
|
), P = /* @__PURE__ */ b(ce, { children: [
|
|
118
|
-
/* @__PURE__ */
|
|
118
|
+
/* @__PURE__ */ r(
|
|
119
119
|
he,
|
|
120
120
|
{
|
|
121
121
|
ref: z,
|
|
@@ -124,13 +124,13 @@ const Te = me, M = {
|
|
|
124
124
|
value: m,
|
|
125
125
|
onChange: oe,
|
|
126
126
|
onBlur: ae,
|
|
127
|
-
onKeyDown:
|
|
128
|
-
disabled:
|
|
127
|
+
onKeyDown: re,
|
|
128
|
+
disabled: i,
|
|
129
129
|
readOnly: d || s,
|
|
130
130
|
autoComplete: H,
|
|
131
131
|
tabIndex: s ? -1 : 0,
|
|
132
132
|
className: p(
|
|
133
|
-
"w-full border-0 bg-transparent p-0 text-kumo-default ring-0
|
|
133
|
+
"w-full border-0 bg-transparent p-0 text-kumo-default ring-0 kumo-input-placeholder disabled:cursor-not-allowed disabled:text-kumo-subtle",
|
|
134
134
|
t === "xs" && "pr-5",
|
|
135
135
|
t === "sm" && "pr-6",
|
|
136
136
|
t === "base" && "pr-8",
|
|
@@ -141,7 +141,7 @@ const Te = me, M = {
|
|
|
141
141
|
...q
|
|
142
142
|
}
|
|
143
143
|
),
|
|
144
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ r(
|
|
145
145
|
"span",
|
|
146
146
|
{
|
|
147
147
|
className: p(
|
|
@@ -167,20 +167,20 @@ const Te = me, M = {
|
|
|
167
167
|
),
|
|
168
168
|
"aria-hidden": "true",
|
|
169
169
|
children: /* @__PURE__ */ b("span", { className: "relative", children: [
|
|
170
|
-
/* @__PURE__ */
|
|
170
|
+
/* @__PURE__ */ r(
|
|
171
171
|
"span",
|
|
172
172
|
{
|
|
173
173
|
className: p(
|
|
174
|
-
s && !
|
|
174
|
+
s && !i && "group-focus-within/container:invisible group-hover/mask:invisible"
|
|
175
175
|
),
|
|
176
176
|
children: "••••••••"
|
|
177
177
|
}
|
|
178
178
|
),
|
|
179
|
-
s && !
|
|
179
|
+
s && !i && /* @__PURE__ */ r("span", { className: "invisible absolute left-0 top-0 whitespace-nowrap text-kumo-subtle group-focus-within/container:visible group-hover/mask:visible", children: "Click to reveal" })
|
|
180
180
|
] })
|
|
181
181
|
}
|
|
182
182
|
),
|
|
183
|
-
/* @__PURE__ */
|
|
183
|
+
/* @__PURE__ */ r(
|
|
184
184
|
"button",
|
|
185
185
|
{
|
|
186
186
|
type: "button",
|
|
@@ -189,7 +189,7 @@ const Te = me, M = {
|
|
|
189
189
|
"aria-label": o === "revealed" ? "Hide value" : "Reveal value",
|
|
190
190
|
tabIndex: _ ? 0 : -1,
|
|
191
191
|
className: p(
|
|
192
|
-
"absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle
|
|
192
|
+
"absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle hover:text-kumo-default focus:text-kumo-default focus-visible:ring-1 focus-visible:ring-kumo-ring focus-visible:rounded-sm",
|
|
193
193
|
// Match right padding from inputVariants
|
|
194
194
|
t === "xs" && "right-1.5",
|
|
195
195
|
t === "sm" && "right-2",
|
|
@@ -198,10 +198,10 @@ const Te = me, M = {
|
|
|
198
198
|
se,
|
|
199
199
|
!_ && "pointer-events-none opacity-0"
|
|
200
200
|
),
|
|
201
|
-
children: o === "revealed" ? /* @__PURE__ */
|
|
201
|
+
children: o === "revealed" ? /* @__PURE__ */ r(ue, { className: "size-full" }) : /* @__PURE__ */ r(pe, { className: "size-full" })
|
|
202
202
|
}
|
|
203
203
|
),
|
|
204
|
-
n && !
|
|
204
|
+
n && !i && /* @__PURE__ */ r(
|
|
205
205
|
"button",
|
|
206
206
|
{
|
|
207
207
|
type: "button",
|
|
@@ -215,28 +215,28 @@ const Te = me, M = {
|
|
|
215
215
|
}
|
|
216
216
|
)
|
|
217
217
|
] }), U = /* @__PURE__ */ b("div", { children: [
|
|
218
|
-
s ? /* @__PURE__ */
|
|
218
|
+
s ? /* @__PURE__ */ r(
|
|
219
219
|
"div",
|
|
220
220
|
{
|
|
221
221
|
ref: u,
|
|
222
222
|
role: "button",
|
|
223
|
-
tabIndex:
|
|
223
|
+
tabIndex: i ? -1 : 0,
|
|
224
224
|
className: D,
|
|
225
225
|
onClick: te,
|
|
226
|
-
onKeyDown:
|
|
226
|
+
onKeyDown: ie,
|
|
227
227
|
"aria-label": `${G}, masked.`,
|
|
228
228
|
"aria-describedby": `${K} ${V}`,
|
|
229
|
-
"aria-disabled":
|
|
229
|
+
"aria-disabled": i,
|
|
230
230
|
children: P
|
|
231
231
|
}
|
|
232
|
-
) : /* @__PURE__ */
|
|
233
|
-
s && /* @__PURE__ */
|
|
232
|
+
) : /* @__PURE__ */ r("div", { ref: u, className: D, children: P }),
|
|
233
|
+
s && /* @__PURE__ */ r("span", { id: K, className: "sr-only", children: "Click or press Enter to reveal." }),
|
|
234
234
|
/* @__PURE__ */ b("span", { id: V, className: "sr-only", "aria-live": "polite", children: [
|
|
235
235
|
o === "masked" && n && "Value hidden",
|
|
236
236
|
v && "Copied to clipboard"
|
|
237
237
|
] })
|
|
238
238
|
] });
|
|
239
|
-
return h ? /* @__PURE__ */
|
|
239
|
+
return h ? /* @__PURE__ */ r(
|
|
240
240
|
ge,
|
|
241
241
|
{
|
|
242
242
|
label: h,
|
|
@@ -255,4 +255,4 @@ export {
|
|
|
255
255
|
ye as S,
|
|
256
256
|
M as a
|
|
257
257
|
};
|
|
258
|
-
//# sourceMappingURL=sensitive-input-
|
|
258
|
+
//# sourceMappingURL=sensitive-input-gtzk3vit4i35n95g.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sensitive-input-gtzk3vit4i35n95g.js","sources":["../../src/components/sensitive-input/sensitive-input.tsx"],"sourcesContent":["import { Eye, EyeSlash } from \"@phosphor-icons/react\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type ReactNode,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Input as BaseInput } from \"@base-ui/react/input\";\nimport {\n inputVariants,\n KUMO_INPUT_VARIANTS,\n type KumoInputSize,\n type KumoInputVariant,\n} from \"../input/input\";\nimport { Field, type FieldErrorMatch } from \"../field/field\";\n\nexport const KUMO_SENSITIVE_INPUT_VARIANTS = KUMO_INPUT_VARIANTS;\n\nexport const KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\ntype Mode = \"masked\" | \"revealed\" | \"empty\";\n\n/**\n * SensitiveInput component props.\n *\n * @example\n * ```tsx\n * <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n * <SensitiveInput label=\"Secret\" value={secret} onValueChange={setSecret} />\n * ```\n */\nexport interface SensitiveInputProps\n extends Omit<\n ComponentPropsWithoutRef<\"input\">,\n \"size\" | \"type\" | \"value\" | \"defaultValue\"\n > {\n /** Controlled value */\n value?: string;\n /** Uncontrolled default value */\n defaultValue?: string;\n /** Simplified change handler receiving just the value */\n onValueChange?: (value: string) => void;\n /** Callback fired after value is copied to clipboard */\n onCopy?: () => void;\n /**\n * Size of the input.\n * - `\"xs\"` — Extra small for compact UIs\n * - `\"sm\"` — Small for secondary fields\n * - `\"base\"` — Default input size\n * - `\"lg\"` — Large for prominent fields\n * @default \"base\"\n */\n size?: KumoInputSize;\n /**\n * Style variant of the input.\n * - `\"default\"` — Default input appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: KumoInputVariant;\n /** Label content for the input (enables Field wrapper and sets masked state label) - can be a string or any React node */\n label?: ReactNode;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /** Helper text displayed below the input */\n description?: ReactNode;\n /** Error message or validation error object */\n error?: string | { message: ReactNode; match: FieldErrorMatch };\n}\n\n/**\n * Password/secret input that masks its value by default and reveals on click.\n * Includes a built-in copy-to-clipboard button on hover.\n *\n * @example\n * ```tsx\n * <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n * ```\n */\nexport const SensitiveInput = forwardRef<HTMLInputElement, SensitiveInputProps>(\n (\n {\n value: controlledValue,\n defaultValue = \"\",\n onChange,\n onValueChange,\n onCopy,\n size = KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS.size,\n variant = KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS.variant,\n disabled = false,\n readOnly = false,\n id,\n autoComplete = \"off\",\n className,\n label,\n labelTooltip,\n description,\n error,\n required,\n ...inputProps\n },\n ref,\n ) => {\n // For aria-label, only use string labels (ReactNode labels can't be used for aria-label)\n const ariaLabelFallback =\n typeof label === \"string\" ? label : \"Sensitive value\";\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue);\n const value = isControlled ? controlledValue : internalValue;\n const hasValue = value.length > 0;\n\n const [mode, setMode] = useState<Mode>(() =>\n hasValue ? \"masked\" : \"empty\",\n );\n\n const [copied, setCopied] = useState(false);\n\n const inputRef = useRef<HTMLInputElement | null>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n const liveRegionId = useId();\n const generatedId = useId();\n const inputId = id ?? generatedId;\n const maskedInstructionId = useId();\n\n const mergedRef = useCallback(\n (node: HTMLInputElement | null) => {\n inputRef.current = node;\n if (typeof ref === \"function\") {\n ref(node);\n } else if (ref) {\n ref.current = node;\n }\n },\n [ref],\n );\n\n // Reset copied state after 2 seconds\n useEffect(() => {\n if (copied) {\n const timeoutId = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timeoutId);\n }\n }, [copied]);\n\n const copyToClipboard = useCallback(\n async (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n try {\n if (\n typeof navigator !== \"undefined\" &&\n navigator.clipboard &&\n typeof navigator.clipboard.writeText === \"function\"\n ) {\n await navigator.clipboard.writeText(value);\n setCopied(true);\n onCopy?.();\n return;\n }\n } catch {\n // Fall through to manual fallback\n }\n\n if (typeof document !== \"undefined\") {\n const textarea = document.createElement(\"textarea\");\n textarea.value = value;\n textarea.setAttribute(\"readonly\", \"\");\n textarea.style.position = \"absolute\";\n textarea.style.left = \"-9999px\";\n document.body.appendChild(textarea);\n const selection = document.getSelection();\n const previousRange = selection?.rangeCount\n ? selection.getRangeAt(0)\n : null;\n textarea.select();\n try {\n document.execCommand(\"copy\");\n setCopied(true);\n onCopy?.();\n } catch (error) {\n console.warn(\"Clipboard copy failed\", error);\n } finally {\n document.body.removeChild(textarea);\n if (previousRange) {\n selection?.removeAllRanges();\n selection?.addRange(previousRange);\n }\n }\n }\n },\n [value, onCopy],\n );\n\n // Sync mode when value changes externally\n const prevHasValueRef = useRef(hasValue);\n if (prevHasValueRef.current !== hasValue) {\n prevHasValueRef.current = hasValue;\n if (!hasValue && mode === \"masked\") {\n setMode(\"empty\");\n }\n }\n\n const handleContainerClick = useCallback(\n (e: React.MouseEvent) => {\n if (disabled) return;\n // Ignore clicks that originated from outside (e.g., label click focusing input)\n // Label clicks trigger a click on the input, but the click coordinates are outside the container\n if (containerRef.current) {\n const rect = containerRef.current.getBoundingClientRect();\n const isClickInsideContainer =\n e.clientX >= rect.left &&\n e.clientX <= rect.right &&\n e.clientY >= rect.top &&\n e.clientY <= rect.bottom;\n if (!isClickInsideContainer) return;\n }\n if (mode === \"masked\" && hasValue) {\n setMode(\"revealed\");\n if (!readOnly) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n }\n },\n [mode, hasValue, disabled, readOnly],\n );\n\n const handleToggleVisibility = useCallback(\n (e: React.MouseEvent<HTMLButtonElement>) => {\n e.stopPropagation();\n if (mode === \"revealed\") {\n setMode(\"masked\");\n } else if (mode === \"empty\" && hasValue) {\n setMode(\"revealed\");\n }\n },\n [mode, hasValue],\n );\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n if (!isControlled) {\n setInternalValue(newValue);\n }\n onChange?.(e);\n onValueChange?.(newValue);\n },\n [isControlled, onChange, onValueChange],\n );\n\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLInputElement>) => {\n // Don't mask if focus is moving to a button inside the container (copy/eye buttons)\n if (\n containerRef.current &&\n e.relatedTarget instanceof Node &&\n containerRef.current.contains(e.relatedTarget)\n ) {\n return;\n }\n if (hasValue) {\n setMode(\"masked\");\n }\n },\n [hasValue],\n );\n\n const handleContainerKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n if (mode === \"masked\" && hasValue) {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n setMode(\"revealed\");\n if (!readOnly) {\n setTimeout(() => inputRef.current?.focus(), 0);\n }\n }\n }\n },\n [mode, hasValue, disabled, readOnly],\n );\n\n const handleInputKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (mode === \"revealed\" && e.key === \"Escape\") {\n setMode(\"masked\");\n // Move focus to container to avoid focus trap (input becomes tabIndex={-1})\n setTimeout(() => containerRef.current?.focus(), 0);\n }\n },\n [mode],\n );\n\n const isMaskedWithValue = mode === \"masked\" && hasValue;\n const showEyeButton =\n !disabled && (mode === \"revealed\" || (mode === \"empty\" && hasValue));\n\n // Icon sizes matching input sizes\n const iconSize = size === \"xs\" || size === \"sm\" ? \"size-3\" : \"size-4\";\n\n const containerClassName = cn(\n inputVariants({ size, variant, parentFocusIndicator: true }),\n \"group/container relative flex w-full items-center\",\n isMaskedWithValue && !disabled && \"cursor-pointer\",\n disabled && \"cursor-not-allowed\",\n className,\n );\n\n const containerContent = (\n <>\n {/* Input - defines the width, always rendered */}\n <BaseInput\n ref={mergedRef}\n id={inputId}\n type={mode === \"revealed\" ? \"text\" : \"password\"}\n value={value}\n onChange={handleChange}\n onBlur={handleBlur}\n onKeyDown={handleInputKeyDown}\n disabled={disabled}\n readOnly={readOnly || isMaskedWithValue}\n autoComplete={autoComplete}\n tabIndex={isMaskedWithValue ? -1 : 0}\n className={cn(\n \"w-full border-0 bg-transparent p-0 text-kumo-default ring-0 kumo-input-placeholder disabled:cursor-not-allowed disabled:text-kumo-subtle\",\n size === \"xs\" && \"pr-5\",\n size === \"sm\" && \"pr-6\",\n size === \"base\" && \"pr-8\",\n size === \"lg\" && \"pr-10\",\n isMaskedWithValue && \"pointer-events-none text-transparent\",\n )}\n aria-hidden={isMaskedWithValue}\n {...inputProps}\n />\n\n {/* Mask overlay - absolutely positioned, doesn't affect layout */}\n <span\n className={cn(\n \"pointer-events-none absolute inset-y-0 left-0 flex items-center overflow-hidden select-none\",\n // Match input pr padding (space for icon)\n size === \"xs\" && \"right-5\",\n size === \"sm\" && \"right-6\",\n size === \"base\" && \"right-8\",\n size === \"lg\" && \"right-10\",\n // Match the padding from inputVariants\n size === \"xs\" && \"px-1.5\",\n size === \"sm\" && \"px-2\",\n size === \"base\" && \"px-3\",\n size === \"lg\" && \"px-4\",\n // Hidden when not masked\n !isMaskedWithValue && \"invisible\",\n // When masked: enable pointer events\n isMaskedWithValue && \"pointer-events-auto\",\n // Text color - use text-kumo-default to contrast with bg-kumo-control input background\n \"text-kumo-default\",\n // Hover state - pure CSS, no React state (group for children)\n \"group/mask\",\n )}\n aria-hidden=\"true\"\n >\n {/* Both texts rendered, stacked. Visibility toggled on hover to prevent layout shift */}\n <span className=\"relative\">\n <span\n className={cn(\n isMaskedWithValue &&\n !disabled &&\n \"group-focus-within/container:invisible group-hover/mask:invisible\",\n )}\n >\n ••••••••\n </span>\n {isMaskedWithValue && !disabled && (\n <span className=\"invisible absolute left-0 top-0 whitespace-nowrap text-kumo-subtle group-focus-within/container:visible group-hover/mask:visible\">\n Click to reveal\n </span>\n )}\n </span>\n </span>\n\n {/* Eye button - absolutely positioned to the right */}\n <button\n type=\"button\"\n onClick={handleToggleVisibility}\n onKeyDown={(e) => e.stopPropagation()}\n aria-label={mode === \"revealed\" ? \"Hide value\" : \"Reveal value\"}\n tabIndex={showEyeButton ? 0 : -1}\n className={cn(\n \"absolute top-1/2 right-0 -translate-y-1/2 cursor-pointer text-kumo-subtle hover:text-kumo-default focus:text-kumo-default focus-visible:ring-1 focus-visible:ring-kumo-ring focus-visible:rounded-sm\",\n // Match right padding from inputVariants\n size === \"xs\" && \"right-1.5\",\n size === \"sm\" && \"right-2\",\n size === \"base\" && \"right-3\",\n size === \"lg\" && \"right-4\",\n iconSize,\n !showEyeButton && \"pointer-events-none opacity-0\",\n )}\n >\n {mode === \"revealed\" ? (\n <EyeSlash className=\"size-full\" />\n ) : (\n <Eye className=\"size-full\" />\n )}\n </button>\n\n {/* Copy tab - appears on hover/focus at top right (hidden when disabled) */}\n {hasValue && !disabled && (\n <button\n type=\"button\"\n onClick={copyToClipboard}\n onKeyDown={(e) => e.stopPropagation()}\n aria-label={copied ? \"Copied\" : \"Copy to clipboard\"}\n className={cn(\n \"absolute -top-px right-2 -translate-y-full cursor-pointer rounded-t-md bg-kumo-brand px-2 py-0.5 text-xs text-white opacity-0 transition-opacity group-focus-within/container:opacity-100 group-hover/container:opacity-100 hover:brightness-120 focus-visible:outline focus-visible:outline-offset-1 focus-visible:outline-kumo-ring\",\n )}\n >\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n )}\n </>\n );\n\n const input = (\n <div>\n {isMaskedWithValue ? (\n <div\n ref={containerRef}\n // Cannot use <button> here because containerContent contains interactive button elements (Copy, Reveal).\n // Using role=\"button\" with proper keyboard handling instead.\n // oxlint-disable-next-line prefer-tag-over-role\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n className={containerClassName}\n onClick={handleContainerClick}\n onKeyDown={handleContainerKeyDown}\n aria-label={`${ariaLabelFallback}, masked.`}\n aria-describedby={`${maskedInstructionId} ${liveRegionId}`}\n aria-disabled={disabled}\n >\n {containerContent}\n </div>\n ) : (\n <div ref={containerRef} className={containerClassName}>\n {containerContent}\n </div>\n )}\n {isMaskedWithValue && (\n <span id={maskedInstructionId} className=\"sr-only\">\n Click or press Enter to reveal.\n </span>\n )}\n <span id={liveRegionId} className=\"sr-only\" aria-live=\"polite\">\n {mode === \"masked\" && hasValue && \"Value hidden\"}\n {copied && \"Copied to clipboard\"}\n </span>\n </div>\n );\n\n // Render with Field wrapper if label is provided\n if (label) {\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n description={description}\n error={\n error\n ? typeof error === \"string\"\n ? { message: error, match: true }\n : error\n : undefined\n }\n >\n {input}\n </Field>\n );\n }\n\n // Render bare input without Field wrapper\n return input;\n },\n);\n\nSensitiveInput.displayName = \"SensitiveInput\";\n"],"names":["KUMO_SENSITIVE_INPUT_VARIANTS","KUMO_INPUT_VARIANTS","KUMO_SENSITIVE_INPUT_DEFAULT_VARIANTS","SensitiveInput","forwardRef","controlledValue","defaultValue","onChange","onValueChange","onCopy","size","variant","disabled","readOnly","id","autoComplete","className","label","labelTooltip","description","error","required","inputProps","ref","ariaLabelFallback","isControlled","internalValue","setInternalValue","useState","value","hasValue","mode","setMode","copied","setCopied","inputRef","useRef","containerRef","liveRegionId","useId","generatedId","inputId","maskedInstructionId","mergedRef","useCallback","node","useEffect","timeoutId","copyToClipboard","textarea","selection","previousRange","prevHasValueRef","handleContainerClick","rect","handleToggleVisibility","handleChange","newValue","handleBlur","handleContainerKeyDown","handleInputKeyDown","isMaskedWithValue","showEyeButton","iconSize","containerClassName","cn","inputVariants","containerContent","jsxs","Fragment","jsx","BaseInput","EyeSlash","Eye","input","Field"],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as e, jsxs as I } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as P, createContext as K, useContext as M } from "react";
|
|
4
|
+
import { c as i } from "./cn-ct4n7r74mh8y0f48.js";
|
|
5
|
+
import { F as O } from "./field-lc4gr226y5aqlctf.js";
|
|
6
|
+
import { P as H, Q as V, b3 as z } from "./vendor-base-ui-cpvkrhz4zgw9nw2b.js";
|
|
7
|
+
const $ = {
|
|
8
|
+
size: {
|
|
9
|
+
sm: {
|
|
10
|
+
classes: "h-5.5 w-8.5",
|
|
11
|
+
description: "Small switch for compact UIs"
|
|
12
|
+
},
|
|
13
|
+
base: {
|
|
14
|
+
classes: "h-6.5 w-10.5",
|
|
15
|
+
description: "Default switch size"
|
|
16
|
+
},
|
|
17
|
+
lg: {
|
|
18
|
+
classes: "h-7.5 w-12.5",
|
|
19
|
+
description: "Large switch for prominent toggles"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
variant: {
|
|
23
|
+
default: {
|
|
24
|
+
classes: "",
|
|
25
|
+
description: "Default switch with squircle shape and brand blue color"
|
|
26
|
+
},
|
|
27
|
+
neutral: {
|
|
28
|
+
classes: "",
|
|
29
|
+
description: "Monochrome switch with squircle shape for subtle toggles"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}, ee = {
|
|
33
|
+
size: "base",
|
|
34
|
+
variant: "default"
|
|
35
|
+
}, A = K({
|
|
36
|
+
controlFirst: !0
|
|
37
|
+
}), T = P(
|
|
38
|
+
({
|
|
39
|
+
className: l,
|
|
40
|
+
checked: c,
|
|
41
|
+
disabled: s,
|
|
42
|
+
size: n = "base",
|
|
43
|
+
variant: u = "default",
|
|
44
|
+
label: t,
|
|
45
|
+
labelTooltip: d,
|
|
46
|
+
required: f,
|
|
47
|
+
controlFirst: w = !0,
|
|
48
|
+
onCheckedChange: x,
|
|
49
|
+
transitioning: N,
|
|
50
|
+
...r
|
|
51
|
+
}, v) => {
|
|
52
|
+
const S = typeof t == "string" ? t : "Switch", b = /* @__PURE__ */ e(
|
|
53
|
+
z,
|
|
54
|
+
{
|
|
55
|
+
ref: v,
|
|
56
|
+
checked: c,
|
|
57
|
+
disabled: s,
|
|
58
|
+
onCheckedChange: x,
|
|
59
|
+
nativeButton: !0,
|
|
60
|
+
render: (_, a) => {
|
|
61
|
+
const {
|
|
62
|
+
ref: y,
|
|
63
|
+
className: m,
|
|
64
|
+
role: g,
|
|
65
|
+
"aria-checked": L,
|
|
66
|
+
"aria-pressed": h,
|
|
67
|
+
...C
|
|
68
|
+
} = _, k = u === "neutral", p = "rounded-[5px] supports-[corner-shape:squircle]:rounded-[10px] [corner-shape:squircle]", o = {
|
|
69
|
+
sm: { track: "h-4 w-8", thumb: "w-4", slide: "left-4" },
|
|
70
|
+
base: { track: "h-4.5 w-9", thumb: "w-4.5", slide: "left-4.5" },
|
|
71
|
+
lg: { track: "h-5 w-10", thumb: "w-5", slide: "left-5" }
|
|
72
|
+
}[n], R = k ? a.checked ? "bg-neutral-500 dark:bg-kumo-base ring-neutral-600 dark:ring-neutral-700" : "bg-neutral-150 dark:bg-kumo-base ring-kumo-line" : a.checked ? "bg-blue-500 dark:bg-blue-600 ring-blue-600 dark:ring-blue-500" : "bg-neutral-200 dark:bg-neutral-700 ring-neutral-300 dark:ring-neutral-600", U = k ? a.checked ? "ring-neutral-600 dark:ring-neutral-200 bg-kumo-base dark:bg-neutral-400" : "bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700" : a.checked ? "ring-blue-600 dark:ring-blue-100 bg-kumo-base dark:bg-blue-300" : "bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700", B = i(
|
|
73
|
+
"relative inline-flex items-center ring cursor-pointer border-none p-0",
|
|
74
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500",
|
|
75
|
+
"transition-colors duration-150 ease-out motion-reduce:transition-none",
|
|
76
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
77
|
+
o.track,
|
|
78
|
+
p,
|
|
79
|
+
R,
|
|
80
|
+
l,
|
|
81
|
+
m
|
|
82
|
+
), D = i(
|
|
83
|
+
"absolute top-0 bottom-0 shadow-sm ring-1",
|
|
84
|
+
o.thumb,
|
|
85
|
+
p,
|
|
86
|
+
U,
|
|
87
|
+
"transition-all duration-150 ease-out motion-reduce:transition-none",
|
|
88
|
+
a.checked ? o.slide : "left-0"
|
|
89
|
+
), F = r.role ?? g ?? "switch", G = F === "switch" ? { "aria-checked": a.checked } : { "aria-pressed": a.checked };
|
|
90
|
+
return /* @__PURE__ */ e(
|
|
91
|
+
"button",
|
|
92
|
+
{
|
|
93
|
+
...C,
|
|
94
|
+
...r,
|
|
95
|
+
ref: y,
|
|
96
|
+
type: "button",
|
|
97
|
+
role: F,
|
|
98
|
+
...G,
|
|
99
|
+
"aria-busy": N || void 0,
|
|
100
|
+
"aria-label": r["aria-label"] ?? S,
|
|
101
|
+
className: B,
|
|
102
|
+
children: /* @__PURE__ */ e("div", { className: D })
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
return t ? /* @__PURE__ */ e(
|
|
109
|
+
O,
|
|
110
|
+
{
|
|
111
|
+
label: t,
|
|
112
|
+
required: f,
|
|
113
|
+
labelTooltip: d,
|
|
114
|
+
controlFirst: w,
|
|
115
|
+
children: b
|
|
116
|
+
}
|
|
117
|
+
) : b;
|
|
118
|
+
}
|
|
119
|
+
);
|
|
120
|
+
T.displayName = "Switch";
|
|
121
|
+
const j = P(
|
|
122
|
+
({
|
|
123
|
+
className: l,
|
|
124
|
+
checked: c,
|
|
125
|
+
disabled: s,
|
|
126
|
+
size: n = "base",
|
|
127
|
+
variant: u = "default",
|
|
128
|
+
label: t,
|
|
129
|
+
onCheckedChange: d,
|
|
130
|
+
transitioning: f
|
|
131
|
+
}, w) => {
|
|
132
|
+
const { controlFirst: x } = M(A);
|
|
133
|
+
return /* @__PURE__ */ I(
|
|
134
|
+
"label",
|
|
135
|
+
{
|
|
136
|
+
className: i(
|
|
137
|
+
"m-0 relative inline-flex items-center gap-2",
|
|
138
|
+
// Control first (default): switch before label
|
|
139
|
+
// Label first: label before switch using flex-row-reverse
|
|
140
|
+
!x && "flex-row-reverse justify-end",
|
|
141
|
+
s ? "cursor-not-allowed opacity-50" : "cursor-pointer",
|
|
142
|
+
l
|
|
143
|
+
),
|
|
144
|
+
children: [
|
|
145
|
+
/* @__PURE__ */ e(
|
|
146
|
+
z,
|
|
147
|
+
{
|
|
148
|
+
ref: w,
|
|
149
|
+
checked: c,
|
|
150
|
+
disabled: s,
|
|
151
|
+
onCheckedChange: d,
|
|
152
|
+
nativeButton: !0,
|
|
153
|
+
render: (N, r) => {
|
|
154
|
+
const {
|
|
155
|
+
ref: v,
|
|
156
|
+
className: S,
|
|
157
|
+
role: b,
|
|
158
|
+
"aria-checked": _,
|
|
159
|
+
"aria-pressed": a,
|
|
160
|
+
...y
|
|
161
|
+
} = N, m = u === "neutral", g = "rounded-[5px] supports-[corner-shape:squircle]:rounded-[10px] [corner-shape:squircle]", h = {
|
|
162
|
+
sm: { track: "h-4 w-8", thumb: "w-4", slide: "left-4" },
|
|
163
|
+
base: { track: "h-4.5 w-9", thumb: "w-4.5", slide: "left-4.5" },
|
|
164
|
+
lg: { track: "h-5 w-10", thumb: "w-5", slide: "left-5" }
|
|
165
|
+
}[n], C = m ? r.checked ? "bg-neutral-500 dark:bg-kumo-base ring-neutral-600 dark:ring-neutral-700" : "bg-neutral-150 dark:bg-kumo-base ring-kumo-line" : r.checked ? "bg-blue-500 dark:bg-blue-600 ring-blue-600 dark:ring-blue-500" : "bg-neutral-200 dark:bg-neutral-700 ring-neutral-300 dark:ring-neutral-600", k = m ? r.checked ? "ring-neutral-600 dark:ring-neutral-200 bg-kumo-base dark:bg-neutral-400" : "bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700" : r.checked ? "ring-blue-600 dark:ring-blue-100 bg-kumo-base dark:bg-blue-300" : "bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700", p = i(
|
|
166
|
+
"relative inline-flex items-center ring cursor-pointer border-none p-0",
|
|
167
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500",
|
|
168
|
+
"transition-colors duration-150 ease-out motion-reduce:transition-none",
|
|
169
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
170
|
+
h.track,
|
|
171
|
+
g,
|
|
172
|
+
C,
|
|
173
|
+
S
|
|
174
|
+
), q = i(
|
|
175
|
+
"absolute top-0 bottom-0 shadow-sm ring-1",
|
|
176
|
+
h.thumb,
|
|
177
|
+
g,
|
|
178
|
+
k,
|
|
179
|
+
"transition-all duration-150 ease-out motion-reduce:transition-none",
|
|
180
|
+
r.checked ? h.slide : "left-0"
|
|
181
|
+
), o = b ?? "switch", R = o === "switch" ? { "aria-checked": r.checked } : { "aria-pressed": r.checked };
|
|
182
|
+
return /* @__PURE__ */ e(
|
|
183
|
+
"button",
|
|
184
|
+
{
|
|
185
|
+
...y,
|
|
186
|
+
ref: v,
|
|
187
|
+
type: "button",
|
|
188
|
+
role: o,
|
|
189
|
+
...R,
|
|
190
|
+
"aria-busy": f || void 0,
|
|
191
|
+
className: p,
|
|
192
|
+
children: /* @__PURE__ */ e("div", { className: q })
|
|
193
|
+
}
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
),
|
|
198
|
+
/* @__PURE__ */ e("span", { className: "text-base font-medium text-kumo-default", children: t })
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
);
|
|
204
|
+
j.displayName = "Switch.Item";
|
|
205
|
+
function W({
|
|
206
|
+
legend: l,
|
|
207
|
+
children: c,
|
|
208
|
+
error: s,
|
|
209
|
+
description: n,
|
|
210
|
+
disabled: u,
|
|
211
|
+
controlFirst: t = !0,
|
|
212
|
+
className: d
|
|
213
|
+
}) {
|
|
214
|
+
return /* @__PURE__ */ e(A.Provider, { value: { controlFirst: t }, children: /* @__PURE__ */ I(
|
|
215
|
+
H,
|
|
216
|
+
{
|
|
217
|
+
className: i(
|
|
218
|
+
"flex flex-col gap-4 rounded-lg border border-kumo-line p-4",
|
|
219
|
+
d
|
|
220
|
+
),
|
|
221
|
+
disabled: u,
|
|
222
|
+
children: [
|
|
223
|
+
/* @__PURE__ */ e(V, { className: "text-lg font-medium text-kumo-default", children: l }),
|
|
224
|
+
/* @__PURE__ */ e("div", { className: "flex flex-col gap-2", children: c }),
|
|
225
|
+
s && /* @__PURE__ */ e("p", { className: "text-sm text-kumo-danger", children: s }),
|
|
226
|
+
n && /* @__PURE__ */ e("p", { className: "text-sm text-kumo-subtle", children: n })
|
|
227
|
+
]
|
|
228
|
+
}
|
|
229
|
+
) });
|
|
230
|
+
}
|
|
231
|
+
const E = Object.assign(T, {
|
|
232
|
+
Item: j,
|
|
233
|
+
Group: W
|
|
234
|
+
});
|
|
235
|
+
E.displayName = "Switch";
|
|
236
|
+
export {
|
|
237
|
+
$ as K,
|
|
238
|
+
E as S,
|
|
239
|
+
ee as a
|
|
240
|
+
};
|
|
241
|
+
//# sourceMappingURL=switch-cpbp0i75jnazkani.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"switch-cpbp0i75jnazkani.js","sources":["../../src/components/switch/switch.tsx"],"sourcesContent":["import { Switch as BaseSwitch } from \"@base-ui/react/switch\";\nimport {\n forwardRef,\n type ButtonHTMLAttributes,\n type Ref,\n type ReactNode,\n createContext,\n useContext,\n} from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Field } from \"../field/field\";\nimport { Fieldset } from \"@base-ui/react/fieldset\";\n\n/** Switch size and variant definitions mapping names to their Tailwind classes. */\nexport const KUMO_SWITCH_VARIANTS = {\n size: {\n sm: {\n classes: \"h-5.5 w-8.5\",\n description: \"Small switch for compact UIs\",\n },\n base: {\n classes: \"h-6.5 w-10.5\",\n description: \"Default switch size\",\n },\n lg: {\n classes: \"h-7.5 w-12.5\",\n description: \"Large switch for prominent toggles\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default switch with squircle shape and brand blue color\",\n },\n neutral: {\n classes: \"\",\n description: \"Monochrome switch with squircle shape for subtle toggles\",\n },\n },\n} as const;\n\nexport const KUMO_SWITCH_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\n// Derived types from KUMO_SWITCH_VARIANTS\nexport type KumoSwitchSize = keyof typeof KUMO_SWITCH_VARIANTS.size;\nexport type KumoSwitchVariant = keyof typeof KUMO_SWITCH_VARIANTS.variant;\n\nexport interface KumoSwitchVariantsProps {\n /**\n * Switch size.\n * - `\"sm\"` — Small for compact UIs\n * - `\"base\"` — Default size\n * - `\"lg\"` — Large for prominent toggles\n * @default \"base\"\n */\n size?: KumoSwitchSize;\n /**\n * Visual variant.\n * - `\"default\"` — Standard switch appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: KumoSwitchVariant;\n}\n\nexport function switchVariants({\n size = KUMO_SWITCH_DEFAULT_VARIANTS.size,\n variant = KUMO_SWITCH_DEFAULT_VARIANTS.variant,\n}: KumoSwitchVariantsProps = {}) {\n // Fallback to defaults if invalid size/variant passed\n const sizeConfig =\n KUMO_SWITCH_VARIANTS.size[size] ?? KUMO_SWITCH_VARIANTS.size.base;\n const variantConfig =\n KUMO_SWITCH_VARIANTS.variant[variant] ??\n KUMO_SWITCH_VARIANTS.variant.default;\n return cn(sizeConfig.classes, variantConfig.classes);\n}\n\n// Legacy type aliases for backwards compatibility\nexport type SwitchSize = KumoSwitchSize;\nexport type SwitchVariant = KumoSwitchVariant;\n\n// Context for passing controlFirst from Group to Items\nconst SwitchGroupContext = createContext<{ controlFirst: boolean }>({\n controlFirst: true,\n});\n\n/**\n * Single switch component props (with built-in Field)\n *\n * Usage patterns:\n *\n * Basic usage:\n * ```tsx\n * <Switch label=\"Enable notifications\" checked={true} onCheckedChange={setChecked} />\n * ```\n *\n * Label first layout:\n * ```tsx\n * <Switch label=\"Dark mode\" checked={false} onCheckedChange={setChecked} controlFirst={false} />\n * ```\n *\n * Neutral variant (monochrome, squircle shape):\n * ```tsx\n * <Switch label=\"Setting\" variant=\"neutral\" checked={false} onCheckedChange={setChecked} />\n * ```\n *\n * @property {string} label - Label text for the switch (Field wrapper is built-in)\n * @property {boolean} [controlFirst] - When true (default), switch appears before label\n */\nexport type SwitchProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> & {\n /** Visual variant: \"default\" (pill, brand color) or \"neutral\" (squircle, monochrome) */\n variant?: SwitchVariant;\n /** Label content for the switch (Field wrapper is built-in) - can be a string or any React node. Optional when used standalone for visual-only purposes. */\n label?: ReactNode;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /**\n * Whether the switch is required.\n * When explicitly false, shows \"(optional)\" text after the label.\n */\n required?: boolean;\n /** When true (default), switch appears before label. When false, label appears before switch. */\n controlFirst?: boolean;\n size?: KumoSwitchSize;\n checked?: boolean;\n disabled?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n transitioning?: boolean;\n};\n\n/**\n * Switch group component props (with built-in Fieldset)\n *\n * Usage:\n * ```tsx\n * <Switch.Group\n * legend=\"Notification settings\"\n * error=\"You must enable at least one notification type\"\n * >\n * <Switch.Item label=\"Email notifications\" value=\"email\" />\n * <Switch.Item label=\"SMS notifications\" value=\"sms\" />\n * </Switch.Group>\n * ```\n */\nexport interface SwitchGroupProps {\n /** Legend text for the group */\n legend: string;\n /** Child Switch.Item components */\n children: ReactNode;\n /** Error message for the group (only appears in groups, not single switches) */\n error?: string;\n /** Helper text for the group */\n description?: ReactNode;\n /** Whether all switches in the group are disabled */\n disabled?: boolean;\n /** When true (default), switch appears before label. When false, label appears before switch. */\n controlFirst?: boolean;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Individual switch item within a group\n */\nexport type SwitchItemProps = {\n /** Visual variant: \"default\" or \"error\" for validation failures */\n variant?: SwitchVariant;\n /** Label text displayed next to switch */\n label: string;\n /** Additional CSS classes for the label wrapper */\n className?: string;\n checked?: boolean;\n disabled?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n size?: KumoSwitchSize;\n transitioning?: boolean;\n};\n\n// Single switch with built-in Field\nconst SwitchBase = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n className,\n checked,\n disabled,\n size = \"base\",\n variant = \"default\",\n label,\n labelTooltip,\n required,\n controlFirst = true,\n onCheckedChange,\n transitioning,\n ...props\n },\n ref,\n ) => {\n // For aria-label, only use string labels (ReactNode labels can't be used for aria-label)\n const ariaLabelFallback = typeof label === \"string\" ? label : \"Switch\";\n const switchControl = (\n <BaseSwitch.Root\n ref={ref}\n checked={checked}\n disabled={disabled}\n onCheckedChange={onCheckedChange}\n nativeButton\n render={(rootProps, state) => {\n const {\n ref: rootRef,\n className: baseClassName,\n role: baseRole,\n \"aria-checked\": _ariaChecked,\n \"aria-pressed\": _ariaPressed,\n ...restRootProps\n } = rootProps as typeof rootProps & {\n ref?: Ref<HTMLButtonElement>;\n className?: string;\n role?: string;\n \"aria-checked\"?: boolean;\n \"aria-pressed\"?: boolean;\n };\n\n const isNeutral = variant === \"neutral\";\n\n // Squircle-aware border-radius (used by both variants)\n const squircleRadius =\n \"rounded-[5px] supports-[corner-shape:squircle]:rounded-[10px] [corner-shape:squircle]\";\n\n // Size styles matching Kyle's stratus implementation\n const sizeStyles = {\n sm: { track: \"h-4 w-8\", thumb: \"w-4\", slide: \"left-4\" },\n base: { track: \"h-4.5 w-9\", thumb: \"w-4.5\", slide: \"left-4.5\" },\n lg: { track: \"h-5 w-10\", thumb: \"w-5\", slide: \"left-5\" },\n };\n const s = sizeStyles[size];\n\n // Track colors based on variant\n const trackColors = isNeutral\n ? state.checked\n ? \"bg-neutral-500 dark:bg-kumo-base ring-neutral-600 dark:ring-neutral-700\"\n : \"bg-neutral-150 dark:bg-kumo-base ring-kumo-line\"\n : state.checked\n ? \"bg-blue-500 dark:bg-blue-600 ring-blue-600 dark:ring-blue-500\"\n : \"bg-neutral-200 dark:bg-neutral-700 ring-neutral-300 dark:ring-neutral-600\";\n\n // Thumb colors based on variant\n const thumbColors = isNeutral\n ? state.checked\n ? \"ring-neutral-600 dark:ring-neutral-200 bg-kumo-base dark:bg-neutral-400\"\n : \"bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700\"\n : state.checked\n ? \"ring-blue-600 dark:ring-blue-100 bg-kumo-base dark:bg-blue-300\"\n : \"bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700\";\n\n const trackClassName = cn(\n \"relative inline-flex items-center ring cursor-pointer border-none p-0\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n \"transition-colors duration-150 ease-out motion-reduce:transition-none\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n s.track,\n squircleRadius,\n trackColors,\n className,\n baseClassName,\n );\n\n const thumbClassName = cn(\n \"absolute top-0 bottom-0 shadow-sm ring-1\",\n s.thumb,\n squircleRadius,\n thumbColors,\n \"transition-all duration-150 ease-out motion-reduce:transition-none\",\n state.checked ? s.slide : \"left-0\",\n );\n\n const role =\n (props.role as string | undefined) ?? baseRole ?? \"switch\";\n const checkedA11yProps =\n role === \"switch\"\n ? { \"aria-checked\": state.checked }\n : { \"aria-pressed\": state.checked };\n\n return (\n <button\n {...restRootProps}\n {...props}\n ref={rootRef}\n type=\"button\"\n role={role}\n {...checkedA11yProps}\n aria-busy={transitioning || undefined}\n aria-label={props[\"aria-label\"] ?? ariaLabelFallback}\n className={trackClassName}\n >\n <div className={thumbClassName} />\n </button>\n );\n }}\n />\n );\n\n // Wrap in Field (built-in) - no description for single switches\n // If no label provided, return bare switch (for use in other components)\n if (!label) {\n return switchControl;\n }\n\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n controlFirst={controlFirst}\n >\n {switchControl}\n </Field>\n );\n },\n);\n\nSwitchBase.displayName = \"Switch\";\n\n// Switch.Item for use within Switch.Group\nconst SwitchItem = forwardRef<HTMLButtonElement, SwitchItemProps>(\n (\n {\n className,\n checked,\n disabled,\n size = \"base\",\n variant = \"default\",\n label,\n onCheckedChange,\n transitioning,\n },\n ref,\n ) => {\n const { controlFirst } = useContext(SwitchGroupContext);\n\n return (\n <label\n className={cn(\n \"m-0 relative inline-flex items-center gap-2\",\n // Control first (default): switch before label\n // Label first: label before switch using flex-row-reverse\n !controlFirst && \"flex-row-reverse justify-end\",\n disabled ? \"cursor-not-allowed opacity-50\" : \"cursor-pointer\",\n className,\n )}\n >\n <BaseSwitch.Root\n ref={ref}\n checked={checked}\n disabled={disabled}\n onCheckedChange={onCheckedChange}\n nativeButton\n render={(rootProps, state) => {\n const {\n ref: rootRef,\n className: baseClassName,\n role: baseRole,\n \"aria-checked\": _ariaChecked,\n \"aria-pressed\": _ariaPressed,\n ...restRootProps\n } = rootProps as typeof rootProps & {\n ref?: Ref<HTMLButtonElement>;\n className?: string;\n role?: string;\n \"aria-checked\"?: boolean;\n \"aria-pressed\"?: boolean;\n };\n\n const isNeutral = variant === \"neutral\";\n\n // Squircle-aware border-radius (used by both variants)\n const squircleRadius =\n \"rounded-[5px] supports-[corner-shape:squircle]:rounded-[10px] [corner-shape:squircle]\";\n\n // Size styles matching Kyle's stratus implementation\n const sizeStyles = {\n sm: { track: \"h-4 w-8\", thumb: \"w-4\", slide: \"left-4\" },\n base: { track: \"h-4.5 w-9\", thumb: \"w-4.5\", slide: \"left-4.5\" },\n lg: { track: \"h-5 w-10\", thumb: \"w-5\", slide: \"left-5\" },\n };\n const s = sizeStyles[size];\n\n // Track colors based on variant\n const trackColors = isNeutral\n ? state.checked\n ? \"bg-neutral-500 dark:bg-kumo-base ring-neutral-600 dark:ring-neutral-700\"\n : \"bg-neutral-150 dark:bg-kumo-base ring-kumo-line\"\n : state.checked\n ? \"bg-blue-500 dark:bg-blue-600 ring-blue-600 dark:ring-blue-500\"\n : \"bg-neutral-200 dark:bg-neutral-700 ring-neutral-300 dark:ring-neutral-600\";\n\n // Thumb colors based on variant\n const thumbColors = isNeutral\n ? state.checked\n ? \"ring-neutral-600 dark:ring-neutral-200 bg-kumo-base dark:bg-neutral-400\"\n : \"bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700\"\n : state.checked\n ? \"ring-blue-600 dark:ring-blue-100 bg-kumo-base dark:bg-blue-300\"\n : \"bg-kumo-base dark:bg-neutral-850 ring-neutral-300 dark:ring-neutral-700\";\n\n const trackClassName = cn(\n \"relative inline-flex items-center ring cursor-pointer border-none p-0\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500\",\n \"transition-colors duration-150 ease-out motion-reduce:transition-none\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n s.track,\n squircleRadius,\n trackColors,\n baseClassName,\n );\n\n const thumbClassName = cn(\n \"absolute top-0 bottom-0 shadow-sm ring-1\",\n s.thumb,\n squircleRadius,\n thumbColors,\n \"transition-all duration-150 ease-out motion-reduce:transition-none\",\n state.checked ? s.slide : \"left-0\",\n );\n\n const role = baseRole ?? \"switch\";\n const checkedA11yProps =\n role === \"switch\"\n ? { \"aria-checked\": state.checked }\n : { \"aria-pressed\": state.checked };\n\n return (\n <button\n {...restRootProps}\n ref={rootRef}\n type=\"button\"\n role={role}\n {...checkedA11yProps}\n aria-busy={transitioning || undefined}\n className={trackClassName}\n >\n <div className={thumbClassName} />\n </button>\n );\n }}\n />\n <span className=\"text-base font-medium text-kumo-default\">{label}</span>\n </label>\n );\n },\n);\n\nSwitchItem.displayName = \"Switch.Item\";\n\n// Switch.Group with built-in Fieldset\nfunction SwitchGroup({\n legend,\n children,\n error,\n description,\n disabled,\n controlFirst = true,\n className,\n}: SwitchGroupProps) {\n return (\n <SwitchGroupContext.Provider value={{ controlFirst }}>\n <Fieldset.Root\n className={cn(\n \"flex flex-col gap-4 rounded-lg border border-kumo-line p-4\",\n className,\n )}\n disabled={disabled}\n >\n <Fieldset.Legend className=\"text-lg font-medium text-kumo-default\">\n {legend}\n </Fieldset.Legend>\n <div className=\"flex flex-col gap-2\">{children}</div>\n {error && <p className=\"text-sm text-kumo-danger\">{error}</p>}\n {description && (\n <p className=\"text-sm text-kumo-subtle\">{description}</p>\n )}\n </Fieldset.Root>\n </SwitchGroupContext.Provider>\n );\n}\n\n// Compound component\nexport const Switch = Object.assign(SwitchBase, {\n Item: SwitchItem,\n Group: SwitchGroup,\n});\n\nSwitch.displayName = \"Switch\";\n"],"names":["KUMO_SWITCH_VARIANTS","KUMO_SWITCH_DEFAULT_VARIANTS","SwitchGroupContext","createContext","SwitchBase","forwardRef","className","checked","disabled","size","variant","label","labelTooltip","required","controlFirst","onCheckedChange","transitioning","props","ref","ariaLabelFallback","switchControl","jsx","BaseSwitch.Root","rootProps","state","rootRef","baseClassName","baseRole","_ariaChecked","_ariaPressed","restRootProps","isNeutral","squircleRadius","s","trackColors","thumbColors","trackClassName","cn","thumbClassName","role","checkedA11yProps","Field","SwitchItem","useContext","jsxs","SwitchGroup","legend","children","error","description","Fieldset.Root","Fieldset.Legend","Switch"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as t } from "react/jsx-runtime";
|
|
3
3
|
import { forwardRef as s } from "react";
|
|
4
4
|
import { c as r } from "./cn-ct4n7r74mh8y0f48.js";
|
|
5
|
-
import { C as m } from "./checkbox-
|
|
5
|
+
import { C as m } from "./checkbox-f4qsbq6xycaji7qw.js";
|
|
6
6
|
const h = {
|
|
7
7
|
layout: {
|
|
8
8
|
auto: {
|
|
@@ -35,7 +35,7 @@ const h = {
|
|
|
35
35
|
// Row border
|
|
36
36
|
"[&_td]:p-3",
|
|
37
37
|
// Cell padding
|
|
38
|
-
"[&_th]:border-b [&_th]:border-kumo-fill [&_th]:p-3 [&_th]:font-semibold",
|
|
38
|
+
"[&_th]:border-b [&_th]:border-kumo-fill [&_th]:p-3 [&_th]:font-semibold [&_th]:text-base",
|
|
39
39
|
// Header styles
|
|
40
40
|
"[&_th]:bg-kumo-base",
|
|
41
41
|
// Header background color
|
|
@@ -152,4 +152,4 @@ export {
|
|
|
152
152
|
R as T,
|
|
153
153
|
h as a
|
|
154
154
|
};
|
|
155
|
-
//# sourceMappingURL=table-
|
|
155
|
+
//# sourceMappingURL=table-g41yb7ruredizqr8.js.map
|