@brycks/core-front 0.3.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/dist/components/data/List/List.cjs +1 -1
  2. package/dist/components/data/List/List.cjs.map +1 -1
  3. package/dist/components/data/List/List.js +68 -148
  4. package/dist/components/data/List/List.js.map +1 -1
  5. package/dist/components/data/Table/Table.cjs +1 -1
  6. package/dist/components/data/Table/Table.cjs.map +1 -1
  7. package/dist/components/data/Table/Table.js +148 -217
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +1 -1
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -1
  11. package/dist/components/data/TreeView/TreeView.js +141 -182
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -1
  13. package/dist/components/data.cjs +1 -1
  14. package/dist/components/data.js +23 -21
  15. package/dist/components/feedback/Banner/Banner.cjs +2 -0
  16. package/dist/components/feedback/Banner/Banner.cjs.map +1 -0
  17. package/dist/components/feedback/Banner/Banner.js +77 -0
  18. package/dist/components/feedback/Banner/Banner.js.map +1 -0
  19. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.cjs +2 -0
  20. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.cjs.map +1 -0
  21. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.js +68 -0
  22. package/dist/components/feedback/ConfirmDialog/ConfirmDialog.js.map +1 -0
  23. package/dist/components/feedback/Drawer/Drawer.cjs +1 -22
  24. package/dist/components/feedback/Drawer/Drawer.cjs.map +1 -1
  25. package/dist/components/feedback/Drawer/Drawer.js +84 -184
  26. package/dist/components/feedback/Drawer/Drawer.js.map +1 -1
  27. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  28. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  29. package/dist/components/feedback/Modal/Modal.js +73 -150
  30. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  31. package/dist/components/feedback/Popover/Popover.cjs +2 -2
  32. package/dist/components/feedback/Popover/Popover.cjs.map +1 -1
  33. package/dist/components/feedback/Popover/Popover.js +43 -44
  34. package/dist/components/feedback/Popover/Popover.js.map +1 -1
  35. package/dist/components/feedback/Toast/Toast.cjs +1 -10
  36. package/dist/components/feedback/Toast/Toast.cjs.map +1 -1
  37. package/dist/components/feedback/Toast/Toast.js +94 -187
  38. package/dist/components/feedback/Toast/Toast.js.map +1 -1
  39. package/dist/components/feedback.cjs +1 -1
  40. package/dist/components/feedback.js +17 -13
  41. package/dist/components/feedback.js.map +1 -1
  42. package/dist/components/form/Checkbox/Checkbox.cjs +1 -1
  43. package/dist/components/form/Checkbox/Checkbox.js +11 -11
  44. package/dist/components/form/Combobox/Combobox.cjs +1 -6
  45. package/dist/components/form/Combobox/Combobox.cjs.map +1 -1
  46. package/dist/components/form/Combobox/Combobox.js +190 -266
  47. package/dist/components/form/Combobox/Combobox.js.map +1 -1
  48. package/dist/components/form/Input/Input.cjs +1 -1
  49. package/dist/components/form/Input/Input.cjs.map +1 -1
  50. package/dist/components/form/Input/Input.js +38 -133
  51. package/dist/components/form/Input/Input.js.map +1 -1
  52. package/dist/components/form/SearchInput/SearchInput.cjs +2 -0
  53. package/dist/components/form/SearchInput/SearchInput.cjs.map +1 -0
  54. package/dist/components/form/SearchInput/SearchInput.js +68 -0
  55. package/dist/components/form/SearchInput/SearchInput.js.map +1 -0
  56. package/dist/components/form/Select/Select.cjs +1 -1
  57. package/dist/components/form/Select/Select.cjs.map +1 -1
  58. package/dist/components/form/Select/Select.js +36 -82
  59. package/dist/components/form/Select/Select.js.map +1 -1
  60. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  61. package/dist/components/form/TagInput/TagInput.js +8 -8
  62. package/dist/components/form/Textarea/Textarea.cjs +1 -1
  63. package/dist/components/form/Textarea/Textarea.cjs.map +1 -1
  64. package/dist/components/form/Textarea/Textarea.js +61 -95
  65. package/dist/components/form/Textarea/Textarea.js.map +1 -1
  66. package/dist/components/form.cjs +1 -1
  67. package/dist/components/form.js +15 -13
  68. package/dist/components/form.js.map +1 -1
  69. package/dist/components/layout/Card/Card.cjs +1 -1
  70. package/dist/components/layout/Card/Card.cjs.map +1 -1
  71. package/dist/components/layout/Card/Card.js +7 -5
  72. package/dist/components/layout/Card/Card.js.map +1 -1
  73. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +1 -1
  74. package/dist/components/navigation/ContextMenu/ContextMenu.js +9 -9
  75. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  76. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  77. package/dist/components/navigation/Menu/Menu.js +70 -135
  78. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  79. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  80. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  81. package/dist/components/navigation/Pagination/Pagination.js +87 -157
  82. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  83. package/dist/components/navigation/SegmentedControl/SegmentedControl.cjs +2 -0
  84. package/dist/components/navigation/SegmentedControl/SegmentedControl.cjs.map +1 -0
  85. package/dist/components/navigation/SegmentedControl/SegmentedControl.js +90 -0
  86. package/dist/components/navigation/SegmentedControl/SegmentedControl.js.map +1 -0
  87. package/dist/components/navigation.cjs +1 -1
  88. package/dist/components/navigation.js +25 -23
  89. package/dist/components/navigation.js.map +1 -1
  90. package/dist/components/utility/Avatar/Avatar.cjs +1 -1
  91. package/dist/components/utility/Avatar/Avatar.cjs.map +1 -1
  92. package/dist/components/utility/Avatar/Avatar.js +18 -18
  93. package/dist/components/utility/Avatar/Avatar.js.map +1 -1
  94. package/dist/components/utility/Badge/Badge.cjs +1 -1
  95. package/dist/components/utility/Badge/Badge.cjs.map +1 -1
  96. package/dist/components/utility/Badge/Badge.js +31 -23
  97. package/dist/components/utility/Badge/Badge.js.map +1 -1
  98. package/dist/components/utility/Kbd/Kbd.cjs +2 -0
  99. package/dist/components/utility/Kbd/Kbd.cjs.map +1 -0
  100. package/dist/components/utility/Kbd/Kbd.js +20 -0
  101. package/dist/components/utility/Kbd/Kbd.js.map +1 -0
  102. package/dist/components/utility/Logo/Logo.cjs +1 -1
  103. package/dist/components/utility/Logo/Logo.cjs.map +1 -1
  104. package/dist/components/utility/Logo/Logo.js +19 -19
  105. package/dist/components/utility/Logo/Logo.js.map +1 -1
  106. package/dist/components/utility.cjs +1 -1
  107. package/dist/components/utility.js +9 -7
  108. package/dist/components/utility.js.map +1 -1
  109. package/dist/data.d.ts +34 -1
  110. package/dist/feedback.d.ts +67 -2
  111. package/dist/form.d.ts +31 -0
  112. package/dist/index.cjs +1 -1
  113. package/dist/index.d.ts +184 -3
  114. package/dist/index.js +177 -165
  115. package/dist/index.js.map +1 -1
  116. package/dist/navigation.d.ts +39 -0
  117. package/dist/styles.css +1 -1
  118. package/dist/utility.d.ts +19 -0
  119. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Combobox.js","sources":["../../../../src/components/form/Combobox/Combobox.tsx"],"sourcesContent":["/**\n * Combobox Component\n *\n * A searchable select/autocomplete component with keyboard navigation.\n * Combines the functionality of Input with dropdown selection.\n *\n * @module components/form/Combobox\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n useMemo,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n type ChangeEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\nimport { useId } from '../../../hooks/useId'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport {\n componentHeights,\n componentPaddingX,\n componentGap,\n iconSizes,\n} from '../../../design-system/primitives'\n\nexport type ComboboxSize = 'sm' | 'md' | 'lg'\n\nexport interface ComboboxOption {\n /** Unique identifier for the option */\n value: string\n /** Display label */\n label: string\n /** Optional description */\n description?: string\n /** Optional icon */\n icon?: ReactNode\n /** Whether the option is disabled */\n disabled?: boolean\n}\n\nexport interface ComboboxProps {\n /** Available options */\n options: ComboboxOption[]\n /** Currently selected value (controlled) */\n value?: string | null\n /** Default selected value (uncontrolled) */\n defaultValue?: string | null\n /** Callback when selection changes */\n onChange?: (value: string | null) => void\n /** Callback when input value changes */\n onInputChange?: (value: string) => void\n /** Placeholder text */\n placeholder?: string\n /** Component size */\n size?: ComboboxSize\n /** Whether the combobox is disabled */\n disabled?: boolean\n /** Whether the combobox is invalid */\n isInvalid?: boolean\n /** Whether the combobox is required */\n required?: boolean\n /** Whether to allow clearing the selection */\n clearable?: boolean\n /** Label for accessibility */\n 'aria-label'?: string\n /** ID of element that labels this combobox */\n 'aria-labelledby'?: string\n /** Custom filter function */\n filterFn?: (option: ComboboxOption, inputValue: string) => boolean\n /** Text to show when no options match */\n emptyText?: string\n /** Whether to allow creating new options */\n creatable?: boolean\n /** Callback when creating new option */\n onCreate?: (inputValue: string) => void\n /** Label of the create-option button */\n createLabel?: (inputValue: string) => ReactNode\n /** Accessible label of the clear button */\n clearLabel?: string\n /** Accessible label of the options listbox (when no aria-label is given) */\n listboxLabel?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<ComboboxSize, { height: number; fontSize: number; padding: number; iconSize: number }> = {\n sm: { height: componentHeights.sm, fontSize: fontSizes.base - 1, padding: componentPaddingX.sm, iconSize: iconSizes.sm },\n md: { height: componentHeights.md, fontSize: fontSizes.base, padding: componentPaddingX.md, iconSize: iconSizes.md },\n lg: { height: componentHeights.lg, fontSize: fontSizes.md, padding: componentPaddingX.lg, iconSize: iconSizes.lg },\n}\n\nconst defaultFilterFn = (option: ComboboxOption, inputValue: string): boolean => {\n const search = inputValue.toLowerCase()\n return (\n option.label.toLowerCase().includes(search) ||\n option.value.toLowerCase().includes(search) ||\n (option.description?.toLowerCase().includes(search) ?? false)\n )\n}\n\nfunction ChevronDownIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 6l4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const Combobox = forwardRef<HTMLInputElement, ComboboxProps>(function Combobox(\n {\n options,\n value: controlledValue,\n defaultValue = null,\n onChange,\n onInputChange,\n placeholder = 'Select or search...',\n size = 'md',\n disabled = false,\n isInvalid = false,\n required = false,\n clearable = true,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n filterFn = defaultFilterFn,\n emptyText = 'No options found',\n creatable = false,\n onCreate,\n createLabel = (input) => `Create \"${input}\"`,\n clearLabel = 'Clear selection',\n listboxLabel = 'Options',\n className,\n testId,\n },\n ref\n) {\n const listboxId = useId('combobox-listbox')\n const [internalValue, setInternalValue] = useState(defaultValue)\n const [inputValue, setInputValue] = useState('')\n const [isOpen, setIsOpen] = useState(false)\n const [activeIndex, setActiveIndex] = useState(-1)\n const [isFocused, setIsFocused] = useState(false)\n\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const listRef = useRef<HTMLUListElement>(null)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n const config = sizeConfig[size]\n\n // Get selected option\n const selectedOption = useMemo(\n () => options.find((opt) => opt.value === value),\n [options, value]\n )\n\n // Filter options based on input\n const filteredOptions = useMemo(() => {\n if (!inputValue) return options\n return options.filter((opt) => filterFn(opt, inputValue))\n }, [options, inputValue, filterFn])\n\n // Sync input with selected value\n useEffect(() => {\n if (!isOpen && selectedOption) {\n setInputValue(selectedOption.label)\n } else if (!isOpen && !value) {\n setInputValue('')\n }\n }, [isOpen, selectedOption, value])\n\n const handleSelect = useCallback(\n (optionValue: string | null) => {\n if (controlledValue === undefined) {\n setInternalValue(optionValue)\n }\n onChange?.(optionValue)\n setIsOpen(false)\n setActiveIndex(-1)\n inputRef.current?.focus()\n },\n [controlledValue, onChange]\n )\n\n const handleInputChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value\n setInputValue(newValue)\n onInputChange?.(newValue)\n if (!isOpen) setIsOpen(true)\n setActiveIndex(0)\n },\n [isOpen, onInputChange]\n )\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n handleSelect(null)\n setInputValue('')\n inputRef.current?.focus()\n },\n [handleSelect]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n if (!isOpen) {\n setIsOpen(true)\n setActiveIndex(0)\n } else {\n setActiveIndex((prev) => Math.min(prev + 1, filteredOptions.length - 1))\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (isOpen) {\n setActiveIndex((prev) => Math.max(prev - 1, 0))\n }\n break\n case 'Enter':\n e.preventDefault()\n if (isOpen && activeIndex >= 0 && filteredOptions[activeIndex]) {\n if (!filteredOptions[activeIndex].disabled) {\n handleSelect(filteredOptions[activeIndex].value)\n }\n } else if (creatable && inputValue && filteredOptions.length === 0) {\n onCreate?.(inputValue)\n }\n break\n case 'Escape':\n e.preventDefault()\n setIsOpen(false)\n setActiveIndex(-1)\n if (selectedOption) {\n setInputValue(selectedOption.label)\n }\n break\n case 'Tab':\n if (isOpen) {\n setIsOpen(false)\n setActiveIndex(-1)\n }\n break\n }\n },\n [isOpen, activeIndex, filteredOptions, handleSelect, creatable, inputValue, onCreate, selectedOption]\n )\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setIsOpen(false)\n setActiveIndex(-1)\n if (selectedOption) {\n setInputValue(selectedOption.label)\n }\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen, selectedOption])\n\n // Scroll active option into view\n useEffect(() => {\n if (!isOpen || activeIndex < 0) return\n const list = listRef.current\n const activeItem = list?.children[activeIndex] as HTMLElement | undefined\n activeItem?.scrollIntoView({ block: 'nearest' })\n }, [isOpen, activeIndex])\n\n // Calculate dropdown position\n const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 })\n\n useEffect(() => {\n if (!isOpen || !containerRef.current) return\n\n const updatePosition = () => {\n const rect = containerRef.current!.getBoundingClientRect()\n setDropdownPosition({\n top: rect.bottom + window.scrollY + spacing[1],\n left: rect.left + window.scrollX,\n width: rect.width,\n })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen])\n\n const containerStyle: CSSProperties = {\n position: 'relative',\n display: 'inline-flex',\n width: '100%',\n }\n\n const inputWrapperStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n height: config.height,\n backgroundColor: disabled ? 'var(--brycks-background-muted)' : 'var(--brycks-background-default)',\n border: `1px solid ${\n isInvalid\n ? 'var(--brycks-error-default)'\n : isFocused\n ? 'var(--brycks-primary-default)'\n : 'var(--brycks-border-default)'\n }`,\n borderRadius: 'var(--brycks-radius-md)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n cursor: disabled ? 'not-allowed' : 'text',\n boxShadow: isFocused ? 'var(--brycks-focus-ring)' : undefined,\n }\n\n const inputStyle: CSSProperties = {\n flex: 1,\n height: '100%',\n padding: `0 ${config.padding}px`,\n paddingRight: spacing[10],\n fontSize: config.fontSize,\n color: disabled ? 'var(--brycks-foreground-disabled)' : 'var(--brycks-foreground-default)',\n backgroundColor: 'transparent',\n border: 'none',\n outline: 'none',\n cursor: disabled ? 'not-allowed' : 'text',\n }\n\n const iconsStyle: CSSProperties = {\n position: 'absolute',\n right: config.padding,\n display: 'flex',\n alignItems: 'center',\n gap: spacing[1],\n pointerEvents: 'none',\n }\n\n const clearButtonStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: spacing[5],\n height: spacing[5],\n color: 'var(--brycks-foreground-muted)',\n cursor: 'pointer',\n borderRadius: 'var(--brycks-radius-sm)',\n transition: `all ${durations.fast}ms ${easings.easeOut}`,\n pointerEvents: 'auto',\n }\n\n const chevronStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: 'var(--brycks-foreground-muted)',\n transform: isOpen ? 'rotate(180deg)' : 'rotate(0)',\n transition: `transform ${durations.fast}ms ${easings.easeOut}`,\n }\n\n const dropdownStyle: CSSProperties = {\n position: 'absolute',\n top: dropdownPosition.top,\n left: dropdownPosition.left,\n width: dropdownPosition.width,\n maxHeight: 300,\n overflowY: 'auto',\n backgroundColor: 'var(--brycks-background-elevated)',\n border: '1px solid var(--brycks-border-default)',\n borderRadius: 'var(--brycks-radius-lg)',\n boxShadow: 'var(--brycks-shadow-lg)',\n zIndex: 'var(--brycks-z-dropdown)' as unknown as number,\n padding: spacing[1],\n animation: `brycks-dropdown-in ${durations.quick}ms ${easings.easeOut}`,\n }\n\n const optionStyle = (isActive: boolean, isDisabled: boolean, isSelected: boolean): CSSProperties => ({\n display: 'flex',\n alignItems: 'center',\n gap: componentGap.md,\n padding: `${spacing[2]}px ${componentPaddingX.sm}px`,\n fontSize: config.fontSize,\n color: isDisabled\n ? 'var(--brycks-foreground-disabled)'\n : 'var(--brycks-foreground-default)',\n backgroundColor: isActive\n ? 'var(--brycks-background-muted)'\n : isSelected\n ? 'var(--brycks-primary-muted)'\n : 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: isDisabled ? 'not-allowed' : 'pointer',\n transition: `background-color ${durations.fast}ms ${easings.easeOut}`,\n })\n\n const emptyStyle: CSSProperties = {\n padding: `${spacing[4]}px ${spacing[3]}px`,\n fontSize: config.fontSize,\n color: 'var(--brycks-foreground-muted)',\n textAlign: 'center',\n }\n\n return (\n <div\n ref={containerRef}\n className={cx('brycks-combobox', `brycks-combobox--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n >\n <div\n style={inputWrapperStyle}\n onClick={() => !disabled && inputRef.current?.focus()}\n >\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : undefined}\n aria-invalid={isInvalid}\n aria-required={required}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n style={inputStyle}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n setIsFocused(true)\n setIsOpen(true)\n }}\n onBlur={() => setIsFocused(false)}\n />\n <div style={iconsStyle}>\n {clearable && value && !disabled && (\n <button\n type=\"button\"\n aria-label={clearLabel}\n style={clearButtonStyle}\n onClick={handleClear}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n e.currentTarget.style.color = 'var(--brycks-foreground-default)'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = 'transparent'\n e.currentTarget.style.color = 'var(--brycks-foreground-muted)'\n }}\n >\n <ClearIcon />\n </button>\n )}\n <span style={chevronStyle}>\n <ChevronDownIcon />\n </span>\n </div>\n </div>\n\n {isOpen &&\n createPortal(\n <>\n <style>\n {`\n @keyframes brycks-dropdown-in {\n from { opacity: 0; transform: translateY(-4px); }\n to { opacity: 1; transform: translateY(0); }\n }\n `}\n </style>\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label={ariaLabel || listboxLabel}\n style={dropdownStyle}\n >\n {filteredOptions.length > 0 ? (\n filteredOptions.map((option, index) => (\n <li\n key={option.value}\n id={`${listboxId}-option-${index}`}\n role=\"option\"\n aria-selected={option.value === value}\n aria-disabled={option.disabled}\n style={optionStyle(index === activeIndex, !!option.disabled, option.value === value)}\n onClick={() => !option.disabled && handleSelect(option.value)}\n onMouseEnter={() => setActiveIndex(index)}\n >\n {option.icon && <span style={{ flexShrink: 0 }}>{option.icon}</span>}\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ fontWeight: option.value === value ? 500 : 400 }}>{option.label}</div>\n {option.description && (\n <div style={{ fontSize: fontSizes.sm, color: 'var(--brycks-foreground-muted)' }}>\n {option.description}\n </div>\n )}\n </div>\n {option.value === value && (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" style={{ flexShrink: 0 }}>\n <path\n d=\"M3 8l3 3 7-7\"\n stroke=\"var(--brycks-primary-default)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </li>\n ))\n ) : (\n <li style={emptyStyle}>\n {creatable && inputValue ? (\n <button\n type=\"button\"\n style={{\n ...optionStyle(true, false, false),\n width: '100%',\n border: 'none',\n cursor: 'pointer',\n }}\n onClick={() => onCreate?.(inputValue)}\n >\n {createLabel(inputValue)}\n </button>\n ) : (\n emptyText\n )}\n </li>\n )}\n </ul>\n </>,\n document.body\n )}\n </div>\n )\n})\n\nCombobox.displayName = 'Combobox'\n"],"names":["sizeConfig","componentHeights","fontSizes","componentPaddingX","iconSizes","defaultFilterFn","option","inputValue","search","ChevronDownIcon","jsx","ClearIcon","Combobox","forwardRef","options","controlledValue","defaultValue","onChange","onInputChange","placeholder","size","disabled","isInvalid","required","clearable","ariaLabel","ariaLabelledby","filterFn","emptyText","creatable","onCreate","createLabel","input","clearLabel","listboxLabel","className","testId","ref","listboxId","useId","internalValue","setInternalValue","useState","setInputValue","isOpen","setIsOpen","activeIndex","setActiveIndex","isFocused","setIsFocused","containerRef","useRef","inputRef","listRef","value","config","selectedOption","useMemo","opt","filteredOptions","useEffect","handleSelect","useCallback","optionValue","handleInputChange","newValue","handleClear","handleKeyDown","prev","handleClick","e","dropdownPosition","setDropdownPosition","updatePosition","rect","spacing","containerStyle","inputWrapperStyle","durations","easings","inputStyle","iconsStyle","clearButtonStyle","chevronStyle","dropdownStyle","optionStyle","isActive","isDisabled","isSelected","componentGap","emptyStyle","jsxs","cx","node","createPortal","Fragment","index"],"mappings":"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"}
1
+ {"version":3,"file":"Combobox.js","sources":["../../../../src/components/form/Combobox/Combobox.tsx"],"sourcesContent":["/**\n * Combobox Component\n *\n * A searchable select/autocomplete component with keyboard navigation.\n * Combines the functionality of Input with dropdown selection.\n *\n * @module components/form/Combobox\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useRef,\n useEffect,\n useMemo,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n type ChangeEvent,\n} from 'react'\nimport { createPortal } from 'react-dom'\nimport { cx } from '../../../utils/styles'\nimport { useId } from '../../../hooks/useId'\nimport { spacing } from '../../../design-system'\n\nexport type ComboboxSize = 'sm' | 'md' | 'lg'\n\nexport interface ComboboxOption {\n /** Unique identifier for the option */\n value: string\n /** Display label */\n label: string\n /** Optional description */\n description?: string\n /** Optional icon */\n icon?: ReactNode\n /** Whether the option is disabled */\n disabled?: boolean\n}\n\nexport interface ComboboxProps {\n /** Available options */\n options: ComboboxOption[]\n /** Currently selected value (controlled) */\n value?: string | null\n /** Default selected value (uncontrolled) */\n defaultValue?: string | null\n /** Callback when selection changes */\n onChange?: (value: string | null) => void\n /** Callback when input value changes */\n onInputChange?: (value: string) => void\n /** Placeholder text */\n placeholder?: string\n /** Component size */\n size?: ComboboxSize\n /** Whether the combobox is disabled */\n disabled?: boolean\n /** Whether the combobox is invalid */\n isInvalid?: boolean\n /** Whether the combobox is required */\n required?: boolean\n /** Whether to allow clearing the selection */\n clearable?: boolean\n /** Label for accessibility */\n 'aria-label'?: string\n /** ID of element that labels this combobox */\n 'aria-labelledby'?: string\n /** Custom filter function */\n filterFn?: (option: ComboboxOption, inputValue: string) => boolean\n /** Text to show when no options match */\n emptyText?: string\n /** Whether options are being loaded asynchronously */\n isLoading?: boolean\n /** Text to show while loading */\n loadingText?: string\n /** Whether to allow creating new options */\n creatable?: boolean\n /** Callback when creating new option */\n onCreate?: (inputValue: string) => void\n /** Label of the create-option button */\n createLabel?: (inputValue: string) => ReactNode\n /** Accessible label of the clear button */\n clearLabel?: string\n /** Accessible label of the options listbox (when no aria-label is given) */\n listboxLabel?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst defaultFilterFn = (option: ComboboxOption, inputValue: string): boolean => {\n const search = inputValue.toLowerCase()\n return (\n option.label.toLowerCase().includes(search) ||\n option.value.toLowerCase().includes(search) ||\n (option.description?.toLowerCase().includes(search) ?? false)\n )\n}\n\nfunction ChevronDownIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 6l4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const Combobox = forwardRef<HTMLInputElement, ComboboxProps>(function Combobox(\n {\n options,\n value: controlledValue,\n defaultValue = null,\n onChange,\n onInputChange,\n placeholder = 'Select or search...',\n size = 'md',\n disabled = false,\n isInvalid = false,\n required = false,\n clearable = true,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledby,\n filterFn = defaultFilterFn,\n emptyText = 'No options found',\n isLoading = false,\n loadingText = 'Loading…',\n creatable = false,\n onCreate,\n createLabel = (input) => `Create \"${input}\"`,\n clearLabel = 'Clear selection',\n listboxLabel = 'Options',\n className,\n testId,\n },\n ref\n) {\n const listboxId = useId('combobox-listbox')\n const [internalValue, setInternalValue] = useState(defaultValue)\n const [inputValue, setInputValue] = useState('')\n const [isOpen, setIsOpen] = useState(false)\n const [activeIndex, setActiveIndex] = useState(-1)\n\n const containerRef = useRef<HTMLDivElement>(null)\n const inputRef = useRef<HTMLInputElement>(null)\n const listRef = useRef<HTMLUListElement>(null)\n\n const value = controlledValue !== undefined ? controlledValue : internalValue\n\n // Get selected option\n const selectedOption = useMemo(\n () => options.find((opt) => opt.value === value),\n [options, value]\n )\n\n // Filter options based on input\n const filteredOptions = useMemo(() => {\n if (!inputValue) return options\n return options.filter((opt) => filterFn(opt, inputValue))\n }, [options, inputValue, filterFn])\n\n // Sync input with selected value\n useEffect(() => {\n if (!isOpen && selectedOption) {\n setInputValue(selectedOption.label)\n } else if (!isOpen && !value) {\n setInputValue('')\n }\n }, [isOpen, selectedOption, value])\n\n const handleSelect = useCallback(\n (optionValue: string | null) => {\n if (controlledValue === undefined) {\n setInternalValue(optionValue)\n }\n onChange?.(optionValue)\n setIsOpen(false)\n setActiveIndex(-1)\n inputRef.current?.focus()\n },\n [controlledValue, onChange]\n )\n\n const handleInputChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value\n setInputValue(newValue)\n onInputChange?.(newValue)\n if (!isOpen) setIsOpen(true)\n setActiveIndex(0)\n },\n [isOpen, onInputChange]\n )\n\n const handleClear = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n handleSelect(null)\n setInputValue('')\n inputRef.current?.focus()\n },\n [handleSelect]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault()\n if (!isOpen) {\n setIsOpen(true)\n setActiveIndex(0)\n } else {\n setActiveIndex((prev) => Math.min(prev + 1, filteredOptions.length - 1))\n }\n break\n case 'ArrowUp':\n e.preventDefault()\n if (isOpen) {\n setActiveIndex((prev) => Math.max(prev - 1, 0))\n }\n break\n case 'Enter':\n e.preventDefault()\n if (isOpen && activeIndex >= 0 && filteredOptions[activeIndex]) {\n if (!filteredOptions[activeIndex].disabled) {\n handleSelect(filteredOptions[activeIndex].value)\n }\n } else if (creatable && inputValue && filteredOptions.length === 0) {\n onCreate?.(inputValue)\n }\n break\n case 'Escape':\n e.preventDefault()\n setIsOpen(false)\n setActiveIndex(-1)\n if (selectedOption) {\n setInputValue(selectedOption.label)\n }\n break\n case 'Tab':\n if (isOpen) {\n setIsOpen(false)\n setActiveIndex(-1)\n }\n break\n }\n },\n [isOpen, activeIndex, filteredOptions, handleSelect, creatable, inputValue, onCreate, selectedOption]\n )\n\n // Close on outside click\n useEffect(() => {\n if (!isOpen) return\n\n const handleClick = (e: MouseEvent) => {\n if (!containerRef.current?.contains(e.target as Node)) {\n setIsOpen(false)\n setActiveIndex(-1)\n if (selectedOption) {\n setInputValue(selectedOption.label)\n }\n }\n }\n\n document.addEventListener('mousedown', handleClick)\n return () => document.removeEventListener('mousedown', handleClick)\n }, [isOpen, selectedOption])\n\n // Scroll active option into view\n useEffect(() => {\n if (!isOpen || activeIndex < 0) return\n const list = listRef.current\n const activeItem = list?.children[activeIndex] as HTMLElement | undefined\n activeItem?.scrollIntoView({ block: 'nearest' })\n }, [isOpen, activeIndex])\n\n // Calculate dropdown position\n const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 })\n\n useEffect(() => {\n if (!isOpen || !containerRef.current) return\n\n const updatePosition = () => {\n const rect = containerRef.current!.getBoundingClientRect()\n setDropdownPosition({\n top: rect.bottom + window.scrollY + spacing[1],\n left: rect.left + window.scrollX,\n width: rect.width,\n })\n }\n\n updatePosition()\n window.addEventListener('resize', updatePosition)\n window.addEventListener('scroll', updatePosition, true)\n\n return () => {\n window.removeEventListener('resize', updatePosition)\n window.removeEventListener('scroll', updatePosition, true)\n }\n }, [isOpen])\n\n // Only the portalled dropdown's coordinates are dynamic (measured from the\n // trigger via getBoundingClientRect); everything else lives in CSS.\n const dropdownStyle: CSSProperties = {\n top: dropdownPosition.top,\n left: dropdownPosition.left,\n width: dropdownPosition.width,\n }\n\n return (\n <div\n ref={containerRef}\n className={cx('brycks-combobox', `brycks-combobox--${size}`, className)}\n data-testid={testId}\n >\n <div\n className={cx(\n 'brycks-combobox__wrapper',\n isInvalid && 'brycks-combobox__wrapper--invalid',\n disabled && 'brycks-combobox__wrapper--disabled'\n )}\n onClick={() => !disabled && inputRef.current?.focus()}\n >\n <input\n ref={(node) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current = node\n if (typeof ref === 'function') ref(node)\n else if (ref) ref.current = node\n }}\n type=\"text\"\n role=\"combobox\"\n aria-expanded={isOpen}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n aria-controls={isOpen ? listboxId : undefined}\n aria-activedescendant={isOpen && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : undefined}\n aria-invalid={isInvalid}\n aria-required={required}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n className=\"brycks-combobox__input\"\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n onFocus={() => {\n setIsOpen(true)\n }}\n />\n <div className=\"brycks-combobox__icons\">\n {clearable && value && !disabled && (\n <button\n type=\"button\"\n aria-label={clearLabel}\n className=\"brycks-combobox__clear\"\n onClick={handleClear}\n >\n <ClearIcon />\n </button>\n )}\n <span className={cx('brycks-combobox__chevron', isOpen && 'brycks-combobox__chevron--open')}>\n <ChevronDownIcon />\n </span>\n </div>\n </div>\n\n {isOpen &&\n createPortal(\n <ul\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label={ariaLabel || listboxLabel}\n aria-busy={isLoading || undefined}\n className=\"brycks-combobox__dropdown\"\n style={dropdownStyle}\n >\n {isLoading ? (\n <li className=\"brycks-combobox__empty\" role=\"status\" aria-live=\"polite\">\n <span className=\"brycks-combobox__loading\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n className=\"brycks-animate-spin\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" opacity=\"0.2\" />\n <path d=\"M12 2C6.47715 2 2 6.47715 2 12\" stroke=\"currentColor\" strokeWidth=\"2.5\" strokeLinecap=\"round\" />\n </svg>\n {loadingText}\n </span>\n </li>\n ) : filteredOptions.length > 0 ? (\n filteredOptions.map((option, index) => (\n <li\n key={option.value}\n id={`${listboxId}-option-${index}`}\n role=\"option\"\n aria-selected={option.value === value}\n aria-disabled={option.disabled}\n className={cx(\n 'brycks-combobox__option',\n option.value === value && 'brycks-combobox__option--selected',\n index === activeIndex && 'brycks-combobox__option--active',\n option.disabled && 'brycks-combobox__option--disabled'\n )}\n onClick={() => !option.disabled && handleSelect(option.value)}\n onMouseEnter={() => setActiveIndex(index)}\n >\n {option.icon && <span className=\"brycks-combobox__option-icon\">{option.icon}</span>}\n <div className=\"brycks-combobox__option-body\">\n <div className=\"brycks-combobox__option-label\">{option.label}</div>\n {option.description && (\n <div className=\"brycks-combobox__option-description\">\n {option.description}\n </div>\n )}\n </div>\n {option.value === value && (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" className=\"brycks-combobox__option-check\">\n <path\n d=\"M3 8l3 3 7-7\"\n stroke=\"var(--brycks-primary-default)\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </li>\n ))\n ) : (\n <li className=\"brycks-combobox__empty\">\n {creatable && inputValue ? (\n <button\n type=\"button\"\n className=\"brycks-combobox__option brycks-combobox__option--active brycks-combobox__option--create\"\n onClick={() => onCreate?.(inputValue)}\n >\n {createLabel(inputValue)}\n </button>\n ) : (\n emptyText\n )}\n </li>\n )}\n </ul>,\n document.body\n )}\n </div>\n )\n})\n\nCombobox.displayName = 'Combobox'\n"],"names":["defaultFilterFn","option","inputValue","search","ChevronDownIcon","jsx","ClearIcon","Combobox","forwardRef","options","controlledValue","defaultValue","onChange","onInputChange","placeholder","size","disabled","isInvalid","required","clearable","ariaLabel","ariaLabelledby","filterFn","emptyText","isLoading","loadingText","creatable","onCreate","createLabel","input","clearLabel","listboxLabel","className","testId","ref","listboxId","useId","internalValue","setInternalValue","useState","setInputValue","isOpen","setIsOpen","activeIndex","setActiveIndex","containerRef","useRef","inputRef","listRef","value","selectedOption","useMemo","opt","filteredOptions","useEffect","handleSelect","useCallback","optionValue","handleInputChange","newValue","handleClear","handleKeyDown","prev","handleClick","e","dropdownPosition","setDropdownPosition","updatePosition","rect","spacing","dropdownStyle","jsxs","cx","node","createPortal","index"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),y=require("react"),F=require("../../../utils/styles.cjs"),t=require("../../../design-system/primitives/sizing.cjs"),d=require("../../../design-system/primitives/typography.cjs"),f=require("../../../design-system/primitives/transitions.cjs"),u=require("../../../design-system/primitives/focus.cjs"),C=require("../../../design-system/primitives/opacity.cjs"),O={sm:{height:t.componentHeights.sm,fontSize:d.componentFontSize.sm,paddingX:t.componentPaddingX.sm,radius:"var(--brycks-radius-md)"},md:{height:t.componentHeights.md,fontSize:d.componentFontSize.md,paddingX:t.componentPaddingX.md,radius:"var(--brycks-radius-default)"},lg:{height:t.componentHeights.lg,fontSize:d.componentFontSize.lg,paddingX:t.componentPaddingX.lg,radius:"var(--brycks-radius-lg)"}},m=y.forwardRef(function({size:p="md",variant:l="outline",isInvalid:n,leftElement:i,rightElement:c,className:k,style:h,testId:S,disabled:o,onFocus:v,onBlur:x,...w},j){const[s,g]=y.useState(!1),r=O[p],R=()=>{const e={display:"flex",alignItems:"center",width:"100%",position:"relative",height:r.height,borderRadius:r.radius,transition:f.transition.default};switch(l){case"outline":Object.assign(e,{backgroundColor:"var(--brycks-background-app)",border:`1px solid ${n?"var(--brycks-error-default)":s?"var(--brycks-border-focus)":"var(--brycks-border-default)"}`,boxShadow:s?n?u.focusRing.error:u.focusRing.default:u.focusRing.none});break;case"filled":Object.assign(e,{backgroundColor:"var(--brycks-background-muted)",border:"1px solid transparent",borderColor:n?"var(--brycks-error-default)":s?"var(--brycks-border-focus)":"transparent"});break;case"flushed":Object.assign(e,{backgroundColor:"transparent",borderRadius:0,borderBottom:`2px solid ${n?"var(--brycks-error-default)":s?"var(--brycks-border-focus)":"var(--brycks-border-default)"}`});break}return o&&Object.assign(e,{opacity:C.stateOpacity.disabled,cursor:"not-allowed"}),e},X={width:"100%",height:r.height,fontFamily:"var(--brycks-font-sans)",fontSize:r.fontSize,color:"var(--brycks-foreground-default)",backgroundColor:"transparent",border:"none",outline:"none",borderRadius:r.radius,paddingLeft:i?t.componentGap.md:r.paddingX,paddingRight:c?t.componentGap.md:r.paddingX,cursor:o?"not-allowed":"text",transition:f.transition.default},z=e=>{g(!0),v?.(e)},q=e=>{g(!1),x?.(e)},b={display:"flex",alignItems:"center",justifyContent:"center",color:"var(--brycks-foreground-muted)",flexShrink:0};return a.jsxs("div",{className:F.cx("brycks-input-wrapper",`brycks-input-wrapper--${l}`,`brycks-input-wrapper--${p}`,n&&"brycks-input-wrapper--invalid",o&&"brycks-input-wrapper--disabled",k),style:{...R(),...h},children:[i&&a.jsx("span",{className:"brycks-input-left-element",style:{...b,paddingLeft:r.paddingX},children:i}),a.jsx("input",{ref:j,className:"brycks-input",style:X,disabled:o,"aria-invalid":n,"data-testid":S,onFocus:z,onBlur:q,...w}),c&&a.jsx("span",{className:"brycks-input-right-element",style:{...b,paddingRight:r.paddingX},children:c})]})});m.displayName="Input";exports.Input=m;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("react/jsx-runtime"),b=require("react"),k=require("../../../utils/styles.cjs"),n=require("../../../design-system/primitives/sizing.cjs"),j={sm:n.componentPaddingX.sm,md:n.componentPaddingX.md,lg:n.componentPaddingX.lg},c=b.forwardRef(function({size:i="md",variant:d="outline",isInvalid:p,leftElement:t,rightElement:e,className:o,style:u,testId:m,disabled:r,...l},y){const a=j[i],g={paddingLeft:t?n.componentGap.md:a,paddingRight:e?n.componentGap.md:a};return s.jsxs("div",{className:k.cx("brycks-input-wrapper",`brycks-input-wrapper--${d}`,`brycks-input-wrapper--${i}`,p&&"brycks-input-wrapper--invalid",r&&"brycks-input-wrapper--disabled",o),style:u,children:[t&&s.jsx("span",{className:"brycks-input-left-element",children:t}),s.jsx("input",{ref:y,className:"brycks-input",style:g,disabled:r,"aria-invalid":p,"data-testid":m,...l}),e&&s.jsx("span",{className:"brycks-input-right-element",children:e})]})});c.displayName="Input";exports.Input=c;
2
2
  //# sourceMappingURL=Input.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Input.cjs","sources":["../../../../src/components/form/Input/Input.tsx"],"sourcesContent":["/**\r\n * Input Component\r\n *\r\n * Base input component with Apple-inspired styling.\r\n * Clean, minimal design with smooth focus transitions.\r\n *\r\n * @module components/form/Input\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n useState,\r\n type CSSProperties,\r\n type InputHTMLAttributes,\r\n type ReactNode,\r\n} from 'react'\r\nimport {\r\n componentHeights,\r\n componentPaddingX,\r\n componentGap,\r\n componentFontSize,\r\n focusRing,\r\n transition,\r\n stateOpacity,\r\n} from '../../../design-system'\r\nimport { cx } from '../../../utils/styles'\r\n\r\nexport type InputSize = 'sm' | 'md' | 'lg'\r\nexport type InputVariant = 'outline' | 'filled' | 'flushed'\r\n\r\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\r\n /** Input size */\r\n size?: InputSize\r\n /** Visual variant */\r\n variant?: InputVariant\r\n /** Error state */\r\n isInvalid?: boolean\r\n /** Left element/icon */\r\n leftElement?: ReactNode\r\n /** Right element/icon */\r\n rightElement?: ReactNode\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n}\r\n\r\n/** Size configuration derived from design tokens */\r\nconst sizeConfig: Record<InputSize, { height: number; fontSize: number; paddingX: number; radius: string }> = {\r\n sm: {\r\n height: componentHeights.sm,\r\n fontSize: componentFontSize.sm,\r\n paddingX: componentPaddingX.sm,\r\n radius: 'var(--brycks-radius-md)',\r\n },\r\n md: {\r\n height: componentHeights.md,\r\n fontSize: componentFontSize.md,\r\n paddingX: componentPaddingX.md,\r\n radius: 'var(--brycks-radius-default)',\r\n },\r\n lg: {\r\n height: componentHeights.lg,\r\n fontSize: componentFontSize.lg,\r\n paddingX: componentPaddingX.lg,\r\n radius: 'var(--brycks-radius-lg)',\r\n },\r\n}\r\n\r\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\r\n {\r\n size = 'md',\r\n variant = 'outline',\r\n isInvalid,\r\n leftElement,\r\n rightElement,\r\n className,\r\n style,\r\n testId,\r\n disabled,\r\n onFocus,\r\n onBlur,\r\n ...props\r\n },\r\n ref\r\n) {\r\n const [isFocused, setIsFocused] = useState(false)\r\n\r\n const config = sizeConfig[size]\r\n\r\n const getWrapperStyles = (): CSSProperties => {\r\n const base: CSSProperties = {\r\n display: 'flex',\r\n alignItems: 'center',\r\n width: '100%',\r\n position: 'relative',\r\n height: config.height,\r\n borderRadius: config.radius,\r\n transition: transition.default,\r\n }\r\n\r\n switch (variant) {\r\n case 'outline':\r\n Object.assign(base, {\r\n backgroundColor: 'var(--brycks-background-app)',\r\n border: `1px solid ${\r\n isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : 'var(--brycks-border-default)'\r\n }`,\r\n boxShadow: isFocused\r\n ? isInvalid\r\n ? focusRing.error\r\n : focusRing.default\r\n : focusRing.none,\r\n })\r\n break\r\n\r\n case 'filled':\r\n Object.assign(base, {\r\n backgroundColor: 'var(--brycks-background-muted)',\r\n border: '1px solid transparent',\r\n borderColor: isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : 'transparent',\r\n })\r\n break\r\n\r\n case 'flushed':\r\n Object.assign(base, {\r\n backgroundColor: 'transparent',\r\n borderRadius: 0,\r\n borderBottom: `2px solid ${\r\n isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : 'var(--brycks-border-default)'\r\n }`,\r\n })\r\n break\r\n }\r\n\r\n if (disabled) {\r\n Object.assign(base, {\r\n opacity: stateOpacity.disabled,\r\n cursor: 'not-allowed',\r\n })\r\n }\r\n\r\n return base\r\n }\r\n\r\n const inputStyles: CSSProperties = {\r\n width: '100%',\r\n height: config.height,\r\n fontFamily: 'var(--brycks-font-sans)',\r\n fontSize: config.fontSize,\r\n color: 'var(--brycks-foreground-default)',\r\n backgroundColor: 'transparent',\r\n border: 'none',\r\n outline: 'none',\r\n borderRadius: config.radius,\r\n paddingLeft: leftElement ? componentGap.md : config.paddingX,\r\n paddingRight: rightElement ? componentGap.md : config.paddingX,\r\n cursor: disabled ? 'not-allowed' : 'text',\r\n transition: transition.default,\r\n }\r\n\r\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true)\r\n onFocus?.(e)\r\n }\r\n\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(false)\r\n onBlur?.(e)\r\n }\r\n\r\n const elementStyle: CSSProperties = {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: 'var(--brycks-foreground-muted)',\r\n flexShrink: 0,\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n 'brycks-input-wrapper',\r\n `brycks-input-wrapper--${variant}`,\r\n `brycks-input-wrapper--${size}`,\r\n isInvalid && 'brycks-input-wrapper--invalid',\r\n disabled && 'brycks-input-wrapper--disabled',\r\n className\r\n )}\r\n style={{ ...getWrapperStyles(), ...style }}\r\n >\r\n {leftElement && (\r\n <span\r\n className=\"brycks-input-left-element\"\r\n style={{ ...elementStyle, paddingLeft: config.paddingX }}\r\n >\r\n {leftElement}\r\n </span>\r\n )}\r\n\r\n <input\r\n ref={ref}\r\n className=\"brycks-input\"\r\n style={inputStyles}\r\n disabled={disabled}\r\n aria-invalid={isInvalid}\r\n data-testid={testId}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n {...props}\r\n />\r\n\r\n {rightElement && (\r\n <span\r\n className=\"brycks-input-right-element\"\r\n style={{ ...elementStyle, paddingRight: config.paddingX }}\r\n >\r\n {rightElement}\r\n </span>\r\n )}\r\n </div>\r\n )\r\n})\r\n\r\nInput.displayName = 'Input'\r\n"],"names":["sizeConfig","componentHeights","componentFontSize","componentPaddingX","Input","forwardRef","size","variant","isInvalid","leftElement","rightElement","className","style","testId","disabled","onFocus","onBlur","props","ref","isFocused","setIsFocused","useState","config","getWrapperStyles","base","transition","focusRing","stateOpacity","inputStyles","componentGap","handleFocus","handleBlur","elementStyle","jsxs","cx","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Input.cjs","sources":["../../../../src/components/form/Input/Input.tsx"],"sourcesContent":["/**\n * Input Component\n *\n * Base input component with Apple-inspired styling.\n * Clean, minimal design with smooth focus transitions.\n *\n * @module components/form/Input\n */\n\nimport {\n forwardRef,\n type CSSProperties,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { componentGap, componentPaddingX } from '../../../design-system'\nimport { cx } from '../../../utils/styles'\n\nexport type InputSize = 'sm' | 'md' | 'lg'\nexport type InputVariant = 'outline' | 'filled' | 'flushed'\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /** Input size */\n size?: InputSize\n /** Visual variant */\n variant?: InputVariant\n /** Error state */\n isInvalid?: boolean\n /** Left element/icon */\n leftElement?: ReactNode\n /** Right element/icon */\n rightElement?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\n/** Per-size horizontal padding for the input (used for the dynamic left/right padding). */\nconst sizePaddingX: Record<InputSize, number> = {\n sm: componentPaddingX.sm,\n md: componentPaddingX.md,\n lg: componentPaddingX.lg,\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n size = 'md',\n variant = 'outline',\n isInvalid,\n leftElement,\n rightElement,\n className,\n style,\n testId,\n disabled,\n ...props\n },\n ref\n) {\n const paddingX = sizePaddingX[size]\n\n // Only the input's horizontal padding is dynamic: it collapses to a tighter\n // gap on the side that has an adornment. Everything else lives in CSS.\n const inputStyles: CSSProperties = {\n paddingLeft: leftElement ? componentGap.md : paddingX,\n paddingRight: rightElement ? componentGap.md : paddingX,\n }\n\n return (\n <div\n className={cx(\n 'brycks-input-wrapper',\n `brycks-input-wrapper--${variant}`,\n `brycks-input-wrapper--${size}`,\n isInvalid && 'brycks-input-wrapper--invalid',\n disabled && 'brycks-input-wrapper--disabled',\n className\n )}\n style={style}\n >\n {leftElement && (\n <span className=\"brycks-input-left-element\">{leftElement}</span>\n )}\n\n <input\n ref={ref}\n className=\"brycks-input\"\n style={inputStyles}\n disabled={disabled}\n aria-invalid={isInvalid}\n data-testid={testId}\n {...props}\n />\n\n {rightElement && (\n <span className=\"brycks-input-right-element\">{rightElement}</span>\n )}\n </div>\n )\n})\n\nInput.displayName = 'Input'\n"],"names":["sizePaddingX","componentPaddingX","Input","forwardRef","size","variant","isInvalid","leftElement","rightElement","className","style","testId","disabled","props","ref","paddingX","inputStyles","componentGap","jsxs","cx","jsx"],"mappings":"yOAuCMA,EAA0C,CAC9C,GAAIC,EAAAA,kBAAkB,GACtB,GAAIA,EAAAA,kBAAkB,GACtB,GAAIA,EAAAA,kBAAkB,EACxB,EAEaC,EAAQC,EAAAA,WAAyC,SAC5D,CACE,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,UAAAC,EACA,YAAAC,EACA,aAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,MAAMC,EAAWf,EAAaI,CAAI,EAI5BY,EAA6B,CACjC,YAAaT,EAAcU,eAAa,GAAKF,EAC7C,aAAcP,EAAeS,EAAAA,aAAa,GAAKF,CAAA,EAGjD,OACEG,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,uBACA,yBAAyBd,CAAO,GAChC,yBAAyBD,CAAI,GAC7BE,GAAa,gCACbM,GAAY,iCACZH,CAAA,EAEF,MAAAC,EAEC,SAAA,CAAAH,GACCa,EAAAA,IAAC,OAAA,CAAK,UAAU,4BAA6B,SAAAb,EAAY,EAG3Da,EAAAA,IAAC,QAAA,CACC,IAAAN,EACA,UAAU,eACV,MAAOE,EACP,SAAAJ,EACA,eAAcN,EACd,cAAaK,EACZ,GAAGE,CAAA,CAAA,EAGLL,GACCY,EAAAA,IAAC,OAAA,CAAK,UAAU,6BAA8B,SAAAZ,CAAA,CAAa,CAAA,CAAA,CAAA,CAInE,CAAC,EAEDN,EAAM,YAAc"}
@@ -1,155 +1,60 @@
1
- import { jsxs as F, jsx as d } from "react/jsx-runtime";
2
- import { forwardRef as N, useState as O } from "react";
3
- import { cx as $ } from "../../../utils/styles.js";
4
- import { componentPaddingX as i, componentHeights as c, componentGap as m } from "../../../design-system/primitives/sizing.js";
5
- import { componentFontSize as p } from "../../../design-system/primitives/typography.js";
6
- import { transition as y } from "../../../design-system/primitives/transitions.js";
7
- import { focusRing as u } from "../../../design-system/primitives/focus.js";
8
- import { stateOpacity as B } from "../../../design-system/primitives/opacity.js";
9
- const L = {
10
- sm: {
11
- height: c.sm,
12
- fontSize: p.sm,
13
- paddingX: i.sm,
14
- radius: "var(--brycks-radius-md)"
15
- },
16
- md: {
17
- height: c.md,
18
- fontSize: p.md,
19
- paddingX: i.md,
20
- radius: "var(--brycks-radius-default)"
21
- },
22
- lg: {
23
- height: c.lg,
24
- fontSize: p.lg,
25
- paddingX: i.lg,
26
- radius: "var(--brycks-radius-lg)"
27
- }
28
- }, G = N(function({
29
- size: l = "md",
30
- variant: b = "outline",
1
+ import { jsxs as k, jsx as r } from "react/jsx-runtime";
2
+ import { forwardRef as f } from "react";
3
+ import { cx as g } from "../../../utils/styles.js";
4
+ import { componentGap as c, componentPaddingX as i } from "../../../design-system/primitives/sizing.js";
5
+ const w = {
6
+ sm: i.sm,
7
+ md: i.md,
8
+ lg: i.lg
9
+ }, N = f(function({
10
+ size: s = "md",
11
+ variant: e = "outline",
31
12
  isInvalid: t,
32
- leftElement: s,
13
+ leftElement: p,
33
14
  rightElement: n,
34
- className: k,
35
- style: h,
36
- testId: v,
37
- disabled: o,
38
- onFocus: w,
39
- onBlur: x,
40
- ...S
41
- }, X) {
42
- const [a, f] = O(!1), r = L[l], j = () => {
43
- const e = {
44
- display: "flex",
45
- alignItems: "center",
46
- width: "100%",
47
- position: "relative",
48
- height: r.height,
49
- borderRadius: r.radius,
50
- transition: y.default
51
- };
52
- switch (b) {
53
- case "outline":
54
- Object.assign(e, {
55
- backgroundColor: "var(--brycks-background-app)",
56
- border: `1px solid ${t ? "var(--brycks-error-default)" : a ? "var(--brycks-border-focus)" : "var(--brycks-border-default)"}`,
57
- boxShadow: a ? t ? u.error : u.default : u.none
58
- });
59
- break;
60
- case "filled":
61
- Object.assign(e, {
62
- backgroundColor: "var(--brycks-background-muted)",
63
- border: "1px solid transparent",
64
- borderColor: t ? "var(--brycks-error-default)" : a ? "var(--brycks-border-focus)" : "transparent"
65
- });
66
- break;
67
- case "flushed":
68
- Object.assign(e, {
69
- backgroundColor: "transparent",
70
- borderRadius: 0,
71
- borderBottom: `2px solid ${t ? "var(--brycks-error-default)" : a ? "var(--brycks-border-focus)" : "var(--brycks-border-default)"}`
72
- });
73
- break;
74
- }
75
- return o && Object.assign(e, {
76
- opacity: B.disabled,
77
- cursor: "not-allowed"
78
- }), e;
79
- }, C = {
80
- width: "100%",
81
- height: r.height,
82
- fontFamily: "var(--brycks-font-sans)",
83
- fontSize: r.fontSize,
84
- color: "var(--brycks-foreground-default)",
85
- backgroundColor: "transparent",
86
- border: "none",
87
- outline: "none",
88
- borderRadius: r.radius,
89
- paddingLeft: s ? m.md : r.paddingX,
90
- paddingRight: n ? m.md : r.paddingX,
91
- cursor: o ? "not-allowed" : "text",
92
- transition: y.default
93
- }, R = (e) => {
94
- f(!0), w?.(e);
95
- }, z = (e) => {
96
- f(!1), x?.(e);
97
- }, g = {
98
- display: "flex",
99
- alignItems: "center",
100
- justifyContent: "center",
101
- color: "var(--brycks-foreground-muted)",
102
- flexShrink: 0
15
+ className: m,
16
+ style: o,
17
+ testId: u,
18
+ disabled: a,
19
+ ...l
20
+ }, y) {
21
+ const d = w[s], b = {
22
+ paddingLeft: p ? c.md : d,
23
+ paddingRight: n ? c.md : d
103
24
  };
104
- return /* @__PURE__ */ F(
25
+ return /* @__PURE__ */ k(
105
26
  "div",
106
27
  {
107
- className: $(
28
+ className: g(
108
29
  "brycks-input-wrapper",
109
- `brycks-input-wrapper--${b}`,
110
- `brycks-input-wrapper--${l}`,
30
+ `brycks-input-wrapper--${e}`,
31
+ `brycks-input-wrapper--${s}`,
111
32
  t && "brycks-input-wrapper--invalid",
112
- o && "brycks-input-wrapper--disabled",
113
- k
33
+ a && "brycks-input-wrapper--disabled",
34
+ m
114
35
  ),
115
- style: { ...j(), ...h },
36
+ style: o,
116
37
  children: [
117
- s && /* @__PURE__ */ d(
118
- "span",
119
- {
120
- className: "brycks-input-left-element",
121
- style: { ...g, paddingLeft: r.paddingX },
122
- children: s
123
- }
124
- ),
125
- /* @__PURE__ */ d(
38
+ p && /* @__PURE__ */ r("span", { className: "brycks-input-left-element", children: p }),
39
+ /* @__PURE__ */ r(
126
40
  "input",
127
41
  {
128
- ref: X,
42
+ ref: y,
129
43
  className: "brycks-input",
130
- style: C,
131
- disabled: o,
44
+ style: b,
45
+ disabled: a,
132
46
  "aria-invalid": t,
133
- "data-testid": v,
134
- onFocus: R,
135
- onBlur: z,
136
- ...S
47
+ "data-testid": u,
48
+ ...l
137
49
  }
138
50
  ),
139
- n && /* @__PURE__ */ d(
140
- "span",
141
- {
142
- className: "brycks-input-right-element",
143
- style: { ...g, paddingRight: r.paddingX },
144
- children: n
145
- }
146
- )
51
+ n && /* @__PURE__ */ r("span", { className: "brycks-input-right-element", children: n })
147
52
  ]
148
53
  }
149
54
  );
150
55
  });
151
- G.displayName = "Input";
56
+ N.displayName = "Input";
152
57
  export {
153
- G as Input
58
+ N as Input
154
59
  };
155
60
  //# sourceMappingURL=Input.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../../src/components/form/Input/Input.tsx"],"sourcesContent":["/**\r\n * Input Component\r\n *\r\n * Base input component with Apple-inspired styling.\r\n * Clean, minimal design with smooth focus transitions.\r\n *\r\n * @module components/form/Input\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n useState,\r\n type CSSProperties,\r\n type InputHTMLAttributes,\r\n type ReactNode,\r\n} from 'react'\r\nimport {\r\n componentHeights,\r\n componentPaddingX,\r\n componentGap,\r\n componentFontSize,\r\n focusRing,\r\n transition,\r\n stateOpacity,\r\n} from '../../../design-system'\r\nimport { cx } from '../../../utils/styles'\r\n\r\nexport type InputSize = 'sm' | 'md' | 'lg'\r\nexport type InputVariant = 'outline' | 'filled' | 'flushed'\r\n\r\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\r\n /** Input size */\r\n size?: InputSize\r\n /** Visual variant */\r\n variant?: InputVariant\r\n /** Error state */\r\n isInvalid?: boolean\r\n /** Left element/icon */\r\n leftElement?: ReactNode\r\n /** Right element/icon */\r\n rightElement?: ReactNode\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n}\r\n\r\n/** Size configuration derived from design tokens */\r\nconst sizeConfig: Record<InputSize, { height: number; fontSize: number; paddingX: number; radius: string }> = {\r\n sm: {\r\n height: componentHeights.sm,\r\n fontSize: componentFontSize.sm,\r\n paddingX: componentPaddingX.sm,\r\n radius: 'var(--brycks-radius-md)',\r\n },\r\n md: {\r\n height: componentHeights.md,\r\n fontSize: componentFontSize.md,\r\n paddingX: componentPaddingX.md,\r\n radius: 'var(--brycks-radius-default)',\r\n },\r\n lg: {\r\n height: componentHeights.lg,\r\n fontSize: componentFontSize.lg,\r\n paddingX: componentPaddingX.lg,\r\n radius: 'var(--brycks-radius-lg)',\r\n },\r\n}\r\n\r\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\r\n {\r\n size = 'md',\r\n variant = 'outline',\r\n isInvalid,\r\n leftElement,\r\n rightElement,\r\n className,\r\n style,\r\n testId,\r\n disabled,\r\n onFocus,\r\n onBlur,\r\n ...props\r\n },\r\n ref\r\n) {\r\n const [isFocused, setIsFocused] = useState(false)\r\n\r\n const config = sizeConfig[size]\r\n\r\n const getWrapperStyles = (): CSSProperties => {\r\n const base: CSSProperties = {\r\n display: 'flex',\r\n alignItems: 'center',\r\n width: '100%',\r\n position: 'relative',\r\n height: config.height,\r\n borderRadius: config.radius,\r\n transition: transition.default,\r\n }\r\n\r\n switch (variant) {\r\n case 'outline':\r\n Object.assign(base, {\r\n backgroundColor: 'var(--brycks-background-app)',\r\n border: `1px solid ${\r\n isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : 'var(--brycks-border-default)'\r\n }`,\r\n boxShadow: isFocused\r\n ? isInvalid\r\n ? focusRing.error\r\n : focusRing.default\r\n : focusRing.none,\r\n })\r\n break\r\n\r\n case 'filled':\r\n Object.assign(base, {\r\n backgroundColor: 'var(--brycks-background-muted)',\r\n border: '1px solid transparent',\r\n borderColor: isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : 'transparent',\r\n })\r\n break\r\n\r\n case 'flushed':\r\n Object.assign(base, {\r\n backgroundColor: 'transparent',\r\n borderRadius: 0,\r\n borderBottom: `2px solid ${\r\n isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : 'var(--brycks-border-default)'\r\n }`,\r\n })\r\n break\r\n }\r\n\r\n if (disabled) {\r\n Object.assign(base, {\r\n opacity: stateOpacity.disabled,\r\n cursor: 'not-allowed',\r\n })\r\n }\r\n\r\n return base\r\n }\r\n\r\n const inputStyles: CSSProperties = {\r\n width: '100%',\r\n height: config.height,\r\n fontFamily: 'var(--brycks-font-sans)',\r\n fontSize: config.fontSize,\r\n color: 'var(--brycks-foreground-default)',\r\n backgroundColor: 'transparent',\r\n border: 'none',\r\n outline: 'none',\r\n borderRadius: config.radius,\r\n paddingLeft: leftElement ? componentGap.md : config.paddingX,\r\n paddingRight: rightElement ? componentGap.md : config.paddingX,\r\n cursor: disabled ? 'not-allowed' : 'text',\r\n transition: transition.default,\r\n }\r\n\r\n const handleFocus = (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(true)\r\n onFocus?.(e)\r\n }\r\n\r\n const handleBlur = (e: React.FocusEvent<HTMLInputElement>) => {\r\n setIsFocused(false)\r\n onBlur?.(e)\r\n }\r\n\r\n const elementStyle: CSSProperties = {\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n color: 'var(--brycks-foreground-muted)',\r\n flexShrink: 0,\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n 'brycks-input-wrapper',\r\n `brycks-input-wrapper--${variant}`,\r\n `brycks-input-wrapper--${size}`,\r\n isInvalid && 'brycks-input-wrapper--invalid',\r\n disabled && 'brycks-input-wrapper--disabled',\r\n className\r\n )}\r\n style={{ ...getWrapperStyles(), ...style }}\r\n >\r\n {leftElement && (\r\n <span\r\n className=\"brycks-input-left-element\"\r\n style={{ ...elementStyle, paddingLeft: config.paddingX }}\r\n >\r\n {leftElement}\r\n </span>\r\n )}\r\n\r\n <input\r\n ref={ref}\r\n className=\"brycks-input\"\r\n style={inputStyles}\r\n disabled={disabled}\r\n aria-invalid={isInvalid}\r\n data-testid={testId}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n {...props}\r\n />\r\n\r\n {rightElement && (\r\n <span\r\n className=\"brycks-input-right-element\"\r\n style={{ ...elementStyle, paddingRight: config.paddingX }}\r\n >\r\n {rightElement}\r\n </span>\r\n )}\r\n </div>\r\n )\r\n})\r\n\r\nInput.displayName = 'Input'\r\n"],"names":["sizeConfig","componentHeights","componentFontSize","componentPaddingX","Input","forwardRef","size","variant","isInvalid","leftElement","rightElement","className","style","testId","disabled","onFocus","onBlur","props","ref","isFocused","setIsFocused","useState","config","getWrapperStyles","base","transition","focusRing","stateOpacity","inputStyles","componentGap","handleFocus","handleBlur","elementStyle","jsxs","cx","jsx"],"mappings":"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"}
1
+ {"version":3,"file":"Input.js","sources":["../../../../src/components/form/Input/Input.tsx"],"sourcesContent":["/**\n * Input Component\n *\n * Base input component with Apple-inspired styling.\n * Clean, minimal design with smooth focus transitions.\n *\n * @module components/form/Input\n */\n\nimport {\n forwardRef,\n type CSSProperties,\n type InputHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { componentGap, componentPaddingX } from '../../../design-system'\nimport { cx } from '../../../utils/styles'\n\nexport type InputSize = 'sm' | 'md' | 'lg'\nexport type InputVariant = 'outline' | 'filled' | 'flushed'\n\nexport interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /** Input size */\n size?: InputSize\n /** Visual variant */\n variant?: InputVariant\n /** Error state */\n isInvalid?: boolean\n /** Left element/icon */\n leftElement?: ReactNode\n /** Right element/icon */\n rightElement?: ReactNode\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\n/** Per-size horizontal padding for the input (used for the dynamic left/right padding). */\nconst sizePaddingX: Record<InputSize, number> = {\n sm: componentPaddingX.sm,\n md: componentPaddingX.md,\n lg: componentPaddingX.lg,\n}\n\nexport const Input = forwardRef<HTMLInputElement, InputProps>(function Input(\n {\n size = 'md',\n variant = 'outline',\n isInvalid,\n leftElement,\n rightElement,\n className,\n style,\n testId,\n disabled,\n ...props\n },\n ref\n) {\n const paddingX = sizePaddingX[size]\n\n // Only the input's horizontal padding is dynamic: it collapses to a tighter\n // gap on the side that has an adornment. Everything else lives in CSS.\n const inputStyles: CSSProperties = {\n paddingLeft: leftElement ? componentGap.md : paddingX,\n paddingRight: rightElement ? componentGap.md : paddingX,\n }\n\n return (\n <div\n className={cx(\n 'brycks-input-wrapper',\n `brycks-input-wrapper--${variant}`,\n `brycks-input-wrapper--${size}`,\n isInvalid && 'brycks-input-wrapper--invalid',\n disabled && 'brycks-input-wrapper--disabled',\n className\n )}\n style={style}\n >\n {leftElement && (\n <span className=\"brycks-input-left-element\">{leftElement}</span>\n )}\n\n <input\n ref={ref}\n className=\"brycks-input\"\n style={inputStyles}\n disabled={disabled}\n aria-invalid={isInvalid}\n data-testid={testId}\n {...props}\n />\n\n {rightElement && (\n <span className=\"brycks-input-right-element\">{rightElement}</span>\n )}\n </div>\n )\n})\n\nInput.displayName = 'Input'\n"],"names":["sizePaddingX","componentPaddingX","Input","forwardRef","size","variant","isInvalid","leftElement","rightElement","className","style","testId","disabled","props","ref","paddingX","inputStyles","componentGap","jsxs","cx","jsx"],"mappings":";;;;AAuCA,MAAMA,IAA0C;AAAA,EAC9C,IAAIC,EAAkB;AAAA,EACtB,IAAIA,EAAkB;AAAA,EACtB,IAAIA,EAAkB;AACxB,GAEaC,IAAQC,EAAyC,SAC5D;AAAA,EACE,MAAAC,IAAO;AAAA,EACP,SAAAC,IAAU;AAAA,EACV,WAAAC;AAAA,EACA,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,WAAAC;AAAA,EACA,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAWf,EAAaI,CAAI,GAI5BY,IAA6B;AAAA,IACjC,aAAaT,IAAcU,EAAa,KAAKF;AAAA,IAC7C,cAAcP,IAAeS,EAAa,KAAKF;AAAA,EAAA;AAGjD,SACE,gBAAAG;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA,yBAAyBd,CAAO;AAAA,QAChC,yBAAyBD,CAAI;AAAA,QAC7BE,KAAa;AAAA,QACbM,KAAY;AAAA,QACZH;AAAA,MAAA;AAAA,MAEF,OAAAC;AAAA,MAEC,UAAA;AAAA,QAAAH,KACC,gBAAAa,EAAC,QAAA,EAAK,WAAU,6BAA6B,UAAAb,GAAY;AAAA,QAG3D,gBAAAa;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAAN;AAAA,YACA,WAAU;AAAA,YACV,OAAOE;AAAA,YACP,UAAAJ;AAAA,YACA,gBAAcN;AAAA,YACd,eAAaK;AAAA,YACZ,GAAGE;AAAA,UAAA;AAAA,QAAA;AAAA,QAGLL,KACC,gBAAAY,EAAC,QAAA,EAAK,WAAU,8BAA8B,UAAAZ,EAAA,CAAa;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAInE,CAAC;AAEDN,EAAM,cAAc;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),n=require("react"),C=require("../Input/Input.cjs");function m(){return e.jsxs("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:[e.jsx("circle",{cx:"7",cy:"7",r:"4.5",stroke:"currentColor",strokeWidth:"1.5"}),e.jsx("path",{d:"M10.5 10.5L14 14",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})]})}function y(){return e.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none","aria-hidden":"true",children:e.jsx("path",{d:"M4 4l6 6M10 4l-6 6",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})}const u=n.forwardRef(function({value:a,defaultValue:h="",onValueChange:r,onClear:c,size:d="md",placeholder:p="Search…",leftElement:x,clearLabel:k="Clear search",className:f,testId:j,disabled:s,...v},I){const[b,o]=n.useState(h),t=a!==void 0,i=t?a:b,S=n.useCallback(l=>{t||o(l.target.value),r?.(l.target.value)},[t,r]),g=n.useCallback(()=>{t||o(""),r?.(""),c?.()},[t,r,c]);return e.jsx(C.Input,{ref:I,type:"search",role:"searchbox",size:d,placeholder:p,value:i,onChange:S,disabled:s,className:f,testId:j,leftElement:x??e.jsx(m,{}),rightElement:i&&!s?e.jsx("button",{type:"button",className:"brycks-search-input__clear","aria-label":k,onClick:g,tabIndex:-1,children:e.jsx(y,{})}):void 0,...v})});u.displayName="SearchInput";exports.SearchInput=u;
2
+ //# sourceMappingURL=SearchInput.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchInput.cjs","sources":["../../../../src/components/form/SearchInput/SearchInput.tsx"],"sourcesContent":["/**\n * SearchInput Component\n *\n * A search field built on top of Input: a leading search icon and a trailing\n * clear button that appears once there is text. Works controlled (`value` +\n * `onValueChange`) or uncontrolled (`defaultValue`).\n *\n * All color styles are inherited from Input; the clear button hover state is\n * handled via a CSS class for easy customization.\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n type ChangeEvent,\n type ReactNode,\n type InputHTMLAttributes,\n} from 'react'\nimport { Input, type InputSize } from '../Input'\n\ntype NativeInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'value' | 'defaultValue' | 'onChange' | 'type'\n>\n\nexport interface SearchInputProps extends NativeInputProps {\n /** Current value (controlled) */\n value?: string\n /** Initial value (uncontrolled) */\n defaultValue?: string\n /** Callback when the value changes (typing or clearing) */\n onValueChange?: (value: string) => void\n /** Callback fired when the clear button is pressed */\n onClear?: () => void\n /** Input size */\n size?: InputSize\n /** Placeholder text */\n placeholder?: string\n /** Custom leading element (defaults to a search icon) */\n leftElement?: ReactNode\n /** Accessible label of the clear button */\n clearLabel?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nfunction SearchIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M10.5 10.5L14 14\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n {\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n onClear,\n size = 'md',\n placeholder = 'Search…',\n leftElement,\n clearLabel = 'Clear search',\n className,\n testId,\n disabled,\n ...props\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState(defaultValue)\n const isControlled = controlledValue !== undefined\n const value = isControlled ? controlledValue : internalValue\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInternalValue(e.target.value)\n onValueChange?.(e.target.value)\n },\n [isControlled, onValueChange]\n )\n\n const handleClear = useCallback(() => {\n if (!isControlled) setInternalValue('')\n onValueChange?.('')\n onClear?.()\n }, [isControlled, onValueChange, onClear])\n\n return (\n <Input\n ref={ref}\n type=\"search\"\n role=\"searchbox\"\n size={size}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n disabled={disabled}\n className={className}\n testId={testId}\n leftElement={leftElement ?? <SearchIcon />}\n rightElement={\n value && !disabled ? (\n <button\n type=\"button\"\n className=\"brycks-search-input__clear\"\n aria-label={clearLabel}\n onClick={handleClear}\n tabIndex={-1}\n >\n <ClearIcon />\n </button>\n ) : undefined\n }\n {...props}\n />\n )\n})\n\nSearchInput.displayName = 'SearchInput'\n"],"names":["SearchIcon","jsxs","jsx","ClearIcon","SearchInput","forwardRef","controlledValue","defaultValue","onValueChange","onClear","size","placeholder","leftElement","clearLabel","className","testId","disabled","props","ref","internalValue","setInternalValue","useState","isControlled","value","handleChange","useCallback","e","handleClear","Input"],"mappings":"wKAiDA,SAASA,GAAa,CACpB,OACEC,EAAAA,KAAC,MAAA,CAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,cAAY,OACtE,SAAA,CAAAC,EAAAA,IAAC,SAAA,CAAO,GAAG,IAAI,GAAG,IAAI,EAAE,MAAM,OAAO,eAAe,YAAY,KAAA,CAAM,EACtEA,EAAAA,IAAC,QAAK,EAAE,mBAAmB,OAAO,eAAe,YAAY,MAAM,cAAc,OAAA,CAAQ,CAAA,EAC3F,CAEJ,CAEA,SAASC,GAAY,CACnB,OACED,MAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OAAO,cAAY,OACtE,SAAAA,EAAAA,IAAC,OAAA,CAAK,EAAE,qBAAqB,OAAO,eAAe,YAAY,MAAM,cAAc,OAAA,CAAQ,CAAA,CAC7F,CAEJ,CAEO,MAAME,EAAcC,EAAAA,WAA+C,SACxE,CACE,MAAOC,EACP,aAAAC,EAAe,GACf,cAAAC,EACA,QAAAC,EACA,KAAAC,EAAO,KACP,YAAAC,EAAc,UACd,YAAAC,EACA,WAAAC,EAAa,eACb,UAAAC,EACA,OAAAC,EACA,SAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,KAAM,CAACC,EAAeC,CAAgB,EAAIC,EAAAA,SAASd,CAAY,EACzDe,EAAehB,IAAoB,OACnCiB,EAAQD,EAAehB,EAAkBa,EAEzCK,EAAeC,EAAAA,YAClBC,GAAqC,CAC/BJ,GAAcF,EAAiBM,EAAE,OAAO,KAAK,EAClDlB,IAAgBkB,EAAE,OAAO,KAAK,CAChC,EACA,CAACJ,EAAcd,CAAa,CAAA,EAGxBmB,EAAcF,EAAAA,YAAY,IAAM,CAC/BH,GAAcF,EAAiB,EAAE,EACtCZ,IAAgB,EAAE,EAClBC,IAAA,CACF,EAAG,CAACa,EAAcd,EAAeC,CAAO,CAAC,EAEzC,OACEP,EAAAA,IAAC0B,EAAAA,MAAA,CACC,IAAAV,EACA,KAAK,SACL,KAAK,YACL,KAAAR,EACA,YAAAC,EACA,MAAAY,EACA,SAAUC,EACV,SAAAR,EACA,UAAAF,EACA,OAAAC,EACA,YAAaH,GAAeV,MAACF,EAAA,CAAA,CAAW,EACxC,aACEuB,GAAS,CAACP,EACRd,EAAAA,IAAC,SAAA,CACC,KAAK,SACL,UAAU,6BACV,aAAYW,EACZ,QAASc,EACT,SAAU,GAEV,eAACxB,EAAA,CAAA,CAAU,CAAA,CAAA,EAEX,OAEL,GAAGc,CAAA,CAAA,CAGV,CAAC,EAEDb,EAAY,YAAc"}
@@ -0,0 +1,68 @@
1
+ import { jsx as e, jsxs as g } from "react/jsx-runtime";
2
+ import { forwardRef as S, useState as w, useCallback as s } from "react";
3
+ import { Input as y } from "../Input/Input.js";
4
+ function L() {
5
+ return /* @__PURE__ */ g("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: [
6
+ /* @__PURE__ */ e("circle", { cx: "7", cy: "7", r: "4.5", stroke: "currentColor", strokeWidth: "1.5" }),
7
+ /* @__PURE__ */ e("path", { d: "M10.5 10.5L14 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" })
8
+ ] });
9
+ }
10
+ function M() {
11
+ return /* @__PURE__ */ e("svg", { width: "14", height: "14", viewBox: "0 0 14 14", fill: "none", "aria-hidden": "true", children: /* @__PURE__ */ e("path", { d: "M4 4l6 6M10 4l-6 6", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) });
12
+ }
13
+ const W = S(function({
14
+ value: n,
15
+ defaultValue: h = "",
16
+ onValueChange: t,
17
+ onClear: o,
18
+ size: u = "md",
19
+ placeholder: d = "Search…",
20
+ leftElement: p,
21
+ clearLabel: f = "Clear search",
22
+ className: k,
23
+ testId: m,
24
+ disabled: a,
25
+ ...v
26
+ }, x) {
27
+ const [I, i] = w(h), r = n !== void 0, c = r ? n : I, C = s(
28
+ (l) => {
29
+ r || i(l.target.value), t?.(l.target.value);
30
+ },
31
+ [r, t]
32
+ ), b = s(() => {
33
+ r || i(""), t?.(""), o?.();
34
+ }, [r, t, o]);
35
+ return /* @__PURE__ */ e(
36
+ y,
37
+ {
38
+ ref: x,
39
+ type: "search",
40
+ role: "searchbox",
41
+ size: u,
42
+ placeholder: d,
43
+ value: c,
44
+ onChange: C,
45
+ disabled: a,
46
+ className: k,
47
+ testId: m,
48
+ leftElement: p ?? /* @__PURE__ */ e(L, {}),
49
+ rightElement: c && !a ? /* @__PURE__ */ e(
50
+ "button",
51
+ {
52
+ type: "button",
53
+ className: "brycks-search-input__clear",
54
+ "aria-label": f,
55
+ onClick: b,
56
+ tabIndex: -1,
57
+ children: /* @__PURE__ */ e(M, {})
58
+ }
59
+ ) : void 0,
60
+ ...v
61
+ }
62
+ );
63
+ });
64
+ W.displayName = "SearchInput";
65
+ export {
66
+ W as SearchInput
67
+ };
68
+ //# sourceMappingURL=SearchInput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchInput.js","sources":["../../../../src/components/form/SearchInput/SearchInput.tsx"],"sourcesContent":["/**\n * SearchInput Component\n *\n * A search field built on top of Input: a leading search icon and a trailing\n * clear button that appears once there is text. Works controlled (`value` +\n * `onValueChange`) or uncontrolled (`defaultValue`).\n *\n * All color styles are inherited from Input; the clear button hover state is\n * handled via a CSS class for easy customization.\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n type ChangeEvent,\n type ReactNode,\n type InputHTMLAttributes,\n} from 'react'\nimport { Input, type InputSize } from '../Input'\n\ntype NativeInputProps = Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'value' | 'defaultValue' | 'onChange' | 'type'\n>\n\nexport interface SearchInputProps extends NativeInputProps {\n /** Current value (controlled) */\n value?: string\n /** Initial value (uncontrolled) */\n defaultValue?: string\n /** Callback when the value changes (typing or clearing) */\n onValueChange?: (value: string) => void\n /** Callback fired when the clear button is pressed */\n onClear?: () => void\n /** Input size */\n size?: InputSize\n /** Placeholder text */\n placeholder?: string\n /** Custom leading element (defaults to a search icon) */\n leftElement?: ReactNode\n /** Accessible label of the clear button */\n clearLabel?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nfunction SearchIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <circle cx=\"7\" cy=\"7\" r=\"4.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M10.5 10.5L14 14\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nfunction ClearIcon() {\n return (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M4 4l6 6M10 4l-6 6\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n\nexport const SearchInput = forwardRef<HTMLInputElement, SearchInputProps>(function SearchInput(\n {\n value: controlledValue,\n defaultValue = '',\n onValueChange,\n onClear,\n size = 'md',\n placeholder = 'Search…',\n leftElement,\n clearLabel = 'Clear search',\n className,\n testId,\n disabled,\n ...props\n },\n ref\n) {\n const [internalValue, setInternalValue] = useState(defaultValue)\n const isControlled = controlledValue !== undefined\n const value = isControlled ? controlledValue : internalValue\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) setInternalValue(e.target.value)\n onValueChange?.(e.target.value)\n },\n [isControlled, onValueChange]\n )\n\n const handleClear = useCallback(() => {\n if (!isControlled) setInternalValue('')\n onValueChange?.('')\n onClear?.()\n }, [isControlled, onValueChange, onClear])\n\n return (\n <Input\n ref={ref}\n type=\"search\"\n role=\"searchbox\"\n size={size}\n placeholder={placeholder}\n value={value}\n onChange={handleChange}\n disabled={disabled}\n className={className}\n testId={testId}\n leftElement={leftElement ?? <SearchIcon />}\n rightElement={\n value && !disabled ? (\n <button\n type=\"button\"\n className=\"brycks-search-input__clear\"\n aria-label={clearLabel}\n onClick={handleClear}\n tabIndex={-1}\n >\n <ClearIcon />\n </button>\n ) : undefined\n }\n {...props}\n />\n )\n})\n\nSearchInput.displayName = 'SearchInput'\n"],"names":["SearchIcon","jsxs","jsx","ClearIcon","SearchInput","forwardRef","controlledValue","defaultValue","onValueChange","onClear","size","placeholder","leftElement","clearLabel","className","testId","disabled","props","ref","internalValue","setInternalValue","useState","isControlled","value","handleChange","useCallback","e","handleClear","Input"],"mappings":";;;AAiDA,SAASA,IAAa;AACpB,SACE,gBAAAC,EAAC,OAAA,EAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,eAAY,QACtE,UAAA;AAAA,IAAA,gBAAAC,EAAC,UAAA,EAAO,IAAG,KAAI,IAAG,KAAI,GAAE,OAAM,QAAO,gBAAe,aAAY,MAAA,CAAM;AAAA,IACtE,gBAAAA,EAAC,UAAK,GAAE,oBAAmB,QAAO,gBAAe,aAAY,OAAM,eAAc,QAAA,CAAQ;AAAA,EAAA,GAC3F;AAEJ;AAEA,SAASC,IAAY;AACnB,SACE,gBAAAD,EAAC,SAAI,OAAM,MAAK,QAAO,MAAK,SAAQ,aAAY,MAAK,QAAO,eAAY,QACtE,UAAA,gBAAAA,EAAC,QAAA,EAAK,GAAE,sBAAqB,QAAO,gBAAe,aAAY,OAAM,eAAc,QAAA,CAAQ,EAAA,CAC7F;AAEJ;AAEO,MAAME,IAAcC,EAA+C,SACxE;AAAA,EACE,OAAOC;AAAA,EACP,cAAAC,IAAe;AAAA,EACf,eAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,aAAAC,IAAc;AAAA,EACd,aAAAC;AAAA,EACA,YAAAC,IAAa;AAAA,EACb,WAAAC;AAAA,EACA,QAAAC;AAAA,EACA,UAAAC;AAAA,EACA,GAAGC;AACL,GACAC,GACA;AACA,QAAM,CAACC,GAAeC,CAAgB,IAAIC,EAASd,CAAY,GACzDe,IAAehB,MAAoB,QACnCiB,IAAQD,IAAehB,IAAkBa,GAEzCK,IAAeC;AAAA,IACnB,CAACC,MAAqC;AACpC,MAAKJ,KAAcF,EAAiBM,EAAE,OAAO,KAAK,GAClDlB,IAAgBkB,EAAE,OAAO,KAAK;AAAA,IAChC;AAAA,IACA,CAACJ,GAAcd,CAAa;AAAA,EAAA,GAGxBmB,IAAcF,EAAY,MAAM;AACpC,IAAKH,KAAcF,EAAiB,EAAE,GACtCZ,IAAgB,EAAE,GAClBC,IAAA;AAAA,EACF,GAAG,CAACa,GAAcd,GAAeC,CAAO,CAAC;AAEzC,SACE,gBAAAP;AAAA,IAAC0B;AAAA,IAAA;AAAA,MACC,KAAAV;AAAA,MACA,MAAK;AAAA,MACL,MAAK;AAAA,MACL,MAAAR;AAAA,MACA,aAAAC;AAAA,MACA,OAAAY;AAAA,MACA,UAAUC;AAAA,MACV,UAAAR;AAAA,MACA,WAAAF;AAAA,MACA,QAAAC;AAAA,MACA,aAAaH,KAAe,gBAAAV,EAACF,GAAA,CAAA,CAAW;AAAA,MACxC,cACEuB,KAAS,CAACP,IACR,gBAAAd;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,cAAYW;AAAA,UACZ,SAASc;AAAA,UACT,UAAU;AAAA,UAEV,4BAACxB,GAAA,CAAA,CAAU;AAAA,QAAA;AAAA,MAAA,IAEX;AAAA,MAEL,GAAGc;AAAA,IAAA;AAAA,EAAA;AAGV,CAAC;AAEDb,EAAY,cAAc;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),u=require("react"),L=require("../../../utils/styles.cjs"),R={sm:{height:32,fontSize:13,padding:10},md:{height:40,fontSize:14,padding:12},lg:{height:48,fontSize:15,padding:14}};function q(){return e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:e.jsx("path",{d:"M2.5 4.5L6 8L9.5 4.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const p=u.forwardRef(function({size:c="md",variant:n="outline",isInvalid:s,placeholder:a,className:b,style:f,testId:y,disabled:o,children:g,onFocus:h,onBlur:k,value:i,...S},m){const[d,l]=u.useState(!1),t=R[c],x=i!==void 0&&i!=="",v={position:"relative",display:"inline-flex",width:"100%"},w=()=>{const r={width:"100%",height:t.height,paddingLeft:t.padding,paddingRight:t.padding+24,fontSize:t.fontSize,fontFamily:"var(--brycks-font-sans)",color:x||!a?"var(--brycks-foreground-default)":"var(--brycks-foreground-muted)",backgroundColor:n==="filled"?"var(--brycks-background-muted)":"var(--brycks-background-app)",border:`1px solid ${s?"var(--brycks-error-default)":d?"var(--brycks-border-focus)":n==="filled"?"transparent":"var(--brycks-border-default)"}`,borderRadius:"var(--brycks-radius-default)",outline:"none",cursor:o?"not-allowed":"pointer",appearance:"none",WebkitAppearance:"none",transition:"all 200ms ease-out",boxShadow:d?s?"0 0 0 3px rgba(239, 68, 68, 0.15)":"0 0 0 3px rgba(85, 120, 244, 0.15)":"none"};return o&&(r.opacity=.5),r},j={position:"absolute",right:t.padding,top:"50%",transform:"translateY(-50%)",pointerEvents:"none",color:"var(--brycks-foreground-muted)",transition:"transform 200ms ease-out"},z=r=>{l(!0),h?.(r)},F=r=>{l(!1),k?.(r)};return e.jsxs("div",{className:L.cx("brycks-select-wrapper",`brycks-select-wrapper--${n}`,`brycks-select-wrapper--${c}`,s&&"brycks-select-wrapper--invalid",o&&"brycks-select-wrapper--disabled",b),style:{...v,...f},children:[e.jsxs("select",{ref:m,className:"brycks-select",style:w(),disabled:o,"aria-invalid":s,"data-testid":y,value:i,onFocus:z,onBlur:F,...S,children:[a&&e.jsx("option",{value:"",disabled:!0,children:a}),g]}),e.jsx("span",{style:j,children:e.jsx(q,{})})]})});p.displayName="Select";exports.Select=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("react"),n=require("../../../utils/styles.cjs");function x(){return e.jsx("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:e.jsx("path",{d:"M2.5 4.5L6 8L9.5 4.5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}const l=b.forwardRef(function({size:o="md",variant:i="outline",isInvalid:t,placeholder:s,className:a,style:d,testId:u,disabled:c,children:p,value:r,...h},k){const y=!(r!==void 0&&r!=="")&&!!s;return e.jsxs("div",{className:n.cx("brycks-select-wrapper",`brycks-select-wrapper--${i}`,`brycks-select-wrapper--${o}`,t&&"brycks-select-wrapper--invalid",c&&"brycks-select-wrapper--disabled",a),style:d,children:[e.jsxs("select",{ref:k,className:n.cx("brycks-select",y&&"brycks-select--placeholder"),disabled:c,"aria-invalid":t,"data-testid":u,value:r,...h,children:[s&&e.jsx("option",{value:"",disabled:!0,children:s}),p]}),e.jsx("span",{className:"brycks-select-icon",children:e.jsx(x,{})})]})});l.displayName="Select";exports.Select=l;
2
2
  //# sourceMappingURL=Select.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Select.cjs","sources":["../../../../src/components/form/Select/Select.tsx"],"sourcesContent":["/**\r\n * Select Component\r\n *\r\n * Native select with custom styling for cross-browser consistency.\r\n * Maintains accessibility while providing Apple-inspired visuals.\r\n */\r\n\r\nimport {\r\n forwardRef,\r\n useState,\r\n type CSSProperties,\r\n type SelectHTMLAttributes,\r\n type ReactNode,\r\n} from 'react'\r\nimport { cx } from '../../../utils/styles'\r\n\r\nexport type SelectSize = 'sm' | 'md' | 'lg'\r\nexport type SelectVariant = 'outline' | 'filled'\r\n\r\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\r\n /** Select size */\r\n size?: SelectSize\r\n /** Visual variant */\r\n variant?: SelectVariant\r\n /** Error state */\r\n isInvalid?: boolean\r\n /** Placeholder option */\r\n placeholder?: string\r\n /** Custom class name */\r\n className?: string\r\n /** Test ID */\r\n testId?: string\r\n /** Children (option elements) */\r\n children?: ReactNode\r\n}\r\n\r\nconst sizeStyles: Record<SelectSize, { height: number; fontSize: number; padding: number }> = {\r\n sm: { height: 32, fontSize: 13, padding: 10 },\r\n md: { height: 40, fontSize: 14, padding: 12 },\r\n lg: { height: 48, fontSize: 15, padding: 14 },\r\n}\r\n\r\n/** Chevron down icon */\r\nfunction ChevronIcon() {\r\n return (\r\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\r\n <path\r\n d=\"M2.5 4.5L6 8L9.5 4.5\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"1.5\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n />\r\n </svg>\r\n )\r\n}\r\n\r\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select(\r\n {\r\n size = 'md',\r\n variant = 'outline',\r\n isInvalid,\r\n placeholder,\r\n className,\r\n style,\r\n testId,\r\n disabled,\r\n children,\r\n onFocus,\r\n onBlur,\r\n value,\r\n ...props\r\n },\r\n ref\r\n) {\r\n const [isFocused, setIsFocused] = useState(false)\r\n\r\n const sizeValue = sizeStyles[size]\r\n const hasValue = value !== undefined && value !== ''\r\n\r\n const wrapperStyle: CSSProperties = {\r\n position: 'relative',\r\n display: 'inline-flex',\r\n width: '100%',\r\n }\r\n\r\n const getSelectStyle = (): CSSProperties => {\r\n const base: CSSProperties = {\r\n width: '100%',\r\n height: sizeValue.height,\r\n paddingLeft: sizeValue.padding,\r\n paddingRight: sizeValue.padding + 24,\r\n fontSize: sizeValue.fontSize,\r\n fontFamily: 'var(--brycks-font-sans)',\r\n color: hasValue || !placeholder ? 'var(--brycks-foreground-default)' : 'var(--brycks-foreground-muted)',\r\n backgroundColor: variant === 'filled' ? 'var(--brycks-background-muted)' : 'var(--brycks-background-app)',\r\n border: `1px solid ${\r\n isInvalid\r\n ? 'var(--brycks-error-default)'\r\n : isFocused\r\n ? 'var(--brycks-border-focus)'\r\n : variant === 'filled'\r\n ? 'transparent'\r\n : 'var(--brycks-border-default)'\r\n }`,\r\n borderRadius: 'var(--brycks-radius-default)',\r\n outline: 'none',\r\n cursor: disabled ? 'not-allowed' : 'pointer',\r\n appearance: 'none',\r\n WebkitAppearance: 'none',\r\n transition: 'all 200ms ease-out',\r\n boxShadow: isFocused\r\n ? isInvalid\r\n ? '0 0 0 3px rgba(239, 68, 68, 0.15)'\r\n : '0 0 0 3px rgba(85, 120, 244, 0.15)'\r\n : 'none',\r\n }\r\n\r\n if (disabled) {\r\n base.opacity = 0.5\r\n }\r\n\r\n return base\r\n }\r\n\r\n const iconStyle: CSSProperties = {\r\n position: 'absolute',\r\n right: sizeValue.padding,\r\n top: '50%',\r\n transform: 'translateY(-50%)',\r\n pointerEvents: 'none',\r\n color: 'var(--brycks-foreground-muted)',\r\n transition: 'transform 200ms ease-out',\r\n }\r\n\r\n const handleFocus = (e: React.FocusEvent<HTMLSelectElement>) => {\r\n setIsFocused(true)\r\n onFocus?.(e)\r\n }\r\n\r\n const handleBlur = (e: React.FocusEvent<HTMLSelectElement>) => {\r\n setIsFocused(false)\r\n onBlur?.(e)\r\n }\r\n\r\n return (\r\n <div\r\n className={cx(\r\n 'brycks-select-wrapper',\r\n `brycks-select-wrapper--${variant}`,\r\n `brycks-select-wrapper--${size}`,\r\n isInvalid && 'brycks-select-wrapper--invalid',\r\n disabled && 'brycks-select-wrapper--disabled',\r\n className\r\n )}\r\n style={{ ...wrapperStyle, ...style }}\r\n >\r\n <select\r\n ref={ref}\r\n className=\"brycks-select\"\r\n style={getSelectStyle()}\r\n disabled={disabled}\r\n aria-invalid={isInvalid}\r\n data-testid={testId}\r\n value={value}\r\n onFocus={handleFocus}\r\n onBlur={handleBlur}\r\n {...props}\r\n >\r\n {placeholder && (\r\n <option value=\"\" disabled>\r\n {placeholder}\r\n </option>\r\n )}\r\n {children}\r\n </select>\r\n\r\n <span style={iconStyle}>\r\n <ChevronIcon />\r\n </span>\r\n </div>\r\n )\r\n})\r\n\r\nSelect.displayName = 'Select'\r\n"],"names":["sizeStyles","ChevronIcon","jsx","Select","forwardRef","size","variant","isInvalid","placeholder","className","style","testId","disabled","children","onFocus","onBlur","value","props","ref","isFocused","setIsFocused","useState","sizeValue","hasValue","wrapperStyle","getSelectStyle","base","iconStyle","handleFocus","e","handleBlur","jsxs","cx"],"mappings":"+KAoCMA,EAAwF,CAC5F,GAAI,CAAE,OAAQ,GAAI,SAAU,GAAI,QAAS,EAAA,EACzC,GAAI,CAAE,OAAQ,GAAI,SAAU,GAAI,QAAS,EAAA,EACzC,GAAI,CAAE,OAAQ,GAAI,SAAU,GAAI,QAAS,EAAA,CAC3C,EAGA,SAASC,GAAc,CACrB,OACEC,EAAAA,IAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,EAAAA,IAAC,OAAA,CACC,EAAE,uBACF,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,OAAA,CAAA,EAEnB,CAEJ,CAEO,MAAMC,EAASC,EAAAA,WAA2C,SAC/D,CACE,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,UAAAC,EACA,YAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,QAAAC,EACA,OAAAC,EACA,MAAAC,EACA,GAAGC,CACL,EACAC,EACA,CACA,KAAM,CAACC,EAAWC,CAAY,EAAIC,EAAAA,SAAS,EAAK,EAE1CC,EAAYtB,EAAWK,CAAI,EAC3BkB,EAAWP,IAAU,QAAaA,IAAU,GAE5CQ,EAA8B,CAClC,SAAU,WACV,QAAS,cACT,MAAO,MAAA,EAGHC,EAAiB,IAAqB,CAC1C,MAAMC,EAAsB,CAC1B,MAAO,OACP,OAAQJ,EAAU,OAClB,YAAaA,EAAU,QACvB,aAAcA,EAAU,QAAU,GAClC,SAAUA,EAAU,SACpB,WAAY,0BACZ,MAAOC,GAAY,CAACf,EAAc,mCAAqC,iCACvE,gBAAiBF,IAAY,SAAW,iCAAmC,+BAC3E,OAAQ,aACNC,EACI,8BACAY,EACE,6BACAb,IAAY,SACV,cACA,8BACV,GACA,aAAc,+BACd,QAAS,OACT,OAAQM,EAAW,cAAgB,UACnC,WAAY,OACZ,iBAAkB,OAClB,WAAY,qBACZ,UAAWO,EACPZ,EACE,oCACA,qCACF,MAAA,EAGN,OAAIK,IACFc,EAAK,QAAU,IAGVA,CACT,EAEMC,EAA2B,CAC/B,SAAU,WACV,MAAOL,EAAU,QACjB,IAAK,MACL,UAAW,mBACX,cAAe,OACf,MAAO,iCACP,WAAY,0BAAA,EAGRM,EAAeC,GAA2C,CAC9DT,EAAa,EAAI,EACjBN,IAAUe,CAAC,CACb,EAEMC,EAAcD,GAA2C,CAC7DT,EAAa,EAAK,EAClBL,IAASc,CAAC,CACZ,EAEA,OACEE,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,wBACA,0BAA0B1B,CAAO,GACjC,0BAA0BD,CAAI,GAC9BE,GAAa,iCACbK,GAAY,kCACZH,CAAA,EAEF,MAAO,CAAE,GAAGe,EAAc,GAAGd,CAAA,EAE7B,SAAA,CAAAqB,EAAAA,KAAC,SAAA,CACC,IAAAb,EACA,UAAU,gBACV,MAAOO,EAAA,EACP,SAAAb,EACA,eAAcL,EACd,cAAaI,EACb,MAAAK,EACA,QAASY,EACT,OAAQE,EACP,GAAGb,EAEH,SAAA,CAAAT,SACE,SAAA,CAAO,MAAM,GAAG,SAAQ,GACtB,SAAAA,EACH,EAEDK,CAAA,CAAA,CAAA,QAGF,OAAA,CAAK,MAAOc,EACX,SAAAzB,EAAAA,IAACD,IAAY,CAAA,CACf,CAAA,CAAA,CAAA,CAGN,CAAC,EAEDE,EAAO,YAAc"}
1
+ {"version":3,"file":"Select.cjs","sources":["../../../../src/components/form/Select/Select.tsx"],"sourcesContent":["/**\n * Select Component\n *\n * Native select with custom styling for cross-browser consistency.\n * Maintains accessibility while providing Apple-inspired visuals.\n */\n\nimport {\n forwardRef,\n type SelectHTMLAttributes,\n type ReactNode,\n} from 'react'\nimport { cx } from '../../../utils/styles'\n\nexport type SelectSize = 'sm' | 'md' | 'lg'\nexport type SelectVariant = 'outline' | 'filled'\n\nexport interface SelectProps extends Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> {\n /** Select size */\n size?: SelectSize\n /** Visual variant */\n variant?: SelectVariant\n /** Error state */\n isInvalid?: boolean\n /** Placeholder option */\n placeholder?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n /** Children (option elements) */\n children?: ReactNode\n}\n\n/** Chevron down icon */\nfunction ChevronIcon() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\n <path\n d=\"M2.5 4.5L6 8L9.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )\n}\n\nexport const Select = forwardRef<HTMLSelectElement, SelectProps>(function Select(\n {\n size = 'md',\n variant = 'outline',\n isInvalid,\n placeholder,\n className,\n style,\n testId,\n disabled,\n children,\n value,\n ...props\n },\n ref\n) {\n const hasValue = value !== undefined && value !== ''\n const showPlaceholderColor = !hasValue && !!placeholder\n\n return (\n <div\n className={cx(\n 'brycks-select-wrapper',\n `brycks-select-wrapper--${variant}`,\n `brycks-select-wrapper--${size}`,\n isInvalid && 'brycks-select-wrapper--invalid',\n disabled && 'brycks-select-wrapper--disabled',\n className\n )}\n style={style}\n >\n <select\n ref={ref}\n className={cx('brycks-select', showPlaceholderColor && 'brycks-select--placeholder')}\n disabled={disabled}\n aria-invalid={isInvalid}\n data-testid={testId}\n value={value}\n {...props}\n >\n {placeholder && (\n <option value=\"\" disabled>\n {placeholder}\n </option>\n )}\n {children}\n </select>\n\n <span className=\"brycks-select-icon\">\n <ChevronIcon />\n </span>\n </div>\n )\n})\n\nSelect.displayName = 'Select'\n"],"names":["ChevronIcon","jsx","Select","forwardRef","size","variant","isInvalid","placeholder","className","style","testId","disabled","children","value","props","ref","showPlaceholderColor","jsxs","cx"],"mappings":"+KAmCA,SAASA,GAAc,CACrB,OACEC,EAAAA,IAAC,OAAI,MAAM,KAAK,OAAO,KAAK,QAAQ,YAAY,KAAK,OACnD,SAAAA,EAAAA,IAAC,OAAA,CACC,EAAE,uBACF,OAAO,eACP,YAAY,MACZ,cAAc,QACd,eAAe,OAAA,CAAA,EAEnB,CAEJ,CAEO,MAAMC,EAASC,EAAAA,WAA2C,SAC/D,CACE,KAAAC,EAAO,KACP,QAAAC,EAAU,UACV,UAAAC,EACA,YAAAC,EACA,UAAAC,EACA,MAAAC,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,EACA,MAAAC,EACA,GAAGC,CACL,EACAC,EACA,CAEA,MAAMC,EAAuB,EADZH,IAAU,QAAaA,IAAU,KACR,CAAC,CAACN,EAE5C,OACEU,EAAAA,KAAC,MAAA,CACC,UAAWC,EAAAA,GACT,wBACA,0BAA0Bb,CAAO,GACjC,0BAA0BD,CAAI,GAC9BE,GAAa,iCACbK,GAAY,kCACZH,CAAA,EAEF,MAAAC,EAEA,SAAA,CAAAQ,EAAAA,KAAC,SAAA,CACC,IAAAF,EACA,UAAWG,EAAAA,GAAG,gBAAiBF,GAAwB,4BAA4B,EACnF,SAAAL,EACA,eAAcL,EACd,cAAaI,EACb,MAAAG,EACC,GAAGC,EAEH,SAAA,CAAAP,SACE,SAAA,CAAO,MAAM,GAAG,SAAQ,GACtB,SAAAA,EACH,EAEDK,CAAA,CAAA,CAAA,QAGF,OAAA,CAAK,UAAU,qBACd,SAAAX,EAAAA,IAACD,IAAY,CAAA,CACf,CAAA,CAAA,CAAA,CAGN,CAAC,EAEDE,EAAO,YAAc"}