@cloudflare/kumo 1.15.0 → 1.16.0
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 +34 -0
- package/ai/component-registry.json +317 -13
- package/ai/component-registry.md +507 -26
- package/ai/schemas.ts +18 -2
- package/dist/.build-complete +1 -1
- package/dist/ai/schemas.d.ts +57 -2
- package/dist/ai/schemas.d.ts.map +1 -1
- package/dist/ai/schemas.js +366 -341
- package/dist/ai/schemas.js.map +1 -1
- package/dist/chunks/{Legend-mkh1v83sz972e29d.js → Legend-bov5dqf08wemc2qj.js} +112 -100
- package/dist/chunks/Legend-bov5dqf08wemc2qj.js.map +1 -0
- package/dist/chunks/{checkbox-bvzuggmadtqawis4.js → checkbox-lawmt1894wr6rpgi.js} +3 -3
- package/dist/chunks/{checkbox-bvzuggmadtqawis4.js.map → checkbox-lawmt1894wr6rpgi.js.map} +1 -1
- package/dist/chunks/{clipboard-text-mwcknzn75qdvigrd.js → clipboard-text-ohx8kkpxisz382rj.js} +3 -3
- package/dist/chunks/{clipboard-text-mwcknzn75qdvigrd.js.map → clipboard-text-ohx8kkpxisz382rj.js.map} +1 -1
- package/dist/chunks/{combobox-ndbaroqh1c0u49ye.js → combobox-ft0u7rfaxawk0r0c.js} +4 -4
- package/dist/chunks/{combobox-ndbaroqh1c0u49ye.js.map → combobox-ft0u7rfaxawk0r0c.js.map} +1 -1
- package/dist/chunks/{command-palette-ejoszjfivybu9yi5.js → command-palette-b31nq4wk7o7gx4sa.js} +2 -2
- package/dist/chunks/{command-palette-ejoszjfivybu9yi5.js.map → command-palette-b31nq4wk7o7gx4sa.js.map} +1 -1
- package/dist/chunks/{dialog-gkmecnx48ge38jrr.js → dialog-l5tmwxrzp9g83jmw.js} +2 -2
- package/dist/chunks/{dialog-gkmecnx48ge38jrr.js.map → dialog-l5tmwxrzp9g83jmw.js.map} +1 -1
- package/dist/chunks/{dropdown-i8n7nv3cvkvb1x3e.js → dropdown-icy3xatdwhzr4une.js} +2 -2
- package/dist/chunks/{dropdown-i8n7nv3cvkvb1x3e.js.map → dropdown-icy3xatdwhzr4une.js.map} +1 -1
- package/dist/chunks/{field-lweivfadxgpqhuqi.js → field-csje72m7j9403fj5.js} +3 -3
- package/dist/chunks/{field-lweivfadxgpqhuqi.js.map → field-csje72m7j9403fj5.js.map} +1 -1
- package/dist/chunks/hcl-hcu7d6ja6t540ijn.js +8 -0
- package/dist/chunks/hcl-hcu7d6ja6t540ijn.js.map +1 -0
- package/dist/chunks/{input-area-obli4ufvu40bfpgp.js → input-area-jko15sbc6zeage3l.js} +4 -4
- package/dist/chunks/{input-area-obli4ufvu40bfpgp.js.map → input-area-jko15sbc6zeage3l.js.map} +1 -1
- package/dist/chunks/{input-ko2dne1givlxq7sz.js → input-c8jmidy7gdqfiky1.js} +3 -3
- package/dist/chunks/{input-ko2dne1givlxq7sz.js.map → input-c8jmidy7gdqfiky1.js.map} +1 -1
- package/dist/chunks/{input-group-dwtsd04lzf2bcsdo.js → input-group-cjsy8kh4vf9312xl.js} +2 -2
- package/dist/chunks/{input-group-dwtsd04lzf2bcsdo.js.map → input-group-cjsy8kh4vf9312xl.js.map} +1 -1
- package/dist/chunks/{label-kjahhybc191quieo.js → label-i46xnnzdh9bsxk6a.js} +2 -2
- package/dist/chunks/{label-kjahhybc191quieo.js.map → label-i46xnnzdh9bsxk6a.js.map} +1 -1
- package/dist/chunks/{link-lpzl5s47pmobk361.js → link-o7yfj4kwgl19fklp.js} +2 -2
- package/dist/chunks/{link-lpzl5s47pmobk361.js.map → link-o7yfj4kwgl19fklp.js.map} +1 -1
- package/dist/chunks/{menubar-ifxxdoa35zz79z1q.js → menubar-g1wqqjuyyfvsim83.js} +2 -2
- package/dist/chunks/{menubar-ifxxdoa35zz79z1q.js.map → menubar-g1wqqjuyyfvsim83.js.map} +1 -1
- package/dist/chunks/{meter-fbtqfg0okpwmaiju.js → meter-cqkrg5axjenbsuue.js} +2 -2
- package/dist/chunks/{meter-fbtqfg0okpwmaiju.js.map → meter-cqkrg5axjenbsuue.js.map} +1 -1
- package/dist/chunks/{pagination-eo0gzzm7v5w8niqe.js → pagination-e3dp8bd80s35f7sd.js} +3 -3
- package/dist/chunks/{pagination-eo0gzzm7v5w8niqe.js.map → pagination-e3dp8bd80s35f7sd.js.map} +1 -1
- package/dist/chunks/{popover-dd7hi5ajeoq9od1i.js → popover-jurf834u2uywluux.js} +2 -2
- package/dist/chunks/{popover-dd7hi5ajeoq9od1i.js.map → popover-jurf834u2uywluux.js.map} +1 -1
- package/dist/chunks/{radio-oi9iw7ls1t04j377.js → radio-l9dzm6sohcvvrsdc.js} +2 -2
- package/dist/chunks/{radio-oi9iw7ls1t04j377.js.map → radio-l9dzm6sohcvvrsdc.js.map} +1 -1
- package/dist/chunks/{select-0m0xklfwdlx8dwba.js → select-hnt87e3cfos48qql.js} +3 -3
- package/dist/chunks/{select-0m0xklfwdlx8dwba.js.map → select-hnt87e3cfos48qql.js.map} +1 -1
- package/dist/chunks/{sensitive-input-rjpykxn2llh0thx1.js → sensitive-input-lvtccf3iqc06lj7b.js} +4 -4
- package/dist/chunks/{sensitive-input-rjpykxn2llh0thx1.js.map → sensitive-input-lvtccf3iqc06lj7b.js.map} +1 -1
- package/dist/chunks/sidebar-l6rk9o5qf8k5vth1.js +875 -0
- package/dist/chunks/sidebar-l6rk9o5qf8k5vth1.js.map +1 -0
- package/dist/chunks/{switch-lv4mrrkfl5uc99xo.js → switch-fukrbip86khvqjn7.js} +3 -3
- package/dist/chunks/{switch-lv4mrrkfl5uc99xo.js.map → switch-fukrbip86khvqjn7.js.map} +1 -1
- package/dist/chunks/{table-fh7jmfip27vdapxm.js → table-orfgzwvxh8yr90dk.js} +2 -2
- package/dist/chunks/{table-fh7jmfip27vdapxm.js.map → table-orfgzwvxh8yr90dk.js.map} +1 -1
- package/dist/chunks/{tabs-hy6oa7xtf96d9mxt.js → tabs-n0t7iro7wr0pzgk2.js} +2 -2
- package/dist/chunks/{tabs-hy6oa7xtf96d9mxt.js.map → tabs-n0t7iro7wr0pzgk2.js.map} +1 -1
- package/dist/chunks/{toast-kswfqmjysxcrwij3.js → toast-r9ajsces7xp8l85w.js} +8 -8
- package/dist/chunks/{toast-kswfqmjysxcrwij3.js.map → toast-r9ajsces7xp8l85w.js.map} +1 -1
- package/dist/chunks/{tooltip-k68wcv9mrigb7rcb.js → tooltip-hnc71tg4gz2gpcvc.js} +2 -2
- package/dist/chunks/{tooltip-k68wcv9mrigb7rcb.js.map → tooltip-hnc71tg4gz2gpcvc.js.map} +1 -1
- package/dist/chunks/{vendor-base-ui-cpvkrhz4zgw9nw2b.js → vendor-base-ui-ccr5l0ynrievzzv3.js} +564 -563
- package/dist/chunks/{vendor-base-ui-cpvkrhz4zgw9nw2b.js.map → vendor-base-ui-ccr5l0ynrievzzv3.js.map} +1 -1
- package/dist/code/server.js +2 -1
- package/dist/code/server.js.map +1 -1
- package/dist/code.js +14 -13
- package/dist/code.js.map +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/field.js +1 -1
- package/dist/components/flow.js +2138 -2087
- 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/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/sidebar.js +35 -0
- package/dist/components/sidebar.js.map +1 -0
- 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 +194 -163
- package/dist/index.js.map +1 -1
- 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/src/code/provider.d.ts.map +1 -1
- package/dist/src/code/server.d.ts.map +1 -1
- package/dist/src/code/types.d.ts +1 -1
- package/dist/src/code/types.d.ts.map +1 -1
- package/dist/src/components/chart/EChart.d.ts.map +1 -1
- package/dist/src/components/chart/TimeseriesChart.d.ts +11 -1
- package/dist/src/components/chart/TimeseriesChart.d.ts.map +1 -1
- package/dist/src/components/flow/diagram.d.ts.map +1 -1
- package/dist/src/components/flow/node.d.ts.map +1 -1
- package/dist/src/components/flow/parallel.d.ts.map +1 -1
- package/dist/src/components/sidebar/index.d.ts +2 -0
- package/dist/src/components/sidebar/index.d.ts.map +1 -0
- package/dist/src/components/sidebar/sidebar.d.ts +556 -0
- package/dist/src/components/sidebar/sidebar.d.ts.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/styles/kumo-standalone.css +1 -1
- package/package.json +6 -2
- package/scripts/component-registry/index.ts +12 -0
- package/dist/chunks/Legend-mkh1v83sz972e29d.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensitive-input-rjpykxn2llh0thx1.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":";;;;;;;;AAqBO,MAAMA,KAAgCC,IAEhCC,IAAwC;AAAA,EACnD,MAAM;AAAA,EACN,SAAS;AACX,GA6DaC,KAAiBC;AAAA,EAC5B,CACE;AAAA,IACE,OAAOC;AAAA,IACP,cAAAC,IAAe;AAAA,IACf,UAAAC;AAAA,IACA,eAAAC;AAAA,IACA,QAAAC;AAAA,IACA,MAAAC,IAAOR,EAAsC;AAAA,IAC7C,SAAAS,IAAUT,EAAsC;AAAA,IAChD,UAAAU,IAAW;AAAA,IACX,UAAAC,IAAW;AAAA,IACX,IAAAC;AAAA,IACA,cAAAC,IAAe;AAAA,IACf,WAAAC;AAAA,IACA,OAAAC;AAAA,IACA,cAAAC;AAAA,IACA,aAAAC;AAAA,IACA,OAAAC;AAAA,IACA,UAAAC;AAAA,IACA,GAAGC;AAAA,EAAA,GAELC,MACG;AAEH,UAAMC,IACJ,OAAOP,KAAU,WAAWA,IAAQ,mBAChCQ,IAAepB,MAAoB,QACnC,CAACqB,GAAeC,CAAgB,IAAIC,EAAStB,CAAY,GACzDuB,IAAQJ,IAAepB,IAAkBqB,GACzCI,IAAWD,EAAM,SAAS,GAE1B,CAACE,GAAMC,CAAO,IAAIJ;AAAA,MAAe,MACrCE,IAAW,WAAW;AAAA,IAAA,GAGlB,CAACG,GAAQC,CAAS,IAAIN,EAAS,EAAK,GAEpCO,IAAWC,EAAgC,IAAI,GAC/CC,IAAeD,EAAuB,IAAI,GAC1CE,IAAeC,EAAA,GACfC,IAAcD,EAAA,GACdE,IAAU3B,KAAM0B,GAChBE,IAAsBH,EAAA,GAEtBI,IAAYC;AAAA,MAChB,CAACC,MAAkC;AACjC,QAAAV,EAAS,UAAUU,GACf,OAAOtB,KAAQ,aACjBA,EAAIsB,CAAI,IACCtB,MACTA,EAAI,UAAUsB;AAAA,MAElB;AAAA,MACA,CAACtB,CAAG;AAAA,IAAA;AAIN,IAAAuB,GAAU,MAAM;AACd,UAAIb,GAAQ;AACV,cAAMc,IAAY,WAAW,MAAMb,EAAU,EAAK,GAAG,GAAI;AACzD,eAAO,MAAM,aAAaa,CAAS;AAAA,MACrC;AAAA,IACF,GAAG,CAACd,CAAM,CAAC;AAEX,UAAMe,KAAkBJ;AAAA,MACtB,OAAO,MAA2C;AAChD,UAAE,gBAAA;AACF,YAAI;AACF,cACE,OAAO,YAAc,OACrB,UAAU,aACV,OAAO,UAAU,UAAU,aAAc,YACzC;AACA,kBAAM,UAAU,UAAU,UAAUf,CAAK,GACzCK,EAAU,EAAI,GACdzB,IAAA;AACA;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAER;AAEA,YAAI,OAAO,WAAa,KAAa;AACnC,gBAAMwC,IAAW,SAAS,cAAc,UAAU;AAClD,UAAAA,EAAS,QAAQpB,GACjBoB,EAAS,aAAa,YAAY,EAAE,GACpCA,EAAS,MAAM,WAAW,YAC1BA,EAAS,MAAM,OAAO,WACtB,SAAS,KAAK,YAAYA,CAAQ;AAClC,gBAAMC,IAAY,SAAS,aAAA,GACrBC,IAAgBD,GAAW,aAC7BA,EAAU,WAAW,CAAC,IACtB;AACJ,UAAAD,EAAS,OAAA;AACT,cAAI;AACF,qBAAS,YAAY,MAAM,GAC3Bf,EAAU,EAAI,GACdzB,IAAA;AAAA,UACF,SAASW,IAAO;AACd,oBAAQ,KAAK,yBAAyBA,EAAK;AAAA,UAC7C,UAAA;AACE,qBAAS,KAAK,YAAY6B,CAAQ,GAC9BE,MACFD,GAAW,gBAAA,GACXA,GAAW,SAASC,CAAa;AAAA,UAErC;AAAA,QACF;AAAA,MACF;AAAA,MACA,CAACtB,GAAOpB,CAAM;AAAA,IAAA,GAIV2C,IAAkBhB,EAAON,CAAQ;AACvC,IAAIsB,EAAgB,YAAYtB,MAC9BsB,EAAgB,UAAUtB,GACtB,CAACA,KAAYC,MAAS,YACxBC,EAAQ,OAAO;AAInB,UAAMqB,KAAuBT;AAAA,MAC3B,CAAC,MAAwB;AACvB,YAAI,CAAAhC,GAGJ;AAAA,cAAIyB,EAAa,SAAS;AACxB,kBAAMiB,IAAOjB,EAAa,QAAQ,sBAAA;AAMlC,gBAAI,EAJF,EAAE,WAAWiB,EAAK,QAClB,EAAE,WAAWA,EAAK,SAClB,EAAE,WAAWA,EAAK,OAClB,EAAE,WAAWA,EAAK,QACS;AAAA,UAC/B;AACA,UAAIvB,MAAS,YAAYD,MACvBE,EAAQ,UAAU,GACbnB,KACH,WAAW,MAAMsB,EAAS,SAAS,MAAA,GAAS,CAAC;AAAA;AAAA,MAGnD;AAAA,MACA,CAACJ,GAAMD,GAAUlB,GAAUC,CAAQ;AAAA,IAAA,GAG/B0C,KAAyBX;AAAA,MAC7B,CAAC,MAA2C;AAC1C,UAAE,gBAAA,GACEb,MAAS,aACXC,EAAQ,QAAQ,IACPD,MAAS,WAAWD,KAC7BE,EAAQ,UAAU;AAAA,MAEtB;AAAA,MACA,CAACD,GAAMD,CAAQ;AAAA,IAAA,GAGX0B,KAAeZ;AAAA,MACnB,CAAC,MAA2C;AAC1C,cAAMa,IAAW,EAAE,OAAO;AAC1B,QAAKhC,KACHE,EAAiB8B,CAAQ,GAE3BlD,IAAW,CAAC,GACZC,IAAgBiD,CAAQ;AAAA,MAC1B;AAAA,MACA,CAAChC,GAAclB,GAAUC,CAAa;AAAA,IAAA,GAGlCkD,KAAad;AAAA,MACjB,CAAC,MAA0C;AAEzC,QACEP,EAAa,WACb,EAAE,yBAAyB,QAC3BA,EAAa,QAAQ,SAAS,EAAE,aAAa,KAI3CP,KACFE,EAAQ,QAAQ;AAAA,MAEpB;AAAA,MACA,CAACF,CAAQ;AAAA,IAAA,GAGL6B,KAAyBf;AAAA,MAC7B,CAAC,MAA2C;AAC1C,QAAIhC,KACAmB,MAAS,YAAYD,MACnB,EAAE,QAAQ,WAAW,EAAE,QAAQ,SACjC,EAAE,eAAA,GACFE,EAAQ,UAAU,GACbnB,KACH,WAAW,MAAMsB,EAAS,SAAS,MAAA,GAAS,CAAC;AAAA,MAIrD;AAAA,MACA,CAACJ,GAAMD,GAAUlB,GAAUC,CAAQ;AAAA,IAAA,GAG/B+C,KAAqBhB;AAAA,MACzB,CAAC,MAA6C;AAC5C,QAAIb,MAAS,cAAc,EAAE,QAAQ,aACnCC,EAAQ,QAAQ,GAEhB,WAAW,MAAMK,EAAa,SAAS,MAAA,GAAS,CAAC;AAAA,MAErD;AAAA,MACA,CAACN,CAAI;AAAA,IAAA,GAGD8B,IAAoB9B,MAAS,YAAYD,GACzCgC,IACJ,CAAClD,MAAamB,MAAS,cAAeA,MAAS,WAAWD,IAGtDiC,KAAWrD,MAAS,QAAQA,MAAS,OAAO,WAAW,UAEvDsD,IAAqBC;AAAA,MACzBC,GAAc,EAAE,MAAAxD,GAAM,SAAAC,GAAS,sBAAsB,IAAM;AAAA,MAC3D;AAAA,MACAkD,KAAqB,CAACjD,KAAY;AAAA,MAClCA,KAAY;AAAA,MACZI;AAAA,IAAA,GAGImD,IACJ,gBAAAC,EAAAC,IAAA,EAEE,UAAA;AAAA,MAAA,gBAAAC;AAAA,QAACC;AAAAA,QAAA;AAAA,UACC,KAAK5B;AAAA,UACL,IAAIF;AAAA,UACJ,MAAMV,MAAS,aAAa,SAAS;AAAA,UACrC,OAAAF;AAAA,UACA,UAAU2B;AAAA,UACV,QAAQE;AAAA,UACR,WAAWE;AAAA,UACX,UAAAhD;AAAA,UACA,UAAUC,KAAYgD;AAAA,UACtB,cAAA9C;AAAA,UACA,UAAU8C,IAAoB,KAAK;AAAA,UACnC,WAAWI;AAAA,YACT;AAAA,YACAvD,MAAS,QAAQ;AAAA,YACjBA,MAAS,QAAQ;AAAA,YACjBA,MAAS,UAAU;AAAA,YACnBA,MAAS,QAAQ;AAAA,YACjBmD,KAAqB;AAAA,UAAA;AAAA,UAEvB,eAAaA;AAAA,UACZ,GAAGvC;AAAA,QAAA;AAAA,MAAA;AAAA,MAIN,gBAAAgD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWL;AAAA,YACT;AAAA;AAAA,YAEAvD,MAAS,QAAQ;AAAA,YACjBA,MAAS,QAAQ;AAAA,YACjBA,MAAS,UAAU;AAAA,YACnBA,MAAS,QAAQ;AAAA;AAAA,YAEjBA,MAAS,QAAQ;AAAA,YACjBA,MAAS,QAAQ;AAAA,YACjBA,MAAS,UAAU;AAAA,YACnBA,MAAS,QAAQ;AAAA;AAAA,YAEjB,CAACmD,KAAqB;AAAA;AAAA,YAEtBA,KAAqB;AAAA;AAAA,YAErB;AAAA;AAAA,YAEA;AAAA,UAAA;AAAA,UAEF,eAAY;AAAA,UAGZ,UAAA,gBAAAO,EAAC,QAAA,EAAK,WAAU,YACd,UAAA;AAAA,YAAA,gBAAAE;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,WAAWL;AAAA,kBACTJ,KACE,CAACjD,KACD;AAAA,gBAAA;AAAA,gBAEL,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGAiD,KAAqB,CAACjD,uBACpB,QAAA,EAAK,WAAU,oIAAmI,UAAA,kBAAA,CAEnJ;AAAA,UAAA,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,MAIF,gBAAA0D;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAASf;AAAA,UACT,WAAW,CAAC,MAAM,EAAE,gBAAA;AAAA,UACpB,cAAYxB,MAAS,aAAa,eAAe;AAAA,UACjD,UAAU+B,IAAgB,IAAI;AAAA,UAC9B,WAAWG;AAAA,YACT;AAAA;AAAA,YAEAvD,MAAS,QAAQ;AAAA,YACjBA,MAAS,QAAQ;AAAA,YACjBA,MAAS,UAAU;AAAA,YACnBA,MAAS,QAAQ;AAAA,YACjBqD;AAAA,YACA,CAACD,KAAiB;AAAA,UAAA;AAAA,UAGnB,UAAA/B,MAAS,aACR,gBAAAuC,EAACE,IAAA,EAAS,WAAU,aAAY,IAEhC,gBAAAF,EAACG,IAAA,EAAI,WAAU,YAAA,CAAY;AAAA,QAAA;AAAA,MAAA;AAAA,MAK9B3C,KAAY,CAAClB,KACZ,gBAAA0D;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAStB;AAAA,UACT,WAAW,CAAC,MAAM,EAAE,gBAAA;AAAA,UACpB,cAAYf,IAAS,WAAW;AAAA,UAChC,WAAWgC;AAAA,YACT;AAAA,UAAA;AAAA,UAGD,cAAS,WAAW;AAAA,QAAA;AAAA,MAAA;AAAA,IACvB,GAEJ,GAGIS,sBACH,OAAA,EACE,UAAA;AAAA,MAAAb,IACC,gBAAAS;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAKjC;AAAA,UAIL,MAAK;AAAA,UACL,UAAUzB,IAAW,KAAK;AAAA,UAC1B,WAAWoD;AAAA,UACX,SAASX;AAAA,UACT,WAAWM;AAAA,UACX,cAAY,GAAGnC,CAAiB;AAAA,UAChC,oBAAkB,GAAGkB,CAAmB,IAAIJ,CAAY;AAAA,UACxD,iBAAe1B;AAAA,UAEd,UAAAuD;AAAA,QAAA;AAAA,MAAA,IAGH,gBAAAG,EAAC,OAAA,EAAI,KAAKjC,GAAc,WAAW2B,GAChC,UAAAG,GACH;AAAA,MAEDN,KACC,gBAAAS,EAAC,QAAA,EAAK,IAAI5B,GAAqB,WAAU,WAAU,UAAA,mCAEnD;AAAA,wBAED,QAAA,EAAK,IAAIJ,GAAc,WAAU,WAAU,aAAU,UACnD,UAAA;AAAA,QAAAP,MAAS,YAAYD,KAAY;AAAA,QACjCG,KAAU;AAAA,MAAA,EAAA,CACb;AAAA,IAAA,GACF;AAIF,WAAIhB,IAEA,gBAAAqD;AAAA,MAACK;AAAA,MAAA;AAAA,QACC,OAAA1D;AAAA,QACA,UAAAI;AAAA,QACA,cAAAH;AAAA,QACA,aAAAC;AAAA,QACA,OACEC,IACI,OAAOA,KAAU,WACf,EAAE,SAASA,GAAO,OAAO,GAAA,IACzBA,IACF;AAAA,QAGL,UAAAsD;AAAA,MAAA;AAAA,IAAA,IAMAA;AAAA,EACT;AACF;AAEAvE,GAAe,cAAc;"}
|
|
1
|
+
{"version":3,"file":"sensitive-input-lvtccf3iqc06lj7b.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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"}
|