@spark-ui/components 17.10.5-beta.0 → 17.11.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/dist/accordion/index.js +1 -1
- package/dist/accordion/index.js.map +1 -1
- package/dist/accordion/index.mjs +1 -1
- package/dist/accordion/index.mjs.map +1 -1
- package/dist/alert-dialog/index.js +1 -1
- package/dist/alert-dialog/index.js.map +1 -1
- package/dist/alert-dialog/index.mjs +1 -1
- package/dist/alert-dialog/index.mjs.map +1 -1
- package/dist/avatar/index.js +1 -1
- package/dist/avatar/index.js.map +1 -1
- package/dist/avatar/index.mjs +17 -17
- package/dist/avatar/index.mjs.map +1 -1
- package/dist/button/index.js +1 -1
- package/dist/button/index.mjs +1 -1
- package/dist/{button-BtuAr9qV.mjs → button-CNabSkd_.mjs} +2 -2
- package/dist/{button-BtuAr9qV.mjs.map → button-CNabSkd_.mjs.map} +1 -1
- package/dist/{button-BaJmiSYq.js → button-Tv2N8_24.js} +2 -2
- package/dist/{button-BaJmiSYq.js.map → button-Tv2N8_24.js.map} +1 -1
- package/dist/card/index.js +1 -1
- package/dist/card/index.js.map +1 -1
- package/dist/card/index.mjs +1 -1
- package/dist/card/index.mjs.map +1 -1
- package/dist/carousel/index.js +1 -1
- package/dist/carousel/index.js.map +1 -1
- package/dist/carousel/index.mjs +2 -2
- package/dist/carousel/index.mjs.map +1 -1
- package/dist/checkbox/index.js +1 -1
- package/dist/checkbox/index.mjs +1 -1
- package/dist/{checkbox-xsURzANi.mjs → checkbox-CbMh-21q.mjs} +2 -2
- package/dist/{checkbox-xsURzANi.mjs.map → checkbox-CbMh-21q.mjs.map} +1 -1
- package/dist/{checkbox-DjwbAH09.js → checkbox-hVGRiWC_.js} +2 -2
- package/dist/{checkbox-DjwbAH09.js.map → checkbox-hVGRiWC_.js.map} +1 -1
- package/dist/chip/index.js +1 -1
- package/dist/chip/index.js.map +1 -1
- package/dist/chip/index.mjs +1 -1
- package/dist/chip/index.mjs.map +1 -1
- package/dist/circular-meter/index.js +1 -1
- package/dist/circular-meter/index.js.map +1 -1
- package/dist/circular-meter/index.mjs +28 -28
- package/dist/circular-meter/index.mjs.map +1 -1
- package/dist/combobox/index.js +1 -1
- package/dist/combobox/index.js.map +1 -1
- package/dist/combobox/index.mjs +10 -13
- package/dist/combobox/index.mjs.map +1 -1
- package/dist/dialog/index.js +1 -1
- package/dist/dialog/index.js.map +1 -1
- package/dist/dialog/index.mjs +2 -2
- package/dist/dialog/index.mjs.map +1 -1
- package/dist/drawer/index.js +1 -1
- package/dist/drawer/index.js.map +1 -1
- package/dist/drawer/index.mjs +2 -2
- package/dist/drawer/index.mjs.map +1 -1
- package/dist/dropdown/index.js +1 -1
- package/dist/dropdown/index.js.map +1 -1
- package/dist/dropdown/index.mjs +9 -12
- package/dist/dropdown/index.mjs.map +1 -1
- package/dist/file-upload/index.js +1 -1
- package/dist/file-upload/index.js.map +1 -1
- package/dist/file-upload/index.mjs +5 -5
- package/dist/file-upload/index.mjs.map +1 -1
- package/dist/form-field/index.js +1 -1
- package/dist/form-field/index.mjs +1 -1
- package/dist/form-field-BCqHBvWN.js +2 -0
- package/dist/form-field-BCqHBvWN.js.map +1 -0
- package/dist/{form-field-CV5dzt-I.mjs → form-field-ByLHXtzx.mjs} +27 -27
- package/dist/form-field-ByLHXtzx.mjs.map +1 -0
- package/dist/icon-button/index.js +1 -1
- package/dist/icon-button/index.mjs +1 -1
- package/dist/icon-button-CTe0v0g7.js +2 -0
- package/dist/{icon-button-BSVlcyAO.js.map → icon-button-CTe0v0g7.js.map} +1 -1
- package/dist/{icon-button-XyQSaVPL.mjs → icon-button-DVbKK2_a.mjs} +3 -3
- package/dist/{icon-button-XyQSaVPL.mjs.map → icon-button-DVbKK2_a.mjs.map} +1 -1
- package/dist/input/index.js +1 -1
- package/dist/input/index.mjs +1 -1
- package/dist/{input-CJOeEIbx.mjs → input-BxuTPD5-.mjs} +6 -6
- package/dist/input-BxuTPD5-.mjs.map +1 -0
- package/dist/input-DIGSkxbh.js +2 -0
- package/dist/input-DIGSkxbh.js.map +1 -0
- package/dist/input-otp/index.js +1 -1
- package/dist/input-otp/index.js.map +1 -1
- package/dist/input-otp/index.mjs +27 -17
- package/dist/input-otp/index.mjs.map +1 -1
- package/dist/menu/index.js +1 -1
- package/dist/menu/index.js.map +1 -1
- package/dist/menu/index.mjs +1 -1
- package/dist/menu/index.mjs.map +1 -1
- package/dist/meter/index.js +1 -1
- package/dist/meter/index.js.map +1 -1
- package/dist/meter/index.mjs +17 -17
- package/dist/meter/index.mjs.map +1 -1
- package/dist/pagination/index.js +1 -1
- package/dist/pagination/index.js.map +1 -1
- package/dist/pagination/index.mjs +3 -3
- package/dist/pagination/index.mjs.map +1 -1
- package/dist/popover/index.js +1 -1
- package/dist/popover/index.mjs +1 -1
- package/dist/{popover-CSmCERcL.mjs → popover-83FABwMs.mjs} +3 -3
- package/dist/popover-83FABwMs.mjs.map +1 -0
- package/dist/popover-Daknmg_Z.js +2 -0
- package/dist/popover-Daknmg_Z.js.map +1 -0
- package/dist/progress/index.js +1 -1
- package/dist/progress/index.mjs +1 -1
- package/dist/{progress-C-Zs94G2.mjs → progress-BfpWgeE1.mjs} +2 -2
- package/dist/{progress-C-Zs94G2.mjs.map → progress-BfpWgeE1.mjs.map} +1 -1
- package/dist/{progress-DaQt4olK.js → progress-DBD2FiQ1.js} +2 -2
- package/dist/{progress-DaQt4olK.js.map → progress-DBD2FiQ1.js.map} +1 -1
- package/dist/progress-tracker/index.js +1 -1
- package/dist/progress-tracker/index.js.map +1 -1
- package/dist/progress-tracker/index.mjs +4 -4
- package/dist/progress-tracker/index.mjs.map +1 -1
- package/dist/radio-group/index.js +1 -1
- package/dist/radio-group/index.js.map +1 -1
- package/dist/radio-group/index.mjs +5 -8
- package/dist/radio-group/index.mjs.map +1 -1
- package/dist/rating/index.js +1 -1
- package/dist/rating/index.mjs +1 -1
- package/dist/rating-display/index.js +1 -1
- package/dist/rating-display/index.js.map +1 -1
- package/dist/rating-display/index.mjs +1 -1
- package/dist/rating-display/index.mjs.map +1 -1
- package/dist/scrolling-list/index.js +1 -1
- package/dist/scrolling-list/index.js.map +1 -1
- package/dist/scrolling-list/index.mjs +17 -17
- package/dist/scrolling-list/index.mjs.map +1 -1
- package/dist/segmented-control/index.js +1 -1
- package/dist/segmented-control/index.js.map +1 -1
- package/dist/segmented-control/index.mjs +1 -1
- package/dist/segmented-control/index.mjs.map +1 -1
- package/dist/segmented-gauge/index.js +1 -1
- package/dist/segmented-gauge/index.js.map +1 -1
- package/dist/segmented-gauge/index.mjs +1 -1
- package/dist/segmented-gauge/index.mjs.map +1 -1
- package/dist/select/index.js +1 -1
- package/dist/select/index.js.map +1 -1
- package/dist/select/index.mjs +2 -2
- package/dist/select/index.mjs.map +1 -1
- package/dist/slider/index.js +1 -1
- package/dist/slider/index.js.map +1 -1
- package/dist/slider/index.mjs +2 -2
- package/dist/slider/index.mjs.map +1 -1
- package/dist/stepper/index.js +1 -1
- package/dist/stepper/index.js.map +1 -1
- package/dist/stepper/index.mjs +3 -3
- package/dist/stepper/index.mjs.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/table/index.js.map +1 -1
- package/dist/table/index.mjs +36 -36
- package/dist/table/index.mjs.map +1 -1
- package/dist/tabs/index.js +1 -1
- package/dist/tabs/index.js.map +1 -1
- package/dist/tabs/index.mjs +16 -16
- package/dist/tabs/index.mjs.map +1 -1
- package/dist/tag/index.js +1 -1
- package/dist/tag/index.js.map +1 -1
- package/dist/tag/index.mjs +1 -1
- package/dist/tag/index.mjs.map +1 -1
- package/dist/textarea/index.js +1 -1
- package/dist/textarea/index.js.map +1 -1
- package/dist/textarea/index.mjs +2 -2
- package/dist/textarea/index.mjs.map +1 -1
- package/dist/toast/index.js +1 -1
- package/dist/toast/index.mjs +2 -2
- package/package.json +5 -5
- package/dist/form-field-CV5dzt-I.mjs.map +0 -1
- package/dist/form-field-CYGgse45.js +0 -2
- package/dist/form-field-CYGgse45.js.map +0 -1
- package/dist/icon-button-BSVlcyAO.js +0 -2
- package/dist/input-CJOeEIbx.mjs.map +0 -1
- package/dist/input-Dv436NKY.js +0 -2
- package/dist/input-Dv436NKY.js.map +0 -1
- package/dist/popover-CSmCERcL.mjs.map +0 -1
- package/dist/popover-CsCB_Fgs.js +0 -2
- package/dist/popover-CsCB_Fgs.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/input-otp/InputOTPContext.tsx","../../src/input-otp/InputOTP.styles.ts","../../src/input-otp/InputOTPSlot.tsx","../../src/input-otp/useInputOTP.ts","../../src/input-otp/InputOTP.tsx","../../src/input-otp/InputOTPGroup.tsx","../../src/input-otp/InputOTPSeparator.tsx","../../src/input-otp/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputOTPContextValue {\n value: string\n maxLength: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n activeIndex: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n disabled: boolean\n readOnly: boolean\n placeholder?: string\n type: 'text' | 'number' | 'password' | 'tel'\n}\n\nexport const InputOTPContext = createContext<InputOTPContextValue | null>(null)\n\nexport const useInputOTPContext = () => {\n const context = useContext(InputOTPContext)\n if (!context) {\n throw new Error('InputOTP components must be used within InputOTP')\n }\n\n return context\n}\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputOTPContainerStyles = cva(['relative', 'inline-flex', 'items-center', 'gap-sm'])\n\nexport const inputOTPSlotStyles = cva(\n [\n // Base slot styles\n 'relative h-[50px] w-sz-40',\n 'border-sm rounded-md',\n 'text-center text-display-3 text-on-surface',\n 'outline-hidden',\n 'transition-colors',\n 'flex items-center justify-center',\n // Slot that receives focus when clicking the group (first empty or last slot)\n // Use data-[focus-target=true]:... for distinct styles\n // Active state (when focused)\n 'data-[active=true]:ring-1',\n 'data-[active=true]:ring-inset',\n 'data-[active=true]:ring-l-2',\n 'data-[active=true]:border-focus',\n 'data-[active=true]:z-raised ring-focus',\n // Disabled state\n 'data-[disabled=true]:cursor-not-allowed',\n 'data-[disabled=true]:border-outline',\n 'data-[disabled=true]:bg-on-surface/dim-5',\n 'data-[disabled=true]:text-on-surface/dim-3',\n // Read-only state (same as disabled but text stays normal)\n 'data-[readonly=true]:cursor-default',\n 'data-[readonly=true]:data-[active=false]:border-outline',\n 'data-[readonly=true]:bg-on-surface/dim-5',\n 'group-hover:data-[focus-target=true]:data-[disabled=false]:border-outline-high',\n ],\n {\n variants: {\n /**\n * Color scheme of the slot\n */\n intent: {\n neutral: ['data-[filled=true]:bg-neutral-container bg-surface border-outline'],\n success: ['border-success bg-success-container text-on-success-container'],\n alert: ['border-alert bg-alert-container text-on-alert-container'],\n error: ['border-error bg-error-container text-on-error-container'],\n },\n },\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputOTPSlotStylesProps = VariantProps<typeof inputOTPSlotStyles>\n\n// Keep for backward compatibility\nexport const inputOTPStyles = inputOTPSlotStyles\nexport type InputOTPStylesProps = InputOTPSlotStylesProps\n","import { ComponentPropsWithoutRef } from 'react'\n\nimport { inputOTPSlotStyles } from './InputOTP.styles'\nimport { useInputOTPContext } from './InputOTPContext'\n\nexport interface InputOTPSlotProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Index of the slot (0-based).\n * If not provided, will be automatically assigned based on position in children.\n */\n index?: number\n}\n\n/**\n * An individual slot for a single OTP character. Renders a <div> element.\n */\nexport const InputOTPSlot = ({ index: indexProp, className, ...props }: InputOTPSlotProps) => {\n const context = useInputOTPContext()\n\n // Use provided index or fallback to 0 (should not happen if auto-assignment works)\n const index = indexProp ?? 0\n const slot = context.slots[index]\n\n if (!slot) {\n return null\n }\n\n const { char, isActive, hasFakeCaret } = slot\n const isEmpty = !char\n const isPlaceholder = isEmpty && !hasFakeCaret && context.placeholder\n\n const isFocusTarget = index === context.activeIndex\n\n return (\n <div\n className={inputOTPSlotStyles({\n intent: context.intent,\n className,\n })}\n data-active={isActive}\n data-disabled={context.disabled}\n data-readonly={context.readOnly}\n data-filled={!isEmpty}\n data-focus-target={isFocusTarget}\n data-valid={context.intent !== 'error'}\n {...props}\n >\n <span className={isPlaceholder ? 'text-on-surface/dim-3' : ''}>\n {context.type === 'password' && char\n ? '•'\n : char || (!hasFakeCaret && context.placeholder ? context.placeholder : '')}\n </span>\n {hasFakeCaret && (\n <span\n className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"bg-on-surface animate-standalone-caret-blink h-sz-24 w-sz-2\" />\n </span>\n )}\n </div>\n )\n}\n\nInputOTPSlot.displayName = 'InputOTP.Slot'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport {\n ChangeEventHandler,\n ClipboardEventHandler,\n KeyboardEventHandler,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport type { InputOTPContextValue } from './InputOTPContext'\n\nconst BACKSPACE_KEY = 'Backspace'\nconst LEFT_ARROW_KEY = 'ArrowLeft'\nconst UP_ARROW_KEY = 'ArrowUp'\nconst RIGHT_ARROW_KEY = 'ArrowRight'\nconst DOWN_ARROW_KEY = 'ArrowDown'\nconst E_KEY = 'e'\n\nexport interface UseInputOTPProps {\n maxLength: number\n type: 'text' | 'number' | 'password' | 'tel'\n value?: string\n defaultValue: string\n onValueChange?: (value: string) => void\n isValid: boolean\n disabledProp: boolean\n readOnlyProp: boolean\n autoFocus: boolean\n forceUppercase: boolean\n filterKeys: string[]\n pattern?: string\n placeholder: string\n nameProp?: string\n}\n\nexport interface UseInputOTPReturn {\n uuid: string\n inputRef: React.RefObject<HTMLInputElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n name: string | undefined\n disabled: boolean\n readOnly: boolean\n isInvalid: boolean\n isRequired: boolean\n description: string | undefined\n maxLength: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n currentValue: string\n activeIndex: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n contextValue: InputOTPContextValue\n handleChange: ChangeEventHandler<HTMLInputElement>\n handleKeyDown: KeyboardEventHandler<HTMLInputElement>\n handleCopy: ClipboardEventHandler<HTMLInputElement>\n handlePaste: ClipboardEventHandler<HTMLInputElement>\n handleFocus: () => void\n handleBlur: () => void\n handleClick: () => void\n labelId: string | undefined\n}\n\nexport const useInputOTP = ({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n readOnlyProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n}: UseInputOTPProps): UseInputOTPReturn => {\n const uuid = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Get FormField context (optional, falls back gracefully if not present)\n const field = useFormFieldControl()\n\n // Use FormField values if available, otherwise fall back to props\n // Use FormField id when available so label htmlFor works correctly\n const id = field.id ?? uuid\n const name = nameProp ?? field.name\n const disabled = field.disabled ?? disabledProp\n const readOnly = field.readOnly ?? readOnlyProp\n const isInvalid = field.isInvalid ?? !isValid\n const isRequired = field.isRequired ?? false\n const labelId = field.labelId\n const description = field.description\n const fieldState = field.state\n\n // Determine intent based on FormField state or isValid prop\n const getIntent = (): 'neutral' | 'success' | 'alert' | 'error' => {\n // FormField state takes priority\n if (['success', 'alert', 'error'].includes(fieldState ?? '')) {\n return fieldState as 'success' | 'alert' | 'error'\n }\n\n // Fallback to isValid prop for backward compatibility\n if (isInvalid) {\n return 'error'\n }\n\n return 'neutral'\n }\n\n const intent = getIntent()\n\n // Initialize value\n const initialValue = controlledValue !== undefined ? controlledValue : defaultValue\n const processedValue = forceUppercase ? initialValue.toUpperCase() : initialValue\n\n const [internalValue, setInternalValue] = useState<string>(processedValue)\n const [isFocused, setIsFocused] = useState<boolean>(false)\n\n // Use controlled value if provided, otherwise use internal state\n const currentValue = controlledValue !== undefined ? controlledValue : internalValue\n\n // Calculate active index: last empty slot, or last slot if all are filled\n const activeIndex = Math.min(currentValue.length, maxLength - 1)\n\n // Sync cursor position with active index\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.setSelectionRange(activeIndex, activeIndex)\n }\n }, [activeIndex, currentValue.length, maxLength])\n\n // Create slots array\n const slots = useMemo(\n () =>\n Array.from({ length: maxLength }, (_, i) => ({\n char: currentValue[i] || '',\n isActive: i === activeIndex && isFocused,\n hasFakeCaret: i === activeIndex && !currentValue[i] && !disabled && !readOnly && isFocused,\n })),\n [maxLength, currentValue, activeIndex, isFocused, disabled, readOnly]\n )\n\n // Sync controlled value with input ref\n useEffect(() => {\n if (inputRef.current && controlledValue !== undefined) {\n inputRef.current.value = controlledValue\n }\n }, [controlledValue])\n\n // Focus management\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n }\n }, [autoFocus])\n\n const processInputValue = (inputValue: string): string => {\n let processed = inputValue\n\n if (forceUppercase) {\n processed = processed.toUpperCase()\n }\n\n if (type === 'number') {\n processed = processed.replace(/[^\\d]/g, '')\n }\n\n // Filter characters using pattern if provided\n if (pattern) {\n try {\n // Convert HTML pattern (string) to RegExp\n // HTML patterns validate the entire string, but we need to test each character\n // We create a regex that tests if a single character matches the pattern\n // For example: [0-9]* becomes ^[0-9]$ to test a single digit\n // We wrap the pattern in ^...$ to ensure it matches a single character\n let regexPattern = pattern\n // If pattern doesn't start with ^, wrap it to test single character\n if (!pattern.startsWith('^')) {\n regexPattern = `^${pattern}$`\n }\n const regex = new RegExp(regexPattern)\n processed = processed\n .split('')\n .filter(currChar => {\n // Test if the character matches the pattern\n return regex.test(currChar)\n })\n .join('')\n } catch (error) {\n // If pattern is invalid, ignore it and continue with other filters\n console.error('Invalid pattern provided to InputOTP:', pattern, error)\n }\n }\n\n return processed\n }\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = e => {\n if (disabled || readOnly) return\n\n const inputValue = e.target.value\n const processedValue = processInputValue(inputValue)\n\n // Limit to maxLength\n const newValue = processedValue.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {\n if (disabled || readOnly) return\n\n // Allow copy/cut/paste/selectAll shortcuts even when key is in filterKeys\n const isShortcut =\n (e.ctrlKey || e.metaKey) && ['a', 'c', 'v', 'x'].includes(e.key.toLowerCase())\n\n // Filter keys\n if (filterKeys.length > 0 && filterKeys.includes(e.key) && !isShortcut) {\n e.preventDefault()\n\n return\n }\n\n switch (e.key) {\n case BACKSPACE_KEY:\n e.preventDefault()\n const currentLength = currentValue.length\n if (currentLength > 0) {\n const newValue = currentValue.slice(0, currentLength - 1)\n\n // Call onValueChange first\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.max(0, newValue.length)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n break\n\n case LEFT_ARROW_KEY:\n case RIGHT_ARROW_KEY:\n // Prevent navigation with arrow keys - focus stays on last empty slot\n e.preventDefault()\n break\n\n case UP_ARROW_KEY:\n case DOWN_ARROW_KEY:\n e.preventDefault()\n break\n\n case E_KEY:\n case 'E':\n // Prevent 'e' or 'E' in number inputs\n if (type === 'number') {\n e.preventDefault()\n }\n break\n\n default:\n break\n }\n }\n\n const handleCopy: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n e.preventDefault()\n if (currentValue.length > 0) {\n e.clipboardData.setData('text/plain', currentValue)\n }\n }\n\n const handlePaste: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled || readOnly) return\n\n e.preventDefault()\n\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText) return\n\n const processedText = processInputValue(pastedText)\n const newValue = processedText.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Move cursor to end\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleFocus = () => {\n setIsFocused(true)\n if (inputRef.current) {\n // Focus on last empty slot, or last slot if all are filled\n const cursorPosition = Math.min(currentValue.length, maxLength - 1)\n inputRef.current.setSelectionRange(cursorPosition, cursorPosition)\n }\n }\n\n const handleBlur = () => {\n setIsFocused(false)\n }\n\n const handleClick = () => {\n if (inputRef.current) {\n inputRef.current.focus()\n }\n }\n\n const contextValue: InputOTPContextValue = {\n value: currentValue,\n maxLength,\n slots,\n activeIndex,\n intent,\n disabled,\n readOnly,\n placeholder,\n type,\n }\n\n const returnValue: UseInputOTPReturn = {\n uuid: id,\n inputRef,\n containerRef,\n name,\n disabled,\n readOnly,\n isInvalid,\n isRequired,\n description,\n maxLength,\n intent,\n currentValue,\n activeIndex,\n slots,\n contextValue,\n handleChange,\n handleKeyDown,\n handleCopy,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n }\n\n return returnValue\n}\n","/* eslint-disable max-lines-per-function */\nimport { cx } from 'class-variance-authority'\nimport {\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n isValidElement,\n ReactElement,\n ReactNode,\n Ref,\n useMemo,\n} from 'react'\n\nimport { InputOTPContext } from './InputOTPContext'\nimport { InputOTPSlot } from './InputOTPSlot'\nimport { useInputOTP } from './useInputOTP'\n\n/**\n * Counts the number of InputOTPSlot components in the children tree\n */\nconst countSlots = (children: ReactNode): number => {\n let count = 0\n\n Children.forEach(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { children?: ReactNode }\n // Check if it's an InputOTPSlot by checking displayName\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n count++\n } else if (props.children) {\n // Recursively count slots in nested children (e.g., inside InputOTPGroup)\n count += countSlots(props.children)\n }\n }\n })\n\n return count\n}\n\n/**\n * Recursively assigns index to InputOTPSlot components\n * Returns a tuple of [processedChildren, nextIndex]\n */\nconst assignSlotIndexes = (children: ReactNode, startIndex: number = 0): [ReactNode, number] => {\n let currentIndex = startIndex\n\n const processed = Children.map(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { index?: number; children?: ReactNode }\n // Check if it's an InputOTPSlot\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n // Only assign index if not already provided\n const slotIndex = typeof props.index === 'number' ? props.index : currentIndex++\n\n return cloneElement(child as ReactElement<{ index?: number }>, {\n ...props,\n index: slotIndex,\n })\n } else if (props.children) {\n // Recursively process nested children\n const [processedChildren, nextIndex] = assignSlotIndexes(props.children, currentIndex)\n currentIndex = nextIndex\n\n return cloneElement(child, {\n ...(child.props as Record<string, unknown>),\n children: processedChildren,\n } as Parameters<typeof cloneElement>[1])\n }\n }\n\n return child\n })\n\n return [processed, currentIndex]\n}\n\nexport interface InputOTPProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'inputMode'\n> {\n /**\n * Maximum length of the input value.\n * If not provided, will be automatically detected from the number of InputOTP.Slot children.\n */\n maxLength?: number\n /**\n * Type of input\n * @default 'text'\n */\n type?: 'text' | 'number' | 'password' | 'tel'\n /**\n * Current value (controlled mode)\n */\n value?: string\n /**\n * Default value (uncontrolled mode)\n */\n defaultValue?: string\n /**\n * Callback fired when the value changes\n */\n onValueChange?: (value: string) => void\n /**\n * Whether the input is valid\n * @default true\n */\n isValid?: boolean\n /**\n * Whether the input is disabled\n * @default false\n */\n disabled?: boolean\n /**\n * Whether the input is read-only (value visible but not editable)\n * @default false\n */\n readOnly?: boolean\n /**\n * Whether to auto-focus the input\n * @default false\n */\n autoFocus?: boolean\n /**\n * Auto-complete attribute\n * @default 'off'\n */\n autoComplete?: string\n /**\n * Whether to force uppercase\n * @default false\n */\n forceUppercase?: boolean\n /**\n * Array of keys to filter out (using KeyboardEvent.key values)\n * @default ['-', '.']\n */\n filterKeys?: string[]\n /**\n * Pattern attribute for input validation and character filtering.\n * Uses a regular expression to filter allowed characters in real-time.\n * For example: \"[0-9]\" for digits only, \"[a-c]\" for letters a, b, c only.\n */\n pattern?: string\n /**\n * Input mode attribute\n */\n inputMode?: string\n /**\n * Placeholder text\n */\n placeholder?: string\n /**\n * Name attribute for form integration\n */\n name?: string\n /**\n * Children components (InputOTPGroup, InputOTPSlot, InputOTPSeparator)\n */\n children: ReactNode\n /**\n * Ref callback for the container\n */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputOTP = ({\n maxLength: maxLengthProp,\n type = 'text',\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n isValid = true,\n disabled: disabledProp = false,\n readOnly: readOnlyProp = false,\n autoFocus = false,\n autoComplete = 'off',\n forceUppercase = false,\n filterKeys = ['-', '.'],\n pattern,\n inputMode,\n placeholder = '-',\n name: nameProp,\n className,\n children,\n ...others\n}: InputOTPProps) => {\n // Auto-detect maxLength from children if not provided\n const maxLength = useMemo(() => {\n if (maxLengthProp !== undefined) {\n return maxLengthProp\n }\n\n const detectedLength = countSlots(children)\n const DEFAULT_MAX_LENGTH = 4\n\n return detectedLength > 0 ? detectedLength : DEFAULT_MAX_LENGTH // fallback to 4 if no slots found\n }, [maxLengthProp, children])\n\n // Assign indexes to slots automatically\n const processedChildren = useMemo(() => {\n const [processed] = assignSlotIndexes(children)\n\n return processed\n }, [children])\n\n // Use the hook for all business logic\n const {\n uuid,\n inputRef,\n containerRef,\n name,\n disabled,\n readOnly,\n isInvalid,\n isRequired,\n description,\n currentValue,\n contextValue,\n handleChange,\n handleKeyDown,\n handleCopy,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n } = useInputOTP({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n readOnlyProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n })\n\n // Extract aria-label from others if provided (for cases without FormField)\n const ariaLabel =\n 'aria-label' in others ? (others['aria-label'] as string | undefined) : undefined\n const { 'aria-label': _, ...restOthers } = others\n\n const getAccessibleNameProps = (): Record<string, string | undefined> => {\n if (labelId) {\n return { 'aria-labelledby': labelId }\n }\n\n if (ariaLabel) {\n return { 'aria-label': ariaLabel }\n }\n\n return {}\n }\n\n const accessibleNameProps = getAccessibleNameProps()\n\n return (\n <InputOTPContext.Provider value={contextValue}>\n <div\n ref={containerRef}\n data-spark-component=\"input-otp\"\n role=\"group\"\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n className={cx(\n 'group gap-md relative inline-flex w-fit items-center default:cursor-text',\n {\n 'cursor-not-allowed': disabled,\n 'cursor-default': readOnly,\n },\n className\n )}\n onClick={handleClick}\n {...restOthers}\n >\n {/* Hidden input for form submission with complete value */}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValue}\n required={isRequired}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n {...accessibleNameProps}\n />\n )}\n {/* Actual input that handles all interactions */}\n <input\n ref={inputRef}\n id={uuid}\n type={type === 'password' ? 'password' : 'text'}\n value={currentValue}\n maxLength={maxLength}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n disabled={disabled}\n readOnly={readOnly}\n pattern={pattern}\n inputMode={inputMode as React.InputHTMLAttributes<HTMLInputElement>['inputMode']}\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onCopy={handleCopy}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 read-only:cursor-default disabled:cursor-not-allowed\"\n tabIndex={0}\n />\n {/* Children render slots with auto-assigned indexes */}\n {processedChildren}\n </div>\n </InputOTPContext.Provider>\n )\n}\n\nInputOTP.displayName = 'InputOTP'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPGroupProps extends ComponentPropsWithoutRef<'div'> {}\n\n/**\n * Container for a group of OTP input slots. Renders a <div> element.\n */\nexport const InputOTPGroup = ({ children, className, ...props }: InputOTPGroupProps) => {\n return (\n <div className={`gap-md flex ${className}`} {...props}>\n {children}\n </div>\n )\n}\n\nInputOTPGroup.displayName = 'InputOTP.Group'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPSeparatorProps extends ComponentPropsWithoutRef<'div'> {}\n\n/**\n * A visual separator between OTP input groups. Renders a <div> element.\n */\nexport const InputOTPSeparator = ({ className, ...props }: InputOTPSeparatorProps) => {\n return (\n <div\n className={`text-on-surface/dim-3 flex items-center justify-center ${className || ''}`}\n {...props}\n >\n <div className=\"h-sz-4 w-sz-8 bg-outline rounded-full\" />\n </div>\n )\n}\n\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n","import { InputOTP as Root } from './InputOTP'\nimport { InputOTPGroup } from './InputOTPGroup'\nimport { InputOTPSeparator } from './InputOTPSeparator'\nimport { InputOTPSlot } from './InputOTPSlot'\n\n/**\n * An input component for entering one-time passwords or verification codes with individual character slots.\n */\nexport const InputOTP: typeof Root & {\n Group: typeof InputOTPGroup\n Slot: typeof InputOTPSlot\n Separator: typeof InputOTPSeparator\n} = Object.assign(Root, {\n Group: InputOTPGroup,\n Slot: InputOTPSlot,\n Separator: InputOTPSeparator,\n})\n\nInputOTP.displayName = 'InputOTP'\nInputOTPGroup.displayName = 'InputOTP.Group'\nInputOTPSlot.displayName = 'InputOTP.Slot'\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n\nexport { type InputOTPProps } from './InputOTP'\nexport { type InputOTPGroupProps } from './InputOTPGroup'\nexport { type InputOTPSlotProps } from './InputOTPSlot'\nexport { type InputOTPSeparatorProps } from './InputOTPSeparator'\nexport {\n inputOTPSlotStyles,\n inputOTPStyles,\n type InputOTPSlotStylesProps,\n type InputOTPStylesProps,\n} from './InputOTP.styles'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/input-otp/InputOTPContext.tsx","../../src/input-otp/InputOTP.styles.ts","../../src/input-otp/InputOTPSlot.tsx","../../src/input-otp/useInputOTP.ts","../../src/input-otp/InputOTP.tsx","../../src/input-otp/InputOTPGroup.tsx","../../src/input-otp/InputOTPSeparator.tsx","../../src/input-otp/index.ts"],"sourcesContent":["import { createContext, useContext } from 'react'\n\nexport interface InputOTPContextValue {\n value: string\n maxLength: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n activeIndex: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n disabled: boolean\n readOnly: boolean\n placeholder?: string\n type: 'text' | 'number' | 'password' | 'tel'\n}\n\nexport const InputOTPContext = createContext<InputOTPContextValue | null>(null)\n\nexport const useInputOTPContext = () => {\n const context = useContext(InputOTPContext)\n if (!context) {\n throw new Error('InputOTP components must be used within InputOTP')\n }\n\n return context\n}\n","import { cva, VariantProps } from 'class-variance-authority'\n\nexport const inputOTPContainerStyles = cva(['relative', 'inline-flex', 'items-center', 'gap-sm'])\n\nexport const inputOTPSlotStyles = cva(\n [\n // Base slot styles\n 'relative h-[50px] w-sz-40',\n 'border-sm rounded-md',\n 'text-center text-display-3 text-on-surface',\n 'outline-hidden',\n 'transition-colors',\n 'flex items-center justify-center',\n // Slot that receives focus when clicking the group (first empty or last slot)\n // Use data-[focus-target=true]:... for distinct styles\n // Active state (when focused)\n 'data-[active=true]:ring-1',\n 'data-[active=true]:ring-inset',\n 'data-[active=true]:ring-l-2',\n 'data-[active=true]:border-focus',\n 'data-[active=true]:z-raised ring-focus',\n // Disabled state\n 'data-[disabled=true]:cursor-not-allowed',\n 'data-[disabled=true]:border-outline',\n 'data-[disabled=true]:bg-on-surface/dim-5',\n 'data-[disabled=true]:text-on-surface/dim-3',\n // Read-only state (same as disabled but text stays normal)\n 'data-[readonly=true]:cursor-default',\n 'data-[readonly=true]:data-[active=false]:border-outline',\n 'data-[readonly=true]:bg-on-surface/dim-5',\n 'group-hover:data-[focus-target=true]:data-[disabled=false]:border-outline-high',\n ],\n {\n variants: {\n /**\n * Color scheme of the slot\n */\n intent: {\n neutral: ['data-[filled=true]:bg-neutral-container bg-surface border-outline'],\n success: ['border-success bg-success-container text-on-success-container'],\n alert: ['border-alert bg-alert-container text-on-alert-container'],\n error: ['border-error bg-error-container text-on-error-container'],\n },\n },\n defaultVariants: {\n intent: 'neutral',\n },\n }\n)\n\nexport type InputOTPSlotStylesProps = VariantProps<typeof inputOTPSlotStyles>\n\n// Keep for backward compatibility\nexport const inputOTPStyles = inputOTPSlotStyles\nexport type InputOTPStylesProps = InputOTPSlotStylesProps\n","import { ComponentPropsWithoutRef } from 'react'\n\nimport { inputOTPSlotStyles } from './InputOTP.styles'\nimport { useInputOTPContext } from './InputOTPContext'\n\nexport interface InputOTPSlotProps extends ComponentPropsWithoutRef<'div'> {\n /**\n * Index of the slot (0-based).\n * If not provided, will be automatically assigned based on position in children.\n */\n index?: number\n}\n\n/**\n * An individual slot for a single OTP character. Renders a <div> element.\n */\nexport const InputOTPSlot = ({ index: indexProp, className, ...props }: InputOTPSlotProps) => {\n const context = useInputOTPContext()\n\n // Use provided index or fallback to 0 (should not happen if auto-assignment works)\n const index = indexProp ?? 0\n const slot = context.slots[index]\n\n if (!slot) {\n return null\n }\n\n const { char, isActive, hasFakeCaret } = slot\n const isEmpty = !char\n const isPlaceholder = isEmpty && !hasFakeCaret && context.placeholder\n\n const isFocusTarget = index === context.activeIndex\n\n return (\n <div\n className={inputOTPSlotStyles({\n intent: context.intent,\n className,\n })}\n data-active={isActive}\n data-disabled={context.disabled}\n data-readonly={context.readOnly}\n data-filled={!isEmpty}\n data-focus-target={isFocusTarget}\n data-valid={context.intent !== 'error'}\n {...props}\n >\n <span className={isPlaceholder ? 'text-on-surface/dim-3' : ''}>\n {context.type === 'password' && char\n ? '•'\n : char || (!hasFakeCaret && context.placeholder ? context.placeholder : '')}\n </span>\n {hasFakeCaret && (\n <span\n className=\"pointer-events-none absolute inset-0 flex items-center justify-center\"\n aria-hidden=\"true\"\n >\n <span className=\"bg-on-surface animate-standalone-caret-blink h-sz-24 w-sz-2\" />\n </span>\n )}\n </div>\n )\n}\n\nInputOTPSlot.displayName = 'InputOTP.Slot'\n","/* eslint-disable max-lines-per-function */\nimport { useFormFieldControl } from '@spark-ui/components/form-field'\nimport {\n ChangeEventHandler,\n ClipboardEventHandler,\n KeyboardEventHandler,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport type { InputOTPContextValue } from './InputOTPContext'\n\nconst BACKSPACE_KEY = 'Backspace'\nconst LEFT_ARROW_KEY = 'ArrowLeft'\nconst UP_ARROW_KEY = 'ArrowUp'\nconst RIGHT_ARROW_KEY = 'ArrowRight'\nconst DOWN_ARROW_KEY = 'ArrowDown'\nconst E_KEY = 'e'\n\nexport interface UseInputOTPProps {\n maxLength: number\n type: 'text' | 'number' | 'password' | 'tel'\n value?: string\n defaultValue: string\n onValueChange?: (value: string) => void\n isValid: boolean\n disabledProp: boolean\n readOnlyProp: boolean\n autoFocus: boolean\n forceUppercase: boolean\n filterKeys: string[]\n pattern?: string\n placeholder: string\n nameProp?: string\n}\n\nexport interface UseInputOTPReturn {\n uuid: string\n inputRef: React.RefObject<HTMLInputElement | null>\n containerRef: React.RefObject<HTMLDivElement | null>\n name: string | undefined\n disabled: boolean\n readOnly: boolean\n isInvalid: boolean\n isRequired: boolean\n description: string | undefined\n maxLength: number\n intent: 'neutral' | 'success' | 'alert' | 'error'\n currentValue: string\n activeIndex: number\n slots: {\n char: string\n isActive: boolean\n hasFakeCaret: boolean\n }[]\n contextValue: InputOTPContextValue\n handleChange: ChangeEventHandler<HTMLInputElement>\n handleKeyDown: KeyboardEventHandler<HTMLInputElement>\n handleCopy: ClipboardEventHandler<HTMLInputElement>\n handlePaste: ClipboardEventHandler<HTMLInputElement>\n handleFocus: () => void\n handleBlur: () => void\n handleClick: () => void\n labelId: string | undefined\n}\n\nexport const useInputOTP = ({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n readOnlyProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n}: UseInputOTPProps): UseInputOTPReturn => {\n const uuid = useId()\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // Get FormField context (optional, falls back gracefully if not present)\n const field = useFormFieldControl()\n\n // Use FormField values if available, otherwise fall back to props\n // Use FormField id when available so label htmlFor works correctly\n const id = field.id ?? uuid\n const name = nameProp ?? field.name\n const disabled = field.disabled ?? disabledProp\n const readOnly = field.readOnly ?? readOnlyProp\n const isInvalid = field.isInvalid ?? !isValid\n const isRequired = field.isRequired ?? false\n const labelId = field.labelId\n const description = field.description\n const fieldState = field.state\n\n // Determine intent based on FormField state or isValid prop\n const getIntent = (): 'neutral' | 'success' | 'alert' | 'error' => {\n // FormField state takes priority\n if (['success', 'alert', 'error'].includes(fieldState ?? '')) {\n return fieldState as 'success' | 'alert' | 'error'\n }\n\n // Fallback to isValid prop for backward compatibility\n if (isInvalid) {\n return 'error'\n }\n\n return 'neutral'\n }\n\n const intent = getIntent()\n\n // Initialize value\n const initialValue = controlledValue !== undefined ? controlledValue : defaultValue\n const processedValue = forceUppercase ? initialValue.toUpperCase() : initialValue\n\n const [internalValue, setInternalValue] = useState<string>(processedValue)\n const [isFocused, setIsFocused] = useState<boolean>(false)\n\n // Use controlled value if provided, otherwise use internal state\n const currentValue = controlledValue !== undefined ? controlledValue : internalValue\n\n // Calculate active index: last empty slot, or last slot if all are filled\n const activeIndex = Math.min(currentValue.length, maxLength - 1)\n\n // Sync cursor position with active index\n useEffect(() => {\n if (inputRef.current) {\n inputRef.current.setSelectionRange(activeIndex, activeIndex)\n }\n }, [activeIndex, currentValue.length, maxLength])\n\n // Create slots array\n const slots = useMemo(\n () =>\n Array.from({ length: maxLength }, (_, i) => ({\n char: currentValue[i] || '',\n isActive: i === activeIndex && isFocused,\n hasFakeCaret: i === activeIndex && !currentValue[i] && !disabled && !readOnly && isFocused,\n })),\n [maxLength, currentValue, activeIndex, isFocused, disabled, readOnly]\n )\n\n // Sync controlled value with input ref\n useEffect(() => {\n if (inputRef.current && controlledValue !== undefined) {\n inputRef.current.value = controlledValue\n }\n }, [controlledValue])\n\n // Focus management\n useEffect(() => {\n if (autoFocus && inputRef.current) {\n inputRef.current.focus()\n }\n }, [autoFocus])\n\n const processInputValue = (inputValue: string): string => {\n let processed = inputValue\n\n if (forceUppercase) {\n processed = processed.toUpperCase()\n }\n\n if (type === 'number') {\n processed = processed.replace(/[^\\d]/g, '')\n }\n\n // Filter characters using pattern if provided\n if (pattern) {\n try {\n // Convert HTML pattern (string) to RegExp\n // HTML patterns validate the entire string, but we need to test each character\n // We create a regex that tests if a single character matches the pattern\n // For example: [0-9]* becomes ^[0-9]$ to test a single digit\n // We wrap the pattern in ^...$ to ensure it matches a single character\n let regexPattern = pattern\n // If pattern doesn't start with ^, wrap it to test single character\n if (!pattern.startsWith('^')) {\n regexPattern = `^${pattern}$`\n }\n const regex = new RegExp(regexPattern)\n processed = processed\n .split('')\n .filter(currChar => {\n // Test if the character matches the pattern\n return regex.test(currChar)\n })\n .join('')\n } catch (error) {\n // If pattern is invalid, ignore it and continue with other filters\n console.error('Invalid pattern provided to InputOTP:', pattern, error)\n }\n }\n\n return processed\n }\n\n const handleChange: ChangeEventHandler<HTMLInputElement> = e => {\n if (disabled || readOnly) return\n\n const inputValue = e.target.value\n const processedValue = processInputValue(inputValue)\n\n // Limit to maxLength\n const newValue = processedValue.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleKeyDown: KeyboardEventHandler<HTMLInputElement> = e => {\n if (disabled || readOnly) return\n\n // Allow copy/cut/paste/selectAll shortcuts even when key is in filterKeys\n const isShortcut =\n (e.ctrlKey || e.metaKey) && ['a', 'c', 'v', 'x'].includes(e.key.toLowerCase())\n\n // Filter keys\n if (filterKeys.length > 0 && filterKeys.includes(e.key) && !isShortcut) {\n e.preventDefault()\n\n return\n }\n\n // Check if user is typing a printable character when input is full\n const isPrintableCharacter = e.key.length === 1 && !e.ctrlKey && !e.metaKey && !e.altKey\n if (isPrintableCharacter && currentValue.length === maxLength) {\n e.preventDefault()\n\n // Process the new character through filters\n const processedChar = processInputValue(e.key)\n\n // If the character is filtered out, don't do anything\n if (processedChar.length === 0) {\n return\n }\n\n // Replace the last character with the new one\n const newValue = currentValue.slice(0, maxLength - 1) + processedChar\n\n // Call onValueChange callback\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Keep cursor at the end\n const newActiveIndex = maxLength - 1\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n\n return\n }\n\n switch (e.key) {\n case BACKSPACE_KEY:\n e.preventDefault()\n const currentLength = currentValue.length\n if (currentLength > 0) {\n const newValue = currentValue.slice(0, currentLength - 1)\n\n // Call onValueChange first\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Sync cursor position\n const newActiveIndex = Math.max(0, newValue.length)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n break\n\n case LEFT_ARROW_KEY:\n case RIGHT_ARROW_KEY:\n // Prevent navigation with arrow keys - focus stays on last empty slot\n e.preventDefault()\n break\n\n case UP_ARROW_KEY:\n case DOWN_ARROW_KEY:\n e.preventDefault()\n break\n\n case E_KEY:\n case 'E':\n // Prevent 'e' or 'E' in number inputs\n if (type === 'number') {\n e.preventDefault()\n }\n break\n\n default:\n break\n }\n }\n\n const handleCopy: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled) return\n\n e.preventDefault()\n if (currentValue.length > 0) {\n e.clipboardData.setData('text/plain', currentValue)\n }\n }\n\n const handlePaste: ClipboardEventHandler<HTMLInputElement> = e => {\n if (disabled || readOnly) return\n\n e.preventDefault()\n\n const pastedText = e.clipboardData.getData('text')\n\n if (!pastedText) return\n\n const processedText = processInputValue(pastedText)\n const newValue = processedText.slice(0, maxLength)\n\n // Call onValueChange callback first (before updating state)\n if (onValueChange) {\n onValueChange(newValue)\n }\n\n // Update state only in uncontrolled mode\n if (controlledValue === undefined) {\n setInternalValue(newValue)\n }\n\n // Active index is automatically calculated based on value length\n // Move cursor to end\n const newActiveIndex = Math.min(newValue.length, maxLength - 1)\n if (inputRef.current) {\n inputRef.current.setSelectionRange(newActiveIndex, newActiveIndex)\n }\n }\n\n const handleFocus = () => {\n setIsFocused(true)\n if (inputRef.current) {\n // Focus on last empty slot, or last slot if all are filled\n const cursorPosition = Math.min(currentValue.length, maxLength - 1)\n inputRef.current.setSelectionRange(cursorPosition, cursorPosition)\n }\n }\n\n const handleBlur = () => {\n setIsFocused(false)\n }\n\n const handleClick = () => {\n if (inputRef.current) {\n inputRef.current.focus()\n }\n }\n\n const contextValue: InputOTPContextValue = {\n value: currentValue,\n maxLength,\n slots,\n activeIndex,\n intent,\n disabled,\n readOnly,\n placeholder,\n type,\n }\n\n const returnValue: UseInputOTPReturn = {\n uuid: id,\n inputRef,\n containerRef,\n name,\n disabled,\n readOnly,\n isInvalid,\n isRequired,\n description,\n maxLength,\n intent,\n currentValue,\n activeIndex,\n slots,\n contextValue,\n handleChange,\n handleKeyDown,\n handleCopy,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n }\n\n return returnValue\n}\n","/* eslint-disable max-lines-per-function */\nimport { cx } from 'class-variance-authority'\nimport {\n Children,\n cloneElement,\n ComponentPropsWithoutRef,\n isValidElement,\n ReactElement,\n ReactNode,\n Ref,\n useMemo,\n} from 'react'\n\nimport { InputOTPContext } from './InputOTPContext'\nimport { InputOTPSlot } from './InputOTPSlot'\nimport { useInputOTP } from './useInputOTP'\n\n/**\n * Counts the number of InputOTPSlot components in the children tree\n */\nconst countSlots = (children: ReactNode): number => {\n let count = 0\n\n Children.forEach(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { children?: ReactNode }\n // Check if it's an InputOTPSlot by checking displayName\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n count++\n } else if (props.children) {\n // Recursively count slots in nested children (e.g., inside InputOTPGroup)\n count += countSlots(props.children)\n }\n }\n })\n\n return count\n}\n\n/**\n * Recursively assigns index to InputOTPSlot components\n * Returns a tuple of [processedChildren, nextIndex]\n */\nconst assignSlotIndexes = (children: ReactNode, startIndex: number = 0): [ReactNode, number] => {\n let currentIndex = startIndex\n\n const processed = Children.map(children, child => {\n if (isValidElement(child)) {\n const props = child.props as { index?: number; children?: ReactNode }\n // Check if it's an InputOTPSlot\n if (\n child.type === InputOTPSlot ||\n (child.type as { displayName?: string })?.displayName === 'InputOTP.Slot'\n ) {\n // Only assign index if not already provided\n const slotIndex = typeof props.index === 'number' ? props.index : currentIndex++\n\n return cloneElement(child as ReactElement<{ index?: number }>, {\n ...props,\n index: slotIndex,\n })\n } else if (props.children) {\n // Recursively process nested children\n const [processedChildren, nextIndex] = assignSlotIndexes(props.children, currentIndex)\n currentIndex = nextIndex\n\n return cloneElement(child, {\n ...(child.props as Record<string, unknown>),\n children: processedChildren,\n } as Parameters<typeof cloneElement>[1])\n }\n }\n\n return child\n })\n\n return [processed, currentIndex]\n}\n\nexport interface InputOTPProps extends Omit<\n ComponentPropsWithoutRef<'div'>,\n 'onChange' | 'inputMode'\n> {\n /**\n * Maximum length of the input value.\n * If not provided, will be automatically detected from the number of InputOTP.Slot children.\n */\n maxLength?: number\n /**\n * Type of input\n * @default 'text'\n */\n type?: 'text' | 'number' | 'password' | 'tel'\n /**\n * Current value (controlled mode)\n */\n value?: string\n /**\n * Default value (uncontrolled mode)\n */\n defaultValue?: string\n /**\n * Callback fired when the value changes\n */\n onValueChange?: (value: string) => void\n /**\n * Whether the input is valid\n * @default true\n */\n isValid?: boolean\n /**\n * Whether the input is disabled\n * @default false\n */\n disabled?: boolean\n /**\n * Whether the input is read-only (value visible but not editable)\n * @default false\n */\n readOnly?: boolean\n /**\n * Whether to auto-focus the input\n * @default false\n */\n autoFocus?: boolean\n /**\n * Auto-complete attribute\n * @default 'off'\n */\n autoComplete?: string\n /**\n * Whether to force uppercase\n * @default false\n */\n forceUppercase?: boolean\n /**\n * Array of keys to filter out (using KeyboardEvent.key values)\n * @default ['-', '.']\n */\n filterKeys?: string[]\n /**\n * Pattern attribute for input validation and character filtering.\n * Uses a regular expression to filter allowed characters in real-time.\n * For example: \"[0-9]\" for digits only, \"[a-c]\" for letters a, b, c only.\n */\n pattern?: string\n /**\n * Input mode attribute\n */\n inputMode?: string\n /**\n * Placeholder text\n */\n placeholder?: string\n /**\n * Name attribute for form integration\n */\n name?: string\n /**\n * Children components (InputOTPGroup, InputOTPSlot, InputOTPSeparator)\n */\n children: ReactNode\n /**\n * Ref callback for the container\n */\n ref?: Ref<HTMLDivElement>\n}\n\nexport const InputOTP = ({\n maxLength: maxLengthProp,\n type = 'text',\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n isValid = true,\n disabled: disabledProp = false,\n readOnly: readOnlyProp = false,\n autoFocus = false,\n autoComplete = 'off',\n forceUppercase = false,\n filterKeys = ['-', '.'],\n pattern,\n inputMode,\n placeholder = '-',\n name: nameProp,\n className,\n children,\n ...others\n}: InputOTPProps) => {\n // Auto-detect maxLength from children if not provided\n const maxLength = useMemo(() => {\n if (maxLengthProp !== undefined) {\n return maxLengthProp\n }\n\n const detectedLength = countSlots(children)\n const DEFAULT_MAX_LENGTH = 4\n\n return detectedLength > 0 ? detectedLength : DEFAULT_MAX_LENGTH // fallback to 4 if no slots found\n }, [maxLengthProp, children])\n\n // Assign indexes to slots automatically\n const processedChildren = useMemo(() => {\n const [processed] = assignSlotIndexes(children)\n\n return processed\n }, [children])\n\n // Use the hook for all business logic\n const {\n uuid,\n inputRef,\n containerRef,\n name,\n disabled,\n readOnly,\n isInvalid,\n isRequired,\n description,\n currentValue,\n contextValue,\n handleChange,\n handleKeyDown,\n handleCopy,\n handlePaste,\n handleFocus,\n handleBlur,\n handleClick,\n labelId,\n } = useInputOTP({\n maxLength,\n type,\n value: controlledValue,\n defaultValue,\n onValueChange,\n isValid,\n disabledProp,\n readOnlyProp,\n autoFocus,\n forceUppercase,\n filterKeys,\n pattern,\n placeholder,\n nameProp,\n })\n\n // Extract aria-label from others if provided (for cases without FormField)\n const ariaLabel =\n 'aria-label' in others ? (others['aria-label'] as string | undefined) : undefined\n const { 'aria-label': _, ...restOthers } = others\n\n const getAccessibleNameProps = (): Record<string, string | undefined> => {\n if (labelId) {\n return { 'aria-labelledby': labelId }\n }\n\n if (ariaLabel) {\n return { 'aria-label': ariaLabel }\n }\n\n return {}\n }\n\n const accessibleNameProps = getAccessibleNameProps()\n\n return (\n <InputOTPContext value={contextValue}>\n <div\n ref={containerRef}\n data-spark-component=\"input-otp\"\n role=\"group\"\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n className={cx(\n 'group gap-md relative inline-flex w-fit items-center default:cursor-text',\n {\n 'cursor-not-allowed': disabled,\n 'cursor-default': readOnly,\n },\n className\n )}\n onClick={handleClick}\n {...restOthers}\n >\n {/* Hidden input for form submission with complete value */}\n {name && (\n <input\n type=\"hidden\"\n name={name}\n value={currentValue}\n required={isRequired}\n aria-required={isRequired}\n aria-invalid={isInvalid}\n {...accessibleNameProps}\n />\n )}\n {/* Actual input that handles all interactions */}\n <input\n ref={inputRef}\n id={uuid}\n type={type === 'password' ? 'password' : 'text'}\n value={currentValue}\n maxLength={maxLength}\n autoFocus={autoFocus}\n autoComplete={autoComplete}\n disabled={disabled}\n readOnly={readOnly}\n pattern={pattern}\n inputMode={inputMode as React.InputHTMLAttributes<HTMLInputElement>['inputMode']}\n {...accessibleNameProps}\n {...(description ? { 'aria-describedby': description } : {})}\n aria-invalid={isInvalid}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onCopy={handleCopy}\n onPaste={handlePaste}\n onFocus={handleFocus}\n onBlur={handleBlur}\n className=\"bg-success z-raised absolute inset-0 m-0 p-0 opacity-0 read-only:cursor-default disabled:cursor-not-allowed\"\n tabIndex={0}\n />\n {/* Children render slots with auto-assigned indexes */}\n {processedChildren}\n </div>\n </InputOTPContext>\n )\n}\n\nInputOTP.displayName = 'InputOTP'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPGroupProps extends ComponentPropsWithoutRef<'div'> {}\n\n/**\n * Container for a group of OTP input slots. Renders a <div> element.\n */\nexport const InputOTPGroup = ({ children, className, ...props }: InputOTPGroupProps) => {\n return (\n <div className={`gap-md flex ${className}`} {...props}>\n {children}\n </div>\n )\n}\n\nInputOTPGroup.displayName = 'InputOTP.Group'\n","import { ComponentPropsWithoutRef } from 'react'\n\nexport interface InputOTPSeparatorProps extends ComponentPropsWithoutRef<'div'> {}\n\n/**\n * A visual separator between OTP input groups. Renders a <div> element.\n */\nexport const InputOTPSeparator = ({ className, ...props }: InputOTPSeparatorProps) => {\n return (\n <div\n className={`text-on-surface/dim-3 flex items-center justify-center ${className || ''}`}\n {...props}\n >\n <div className=\"h-sz-4 w-sz-8 bg-outline rounded-full\" />\n </div>\n )\n}\n\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n","import { InputOTP as Root } from './InputOTP'\nimport { InputOTPGroup } from './InputOTPGroup'\nimport { InputOTPSeparator } from './InputOTPSeparator'\nimport { InputOTPSlot } from './InputOTPSlot'\n\n/**\n * An input component for entering one-time passwords or verification codes with individual character slots.\n */\nexport const InputOTP: typeof Root & {\n Group: typeof InputOTPGroup\n Slot: typeof InputOTPSlot\n Separator: typeof InputOTPSeparator\n} = Object.assign(Root, {\n Group: InputOTPGroup,\n Slot: InputOTPSlot,\n Separator: InputOTPSeparator,\n})\n\nInputOTP.displayName = 'InputOTP'\nInputOTPGroup.displayName = 'InputOTP.Group'\nInputOTPSlot.displayName = 'InputOTP.Slot'\nInputOTPSeparator.displayName = 'InputOTP.Separator'\n\nexport { type InputOTPProps } from './InputOTP'\nexport { type InputOTPGroupProps } from './InputOTPGroup'\nexport { type InputOTPSlotProps } from './InputOTPSlot'\nexport { type InputOTPSeparatorProps } from './InputOTPSeparator'\nexport {\n inputOTPSlotStyles,\n inputOTPStyles,\n type InputOTPSlotStylesProps,\n type InputOTPStylesProps,\n} from './InputOTP.styles'\n"],"mappings":"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"}
|
package/dist/menu/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../slot/index.js`),t=require(`../icon-CRPcdgYp.js`);let n=require(`class-variance-authority`),r=require(`react`),i=require(`react/jsx-runtime`),a=require(`@spark-ui/icons/ArrowHorizontalDown`),o=require(`@spark-ui/internal-utils`),s=require(`@spark-ui/icons/ArrowVerticalRight`),c=require(`@spark-ui/icons/Check`),l=require(`@base-ui/react/menu`),u=require(`@spark-ui/icons/Link`);var d=({children:e,...t})=>(0,i.jsx)(l.Menu.Root,{"data-spark-component":`menu`,...t,children:e});d.displayName=`Menu`;var f=(0,n.cva)([`gap-md flex w-full cursor-pointer items-center justify-start`,`text-left text-body-1`,`transition-colors duration-100`,`outline-none`,`focus-visible:u-outline focus-visible:-outline-offset-2`,`data-disabled:cursor-not-allowed data-disabled:opacity-dim-3`,`min-h-sz-44`,`px-lg py-md`,`data-highlighted:bg-surface-hovered`,`data-popup-open:bg-surface-hovered`],{variants:{intent:(0,o.makeVariants)({surface:[`text-on-surface`],main:[`text-on-surface`],support:[`text-on-surface`],accent:[`text-on-surface`],success:[`text-on-surface`],alert:[`text-on-surface`],danger:[`text-on-surface`],info:[`text-on-surface`],neutral:[`text-on-surface`]})},defaultVariants:{intent:`surface`}});function p(t){return t?({...t})=>(0,i.jsx)(e.Slot,{...t}):void 0}var m=({asChild:e=!1,children:r,className:a,ref:o,...s})=>{let u=p(e);return(0,i.jsxs)(l.Menu.CheckboxItem,{ref:o,"data-spark-component":`menu-checkbox-item`,render:u,className:(0,n.cx)(f({className:a}),`data-checked:font-bold`),...s,children:[(0,i.jsx)(l.Menu.CheckboxItemIndicator,{keepMounted:!0,className:(0,n.cx)(`mr-md flex shrink-0 items-center justify-center`,`w-sz-16 h-sz-16`,`transition-opacity`,`data-checked:opacity-100`,`opacity-0`),children:(0,i.jsx)(t.t,{size:`sm`,intent:`current`,children:(0,i.jsx)(c.Check,{})})}),r]})};m.displayName=`Menu.CheckboxItem`;var h=({children:e,className:t,...r})=>(0,i.jsx)(l.Menu.Group,{"data-spark-component":`menu-group`,className:(0,n.cx)(`py-sm`,t),...r,children:e});h.displayName=`Menu.Group`;var g=({asChild:e=!1,children:t,className:r,ref:a,...o})=>{let s=p(e);return(0,i.jsx)(l.Menu.GroupLabel,{ref:a,"data-spark-component":`menu-group-label`,render:s,className:(0,n.cx)(`text-on-surface/dim-1 text-body-2 font-bold`,`px-lg py-sm`,r),...o,children:t})};g.displayName=`Menu.GroupLabel`;var _=({asChild:e=!1,children:t,className:n,ref:r,...a})=>{let o=p(e);return(0,i.jsx)(l.Menu.Item,{ref:r,"data-spark-component":`menu-item`,render:o,className:f({className:n}),...a,children:t})};_.displayName=`Menu.Item`;var v=({children:e,href:n,target:r,rel:a,...o})=>(0,i.jsx)(_,{asChild:!0,...o,children:(0,i.jsxs)(`a`,{href:n,target:r,rel:a,children:[(0,i.jsx)(t.t,{size:`sm`,intent:`current`,className:`ml-auto shrink-0`,children:(0,i.jsx)(u.Link,{})}),(0,i.jsx)(`span`,{className:`flex-1`,children:e})]})});v.displayName=`Menu.LinkItem`;var y=({asChild:e=!1,children:t,className:r,ref:a,...o})=>{let s=p(e);return(0,i.jsx)(l.Menu.Popup,{ref:a,"data-spark-component":`menu-popup`,render:s,className:(0,n.cx)([`rounded-md bg-surface shadow-lg min-w-sz-192`,`p-sm`,`overflow-auto`,`z-popover`,`data-starting-style:opacity-0`,`data-ending-style:opacity-0`,`opacity-100`,`transition-opacity duration-200`],r),...o,children:t})};y.displayName=`Menu.Popup`;var b=({children:e,...t})=>(0,i.jsx)(l.Menu.Portal,{...t,children:e});b.displayName=`Menu.Portal`;var x=(0,r.createContext)(!1),S=()=>(0,r.useContext)(x),C=({children:e,sideOffset:t,...n})=>{let r=S()?0:8,a=t??r;return(0,i.jsx)(l.Menu.Positioner,{sideOffset:a,...n,children:e})};C.displayName=`Menu.Positioner`;var w=({children:e,className:t,...r})=>(0,i.jsx)(l.Menu.RadioGroup,{"data-spark-component":`menu-radio-group`,className:(0,n.cx)(`py-sm`,t),...r,children:e});w.displayName=`Menu.RadioGroup`;var T=({asChild:e=!1,children:r,className:a,ref:o,...s})=>{let u=p(e);return(0,i.jsxs)(l.Menu.RadioItem,{ref:o,"data-spark-component":`menu-radio-item`,render:u,className:(0,n.cx)(f({className:a}),`data-checked:font-bold`),...s,children:[(0,i.jsx)(l.Menu.RadioItemIndicator,{keepMounted:!0,className:(0,n.cx)(`mr-md flex shrink-0 items-center justify-center`,`w-sz-16 h-sz-16`,`transition-opacity`,`data-checked:opacity-100`,`opacity-0`),children:(0,i.jsx)(t.t,{size:`sm`,intent:`current`,children:(0,i.jsx)(c.Check,{})})}),r]})};T.displayName=`Menu.RadioItem`;var E=({className:e,...t})=>(0,i.jsx)(l.Menu.Separator,{"data-spark-component":`menu-separator`,className:(0,n.cx)(`my-sm h-px bg-outline/dim-2`,e),...t});E.displayName=`Menu.Separator`;var D=({children:e,...t})=>(0,i.jsx)(l.Menu.SubmenuRoot,{"data-spark-component":`menu-submenu`,...t,children:(0,i.jsx)(x
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);const e=require(`../slot/index.js`),t=require(`../icon-CRPcdgYp.js`);let n=require(`class-variance-authority`),r=require(`react`),i=require(`react/jsx-runtime`),a=require(`@spark-ui/icons/ArrowHorizontalDown`),o=require(`@spark-ui/internal-utils`),s=require(`@spark-ui/icons/ArrowVerticalRight`),c=require(`@spark-ui/icons/Check`),l=require(`@base-ui/react/menu`),u=require(`@spark-ui/icons/Link`);var d=({children:e,...t})=>(0,i.jsx)(l.Menu.Root,{"data-spark-component":`menu`,...t,children:e});d.displayName=`Menu`;var f=(0,n.cva)([`gap-md flex w-full cursor-pointer items-center justify-start`,`text-left text-body-1`,`transition-colors duration-100`,`outline-none`,`focus-visible:u-outline focus-visible:-outline-offset-2`,`data-disabled:cursor-not-allowed data-disabled:opacity-dim-3`,`min-h-sz-44`,`px-lg py-md`,`data-highlighted:bg-surface-hovered`,`data-popup-open:bg-surface-hovered`],{variants:{intent:(0,o.makeVariants)({surface:[`text-on-surface`],main:[`text-on-surface`],support:[`text-on-surface`],accent:[`text-on-surface`],success:[`text-on-surface`],alert:[`text-on-surface`],danger:[`text-on-surface`],info:[`text-on-surface`],neutral:[`text-on-surface`]})},defaultVariants:{intent:`surface`}});function p(t){return t?({...t})=>(0,i.jsx)(e.Slot,{...t}):void 0}var m=({asChild:e=!1,children:r,className:a,ref:o,...s})=>{let u=p(e);return(0,i.jsxs)(l.Menu.CheckboxItem,{ref:o,"data-spark-component":`menu-checkbox-item`,render:u,className:(0,n.cx)(f({className:a}),`data-checked:font-bold`),...s,children:[(0,i.jsx)(l.Menu.CheckboxItemIndicator,{keepMounted:!0,className:(0,n.cx)(`mr-md flex shrink-0 items-center justify-center`,`w-sz-16 h-sz-16`,`transition-opacity`,`data-checked:opacity-100`,`opacity-0`),children:(0,i.jsx)(t.t,{size:`sm`,intent:`current`,children:(0,i.jsx)(c.Check,{})})}),r]})};m.displayName=`Menu.CheckboxItem`;var h=({children:e,className:t,...r})=>(0,i.jsx)(l.Menu.Group,{"data-spark-component":`menu-group`,className:(0,n.cx)(`py-sm`,t),...r,children:e});h.displayName=`Menu.Group`;var g=({asChild:e=!1,children:t,className:r,ref:a,...o})=>{let s=p(e);return(0,i.jsx)(l.Menu.GroupLabel,{ref:a,"data-spark-component":`menu-group-label`,render:s,className:(0,n.cx)(`text-on-surface/dim-1 text-body-2 font-bold`,`px-lg py-sm`,r),...o,children:t})};g.displayName=`Menu.GroupLabel`;var _=({asChild:e=!1,children:t,className:n,ref:r,...a})=>{let o=p(e);return(0,i.jsx)(l.Menu.Item,{ref:r,"data-spark-component":`menu-item`,render:o,className:f({className:n}),...a,children:t})};_.displayName=`Menu.Item`;var v=({children:e,href:n,target:r,rel:a,...o})=>(0,i.jsx)(_,{asChild:!0,...o,children:(0,i.jsxs)(`a`,{href:n,target:r,rel:a,children:[(0,i.jsx)(t.t,{size:`sm`,intent:`current`,className:`ml-auto shrink-0`,children:(0,i.jsx)(u.Link,{})}),(0,i.jsx)(`span`,{className:`flex-1`,children:e})]})});v.displayName=`Menu.LinkItem`;var y=({asChild:e=!1,children:t,className:r,ref:a,...o})=>{let s=p(e);return(0,i.jsx)(l.Menu.Popup,{ref:a,"data-spark-component":`menu-popup`,render:s,className:(0,n.cx)([`rounded-md bg-surface shadow-lg min-w-sz-192`,`p-sm`,`overflow-auto`,`z-popover`,`data-starting-style:opacity-0`,`data-ending-style:opacity-0`,`opacity-100`,`transition-opacity duration-200`],r),...o,children:t})};y.displayName=`Menu.Popup`;var b=({children:e,...t})=>(0,i.jsx)(l.Menu.Portal,{...t,children:e});b.displayName=`Menu.Portal`;var x=(0,r.createContext)(!1),S=()=>(0,r.useContext)(x),C=({children:e,sideOffset:t,...n})=>{let r=S()?0:8,a=t??r;return(0,i.jsx)(l.Menu.Positioner,{sideOffset:a,...n,children:e})};C.displayName=`Menu.Positioner`;var w=({children:e,className:t,...r})=>(0,i.jsx)(l.Menu.RadioGroup,{"data-spark-component":`menu-radio-group`,className:(0,n.cx)(`py-sm`,t),...r,children:e});w.displayName=`Menu.RadioGroup`;var T=({asChild:e=!1,children:r,className:a,ref:o,...s})=>{let u=p(e);return(0,i.jsxs)(l.Menu.RadioItem,{ref:o,"data-spark-component":`menu-radio-item`,render:u,className:(0,n.cx)(f({className:a}),`data-checked:font-bold`),...s,children:[(0,i.jsx)(l.Menu.RadioItemIndicator,{keepMounted:!0,className:(0,n.cx)(`mr-md flex shrink-0 items-center justify-center`,`w-sz-16 h-sz-16`,`transition-opacity`,`data-checked:opacity-100`,`opacity-0`),children:(0,i.jsx)(t.t,{size:`sm`,intent:`current`,children:(0,i.jsx)(c.Check,{})})}),r]})};T.displayName=`Menu.RadioItem`;var E=({className:e,...t})=>(0,i.jsx)(l.Menu.Separator,{"data-spark-component":`menu-separator`,className:(0,n.cx)(`my-sm h-px bg-outline/dim-2`,e),...t});E.displayName=`Menu.Separator`;var D=({children:e,...t})=>(0,i.jsx)(l.Menu.SubmenuRoot,{"data-spark-component":`menu-submenu`,...t,children:(0,i.jsx)(x,{value:!0,children:e})});D.displayName=`Menu.Submenu`;var O=({asChild:e=!1,children:n,className:r,ref:a,...o})=>{let c=p(e);return(0,i.jsxs)(l.Menu.SubmenuTrigger,{ref:a,"data-spark-component":`menu-submenu-trigger`,render:c,className:f({className:r}),...o,children:[(0,i.jsx)(`span`,{className:`flex-1`,children:n}),(0,i.jsx)(t.t,{size:`sm`,intent:`current`,className:`ml-auto shrink-0`,children:(0,i.jsx)(s.ArrowVerticalRight,{})})]})};O.displayName=`Menu.SubmenuTrigger`;var k=({asChild:e=!1,children:o,className:s,ref:c,...u})=>{let d=p(e),f=e&&(0,r.isValidElement)(o)?(0,r.cloneElement)(o,{design:o.props.design??`outlined`,intent:o.props.intent??`support`,children:(0,i.jsxs)(i.Fragment,{children:[o.props.children,(0,i.jsx)(t.t,{size:`sm`,intent:`current`,className:`shrink-0`,children:(0,i.jsx)(a.ArrowHorizontalDown,{})})]})}):o;return(0,i.jsx)(l.Menu.Trigger,{ref:c,"data-spark-component":`menu-trigger`,render:d,className:(0,n.cx)(`inline-flex items-center justify-center`,`focus-visible:u-outline`,s),...u,children:f})};k.displayName=`Menu.Trigger`;var A=Object.assign(d,{Trigger:k,Portal:b,Positioner:C,Popup:y,Item:_,LinkItem:v,Submenu:D,SubmenuTrigger:O,Group:h,GroupLabel:g,RadioGroup:w,RadioItem:T,CheckboxItem:m,Separator:E});A.displayName=`Menu`,k.displayName=`Menu.Trigger`,b.displayName=`Menu.Portal`,C.displayName=`Menu.Positioner`,y.displayName=`Menu.Popup`,_.displayName=`Menu.Item`,v.displayName=`Menu.LinkItem`,D.displayName=`Menu.Submenu`,O.displayName=`Menu.SubmenuTrigger`,h.displayName=`Menu.Group`,g.displayName=`Menu.GroupLabel`,w.displayName=`Menu.RadioGroup`,T.displayName=`Menu.RadioItem`,m.displayName=`Menu.CheckboxItem`,E.displayName=`Menu.Separator`,exports.Menu=A;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/menu/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/menu/Menu.tsx","../../src/menu/MenuItemStyles.tsx","../../src/menu/useRenderSlot.tsx","../../src/menu/MenuCheckboxItem.tsx","../../src/menu/MenuGroup.tsx","../../src/menu/MenuGroupLabel.tsx","../../src/menu/MenuItem.tsx","../../src/menu/MenuLinkItem.tsx","../../src/menu/MenuPopup.tsx","../../src/menu/MenuPortal.tsx","../../src/menu/MenuSubmenuContext.tsx","../../src/menu/MenuPositioner.tsx","../../src/menu/MenuRadioGroup.tsx","../../src/menu/MenuRadioItem.tsx","../../src/menu/MenuSeparator.tsx","../../src/menu/MenuSubmenu.tsx","../../src/menu/MenuSubmenuTrigger.tsx","../../src/menu/MenuTrigger.tsx","../../src/menu/index.ts"],"sourcesContent":["import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nexport interface MenuProps extends Omit<ComponentProps<typeof BaseMenu.Root>, 'children'> {\n /**\n * The content of the menu (trigger, portal, etc.)\n */\n children: ReactNode\n}\n\n/**\n * Root container for menu state and styling context.\n */\nexport const Menu = ({ children, ...rest }: MenuProps) => {\n return (\n <BaseMenu.Root data-spark-component=\"menu\" {...rest}>\n {children}\n </BaseMenu.Root>\n )\n}\n\nMenu.displayName = 'Menu'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport const menuItemStyles = cva(\n [\n 'gap-md flex w-full cursor-pointer items-center justify-start',\n 'text-left text-body-1',\n 'transition-colors duration-100',\n 'outline-none',\n 'focus-visible:u-outline focus-visible:-outline-offset-2',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-dim-3',\n 'min-h-sz-44',\n 'px-lg py-md',\n 'data-highlighted:bg-surface-hovered',\n 'data-popup-open:bg-surface-hovered',\n ],\n {\n variants: {\n intent: makeVariants<\n 'intent',\n ['surface', 'main', 'support', 'accent', 'success', 'alert', 'danger', 'info', 'neutral']\n >({\n surface: ['text-on-surface'],\n main: ['text-on-surface'],\n support: ['text-on-surface'],\n accent: ['text-on-surface'],\n success: ['text-on-surface'],\n alert: ['text-on-surface'],\n danger: ['text-on-surface'],\n info: ['text-on-surface'],\n neutral: ['text-on-surface'],\n }),\n },\n defaultVariants: {\n intent: 'surface',\n },\n }\n)\n\nexport type MenuItemStylesProps = VariantProps<typeof menuItemStyles>\n","import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean) {\n return asChild ? ({ ...props }: object) => <Slot {...props} /> : undefined\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuCheckboxItemProps extends Omit<\n ComponentProps<typeof BaseMenu.CheckboxItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with checkbox functionality.\n * Can be toggled on and off, allowing multiple selections.\n * The checkbox indicator is automatically rendered on the left side.\n */\nexport const MenuCheckboxItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuCheckboxItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.CheckboxItem\n ref={ref}\n data-spark-component=\"menu-checkbox-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.CheckboxItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.CheckboxItemIndicator>\n {children}\n </BaseMenu.CheckboxItem>\n )\n}\n\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuGroupProps extends ComponentProps<typeof BaseMenu.Group> {}\n\n/**\n * A container for grouping related menu items together.\n * Works with Menu.GroupLabel for semantic grouping.\n */\nexport const MenuGroup = ({ children, className, ...rest }: MenuGroupProps) => {\n return (\n <BaseMenu.Group data-spark-component=\"menu-group\" className={cx('py-sm', className)} {...rest}>\n {children}\n </BaseMenu.Group>\n )\n}\n\nMenuGroup.displayName = 'Menu.Group'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuGroupLabelProps extends Omit<\n ComponentProps<typeof BaseMenu.GroupLabel>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A label for a group of menu items.\n * Provides semantic context and visual separation for grouped items.\n */\nexport const MenuGroupLabel = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuGroupLabelProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.GroupLabel\n ref={ref}\n data-spark-component=\"menu-group-label\"\n render={renderSlot}\n className={cx('text-on-surface/dim-1 text-body-2 font-bold', 'px-lg py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.GroupLabel>\n )\n}\n\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuItemProps extends Omit<ComponentProps<typeof BaseMenu.Item>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that triggers an action when activated.\n * Renders a clickable menu option with keyboard support.\n */\nexport const MenuItem = ({ asChild = false, children, className, ref, ...rest }: MenuItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Item\n ref={ref}\n data-spark-component=\"menu-item\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n {children}\n </BaseMenu.Item>\n )\n}\n\nMenuItem.displayName = 'Menu.Item'\n","import { Link } from '@spark-ui/icons/Link'\nimport { type ComponentPropsWithoutRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { MenuItem } from './MenuItem'\n\nexport interface MenuLinkItemProps extends Omit<\n ComponentPropsWithoutRef<typeof MenuItem>,\n 'asChild'\n> {\n /**\n * The URL to navigate to.\n */\n href: string\n /**\n * Where to display the linked URL.\n * @default undefined\n */\n target?: string\n /**\n * The relationship between the current document and the linked document.\n * @default undefined\n */\n rel?: string\n}\n\n/**\n * A menu item that acts as a link.\n * Navigates to a URL when activated, useful for navigation menus.\n * Use with Next.js Link or React Router Link via the children prop.\n */\nexport const MenuLinkItem = ({ children, href, target, rel, ...rest }: MenuLinkItemProps) => {\n return (\n <MenuItem asChild {...rest}>\n <a href={href} target={target} rel={rel}>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <Link />\n </Icon>\n <span className=\"flex-1\">{children}</span>\n </a>\n </MenuItem>\n )\n}\n\nMenuLinkItem.displayName = 'Menu.LinkItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuPopupProps extends Omit<ComponentProps<typeof BaseMenu.Popup>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * The scrollable menu container that holds menu items.\n * Serves as the viewport for menu content with overflow handling.\n */\nexport const MenuPopup = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuPopupProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Popup\n ref={ref}\n data-spark-component=\"menu-popup\"\n render={renderSlot}\n className={cx(\n [\n 'rounded-md bg-surface shadow-lg min-w-sz-192',\n 'p-sm',\n 'overflow-auto',\n 'z-popover',\n 'data-starting-style:opacity-0',\n 'data-ending-style:opacity-0',\n 'opacity-100',\n 'transition-opacity duration-200',\n ],\n className\n )}\n {...rest}\n >\n {children}\n </BaseMenu.Popup>\n )\n}\n\nMenuPopup.displayName = 'Menu.Popup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuPortalProps extends ComponentProps<typeof BaseMenu.Portal> {}\n\n/**\n * Portal wrapper that renders the menu in a different part of the DOM tree.\n * Useful for avoiding z-index and overflow issues.\n */\nexport const MenuPortal = ({ children, ...rest }: MenuPortalProps) => {\n return <BaseMenu.Portal {...rest}>{children}</BaseMenu.Portal>\n}\n\nMenuPortal.displayName = 'Menu.Portal'\n","import { createContext, useContext } from 'react'\n\n/**\n * Context to track if we're inside a submenu\n */\nexport const MenuSubmenuContext = createContext<boolean>(false)\n\n/**\n * Hook to check if the current menu is a submenu\n */\nexport const useIsSubmenu = () => {\n return useContext(MenuSubmenuContext)\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nimport { useIsSubmenu } from './MenuSubmenuContext'\n\nexport interface MenuPositionerProps extends ComponentProps<typeof BaseMenu.Positioner> {}\n\n/**\n * Positioning wrapper for the menu with collision detection.\n * Handles menu placement relative to the trigger and viewport boundaries.\n */\nexport const MenuPositioner = ({ children, sideOffset, ...rest }: MenuPositionerProps) => {\n const isSubmenu = useIsSubmenu()\n\n // Apply sideOffset of 8 for root menu, 0 for submenus (unless explicitly overridden)\n const defaultSideOffset = isSubmenu ? 0 : 8\n const finalSideOffset = sideOffset ?? defaultSideOffset\n\n return (\n <BaseMenu.Positioner sideOffset={finalSideOffset} {...rest}>\n {children}\n </BaseMenu.Positioner>\n )\n}\n\nMenuPositioner.displayName = 'Menu.Positioner'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuRadioGroupProps extends ComponentProps<typeof BaseMenu.RadioGroup> {}\n\n/**\n * A container for radio menu items where only one item can be selected at a time.\n * Manages the selection state for its radio items.\n */\nexport const MenuRadioGroup = ({ children, className, ...rest }: MenuRadioGroupProps) => {\n return (\n <BaseMenu.RadioGroup\n data-spark-component=\"menu-radio-group\"\n className={cx('py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.RadioGroup>\n )\n}\n\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuRadioItemProps extends Omit<\n ComponentProps<typeof BaseMenu.RadioItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with radio button functionality.\n * Only one radio item can be selected within its RadioGroup.\n * The radio indicator is automatically rendered on the left side.\n */\nexport const MenuRadioItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuRadioItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.RadioItem\n ref={ref}\n data-spark-component=\"menu-radio-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.RadioItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.RadioItemIndicator>\n {children}\n </BaseMenu.RadioItem>\n )\n}\n\nMenuRadioItem.displayName = 'Menu.RadioItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuSeparatorProps extends ComponentProps<typeof BaseMenu.Separator> {}\n\n/**\n * A visual divider between menu items or groups.\n * Creates clear separation between different sections of the menu.\n */\nexport const MenuSeparator = ({ className, ...rest }: MenuSeparatorProps) => {\n return (\n <BaseMenu.Separator\n data-spark-component=\"menu-separator\"\n className={cx('my-sm h-px bg-outline/dim-2', className)}\n {...rest}\n />\n )\n}\n\nMenuSeparator.displayName = 'Menu.Separator'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nimport { MenuSubmenuContext } from './MenuSubmenuContext'\n\nexport interface MenuSubmenuProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuRoot>,\n 'children'\n> {\n /**\n * The content of the submenu (trigger, positioner, popup, etc.)\n */\n children: ReactNode\n}\n\n/**\n * A nested submenu that appears when its trigger is activated.\n * Inherits styling context from the parent menu.\n */\nexport const MenuSubmenu = ({ children, ...rest }: MenuSubmenuProps) => {\n return (\n <BaseMenu.SubmenuRoot data-spark-component=\"menu-submenu\" {...rest}>\n <MenuSubmenuContext.Provider value={true}>{children}</MenuSubmenuContext.Provider>\n </BaseMenu.SubmenuRoot>\n )\n}\n\nMenuSubmenu.displayName = 'Menu.Submenu'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowVerticalRight } from '@spark-ui/icons/ArrowVerticalRight'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuSubmenuTriggerProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuTrigger>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that opens a submenu when activated.\n * Displays an arrow indicator to show submenu availability.\n */\nexport const MenuSubmenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuSubmenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.SubmenuTrigger\n ref={ref}\n data-spark-component=\"menu-submenu-trigger\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n <span className=\"flex-1\">{children}</span>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <ArrowVerticalRight />\n </Icon>\n </BaseMenu.SubmenuTrigger>\n )\n}\n\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowHorizontalDown } from '@spark-ui/icons/ArrowHorizontalDown'\nimport { cx } from 'class-variance-authority'\nimport {\n cloneElement,\n isValidElement,\n type ComponentProps,\n type ReactElement,\n type Ref,\n} from 'react'\n\nimport { Icon } from '../icon'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuTriggerProps extends Omit<ComponentProps<typeof BaseMenu.Trigger>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\n/**\n * The button that toggles the menu.\n * Renders a <button> element by default, or uses asChild for custom elements.\n * When used with asChild and a Button component, automatically adds an ArrowHorizontalDown icon.\n * Button components should use design=\"outlined\" and intent=\"support\".\n */\nexport const MenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n // When asChild is used with a Button, enhance it with the arrow icon\n const enhancedChildren =\n asChild && isValidElement(children)\n ? cloneElement(\n children as ReactElement,\n {\n design: (children.props as { design?: string }).design ?? 'outlined',\n intent: (children.props as { intent?: string }).intent ?? 'support',\n children: (\n <>\n {(children.props as { children: React.ReactNode }).children}\n <Icon size=\"sm\" intent=\"current\" className=\"shrink-0\">\n <ArrowHorizontalDown />\n </Icon>\n </>\n ),\n } as Partial<unknown>\n )\n : children\n\n return (\n <BaseMenu.Trigger\n ref={ref}\n data-spark-component=\"menu-trigger\"\n render={renderSlot}\n className={cx(\n 'inline-flex items-center justify-center',\n 'focus-visible:u-outline',\n className\n )}\n {...rest}\n >\n {enhancedChildren}\n </BaseMenu.Trigger>\n )\n}\n\nMenuTrigger.displayName = 'Menu.Trigger'\n","import { Menu as Root } from './Menu'\nimport { MenuCheckboxItem } from './MenuCheckboxItem'\nimport { MenuGroup } from './MenuGroup'\nimport { MenuGroupLabel } from './MenuGroupLabel'\nimport { MenuItem } from './MenuItem'\nimport { MenuLinkItem } from './MenuLinkItem'\nimport { MenuPopup } from './MenuPopup'\nimport { MenuPortal } from './MenuPortal'\nimport { MenuPositioner } from './MenuPositioner'\nimport { MenuRadioGroup } from './MenuRadioGroup'\nimport { MenuRadioItem } from './MenuRadioItem'\nimport { MenuSeparator } from './MenuSeparator'\nimport { MenuSubmenu } from './MenuSubmenu'\nimport { MenuSubmenuTrigger } from './MenuSubmenuTrigger'\nimport { MenuTrigger } from './MenuTrigger'\n\n/**\n * A menu component that enables users to select options from a dropdown menu triggered by a button or other interactive element.\n */\nexport const Menu: typeof Root & {\n Trigger: typeof MenuTrigger\n Portal: typeof MenuPortal\n Positioner: typeof MenuPositioner\n Popup: typeof MenuPopup\n Item: typeof MenuItem\n LinkItem: typeof MenuLinkItem\n Submenu: typeof MenuSubmenu\n SubmenuTrigger: typeof MenuSubmenuTrigger\n Group: typeof MenuGroup\n GroupLabel: typeof MenuGroupLabel\n RadioGroup: typeof MenuRadioGroup\n RadioItem: typeof MenuRadioItem\n CheckboxItem: typeof MenuCheckboxItem\n Separator: typeof MenuSeparator\n} = Object.assign(Root, {\n Trigger: MenuTrigger,\n Portal: MenuPortal,\n Positioner: MenuPositioner,\n Popup: MenuPopup,\n Item: MenuItem,\n LinkItem: MenuLinkItem,\n Submenu: MenuSubmenu,\n SubmenuTrigger: MenuSubmenuTrigger,\n Group: MenuGroup,\n GroupLabel: MenuGroupLabel,\n RadioGroup: MenuRadioGroup,\n RadioItem: MenuRadioItem,\n CheckboxItem: MenuCheckboxItem,\n Separator: MenuSeparator,\n})\n\nMenu.displayName = 'Menu'\nMenuTrigger.displayName = 'Menu.Trigger'\nMenuPortal.displayName = 'Menu.Portal'\nMenuPositioner.displayName = 'Menu.Positioner'\nMenuPopup.displayName = 'Menu.Popup'\nMenuItem.displayName = 'Menu.Item'\nMenuLinkItem.displayName = 'Menu.LinkItem'\nMenuSubmenu.displayName = 'Menu.Submenu'\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\nMenuGroup.displayName = 'Menu.Group'\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\nMenuRadioItem.displayName = 'Menu.RadioItem'\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\nMenuSeparator.displayName = 'Menu.Separator'\n\nexport { type MenuProps } from './Menu'\nexport { type MenuTriggerProps } from './MenuTrigger'\nexport { type MenuPortalProps } from './MenuPortal'\nexport { type MenuPositionerProps } from './MenuPositioner'\nexport { type MenuPopupProps } from './MenuPopup'\nexport { type MenuItemProps } from './MenuItem'\nexport { type MenuLinkItemProps } from './MenuLinkItem'\nexport { type MenuSubmenuProps } from './MenuSubmenu'\nexport { type MenuSubmenuTriggerProps } from './MenuSubmenuTrigger'\nexport { type MenuGroupProps } from './MenuGroup'\nexport { type MenuGroupLabelProps } from './MenuGroupLabel'\nexport { type MenuRadioGroupProps } from './MenuRadioGroup'\nexport { type MenuRadioItemProps } from './MenuRadioItem'\nexport { type MenuCheckboxItemProps } from './MenuCheckboxItem'\nexport { type MenuSeparatorProps } from './MenuSeparator'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/menu/Menu.tsx","../../src/menu/MenuItemStyles.tsx","../../src/menu/useRenderSlot.tsx","../../src/menu/MenuCheckboxItem.tsx","../../src/menu/MenuGroup.tsx","../../src/menu/MenuGroupLabel.tsx","../../src/menu/MenuItem.tsx","../../src/menu/MenuLinkItem.tsx","../../src/menu/MenuPopup.tsx","../../src/menu/MenuPortal.tsx","../../src/menu/MenuSubmenuContext.tsx","../../src/menu/MenuPositioner.tsx","../../src/menu/MenuRadioGroup.tsx","../../src/menu/MenuRadioItem.tsx","../../src/menu/MenuSeparator.tsx","../../src/menu/MenuSubmenu.tsx","../../src/menu/MenuSubmenuTrigger.tsx","../../src/menu/MenuTrigger.tsx","../../src/menu/index.ts"],"sourcesContent":["import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nexport interface MenuProps extends Omit<ComponentProps<typeof BaseMenu.Root>, 'children'> {\n /**\n * The content of the menu (trigger, portal, etc.)\n */\n children: ReactNode\n}\n\n/**\n * Root container for menu state and styling context.\n */\nexport const Menu = ({ children, ...rest }: MenuProps) => {\n return (\n <BaseMenu.Root data-spark-component=\"menu\" {...rest}>\n {children}\n </BaseMenu.Root>\n )\n}\n\nMenu.displayName = 'Menu'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport const menuItemStyles = cva(\n [\n 'gap-md flex w-full cursor-pointer items-center justify-start',\n 'text-left text-body-1',\n 'transition-colors duration-100',\n 'outline-none',\n 'focus-visible:u-outline focus-visible:-outline-offset-2',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-dim-3',\n 'min-h-sz-44',\n 'px-lg py-md',\n 'data-highlighted:bg-surface-hovered',\n 'data-popup-open:bg-surface-hovered',\n ],\n {\n variants: {\n intent: makeVariants<\n 'intent',\n ['surface', 'main', 'support', 'accent', 'success', 'alert', 'danger', 'info', 'neutral']\n >({\n surface: ['text-on-surface'],\n main: ['text-on-surface'],\n support: ['text-on-surface'],\n accent: ['text-on-surface'],\n success: ['text-on-surface'],\n alert: ['text-on-surface'],\n danger: ['text-on-surface'],\n info: ['text-on-surface'],\n neutral: ['text-on-surface'],\n }),\n },\n defaultVariants: {\n intent: 'surface',\n },\n }\n)\n\nexport type MenuItemStylesProps = VariantProps<typeof menuItemStyles>\n","import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean) {\n return asChild ? ({ ...props }: object) => <Slot {...props} /> : undefined\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuCheckboxItemProps extends Omit<\n ComponentProps<typeof BaseMenu.CheckboxItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with checkbox functionality.\n * Can be toggled on and off, allowing multiple selections.\n * The checkbox indicator is automatically rendered on the left side.\n */\nexport const MenuCheckboxItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuCheckboxItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.CheckboxItem\n ref={ref}\n data-spark-component=\"menu-checkbox-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.CheckboxItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.CheckboxItemIndicator>\n {children}\n </BaseMenu.CheckboxItem>\n )\n}\n\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuGroupProps extends ComponentProps<typeof BaseMenu.Group> {}\n\n/**\n * A container for grouping related menu items together.\n * Works with Menu.GroupLabel for semantic grouping.\n */\nexport const MenuGroup = ({ children, className, ...rest }: MenuGroupProps) => {\n return (\n <BaseMenu.Group data-spark-component=\"menu-group\" className={cx('py-sm', className)} {...rest}>\n {children}\n </BaseMenu.Group>\n )\n}\n\nMenuGroup.displayName = 'Menu.Group'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuGroupLabelProps extends Omit<\n ComponentProps<typeof BaseMenu.GroupLabel>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A label for a group of menu items.\n * Provides semantic context and visual separation for grouped items.\n */\nexport const MenuGroupLabel = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuGroupLabelProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.GroupLabel\n ref={ref}\n data-spark-component=\"menu-group-label\"\n render={renderSlot}\n className={cx('text-on-surface/dim-1 text-body-2 font-bold', 'px-lg py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.GroupLabel>\n )\n}\n\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuItemProps extends Omit<ComponentProps<typeof BaseMenu.Item>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that triggers an action when activated.\n * Renders a clickable menu option with keyboard support.\n */\nexport const MenuItem = ({ asChild = false, children, className, ref, ...rest }: MenuItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Item\n ref={ref}\n data-spark-component=\"menu-item\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n {children}\n </BaseMenu.Item>\n )\n}\n\nMenuItem.displayName = 'Menu.Item'\n","import { Link } from '@spark-ui/icons/Link'\nimport { type ComponentPropsWithoutRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { MenuItem } from './MenuItem'\n\nexport interface MenuLinkItemProps extends Omit<\n ComponentPropsWithoutRef<typeof MenuItem>,\n 'asChild'\n> {\n /**\n * The URL to navigate to.\n */\n href: string\n /**\n * Where to display the linked URL.\n * @default undefined\n */\n target?: string\n /**\n * The relationship between the current document and the linked document.\n * @default undefined\n */\n rel?: string\n}\n\n/**\n * A menu item that acts as a link.\n * Navigates to a URL when activated, useful for navigation menus.\n * Use with Next.js Link or React Router Link via the children prop.\n */\nexport const MenuLinkItem = ({ children, href, target, rel, ...rest }: MenuLinkItemProps) => {\n return (\n <MenuItem asChild {...rest}>\n <a href={href} target={target} rel={rel}>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <Link />\n </Icon>\n <span className=\"flex-1\">{children}</span>\n </a>\n </MenuItem>\n )\n}\n\nMenuLinkItem.displayName = 'Menu.LinkItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuPopupProps extends Omit<ComponentProps<typeof BaseMenu.Popup>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * The scrollable menu container that holds menu items.\n * Serves as the viewport for menu content with overflow handling.\n */\nexport const MenuPopup = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuPopupProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Popup\n ref={ref}\n data-spark-component=\"menu-popup\"\n render={renderSlot}\n className={cx(\n [\n 'rounded-md bg-surface shadow-lg min-w-sz-192',\n 'p-sm',\n 'overflow-auto',\n 'z-popover',\n 'data-starting-style:opacity-0',\n 'data-ending-style:opacity-0',\n 'opacity-100',\n 'transition-opacity duration-200',\n ],\n className\n )}\n {...rest}\n >\n {children}\n </BaseMenu.Popup>\n )\n}\n\nMenuPopup.displayName = 'Menu.Popup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuPortalProps extends ComponentProps<typeof BaseMenu.Portal> {}\n\n/**\n * Portal wrapper that renders the menu in a different part of the DOM tree.\n * Useful for avoiding z-index and overflow issues.\n */\nexport const MenuPortal = ({ children, ...rest }: MenuPortalProps) => {\n return <BaseMenu.Portal {...rest}>{children}</BaseMenu.Portal>\n}\n\nMenuPortal.displayName = 'Menu.Portal'\n","import { createContext, useContext } from 'react'\n\n/**\n * Context to track if we're inside a submenu\n */\nexport const MenuSubmenuContext = createContext<boolean>(false)\n\n/**\n * Hook to check if the current menu is a submenu\n */\nexport const useIsSubmenu = () => {\n return useContext(MenuSubmenuContext)\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nimport { useIsSubmenu } from './MenuSubmenuContext'\n\nexport interface MenuPositionerProps extends ComponentProps<typeof BaseMenu.Positioner> {}\n\n/**\n * Positioning wrapper for the menu with collision detection.\n * Handles menu placement relative to the trigger and viewport boundaries.\n */\nexport const MenuPositioner = ({ children, sideOffset, ...rest }: MenuPositionerProps) => {\n const isSubmenu = useIsSubmenu()\n\n // Apply sideOffset of 8 for root menu, 0 for submenus (unless explicitly overridden)\n const defaultSideOffset = isSubmenu ? 0 : 8\n const finalSideOffset = sideOffset ?? defaultSideOffset\n\n return (\n <BaseMenu.Positioner sideOffset={finalSideOffset} {...rest}>\n {children}\n </BaseMenu.Positioner>\n )\n}\n\nMenuPositioner.displayName = 'Menu.Positioner'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuRadioGroupProps extends ComponentProps<typeof BaseMenu.RadioGroup> {}\n\n/**\n * A container for radio menu items where only one item can be selected at a time.\n * Manages the selection state for its radio items.\n */\nexport const MenuRadioGroup = ({ children, className, ...rest }: MenuRadioGroupProps) => {\n return (\n <BaseMenu.RadioGroup\n data-spark-component=\"menu-radio-group\"\n className={cx('py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.RadioGroup>\n )\n}\n\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuRadioItemProps extends Omit<\n ComponentProps<typeof BaseMenu.RadioItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with radio button functionality.\n * Only one radio item can be selected within its RadioGroup.\n * The radio indicator is automatically rendered on the left side.\n */\nexport const MenuRadioItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuRadioItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.RadioItem\n ref={ref}\n data-spark-component=\"menu-radio-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.RadioItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.RadioItemIndicator>\n {children}\n </BaseMenu.RadioItem>\n )\n}\n\nMenuRadioItem.displayName = 'Menu.RadioItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuSeparatorProps extends ComponentProps<typeof BaseMenu.Separator> {}\n\n/**\n * A visual divider between menu items or groups.\n * Creates clear separation between different sections of the menu.\n */\nexport const MenuSeparator = ({ className, ...rest }: MenuSeparatorProps) => {\n return (\n <BaseMenu.Separator\n data-spark-component=\"menu-separator\"\n className={cx('my-sm h-px bg-outline/dim-2', className)}\n {...rest}\n />\n )\n}\n\nMenuSeparator.displayName = 'Menu.Separator'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nimport { MenuSubmenuContext } from './MenuSubmenuContext'\n\nexport interface MenuSubmenuProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuRoot>,\n 'children'\n> {\n /**\n * The content of the submenu (trigger, positioner, popup, etc.)\n */\n children: ReactNode\n}\n\n/**\n * A nested submenu that appears when its trigger is activated.\n * Inherits styling context from the parent menu.\n */\nexport const MenuSubmenu = ({ children, ...rest }: MenuSubmenuProps) => {\n return (\n <BaseMenu.SubmenuRoot data-spark-component=\"menu-submenu\" {...rest}>\n <MenuSubmenuContext value={true}>{children}</MenuSubmenuContext>\n </BaseMenu.SubmenuRoot>\n )\n}\n\nMenuSubmenu.displayName = 'Menu.Submenu'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowVerticalRight } from '@spark-ui/icons/ArrowVerticalRight'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuSubmenuTriggerProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuTrigger>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that opens a submenu when activated.\n * Displays an arrow indicator to show submenu availability.\n */\nexport const MenuSubmenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuSubmenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.SubmenuTrigger\n ref={ref}\n data-spark-component=\"menu-submenu-trigger\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n <span className=\"flex-1\">{children}</span>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <ArrowVerticalRight />\n </Icon>\n </BaseMenu.SubmenuTrigger>\n )\n}\n\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowHorizontalDown } from '@spark-ui/icons/ArrowHorizontalDown'\nimport { cx } from 'class-variance-authority'\nimport {\n cloneElement,\n isValidElement,\n type ComponentProps,\n type ReactElement,\n type Ref,\n} from 'react'\n\nimport { Icon } from '../icon'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuTriggerProps extends Omit<ComponentProps<typeof BaseMenu.Trigger>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\n/**\n * The button that toggles the menu.\n * Renders a <button> element by default, or uses asChild for custom elements.\n * When used with asChild and a Button component, automatically adds an ArrowHorizontalDown icon.\n * Button components should use design=\"outlined\" and intent=\"support\".\n */\nexport const MenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n // When asChild is used with a Button, enhance it with the arrow icon\n const enhancedChildren =\n asChild && isValidElement(children)\n ? cloneElement(\n children as ReactElement,\n {\n design: (children.props as { design?: string }).design ?? 'outlined',\n intent: (children.props as { intent?: string }).intent ?? 'support',\n children: (\n <>\n {(children.props as { children: React.ReactNode }).children}\n <Icon size=\"sm\" intent=\"current\" className=\"shrink-0\">\n <ArrowHorizontalDown />\n </Icon>\n </>\n ),\n } as Partial<unknown>\n )\n : children\n\n return (\n <BaseMenu.Trigger\n ref={ref}\n data-spark-component=\"menu-trigger\"\n render={renderSlot}\n className={cx(\n 'inline-flex items-center justify-center',\n 'focus-visible:u-outline',\n className\n )}\n {...rest}\n >\n {enhancedChildren}\n </BaseMenu.Trigger>\n )\n}\n\nMenuTrigger.displayName = 'Menu.Trigger'\n","import { Menu as Root } from './Menu'\nimport { MenuCheckboxItem } from './MenuCheckboxItem'\nimport { MenuGroup } from './MenuGroup'\nimport { MenuGroupLabel } from './MenuGroupLabel'\nimport { MenuItem } from './MenuItem'\nimport { MenuLinkItem } from './MenuLinkItem'\nimport { MenuPopup } from './MenuPopup'\nimport { MenuPortal } from './MenuPortal'\nimport { MenuPositioner } from './MenuPositioner'\nimport { MenuRadioGroup } from './MenuRadioGroup'\nimport { MenuRadioItem } from './MenuRadioItem'\nimport { MenuSeparator } from './MenuSeparator'\nimport { MenuSubmenu } from './MenuSubmenu'\nimport { MenuSubmenuTrigger } from './MenuSubmenuTrigger'\nimport { MenuTrigger } from './MenuTrigger'\n\n/**\n * A menu component that enables users to select options from a dropdown menu triggered by a button or other interactive element.\n */\nexport const Menu: typeof Root & {\n Trigger: typeof MenuTrigger\n Portal: typeof MenuPortal\n Positioner: typeof MenuPositioner\n Popup: typeof MenuPopup\n Item: typeof MenuItem\n LinkItem: typeof MenuLinkItem\n Submenu: typeof MenuSubmenu\n SubmenuTrigger: typeof MenuSubmenuTrigger\n Group: typeof MenuGroup\n GroupLabel: typeof MenuGroupLabel\n RadioGroup: typeof MenuRadioGroup\n RadioItem: typeof MenuRadioItem\n CheckboxItem: typeof MenuCheckboxItem\n Separator: typeof MenuSeparator\n} = Object.assign(Root, {\n Trigger: MenuTrigger,\n Portal: MenuPortal,\n Positioner: MenuPositioner,\n Popup: MenuPopup,\n Item: MenuItem,\n LinkItem: MenuLinkItem,\n Submenu: MenuSubmenu,\n SubmenuTrigger: MenuSubmenuTrigger,\n Group: MenuGroup,\n GroupLabel: MenuGroupLabel,\n RadioGroup: MenuRadioGroup,\n RadioItem: MenuRadioItem,\n CheckboxItem: MenuCheckboxItem,\n Separator: MenuSeparator,\n})\n\nMenu.displayName = 'Menu'\nMenuTrigger.displayName = 'Menu.Trigger'\nMenuPortal.displayName = 'Menu.Portal'\nMenuPositioner.displayName = 'Menu.Positioner'\nMenuPopup.displayName = 'Menu.Popup'\nMenuItem.displayName = 'Menu.Item'\nMenuLinkItem.displayName = 'Menu.LinkItem'\nMenuSubmenu.displayName = 'Menu.Submenu'\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\nMenuGroup.displayName = 'Menu.Group'\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\nMenuRadioItem.displayName = 'Menu.RadioItem'\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\nMenuSeparator.displayName = 'Menu.Separator'\n\nexport { type MenuProps } from './Menu'\nexport { type MenuTriggerProps } from './MenuTrigger'\nexport { type MenuPortalProps } from './MenuPortal'\nexport { type MenuPositionerProps } from './MenuPositioner'\nexport { type MenuPopupProps } from './MenuPopup'\nexport { type MenuItemProps } from './MenuItem'\nexport { type MenuLinkItemProps } from './MenuLinkItem'\nexport { type MenuSubmenuProps } from './MenuSubmenu'\nexport { type MenuSubmenuTriggerProps } from './MenuSubmenuTrigger'\nexport { type MenuGroupProps } from './MenuGroup'\nexport { type MenuGroupLabelProps } from './MenuGroupLabel'\nexport { type MenuRadioGroupProps } from './MenuRadioGroup'\nexport { type MenuRadioItemProps } from './MenuRadioItem'\nexport { type MenuCheckboxItemProps } from './MenuCheckboxItem'\nexport { type MenuSeparatorProps } from './MenuSeparator'\n"],"mappings":"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"}
|
package/dist/menu/index.mjs
CHANGED
|
@@ -213,7 +213,7 @@ M.displayName = "Menu.Separator";
|
|
|
213
213
|
var N = ({ children: e, ...t }) => /* @__PURE__ */ l(h.SubmenuRoot, {
|
|
214
214
|
"data-spark-component": "menu-submenu",
|
|
215
215
|
...t,
|
|
216
|
-
children: /* @__PURE__ */ l(D
|
|
216
|
+
children: /* @__PURE__ */ l(D, {
|
|
217
217
|
value: !0,
|
|
218
218
|
children: e
|
|
219
219
|
})
|
package/dist/menu/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/menu/Menu.tsx","../../src/menu/MenuItemStyles.tsx","../../src/menu/useRenderSlot.tsx","../../src/menu/MenuCheckboxItem.tsx","../../src/menu/MenuGroup.tsx","../../src/menu/MenuGroupLabel.tsx","../../src/menu/MenuItem.tsx","../../src/menu/MenuLinkItem.tsx","../../src/menu/MenuPopup.tsx","../../src/menu/MenuPortal.tsx","../../src/menu/MenuSubmenuContext.tsx","../../src/menu/MenuPositioner.tsx","../../src/menu/MenuRadioGroup.tsx","../../src/menu/MenuRadioItem.tsx","../../src/menu/MenuSeparator.tsx","../../src/menu/MenuSubmenu.tsx","../../src/menu/MenuSubmenuTrigger.tsx","../../src/menu/MenuTrigger.tsx","../../src/menu/index.ts"],"sourcesContent":["import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nexport interface MenuProps extends Omit<ComponentProps<typeof BaseMenu.Root>, 'children'> {\n /**\n * The content of the menu (trigger, portal, etc.)\n */\n children: ReactNode\n}\n\n/**\n * Root container for menu state and styling context.\n */\nexport const Menu = ({ children, ...rest }: MenuProps) => {\n return (\n <BaseMenu.Root data-spark-component=\"menu\" {...rest}>\n {children}\n </BaseMenu.Root>\n )\n}\n\nMenu.displayName = 'Menu'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport const menuItemStyles = cva(\n [\n 'gap-md flex w-full cursor-pointer items-center justify-start',\n 'text-left text-body-1',\n 'transition-colors duration-100',\n 'outline-none',\n 'focus-visible:u-outline focus-visible:-outline-offset-2',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-dim-3',\n 'min-h-sz-44',\n 'px-lg py-md',\n 'data-highlighted:bg-surface-hovered',\n 'data-popup-open:bg-surface-hovered',\n ],\n {\n variants: {\n intent: makeVariants<\n 'intent',\n ['surface', 'main', 'support', 'accent', 'success', 'alert', 'danger', 'info', 'neutral']\n >({\n surface: ['text-on-surface'],\n main: ['text-on-surface'],\n support: ['text-on-surface'],\n accent: ['text-on-surface'],\n success: ['text-on-surface'],\n alert: ['text-on-surface'],\n danger: ['text-on-surface'],\n info: ['text-on-surface'],\n neutral: ['text-on-surface'],\n }),\n },\n defaultVariants: {\n intent: 'surface',\n },\n }\n)\n\nexport type MenuItemStylesProps = VariantProps<typeof menuItemStyles>\n","import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean) {\n return asChild ? ({ ...props }: object) => <Slot {...props} /> : undefined\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuCheckboxItemProps extends Omit<\n ComponentProps<typeof BaseMenu.CheckboxItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with checkbox functionality.\n * Can be toggled on and off, allowing multiple selections.\n * The checkbox indicator is automatically rendered on the left side.\n */\nexport const MenuCheckboxItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuCheckboxItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.CheckboxItem\n ref={ref}\n data-spark-component=\"menu-checkbox-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.CheckboxItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.CheckboxItemIndicator>\n {children}\n </BaseMenu.CheckboxItem>\n )\n}\n\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuGroupProps extends ComponentProps<typeof BaseMenu.Group> {}\n\n/**\n * A container for grouping related menu items together.\n * Works with Menu.GroupLabel for semantic grouping.\n */\nexport const MenuGroup = ({ children, className, ...rest }: MenuGroupProps) => {\n return (\n <BaseMenu.Group data-spark-component=\"menu-group\" className={cx('py-sm', className)} {...rest}>\n {children}\n </BaseMenu.Group>\n )\n}\n\nMenuGroup.displayName = 'Menu.Group'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuGroupLabelProps extends Omit<\n ComponentProps<typeof BaseMenu.GroupLabel>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A label for a group of menu items.\n * Provides semantic context and visual separation for grouped items.\n */\nexport const MenuGroupLabel = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuGroupLabelProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.GroupLabel\n ref={ref}\n data-spark-component=\"menu-group-label\"\n render={renderSlot}\n className={cx('text-on-surface/dim-1 text-body-2 font-bold', 'px-lg py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.GroupLabel>\n )\n}\n\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuItemProps extends Omit<ComponentProps<typeof BaseMenu.Item>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that triggers an action when activated.\n * Renders a clickable menu option with keyboard support.\n */\nexport const MenuItem = ({ asChild = false, children, className, ref, ...rest }: MenuItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Item\n ref={ref}\n data-spark-component=\"menu-item\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n {children}\n </BaseMenu.Item>\n )\n}\n\nMenuItem.displayName = 'Menu.Item'\n","import { Link } from '@spark-ui/icons/Link'\nimport { type ComponentPropsWithoutRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { MenuItem } from './MenuItem'\n\nexport interface MenuLinkItemProps extends Omit<\n ComponentPropsWithoutRef<typeof MenuItem>,\n 'asChild'\n> {\n /**\n * The URL to navigate to.\n */\n href: string\n /**\n * Where to display the linked URL.\n * @default undefined\n */\n target?: string\n /**\n * The relationship between the current document and the linked document.\n * @default undefined\n */\n rel?: string\n}\n\n/**\n * A menu item that acts as a link.\n * Navigates to a URL when activated, useful for navigation menus.\n * Use with Next.js Link or React Router Link via the children prop.\n */\nexport const MenuLinkItem = ({ children, href, target, rel, ...rest }: MenuLinkItemProps) => {\n return (\n <MenuItem asChild {...rest}>\n <a href={href} target={target} rel={rel}>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <Link />\n </Icon>\n <span className=\"flex-1\">{children}</span>\n </a>\n </MenuItem>\n )\n}\n\nMenuLinkItem.displayName = 'Menu.LinkItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuPopupProps extends Omit<ComponentProps<typeof BaseMenu.Popup>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * The scrollable menu container that holds menu items.\n * Serves as the viewport for menu content with overflow handling.\n */\nexport const MenuPopup = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuPopupProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Popup\n ref={ref}\n data-spark-component=\"menu-popup\"\n render={renderSlot}\n className={cx(\n [\n 'rounded-md bg-surface shadow-lg min-w-sz-192',\n 'p-sm',\n 'overflow-auto',\n 'z-popover',\n 'data-starting-style:opacity-0',\n 'data-ending-style:opacity-0',\n 'opacity-100',\n 'transition-opacity duration-200',\n ],\n className\n )}\n {...rest}\n >\n {children}\n </BaseMenu.Popup>\n )\n}\n\nMenuPopup.displayName = 'Menu.Popup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuPortalProps extends ComponentProps<typeof BaseMenu.Portal> {}\n\n/**\n * Portal wrapper that renders the menu in a different part of the DOM tree.\n * Useful for avoiding z-index and overflow issues.\n */\nexport const MenuPortal = ({ children, ...rest }: MenuPortalProps) => {\n return <BaseMenu.Portal {...rest}>{children}</BaseMenu.Portal>\n}\n\nMenuPortal.displayName = 'Menu.Portal'\n","import { createContext, useContext } from 'react'\n\n/**\n * Context to track if we're inside a submenu\n */\nexport const MenuSubmenuContext = createContext<boolean>(false)\n\n/**\n * Hook to check if the current menu is a submenu\n */\nexport const useIsSubmenu = () => {\n return useContext(MenuSubmenuContext)\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nimport { useIsSubmenu } from './MenuSubmenuContext'\n\nexport interface MenuPositionerProps extends ComponentProps<typeof BaseMenu.Positioner> {}\n\n/**\n * Positioning wrapper for the menu with collision detection.\n * Handles menu placement relative to the trigger and viewport boundaries.\n */\nexport const MenuPositioner = ({ children, sideOffset, ...rest }: MenuPositionerProps) => {\n const isSubmenu = useIsSubmenu()\n\n // Apply sideOffset of 8 for root menu, 0 for submenus (unless explicitly overridden)\n const defaultSideOffset = isSubmenu ? 0 : 8\n const finalSideOffset = sideOffset ?? defaultSideOffset\n\n return (\n <BaseMenu.Positioner sideOffset={finalSideOffset} {...rest}>\n {children}\n </BaseMenu.Positioner>\n )\n}\n\nMenuPositioner.displayName = 'Menu.Positioner'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuRadioGroupProps extends ComponentProps<typeof BaseMenu.RadioGroup> {}\n\n/**\n * A container for radio menu items where only one item can be selected at a time.\n * Manages the selection state for its radio items.\n */\nexport const MenuRadioGroup = ({ children, className, ...rest }: MenuRadioGroupProps) => {\n return (\n <BaseMenu.RadioGroup\n data-spark-component=\"menu-radio-group\"\n className={cx('py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.RadioGroup>\n )\n}\n\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuRadioItemProps extends Omit<\n ComponentProps<typeof BaseMenu.RadioItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with radio button functionality.\n * Only one radio item can be selected within its RadioGroup.\n * The radio indicator is automatically rendered on the left side.\n */\nexport const MenuRadioItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuRadioItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.RadioItem\n ref={ref}\n data-spark-component=\"menu-radio-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.RadioItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.RadioItemIndicator>\n {children}\n </BaseMenu.RadioItem>\n )\n}\n\nMenuRadioItem.displayName = 'Menu.RadioItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuSeparatorProps extends ComponentProps<typeof BaseMenu.Separator> {}\n\n/**\n * A visual divider between menu items or groups.\n * Creates clear separation between different sections of the menu.\n */\nexport const MenuSeparator = ({ className, ...rest }: MenuSeparatorProps) => {\n return (\n <BaseMenu.Separator\n data-spark-component=\"menu-separator\"\n className={cx('my-sm h-px bg-outline/dim-2', className)}\n {...rest}\n />\n )\n}\n\nMenuSeparator.displayName = 'Menu.Separator'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nimport { MenuSubmenuContext } from './MenuSubmenuContext'\n\nexport interface MenuSubmenuProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuRoot>,\n 'children'\n> {\n /**\n * The content of the submenu (trigger, positioner, popup, etc.)\n */\n children: ReactNode\n}\n\n/**\n * A nested submenu that appears when its trigger is activated.\n * Inherits styling context from the parent menu.\n */\nexport const MenuSubmenu = ({ children, ...rest }: MenuSubmenuProps) => {\n return (\n <BaseMenu.SubmenuRoot data-spark-component=\"menu-submenu\" {...rest}>\n <MenuSubmenuContext.Provider value={true}>{children}</MenuSubmenuContext.Provider>\n </BaseMenu.SubmenuRoot>\n )\n}\n\nMenuSubmenu.displayName = 'Menu.Submenu'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowVerticalRight } from '@spark-ui/icons/ArrowVerticalRight'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuSubmenuTriggerProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuTrigger>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that opens a submenu when activated.\n * Displays an arrow indicator to show submenu availability.\n */\nexport const MenuSubmenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuSubmenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.SubmenuTrigger\n ref={ref}\n data-spark-component=\"menu-submenu-trigger\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n <span className=\"flex-1\">{children}</span>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <ArrowVerticalRight />\n </Icon>\n </BaseMenu.SubmenuTrigger>\n )\n}\n\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowHorizontalDown } from '@spark-ui/icons/ArrowHorizontalDown'\nimport { cx } from 'class-variance-authority'\nimport {\n cloneElement,\n isValidElement,\n type ComponentProps,\n type ReactElement,\n type Ref,\n} from 'react'\n\nimport { Icon } from '../icon'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuTriggerProps extends Omit<ComponentProps<typeof BaseMenu.Trigger>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\n/**\n * The button that toggles the menu.\n * Renders a <button> element by default, or uses asChild for custom elements.\n * When used with asChild and a Button component, automatically adds an ArrowHorizontalDown icon.\n * Button components should use design=\"outlined\" and intent=\"support\".\n */\nexport const MenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n // When asChild is used with a Button, enhance it with the arrow icon\n const enhancedChildren =\n asChild && isValidElement(children)\n ? cloneElement(\n children as ReactElement,\n {\n design: (children.props as { design?: string }).design ?? 'outlined',\n intent: (children.props as { intent?: string }).intent ?? 'support',\n children: (\n <>\n {(children.props as { children: React.ReactNode }).children}\n <Icon size=\"sm\" intent=\"current\" className=\"shrink-0\">\n <ArrowHorizontalDown />\n </Icon>\n </>\n ),\n } as Partial<unknown>\n )\n : children\n\n return (\n <BaseMenu.Trigger\n ref={ref}\n data-spark-component=\"menu-trigger\"\n render={renderSlot}\n className={cx(\n 'inline-flex items-center justify-center',\n 'focus-visible:u-outline',\n className\n )}\n {...rest}\n >\n {enhancedChildren}\n </BaseMenu.Trigger>\n )\n}\n\nMenuTrigger.displayName = 'Menu.Trigger'\n","import { Menu as Root } from './Menu'\nimport { MenuCheckboxItem } from './MenuCheckboxItem'\nimport { MenuGroup } from './MenuGroup'\nimport { MenuGroupLabel } from './MenuGroupLabel'\nimport { MenuItem } from './MenuItem'\nimport { MenuLinkItem } from './MenuLinkItem'\nimport { MenuPopup } from './MenuPopup'\nimport { MenuPortal } from './MenuPortal'\nimport { MenuPositioner } from './MenuPositioner'\nimport { MenuRadioGroup } from './MenuRadioGroup'\nimport { MenuRadioItem } from './MenuRadioItem'\nimport { MenuSeparator } from './MenuSeparator'\nimport { MenuSubmenu } from './MenuSubmenu'\nimport { MenuSubmenuTrigger } from './MenuSubmenuTrigger'\nimport { MenuTrigger } from './MenuTrigger'\n\n/**\n * A menu component that enables users to select options from a dropdown menu triggered by a button or other interactive element.\n */\nexport const Menu: typeof Root & {\n Trigger: typeof MenuTrigger\n Portal: typeof MenuPortal\n Positioner: typeof MenuPositioner\n Popup: typeof MenuPopup\n Item: typeof MenuItem\n LinkItem: typeof MenuLinkItem\n Submenu: typeof MenuSubmenu\n SubmenuTrigger: typeof MenuSubmenuTrigger\n Group: typeof MenuGroup\n GroupLabel: typeof MenuGroupLabel\n RadioGroup: typeof MenuRadioGroup\n RadioItem: typeof MenuRadioItem\n CheckboxItem: typeof MenuCheckboxItem\n Separator: typeof MenuSeparator\n} = Object.assign(Root, {\n Trigger: MenuTrigger,\n Portal: MenuPortal,\n Positioner: MenuPositioner,\n Popup: MenuPopup,\n Item: MenuItem,\n LinkItem: MenuLinkItem,\n Submenu: MenuSubmenu,\n SubmenuTrigger: MenuSubmenuTrigger,\n Group: MenuGroup,\n GroupLabel: MenuGroupLabel,\n RadioGroup: MenuRadioGroup,\n RadioItem: MenuRadioItem,\n CheckboxItem: MenuCheckboxItem,\n Separator: MenuSeparator,\n})\n\nMenu.displayName = 'Menu'\nMenuTrigger.displayName = 'Menu.Trigger'\nMenuPortal.displayName = 'Menu.Portal'\nMenuPositioner.displayName = 'Menu.Positioner'\nMenuPopup.displayName = 'Menu.Popup'\nMenuItem.displayName = 'Menu.Item'\nMenuLinkItem.displayName = 'Menu.LinkItem'\nMenuSubmenu.displayName = 'Menu.Submenu'\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\nMenuGroup.displayName = 'Menu.Group'\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\nMenuRadioItem.displayName = 'Menu.RadioItem'\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\nMenuSeparator.displayName = 'Menu.Separator'\n\nexport { type MenuProps } from './Menu'\nexport { type MenuTriggerProps } from './MenuTrigger'\nexport { type MenuPortalProps } from './MenuPortal'\nexport { type MenuPositionerProps } from './MenuPositioner'\nexport { type MenuPopupProps } from './MenuPopup'\nexport { type MenuItemProps } from './MenuItem'\nexport { type MenuLinkItemProps } from './MenuLinkItem'\nexport { type MenuSubmenuProps } from './MenuSubmenu'\nexport { type MenuSubmenuTriggerProps } from './MenuSubmenuTrigger'\nexport { type MenuGroupProps } from './MenuGroup'\nexport { type MenuGroupLabelProps } from './MenuGroupLabel'\nexport { type MenuRadioGroupProps } from './MenuRadioGroup'\nexport { type MenuRadioItemProps } from './MenuRadioItem'\nexport { type MenuCheckboxItemProps } from './MenuCheckboxItem'\nexport { type MenuSeparatorProps } from './MenuSeparator'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/menu/Menu.tsx","../../src/menu/MenuItemStyles.tsx","../../src/menu/useRenderSlot.tsx","../../src/menu/MenuCheckboxItem.tsx","../../src/menu/MenuGroup.tsx","../../src/menu/MenuGroupLabel.tsx","../../src/menu/MenuItem.tsx","../../src/menu/MenuLinkItem.tsx","../../src/menu/MenuPopup.tsx","../../src/menu/MenuPortal.tsx","../../src/menu/MenuSubmenuContext.tsx","../../src/menu/MenuPositioner.tsx","../../src/menu/MenuRadioGroup.tsx","../../src/menu/MenuRadioItem.tsx","../../src/menu/MenuSeparator.tsx","../../src/menu/MenuSubmenu.tsx","../../src/menu/MenuSubmenuTrigger.tsx","../../src/menu/MenuTrigger.tsx","../../src/menu/index.ts"],"sourcesContent":["import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nexport interface MenuProps extends Omit<ComponentProps<typeof BaseMenu.Root>, 'children'> {\n /**\n * The content of the menu (trigger, portal, etc.)\n */\n children: ReactNode\n}\n\n/**\n * Root container for menu state and styling context.\n */\nexport const Menu = ({ children, ...rest }: MenuProps) => {\n return (\n <BaseMenu.Root data-spark-component=\"menu\" {...rest}>\n {children}\n </BaseMenu.Root>\n )\n}\n\nMenu.displayName = 'Menu'\n","import { makeVariants } from '@spark-ui/internal-utils'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nexport const menuItemStyles = cva(\n [\n 'gap-md flex w-full cursor-pointer items-center justify-start',\n 'text-left text-body-1',\n 'transition-colors duration-100',\n 'outline-none',\n 'focus-visible:u-outline focus-visible:-outline-offset-2',\n 'data-disabled:cursor-not-allowed data-disabled:opacity-dim-3',\n 'min-h-sz-44',\n 'px-lg py-md',\n 'data-highlighted:bg-surface-hovered',\n 'data-popup-open:bg-surface-hovered',\n ],\n {\n variants: {\n intent: makeVariants<\n 'intent',\n ['surface', 'main', 'support', 'accent', 'success', 'alert', 'danger', 'info', 'neutral']\n >({\n surface: ['text-on-surface'],\n main: ['text-on-surface'],\n support: ['text-on-surface'],\n accent: ['text-on-surface'],\n success: ['text-on-surface'],\n alert: ['text-on-surface'],\n danger: ['text-on-surface'],\n info: ['text-on-surface'],\n neutral: ['text-on-surface'],\n }),\n },\n defaultVariants: {\n intent: 'surface',\n },\n }\n)\n\nexport type MenuItemStylesProps = VariantProps<typeof menuItemStyles>\n","import { Slot } from '../slot'\n\nexport function useRenderSlot(asChild: boolean) {\n return asChild ? ({ ...props }: object) => <Slot {...props} /> : undefined\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuCheckboxItemProps extends Omit<\n ComponentProps<typeof BaseMenu.CheckboxItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with checkbox functionality.\n * Can be toggled on and off, allowing multiple selections.\n * The checkbox indicator is automatically rendered on the left side.\n */\nexport const MenuCheckboxItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuCheckboxItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.CheckboxItem\n ref={ref}\n data-spark-component=\"menu-checkbox-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.CheckboxItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.CheckboxItemIndicator>\n {children}\n </BaseMenu.CheckboxItem>\n )\n}\n\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuGroupProps extends ComponentProps<typeof BaseMenu.Group> {}\n\n/**\n * A container for grouping related menu items together.\n * Works with Menu.GroupLabel for semantic grouping.\n */\nexport const MenuGroup = ({ children, className, ...rest }: MenuGroupProps) => {\n return (\n <BaseMenu.Group data-spark-component=\"menu-group\" className={cx('py-sm', className)} {...rest}>\n {children}\n </BaseMenu.Group>\n )\n}\n\nMenuGroup.displayName = 'Menu.Group'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuGroupLabelProps extends Omit<\n ComponentProps<typeof BaseMenu.GroupLabel>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A label for a group of menu items.\n * Provides semantic context and visual separation for grouped items.\n */\nexport const MenuGroupLabel = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuGroupLabelProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.GroupLabel\n ref={ref}\n data-spark-component=\"menu-group-label\"\n render={renderSlot}\n className={cx('text-on-surface/dim-1 text-body-2 font-bold', 'px-lg py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.GroupLabel>\n )\n}\n\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuItemProps extends Omit<ComponentProps<typeof BaseMenu.Item>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that triggers an action when activated.\n * Renders a clickable menu option with keyboard support.\n */\nexport const MenuItem = ({ asChild = false, children, className, ref, ...rest }: MenuItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Item\n ref={ref}\n data-spark-component=\"menu-item\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n {children}\n </BaseMenu.Item>\n )\n}\n\nMenuItem.displayName = 'Menu.Item'\n","import { Link } from '@spark-ui/icons/Link'\nimport { type ComponentPropsWithoutRef } from 'react'\n\nimport { Icon } from '../icon'\nimport { MenuItem } from './MenuItem'\n\nexport interface MenuLinkItemProps extends Omit<\n ComponentPropsWithoutRef<typeof MenuItem>,\n 'asChild'\n> {\n /**\n * The URL to navigate to.\n */\n href: string\n /**\n * Where to display the linked URL.\n * @default undefined\n */\n target?: string\n /**\n * The relationship between the current document and the linked document.\n * @default undefined\n */\n rel?: string\n}\n\n/**\n * A menu item that acts as a link.\n * Navigates to a URL when activated, useful for navigation menus.\n * Use with Next.js Link or React Router Link via the children prop.\n */\nexport const MenuLinkItem = ({ children, href, target, rel, ...rest }: MenuLinkItemProps) => {\n return (\n <MenuItem asChild {...rest}>\n <a href={href} target={target} rel={rel}>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <Link />\n </Icon>\n <span className=\"flex-1\">{children}</span>\n </a>\n </MenuItem>\n )\n}\n\nMenuLinkItem.displayName = 'Menu.LinkItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuPopupProps extends Omit<ComponentProps<typeof BaseMenu.Popup>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * The scrollable menu container that holds menu items.\n * Serves as the viewport for menu content with overflow handling.\n */\nexport const MenuPopup = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuPopupProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.Popup\n ref={ref}\n data-spark-component=\"menu-popup\"\n render={renderSlot}\n className={cx(\n [\n 'rounded-md bg-surface shadow-lg min-w-sz-192',\n 'p-sm',\n 'overflow-auto',\n 'z-popover',\n 'data-starting-style:opacity-0',\n 'data-ending-style:opacity-0',\n 'opacity-100',\n 'transition-opacity duration-200',\n ],\n className\n )}\n {...rest}\n >\n {children}\n </BaseMenu.Popup>\n )\n}\n\nMenuPopup.displayName = 'Menu.Popup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuPortalProps extends ComponentProps<typeof BaseMenu.Portal> {}\n\n/**\n * Portal wrapper that renders the menu in a different part of the DOM tree.\n * Useful for avoiding z-index and overflow issues.\n */\nexport const MenuPortal = ({ children, ...rest }: MenuPortalProps) => {\n return <BaseMenu.Portal {...rest}>{children}</BaseMenu.Portal>\n}\n\nMenuPortal.displayName = 'Menu.Portal'\n","import { createContext, useContext } from 'react'\n\n/**\n * Context to track if we're inside a submenu\n */\nexport const MenuSubmenuContext = createContext<boolean>(false)\n\n/**\n * Hook to check if the current menu is a submenu\n */\nexport const useIsSubmenu = () => {\n return useContext(MenuSubmenuContext)\n}\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps } from 'react'\n\nimport { useIsSubmenu } from './MenuSubmenuContext'\n\nexport interface MenuPositionerProps extends ComponentProps<typeof BaseMenu.Positioner> {}\n\n/**\n * Positioning wrapper for the menu with collision detection.\n * Handles menu placement relative to the trigger and viewport boundaries.\n */\nexport const MenuPositioner = ({ children, sideOffset, ...rest }: MenuPositionerProps) => {\n const isSubmenu = useIsSubmenu()\n\n // Apply sideOffset of 8 for root menu, 0 for submenus (unless explicitly overridden)\n const defaultSideOffset = isSubmenu ? 0 : 8\n const finalSideOffset = sideOffset ?? defaultSideOffset\n\n return (\n <BaseMenu.Positioner sideOffset={finalSideOffset} {...rest}>\n {children}\n </BaseMenu.Positioner>\n )\n}\n\nMenuPositioner.displayName = 'Menu.Positioner'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuRadioGroupProps extends ComponentProps<typeof BaseMenu.RadioGroup> {}\n\n/**\n * A container for radio menu items where only one item can be selected at a time.\n * Manages the selection state for its radio items.\n */\nexport const MenuRadioGroup = ({ children, className, ...rest }: MenuRadioGroupProps) => {\n return (\n <BaseMenu.RadioGroup\n data-spark-component=\"menu-radio-group\"\n className={cx('py-sm', className)}\n {...rest}\n >\n {children}\n </BaseMenu.RadioGroup>\n )\n}\n\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { Check } from '@spark-ui/icons/Check'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuRadioItemProps extends Omit<\n ComponentProps<typeof BaseMenu.RadioItem>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item with radio button functionality.\n * Only one radio item can be selected within its RadioGroup.\n * The radio indicator is automatically rendered on the left side.\n */\nexport const MenuRadioItem = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuRadioItemProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.RadioItem\n ref={ref}\n data-spark-component=\"menu-radio-item\"\n render={renderSlot}\n className={cx(\n menuItemStyles({\n className,\n }),\n 'data-checked:font-bold'\n )}\n {...rest}\n >\n <BaseMenu.RadioItemIndicator\n keepMounted\n className={cx(\n 'mr-md flex shrink-0 items-center justify-center',\n 'w-sz-16 h-sz-16',\n 'transition-opacity',\n 'data-checked:opacity-100',\n 'opacity-0'\n )}\n >\n <Icon size=\"sm\" intent=\"current\">\n <Check />\n </Icon>\n </BaseMenu.RadioItemIndicator>\n {children}\n </BaseMenu.RadioItem>\n )\n}\n\nMenuRadioItem.displayName = 'Menu.RadioItem'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { cx } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport interface MenuSeparatorProps extends ComponentProps<typeof BaseMenu.Separator> {}\n\n/**\n * A visual divider between menu items or groups.\n * Creates clear separation between different sections of the menu.\n */\nexport const MenuSeparator = ({ className, ...rest }: MenuSeparatorProps) => {\n return (\n <BaseMenu.Separator\n data-spark-component=\"menu-separator\"\n className={cx('my-sm h-px bg-outline/dim-2', className)}\n {...rest}\n />\n )\n}\n\nMenuSeparator.displayName = 'Menu.Separator'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { type ComponentProps, type ReactNode } from 'react'\n\nimport { MenuSubmenuContext } from './MenuSubmenuContext'\n\nexport interface MenuSubmenuProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuRoot>,\n 'children'\n> {\n /**\n * The content of the submenu (trigger, positioner, popup, etc.)\n */\n children: ReactNode\n}\n\n/**\n * A nested submenu that appears when its trigger is activated.\n * Inherits styling context from the parent menu.\n */\nexport const MenuSubmenu = ({ children, ...rest }: MenuSubmenuProps) => {\n return (\n <BaseMenu.SubmenuRoot data-spark-component=\"menu-submenu\" {...rest}>\n <MenuSubmenuContext value={true}>{children}</MenuSubmenuContext>\n </BaseMenu.SubmenuRoot>\n )\n}\n\nMenuSubmenu.displayName = 'Menu.Submenu'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowVerticalRight } from '@spark-ui/icons/ArrowVerticalRight'\nimport { type ComponentProps, type Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport { menuItemStyles } from './MenuItemStyles'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuSubmenuTriggerProps extends Omit<\n ComponentProps<typeof BaseMenu.SubmenuTrigger>,\n 'render'\n> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLDivElement>\n}\n\n/**\n * A menu item that opens a submenu when activated.\n * Displays an arrow indicator to show submenu availability.\n */\nexport const MenuSubmenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuSubmenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n return (\n <BaseMenu.SubmenuTrigger\n ref={ref}\n data-spark-component=\"menu-submenu-trigger\"\n render={renderSlot}\n className={menuItemStyles({\n className,\n })}\n {...rest}\n >\n <span className=\"flex-1\">{children}</span>\n <Icon size=\"sm\" intent=\"current\" className=\"ml-auto shrink-0\">\n <ArrowVerticalRight />\n </Icon>\n </BaseMenu.SubmenuTrigger>\n )\n}\n\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\n","import { Menu as BaseMenu } from '@base-ui/react/menu'\nimport { ArrowHorizontalDown } from '@spark-ui/icons/ArrowHorizontalDown'\nimport { cx } from 'class-variance-authority'\nimport {\n cloneElement,\n isValidElement,\n type ComponentProps,\n type ReactElement,\n type Ref,\n} from 'react'\n\nimport { Icon } from '../icon'\nimport { useRenderSlot } from './useRenderSlot'\n\nexport interface MenuTriggerProps extends Omit<ComponentProps<typeof BaseMenu.Trigger>, 'render'> {\n /**\n * Change the component to the HTML tag or custom component of the only child.\n * This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.\n * @default false\n */\n asChild?: boolean\n ref?: Ref<HTMLButtonElement>\n}\n\n/**\n * The button that toggles the menu.\n * Renders a <button> element by default, or uses asChild for custom elements.\n * When used with asChild and a Button component, automatically adds an ArrowHorizontalDown icon.\n * Button components should use design=\"outlined\" and intent=\"support\".\n */\nexport const MenuTrigger = ({\n asChild = false,\n children,\n className,\n ref,\n ...rest\n}: MenuTriggerProps) => {\n const renderSlot = useRenderSlot(asChild)\n\n // When asChild is used with a Button, enhance it with the arrow icon\n const enhancedChildren =\n asChild && isValidElement(children)\n ? cloneElement(\n children as ReactElement,\n {\n design: (children.props as { design?: string }).design ?? 'outlined',\n intent: (children.props as { intent?: string }).intent ?? 'support',\n children: (\n <>\n {(children.props as { children: React.ReactNode }).children}\n <Icon size=\"sm\" intent=\"current\" className=\"shrink-0\">\n <ArrowHorizontalDown />\n </Icon>\n </>\n ),\n } as Partial<unknown>\n )\n : children\n\n return (\n <BaseMenu.Trigger\n ref={ref}\n data-spark-component=\"menu-trigger\"\n render={renderSlot}\n className={cx(\n 'inline-flex items-center justify-center',\n 'focus-visible:u-outline',\n className\n )}\n {...rest}\n >\n {enhancedChildren}\n </BaseMenu.Trigger>\n )\n}\n\nMenuTrigger.displayName = 'Menu.Trigger'\n","import { Menu as Root } from './Menu'\nimport { MenuCheckboxItem } from './MenuCheckboxItem'\nimport { MenuGroup } from './MenuGroup'\nimport { MenuGroupLabel } from './MenuGroupLabel'\nimport { MenuItem } from './MenuItem'\nimport { MenuLinkItem } from './MenuLinkItem'\nimport { MenuPopup } from './MenuPopup'\nimport { MenuPortal } from './MenuPortal'\nimport { MenuPositioner } from './MenuPositioner'\nimport { MenuRadioGroup } from './MenuRadioGroup'\nimport { MenuRadioItem } from './MenuRadioItem'\nimport { MenuSeparator } from './MenuSeparator'\nimport { MenuSubmenu } from './MenuSubmenu'\nimport { MenuSubmenuTrigger } from './MenuSubmenuTrigger'\nimport { MenuTrigger } from './MenuTrigger'\n\n/**\n * A menu component that enables users to select options from a dropdown menu triggered by a button or other interactive element.\n */\nexport const Menu: typeof Root & {\n Trigger: typeof MenuTrigger\n Portal: typeof MenuPortal\n Positioner: typeof MenuPositioner\n Popup: typeof MenuPopup\n Item: typeof MenuItem\n LinkItem: typeof MenuLinkItem\n Submenu: typeof MenuSubmenu\n SubmenuTrigger: typeof MenuSubmenuTrigger\n Group: typeof MenuGroup\n GroupLabel: typeof MenuGroupLabel\n RadioGroup: typeof MenuRadioGroup\n RadioItem: typeof MenuRadioItem\n CheckboxItem: typeof MenuCheckboxItem\n Separator: typeof MenuSeparator\n} = Object.assign(Root, {\n Trigger: MenuTrigger,\n Portal: MenuPortal,\n Positioner: MenuPositioner,\n Popup: MenuPopup,\n Item: MenuItem,\n LinkItem: MenuLinkItem,\n Submenu: MenuSubmenu,\n SubmenuTrigger: MenuSubmenuTrigger,\n Group: MenuGroup,\n GroupLabel: MenuGroupLabel,\n RadioGroup: MenuRadioGroup,\n RadioItem: MenuRadioItem,\n CheckboxItem: MenuCheckboxItem,\n Separator: MenuSeparator,\n})\n\nMenu.displayName = 'Menu'\nMenuTrigger.displayName = 'Menu.Trigger'\nMenuPortal.displayName = 'Menu.Portal'\nMenuPositioner.displayName = 'Menu.Positioner'\nMenuPopup.displayName = 'Menu.Popup'\nMenuItem.displayName = 'Menu.Item'\nMenuLinkItem.displayName = 'Menu.LinkItem'\nMenuSubmenu.displayName = 'Menu.Submenu'\nMenuSubmenuTrigger.displayName = 'Menu.SubmenuTrigger'\nMenuGroup.displayName = 'Menu.Group'\nMenuGroupLabel.displayName = 'Menu.GroupLabel'\nMenuRadioGroup.displayName = 'Menu.RadioGroup'\nMenuRadioItem.displayName = 'Menu.RadioItem'\nMenuCheckboxItem.displayName = 'Menu.CheckboxItem'\nMenuSeparator.displayName = 'Menu.Separator'\n\nexport { type MenuProps } from './Menu'\nexport { type MenuTriggerProps } from './MenuTrigger'\nexport { type MenuPortalProps } from './MenuPortal'\nexport { type MenuPositionerProps } from './MenuPositioner'\nexport { type MenuPopupProps } from './MenuPopup'\nexport { type MenuItemProps } from './MenuItem'\nexport { type MenuLinkItemProps } from './MenuLinkItem'\nexport { type MenuSubmenuProps } from './MenuSubmenu'\nexport { type MenuSubmenuTriggerProps } from './MenuSubmenuTrigger'\nexport { type MenuGroupProps } from './MenuGroup'\nexport { type MenuGroupLabelProps } from './MenuGroupLabel'\nexport { type MenuRadioGroupProps } from './MenuRadioGroup'\nexport { type MenuRadioItemProps } from './MenuRadioItem'\nexport { type MenuCheckboxItemProps } from './MenuCheckboxItem'\nexport { type MenuSeparatorProps } from './MenuSeparator'\n"],"mappings":"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"}
|
package/dist/meter/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);let e=require(`class-variance-authority`),t=require(`react`),n=require(`react/jsx-runtime`),r=require(`@spark-ui/hooks/use-merge-refs`),i=require(`@base-ui/react/meter`);var a=(0,t.createContext)(null),o=`:meter`,s=()=>{let e=(0,t.useContext)(a);if(!e)throw Error(`useMeter must be used within a Meter provider`);return e},c=({className:r,value:o,max:s=100,min:c=0,shape:l=`rounded`,intent:u=`support`,children:d,ref:f,...p})=>{let[m,h]=(0,t.useState)(),
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require(`../chunk-C91j1N6u.js`);let e=require(`class-variance-authority`),t=require(`react`),n=require(`react/jsx-runtime`),r=require(`@spark-ui/hooks/use-merge-refs`),i=require(`@base-ui/react/meter`);var a=(0,t.createContext)(null),o=`:meter`,s=()=>{let e=(0,t.useContext)(a);if(!e)throw Error(`useMeter must be used within a Meter provider`);return e},c=({className:r,value:o,max:s=100,min:c=0,shape:l=`rounded`,intent:u=`support`,children:d,ref:f,...p})=>{let[m,h]=(0,t.useState)();return(0,n.jsx)(a,{value:(0,t.useMemo)(()=>({value:o??0,max:s,min:c,intent:u,shape:l,onLabelId:h}),[s,c,o,u,l,h]),children:(0,n.jsx)(i.Meter.Root,{"data-spark-component":`meter`,ref:f,className:(0,e.cx)(`gap-y-sm gap-x-md focus-visible:u-outline box-border grid grid-cols-[1fr_auto]`,r),value:o,max:s,min:c,"aria-labelledby":m,...p,children:d})})};c.displayName=`Meter`;var l=({id:e,children:a,ref:c,...l})=>{let u=`${o}-label-${(0,t.useId)()}`,d=e||u,{onLabelId:f}=s(),p=(0,r.useMergeRefs)(c,(0,t.useCallback)(e=>{f(e?d:void 0)},[d,f]));return(0,n.jsx)(i.Meter.Label,{"data-spark-component":`meter-label`,id:d,className:`default:text-body-1-highlight text-on-surface`,ref:p,...l,children:a})};l.displayName=`Meter.Label`;var u=(0,e.cva)([`relative col-span-2`,`h-sz-8 w-full`,`transform-gpu overflow-hidden`,`bg-on-background/dim-4`]),d=(0,e.cva)([`size-full`,`ease-standard transition-[width] duration-700`,`motion-reduce:transition-none`],{variants:{intent:{main:[`bg-main`],support:[`bg-support`],success:[`bg-success`],alert:[`bg-alert`],danger:[`bg-error`],info:[`bg-info`]},shape:{square:[],rounded:[`rounded-sm`]}}});function f(e,n,r={}){let{threshold:i=.1,rootMargin:a}=r,o=(0,t.useRef)(!1),s=(0,t.useRef)(n);return(0,t.useEffect)(()=>{s.current=n},[n]),(0,t.useEffect)(()=>{let t=e.current;if(!t||o.current)return;let n=new IntersectionObserver(e=>{e.forEach(e=>{e.isIntersecting&&!o.current&&requestAnimationFrame(()=>{o.current||(o.current=!0,s.current(),n.disconnect())})})},{threshold:i,rootMargin:a});return n.observe(t),()=>{n.disconnect()}},[e,i,a]),o.current}var p=({className:r,...a})=>{let{value:o,max:c,min:l,intent:p,shape:m}=s(),h=(o-l)/(c-l)*100,g=(0,t.useRef)(null),[_,v]=(0,t.useState)(!1);return f(g,()=>{v(!0)}),(0,n.jsx)(i.Meter.Track,{ref:g,"data-spark-component":`meter-track`,className:(0,e.cx)(u(),{"rounded-sm":m===`rounded`},r),...a,children:(0,n.jsx)(i.Meter.Indicator,{"data-spark-component":`meter-indicator`,className:d({intent:p,shape:m}),style:{width:_?`${h}%`:`0%`}})})};p.displayName=`Meter.Track`;var m=({className:t,children:r,...a})=>(0,n.jsx)(i.Meter.Value,{"data-spark-component":`meter-value`,className:(0,e.cx)(`default:text-body-1 text-on-surface`,`col-start-2 text-right`,t),...a,children:r});m.displayName=`Meter.Value`;var h=Object.assign(c,{Label:l,Track:p,Value:m});h.displayName=`Meter`,l.displayName=`Meter.Label`,p.displayName=`Meter.Track`,m.displayName=`Meter.Value`,exports.Meter=h;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|