@spear-ai/spectral 1.22.5 → 1.22.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Accordion.d.ts.map +1 -1
- package/dist/Accordion.js +1 -1
- package/dist/Accordion.js.map +1 -1
- package/dist/Alert/AlertBase.d.ts.map +1 -1
- package/dist/Alert/AlertBase.js +2 -3
- package/dist/Alert/AlertBase.js.map +1 -1
- package/dist/Alert.js.map +1 -1
- package/dist/AlertDialog.d.ts.map +1 -1
- package/dist/AlertDialog.js +8 -8
- package/dist/AlertDialog.js.map +1 -1
- package/dist/Avatar.js +4 -4
- package/dist/Avatar.js.map +1 -1
- package/dist/Badge.d.ts.map +1 -1
- package/dist/Badge.js.map +1 -1
- package/dist/Button.d.ts +2 -2
- package/dist/Button.d.ts.map +1 -1
- package/dist/Button.js +6 -9
- package/dist/Button.js.map +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.js +1 -2
- package/dist/ButtonGroup/ButtonGroupButton.js.map +1 -1
- package/dist/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup.js +1 -1
- package/dist/ButtonGroup.js.map +1 -1
- package/dist/ButtonIcon.d.ts +4 -0
- package/dist/ButtonIcon.d.ts.map +1 -1
- package/dist/ButtonIcon.js +7 -2
- package/dist/ButtonIcon.js.map +1 -1
- package/dist/Card.d.ts +43 -0
- package/dist/Card.d.ts.map +1 -0
- package/dist/{DataCard/Card.js → Card.js} +20 -20
- package/dist/Card.js.map +1 -0
- package/dist/Checkbox/CheckboxBase.js +1 -1
- package/dist/Checkbox/CheckboxBase.js.map +1 -1
- package/dist/Checkbox.js +1 -1
- package/dist/Checkbox.js.map +1 -1
- package/dist/Combobox.js.map +1 -1
- package/dist/ControlGroup/ControlGroupSelect.js.map +1 -1
- package/dist/ControlGroup.d.ts.map +1 -1
- package/dist/ControlGroup.js +1 -1
- package/dist/ControlGroup.js.map +1 -1
- package/dist/DateTimePicker/Calendar.js.map +1 -1
- package/dist/DateTimePicker/DateTimeDisplayInput.js.map +1 -1
- package/dist/DateTimePicker/TimePeriodSelect.js +1 -1
- package/dist/DateTimePicker/TimePeriodSelect.js.map +1 -1
- package/dist/DateTimePicker/TimePicker.js.map +1 -1
- package/dist/DateTimePicker.d.ts +1 -1
- package/dist/DateTimePicker.js.map +1 -1
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js +3 -3
- package/dist/Dialog.js.map +1 -1
- package/dist/DirectionalColorWheel/DirectionalColorWheelDisclosure.js +1 -1
- package/dist/DirectionalColorWheel/DirectionalColorWheelDisclosure.js.map +1 -1
- package/dist/Drawer.d.ts.map +1 -1
- package/dist/Drawer.js.map +1 -1
- package/dist/DropdownMenu.js.map +1 -1
- package/dist/HoverCard.d.ts.map +1 -1
- package/dist/HoverCard.js.map +1 -1
- package/dist/Icons/AdjustmentsIcon.d.ts.map +1 -1
- package/dist/Icons/AdjustmentsIcon.js +11 -20
- package/dist/Icons/AdjustmentsIcon.js.map +1 -1
- package/dist/Icons/AnalyzeIcon.d.ts.map +1 -1
- package/dist/Icons/AnalyzeIcon.js +4 -9
- package/dist/Icons/AnalyzeIcon.js.map +1 -1
- package/dist/Icons/AnnotationsIcon.d.ts +2 -17
- package/dist/Icons/AnnotationsIcon.js +2 -25
- package/dist/Icons/ApprovedIcon.d.ts.map +1 -1
- package/dist/Icons/ApprovedIcon.js +4 -6
- package/dist/Icons/ApprovedIcon.js.map +1 -1
- package/dist/Icons/ArrowDownIcon.d.ts.map +1 -1
- package/dist/Icons/ArrowDownIcon.js +24 -11
- package/dist/Icons/ArrowDownIcon.js.map +1 -1
- package/dist/Icons/ArrowUpIcon.d.ts.map +1 -1
- package/dist/Icons/ArrowUpIcon.js +24 -11
- package/dist/Icons/ArrowUpIcon.js.map +1 -1
- package/dist/Icons/BoxToolIcon.d.ts.map +1 -1
- package/dist/Icons/BoxToolIcon.js +2 -2
- package/dist/Icons/BoxToolIcon.js.map +1 -1
- package/dist/Icons/{PanelIconOpen.d.ts → BuoyIcon.d.ts} +4 -4
- package/dist/Icons/BuoyIcon.d.ts.map +1 -0
- package/dist/Icons/BuoyIcon.js +40 -0
- package/dist/Icons/BuoyIcon.js.map +1 -0
- package/dist/Icons/CalendarIcon.d.ts.map +1 -1
- package/dist/Icons/CalendarIcon.js +5 -9
- package/dist/Icons/CalendarIcon.js.map +1 -1
- package/dist/Icons/CheckCircleIcon.d.ts.map +1 -1
- package/dist/Icons/CheckCircleIcon.js +13 -15
- package/dist/Icons/CheckCircleIcon.js.map +1 -1
- package/dist/Icons/CheckSquareIcon.d.ts.map +1 -1
- package/dist/Icons/CheckSquareIcon.js +25 -17
- package/dist/Icons/CheckSquareIcon.js.map +1 -1
- package/dist/Icons/CheckmarkIcon.d.ts +0 -1
- package/dist/Icons/CheckmarkIcon.d.ts.map +1 -1
- package/dist/Icons/CheckmarkIcon.js +11 -14
- package/dist/Icons/CheckmarkIcon.js.map +1 -1
- package/dist/Icons/ChevronDownIcon.d.ts.map +1 -1
- package/dist/Icons/ChevronDownIcon.js +10 -13
- package/dist/Icons/ChevronDownIcon.js.map +1 -1
- package/dist/Icons/ChevronUpIcon.d.ts.map +1 -1
- package/dist/Icons/ChevronUpIcon.js +10 -13
- package/dist/Icons/ChevronUpIcon.js.map +1 -1
- package/dist/Icons/{PanelIconClose.d.ts → CircleDotIcon.d.ts} +4 -4
- package/dist/Icons/CircleDotIcon.d.ts.map +1 -0
- package/dist/Icons/CircleDotIcon.js +31 -0
- package/dist/Icons/CircleDotIcon.js.map +1 -0
- package/dist/Icons/ClockIcon.d.ts.map +1 -1
- package/dist/Icons/ClockIcon.js +2 -4
- package/dist/Icons/ClockIcon.js.map +1 -1
- package/dist/Icons/CloseCircleIcon.d.ts.map +1 -1
- package/dist/Icons/CloseCircleIcon.js +19 -12
- package/dist/Icons/CloseCircleIcon.js.map +1 -1
- package/dist/Icons/CloseIcon.d.ts.map +1 -1
- package/dist/Icons/CloseIcon.js +13 -7
- package/dist/Icons/CloseIcon.js.map +1 -1
- package/dist/Icons/Crosshairs2Icon.d.ts.map +1 -1
- package/dist/Icons/Crosshairs2Icon.js +2 -7
- package/dist/Icons/Crosshairs2Icon.js.map +1 -1
- package/dist/Icons/CrosshairsIcon.d.ts.map +1 -1
- package/dist/Icons/CrosshairsIcon.js +2 -3
- package/dist/Icons/CrosshairsIcon.js.map +1 -1
- package/dist/Icons/DashboardIcon.d.ts.map +1 -1
- package/dist/Icons/DashboardIcon.js +2 -5
- package/dist/Icons/DashboardIcon.js.map +1 -1
- package/dist/Icons/DatabaseIcon.d.ts.map +1 -1
- package/dist/Icons/DatabaseIcon.js +2 -5
- package/dist/Icons/DatabaseIcon.js.map +1 -1
- package/dist/Icons/DeleteIcon.d.ts.map +1 -1
- package/dist/Icons/DeleteIcon.js +5 -8
- package/dist/Icons/DeleteIcon.js.map +1 -1
- package/dist/Icons/DeploymentsIcon.d.ts +18 -0
- package/dist/Icons/DeploymentsIcon.d.ts.map +1 -0
- package/dist/Icons/DeploymentsIcon.js +46 -0
- package/dist/Icons/DeploymentsIcon.js.map +1 -0
- package/dist/Icons/DotIcon.d.ts +18 -0
- package/dist/Icons/DotIcon.d.ts.map +1 -0
- package/dist/Icons/DotIcon.js +24 -0
- package/dist/Icons/DotIcon.js.map +1 -0
- package/dist/Icons/DurationIcon.d.ts.map +1 -1
- package/dist/Icons/DurationIcon.js +2 -8
- package/dist/Icons/DurationIcon.js.map +1 -1
- package/dist/Icons/EditIcon.d.ts.map +1 -1
- package/dist/Icons/EditIcon.js +7 -14
- package/dist/Icons/EditIcon.js.map +1 -1
- package/dist/Icons/EmailIcon.d.ts.map +1 -1
- package/dist/Icons/EmailIcon.js +13 -15
- package/dist/Icons/EmailIcon.js.map +1 -1
- package/dist/Icons/EraserIcon.d.ts.map +1 -1
- package/dist/Icons/EraserIcon.js +7 -11
- package/dist/Icons/EraserIcon.js.map +1 -1
- package/dist/Icons/ErrorIcon.d.ts.map +1 -1
- package/dist/Icons/ErrorIcon.js +18 -12
- package/dist/Icons/ErrorIcon.js.map +1 -1
- package/dist/Icons/EyeClosedIcon.d.ts.map +1 -1
- package/dist/Icons/EyeClosedIcon.js +30 -14
- package/dist/Icons/EyeClosedIcon.js.map +1 -1
- package/dist/Icons/EyeClosedIcon2.d.ts.map +1 -1
- package/dist/Icons/EyeClosedIcon2.js +24 -12
- package/dist/Icons/EyeClosedIcon2.js.map +1 -1
- package/dist/Icons/EyeOpenIcon.d.ts.map +1 -1
- package/dist/Icons/EyeOpenIcon.js +12 -10
- package/dist/Icons/EyeOpenIcon.js.map +1 -1
- package/dist/Icons/FileDownloadIcon.d.ts.map +1 -1
- package/dist/Icons/FileDownloadIcon.js +2 -6
- package/dist/Icons/FileDownloadIcon.js.map +1 -1
- package/dist/Icons/GeofenceIcon.d.ts +18 -0
- package/dist/Icons/GeofenceIcon.d.ts.map +1 -0
- package/dist/Icons/GeofenceIcon.js +38 -0
- package/dist/Icons/GeofenceIcon.js.map +1 -0
- package/dist/Icons/GeospatialIcon.d.ts +18 -0
- package/dist/Icons/GeospatialIcon.d.ts.map +1 -0
- package/dist/Icons/GeospatialIcon.js +53 -0
- package/dist/Icons/GeospatialIcon.js.map +1 -0
- package/dist/Icons/GlobeIcon.d.ts +18 -0
- package/dist/Icons/GlobeIcon.d.ts.map +1 -0
- package/dist/Icons/GlobeIcon.js +52 -0
- package/dist/Icons/GlobeIcon.js.map +1 -0
- package/dist/Icons/GoToFirstIcon.d.ts.map +1 -1
- package/dist/Icons/GoToFirstIcon.js +2 -4
- package/dist/Icons/GoToFirstIcon.js.map +1 -1
- package/dist/Icons/GoToLastIcon.d.ts.map +1 -1
- package/dist/Icons/GoToLastIcon.js +2 -4
- package/dist/Icons/GoToLastIcon.js.map +1 -1
- package/dist/Icons/GpsIcon.d.ts +18 -0
- package/dist/Icons/GpsIcon.d.ts.map +1 -0
- package/dist/Icons/GpsIcon.js +31 -0
- package/dist/Icons/GpsIcon.js.map +1 -0
- package/dist/Icons/HarmonicCursorsIcon.d.ts.map +1 -1
- package/dist/Icons/HarmonicCursorsIcon.js +2 -2
- package/dist/Icons/HarmonicCursorsIcon.js.map +1 -1
- package/dist/Icons/IconBase.d.ts +11 -8
- package/dist/Icons/IconBase.d.ts.map +1 -1
- package/dist/Icons/IconBase.js +3 -2
- package/dist/Icons/IconBase.js.map +1 -1
- package/dist/Icons/InfoIcon.d.ts.map +1 -1
- package/dist/Icons/InfoIcon.js +33 -26
- package/dist/Icons/InfoIcon.js.map +1 -1
- package/dist/Icons/IterationArrowIcon.d.ts.map +1 -1
- package/dist/Icons/IterationArrowIcon.js +2 -5
- package/dist/Icons/IterationArrowIcon.js.map +1 -1
- package/dist/Icons/KeyIcon.d.ts +18 -0
- package/dist/Icons/KeyIcon.d.ts.map +1 -0
- package/dist/Icons/KeyIcon.js +46 -0
- package/dist/Icons/KeyIcon.js.map +1 -0
- package/dist/Icons/KeyboardIcon.d.ts.map +1 -1
- package/dist/Icons/KeyboardIcon.js +4 -4
- package/dist/Icons/KeyboardIcon.js.map +1 -1
- package/dist/Icons/LabelIcon.d.ts.map +1 -1
- package/dist/Icons/LabelIcon.js +2 -3
- package/dist/Icons/LabelIcon.js.map +1 -1
- package/dist/Icons/LassoIcon.d.ts.map +1 -1
- package/dist/Icons/LassoIcon.js +5 -8
- package/dist/Icons/LassoIcon.js.map +1 -1
- package/dist/Icons/LineDashedIcon.d.ts +18 -0
- package/dist/Icons/LineDashedIcon.d.ts.map +1 -0
- package/dist/Icons/LineDashedIcon.js +50 -0
- package/dist/Icons/LineDashedIcon.js.map +1 -0
- package/dist/Icons/LineToolIcon.d.ts.map +1 -1
- package/dist/Icons/LineToolIcon.js +11 -14
- package/dist/Icons/LineToolIcon.js.map +1 -1
- package/dist/Icons/LinkIcon.d.ts.map +1 -1
- package/dist/Icons/LinkIcon.js +5 -8
- package/dist/Icons/LinkIcon.js.map +1 -1
- package/dist/Icons/LiveViewIcon.d.ts.map +1 -1
- package/dist/Icons/LiveViewIcon.js +14 -12
- package/dist/Icons/LiveViewIcon.js.map +1 -1
- package/dist/Icons/LoaderIcon.d.ts.map +1 -1
- package/dist/Icons/LoaderIcon.js +5 -7
- package/dist/Icons/LoaderIcon.js.map +1 -1
- package/dist/Icons/LocationIcon.d.ts.map +1 -1
- package/dist/Icons/LocationIcon.js +2 -4
- package/dist/Icons/LocationIcon.js.map +1 -1
- package/dist/Icons/LockIcon.d.ts.map +1 -1
- package/dist/Icons/LockIcon.js +2 -3
- package/dist/Icons/LockIcon.js.map +1 -1
- package/dist/Icons/LogoutIcon.d.ts.map +1 -1
- package/dist/Icons/LogoutIcon.js +3 -4
- package/dist/Icons/LogoutIcon.js.map +1 -1
- package/dist/Icons/MapIcon.d.ts +18 -0
- package/dist/Icons/MapIcon.d.ts.map +1 -0
- package/dist/Icons/MapIcon.js +40 -0
- package/dist/Icons/MapIcon.js.map +1 -0
- package/dist/Icons/MapPinIcon.d.ts +18 -0
- package/dist/Icons/MapPinIcon.d.ts.map +1 -0
- package/dist/Icons/MapPinIcon.js +31 -0
- package/dist/Icons/MapPinIcon.js.map +1 -0
- package/dist/Icons/MaximizeIcon.d.ts.map +1 -1
- package/dist/Icons/MaximizeIcon.js +2 -6
- package/dist/Icons/MaximizeIcon.js.map +1 -1
- package/dist/Icons/MeasureIcon.d.ts.map +1 -1
- package/dist/Icons/MeasureIcon.js +2 -11
- package/dist/Icons/MeasureIcon.js.map +1 -1
- package/dist/Icons/MenuDotsIcon.d.ts.map +1 -1
- package/dist/Icons/MenuDotsIcon.js +2 -5
- package/dist/Icons/MenuDotsIcon.js.map +1 -1
- package/dist/Icons/MenuIcon.d.ts.map +1 -1
- package/dist/Icons/MenuIcon.js +5 -8
- package/dist/Icons/MenuIcon.js.map +1 -1
- package/dist/Icons/MessagesIcon.d.ts.map +1 -1
- package/dist/Icons/MessagesIcon.js +5 -8
- package/dist/Icons/MessagesIcon.js.map +1 -1
- package/dist/Icons/MetadataIcon.d.ts.map +1 -1
- package/dist/Icons/MetadataIcon.js +2 -3
- package/dist/Icons/MetadataIcon.js.map +1 -1
- package/dist/Icons/MinimizeIcon.d.ts.map +1 -1
- package/dist/Icons/MinimizeIcon.js +2 -6
- package/dist/Icons/MinimizeIcon.js.map +1 -1
- package/dist/Icons/MinusIcon.d.ts.map +1 -1
- package/dist/Icons/MinusIcon.js +8 -7
- package/dist/Icons/MinusIcon.js.map +1 -1
- package/dist/Icons/OntologyIcon.d.ts.map +1 -1
- package/dist/Icons/OntologyIcon.js +8 -19
- package/dist/Icons/OntologyIcon.js.map +1 -1
- package/dist/Icons/PanelCloseIcon.d.ts +18 -0
- package/dist/Icons/PanelCloseIcon.d.ts.map +1 -0
- package/dist/Icons/PanelCloseIcon.js +40 -0
- package/dist/Icons/PanelCloseIcon.js.map +1 -0
- package/dist/Icons/PanelOpenIcon.d.ts +18 -0
- package/dist/Icons/PanelOpenIcon.d.ts.map +1 -0
- package/dist/Icons/PanelOpenIcon.js +40 -0
- package/dist/Icons/PanelOpenIcon.js.map +1 -0
- package/dist/Icons/PaperclipIcon.d.ts +18 -0
- package/dist/Icons/PaperclipIcon.d.ts.map +1 -0
- package/dist/Icons/PaperclipIcon.js +26 -0
- package/dist/Icons/PaperclipIcon.js.map +1 -0
- package/dist/Icons/PathIcon.d.ts +18 -0
- package/dist/Icons/PathIcon.d.ts.map +1 -0
- package/dist/Icons/PathIcon.js +86 -0
- package/dist/Icons/PathIcon.js.map +1 -0
- package/dist/Icons/PauseIcon.d.ts.map +1 -1
- package/dist/Icons/PauseIcon.js +4 -6
- package/dist/Icons/PauseIcon.js.map +1 -1
- package/dist/Icons/PdfIcon.d.ts.map +1 -1
- package/dist/Icons/PdfIcon.js +3 -8
- package/dist/Icons/PdfIcon.js.map +1 -1
- package/dist/Icons/PinIcon.d.ts +18 -0
- package/dist/Icons/PinIcon.d.ts.map +1 -0
- package/dist/Icons/PinIcon.js +40 -0
- package/dist/Icons/PinIcon.js.map +1 -0
- package/dist/Icons/PlayIcon.d.ts.map +1 -1
- package/dist/Icons/PlayIcon.js +3 -5
- package/dist/Icons/PlayIcon.js.map +1 -1
- package/dist/Icons/PlusIcon.d.ts.map +1 -1
- package/dist/Icons/PlusIcon.js +5 -6
- package/dist/Icons/PlusIcon.js.map +1 -1
- package/dist/Icons/PolygonIcon.d.ts +0 -1
- package/dist/Icons/PolygonIcon.d.ts.map +1 -1
- package/dist/Icons/PolygonIcon.js +28 -15
- package/dist/Icons/PolygonIcon.js.map +1 -1
- package/dist/Icons/PrinterIcon.d.ts.map +1 -1
- package/dist/Icons/PrinterIcon.js +3 -4
- package/dist/Icons/PrinterIcon.js.map +1 -1
- package/dist/Icons/ProgressArrowIcon.d.ts.map +1 -1
- package/dist/Icons/ProgressArrowIcon.js +20 -14
- package/dist/Icons/ProgressArrowIcon.js.map +1 -1
- package/dist/Icons/ProgressCheckIcon.d.ts.map +1 -1
- package/dist/Icons/ProgressCheckIcon.js +5 -11
- package/dist/Icons/ProgressCheckIcon.js.map +1 -1
- package/dist/Icons/ResetIcon.d.ts.map +1 -1
- package/dist/Icons/ResetIcon.js +2 -2
- package/dist/Icons/ResetIcon.js.map +1 -1
- package/dist/Icons/ReviewedIcon.d.ts.map +1 -1
- package/dist/Icons/ReviewedIcon.js +2 -5
- package/dist/Icons/ReviewedIcon.js.map +1 -1
- package/dist/Icons/Route2Icon.d.ts +18 -0
- package/dist/Icons/Route2Icon.d.ts.map +1 -0
- package/dist/Icons/Route2Icon.js +40 -0
- package/dist/Icons/Route2Icon.js.map +1 -0
- package/dist/Icons/Route3Icon.d.ts +18 -0
- package/dist/Icons/Route3Icon.d.ts.map +1 -0
- package/dist/Icons/Route3Icon.js +40 -0
- package/dist/Icons/Route3Icon.js.map +1 -0
- package/dist/Icons/RouteIcon.d.ts +18 -0
- package/dist/Icons/RouteIcon.d.ts.map +1 -0
- package/dist/Icons/RouteIcon.js +40 -0
- package/dist/Icons/RouteIcon.js.map +1 -0
- package/dist/Icons/SaveIcon.d.ts +18 -0
- package/dist/Icons/SaveIcon.d.ts.map +1 -0
- package/dist/Icons/SaveIcon.js +26 -0
- package/dist/Icons/SaveIcon.js.map +1 -0
- package/dist/Icons/ScissorsIcon.d.ts.map +1 -1
- package/dist/Icons/ScissorsIcon.js +6 -6
- package/dist/Icons/ScissorsIcon.js.map +1 -1
- package/dist/Icons/SearchIcon.d.ts.map +1 -1
- package/dist/Icons/SearchIcon.js +4 -6
- package/dist/Icons/SearchIcon.js.map +1 -1
- package/dist/Icons/SettingsIcon.d.ts.map +1 -1
- package/dist/Icons/SettingsIcon.js +3 -5
- package/dist/Icons/SettingsIcon.js.map +1 -1
- package/dist/Icons/SortAscendingIcon.d.ts.map +1 -1
- package/dist/Icons/SortAscendingIcon.js +7 -12
- package/dist/Icons/SortAscendingIcon.js.map +1 -1
- package/dist/Icons/SortAtoZIcon.d.ts.map +1 -1
- package/dist/Icons/SortAtoZIcon.js +2 -7
- package/dist/Icons/SortAtoZIcon.js.map +1 -1
- package/dist/Icons/SortDescendingIcon.d.ts.map +1 -1
- package/dist/Icons/SortDescendingIcon.js +6 -11
- package/dist/Icons/SortDescendingIcon.js.map +1 -1
- package/dist/Icons/SortZtoAIcon.d.ts.map +1 -1
- package/dist/Icons/SortZtoAIcon.js +2 -7
- package/dist/Icons/SortZtoAIcon.js.map +1 -1
- package/dist/Icons/SparklesAIIcon.d.ts +18 -0
- package/dist/Icons/SparklesAIIcon.d.ts.map +1 -0
- package/dist/Icons/SparklesAIIcon.js +33 -0
- package/dist/Icons/SparklesAIIcon.js.map +1 -0
- package/dist/Icons/SparklesIcon.d.ts.map +1 -1
- package/dist/Icons/SparklesIcon.js +2 -3
- package/dist/Icons/SparklesIcon.js.map +1 -1
- package/dist/Icons/StackIcon.d.ts.map +1 -1
- package/dist/Icons/StackIcon.js +3 -5
- package/dist/Icons/StackIcon.js.map +1 -1
- package/dist/Icons/StarIcon.d.ts.map +1 -1
- package/dist/Icons/StarIcon.js +2 -3
- package/dist/Icons/StarIcon.js.map +1 -1
- package/dist/Icons/SyncIcon.d.ts.map +1 -1
- package/dist/Icons/SyncIcon.js +2 -4
- package/dist/Icons/SyncIcon.js.map +1 -1
- package/dist/Icons/SyncOffIcon.d.ts.map +1 -1
- package/dist/Icons/SyncOffIcon.js +3 -6
- package/dist/Icons/SyncOffIcon.js.map +1 -1
- package/dist/Icons/ToolsIcon.d.ts +18 -0
- package/dist/Icons/ToolsIcon.d.ts.map +1 -0
- package/dist/Icons/ToolsIcon.js +58 -0
- package/dist/Icons/ToolsIcon.js.map +1 -0
- package/dist/Icons/TrashIcon.d.ts.map +1 -1
- package/dist/Icons/TrashIcon.js +2 -2
- package/dist/Icons/TrashIcon.js.map +1 -1
- package/dist/Icons/UndoIcon.d.ts.map +1 -1
- package/dist/Icons/UndoIcon.js +3 -4
- package/dist/Icons/UndoIcon.js.map +1 -1
- package/dist/Icons/UnlinkIcon.d.ts.map +1 -1
- package/dist/Icons/UnlinkIcon.js +46 -65
- package/dist/Icons/UnlinkIcon.js.map +1 -1
- package/dist/Icons/UnlockIcon.d.ts.map +1 -1
- package/dist/Icons/UnlockIcon.js +3 -4
- package/dist/Icons/UnlockIcon.js.map +1 -1
- package/dist/Icons/UploadIcon.d.ts.map +1 -1
- package/dist/Icons/UploadIcon.js +3 -6
- package/dist/Icons/UploadIcon.js.map +1 -1
- package/dist/Icons/User2Icon.d.ts.map +1 -1
- package/dist/Icons/User2Icon.js +13 -15
- package/dist/Icons/User2Icon.js.map +1 -1
- package/dist/Icons/UserAddIcon.d.ts +18 -0
- package/dist/Icons/UserAddIcon.d.ts.map +1 -0
- package/dist/Icons/UserAddIcon.js +46 -0
- package/dist/Icons/UserAddIcon.js.map +1 -0
- package/dist/Icons/UserDeleteIcon.d.ts +18 -0
- package/dist/Icons/UserDeleteIcon.d.ts.map +1 -0
- package/dist/Icons/UserDeleteIcon.js +46 -0
- package/dist/Icons/UserDeleteIcon.js.map +1 -0
- package/dist/Icons/UserEditIcon.d.ts +18 -0
- package/dist/Icons/UserEditIcon.d.ts.map +1 -0
- package/dist/Icons/UserEditIcon.js +40 -0
- package/dist/Icons/UserEditIcon.js.map +1 -0
- package/dist/Icons/UserIcon.d.ts.map +1 -1
- package/dist/Icons/UserIcon.js +3 -4
- package/dist/Icons/UserIcon.js.map +1 -1
- package/dist/Icons/UserSearchIcon.d.ts +18 -0
- package/dist/Icons/UserSearchIcon.d.ts.map +1 -0
- package/dist/Icons/UserSearchIcon.js +56 -0
- package/dist/Icons/UserSearchIcon.js.map +1 -0
- package/dist/Icons/UserSquareIcon.d.ts +18 -0
- package/dist/Icons/UserSquareIcon.d.ts.map +1 -0
- package/dist/Icons/UserSquareIcon.js +40 -0
- package/dist/Icons/UserSquareIcon.js.map +1 -0
- package/dist/Icons/UsersIcon.d.ts +18 -0
- package/dist/Icons/UsersIcon.d.ts.map +1 -0
- package/dist/Icons/UsersIcon.js +46 -0
- package/dist/Icons/UsersIcon.js.map +1 -0
- package/dist/Icons/WarningIcon.d.ts.map +1 -1
- package/dist/Icons/WarningIcon.js +2 -3
- package/dist/Icons/WarningIcon.js.map +1 -1
- package/dist/Icons/ZoomAllIcon.d.ts.map +1 -1
- package/dist/Icons/ZoomAllIcon.js +6 -38
- package/dist/Icons/ZoomAllIcon.js.map +1 -1
- package/dist/Icons/ZoomXIcon.d.ts.map +1 -1
- package/dist/Icons/ZoomXIcon.js +5 -8
- package/dist/Icons/ZoomXIcon.js.map +1 -1
- package/dist/Icons/ZoomYIcon.d.ts.map +1 -1
- package/dist/Icons/ZoomYIcon.js +5 -8
- package/dist/Icons/ZoomYIcon.js.map +1 -1
- package/dist/Icons.d.ts +31 -5
- package/dist/Icons.js +31 -5
- package/dist/IconsAnimated/PanelLeftCloseIcon.js.map +1 -1
- package/dist/IconsAnimated/PanelLeftOpenIcon.js.map +1 -1
- package/dist/Input.d.ts.map +1 -1
- package/dist/Input.js +2 -2
- package/dist/Input.js.map +1 -1
- package/dist/InputNumeric.d.ts.map +1 -1
- package/dist/InputNumeric.js.map +1 -1
- package/dist/InputOTP.d.ts.map +1 -1
- package/dist/InputOTP.js +1 -1
- package/dist/InputOTP.js.map +1 -1
- package/dist/InputSearch.d.ts.map +1 -1
- package/dist/InputSearch.js +7 -7
- package/dist/InputSearch.js.map +1 -1
- package/dist/Kbd.d.ts.map +1 -1
- package/dist/Kbd.js.map +1 -1
- package/dist/Label.js.map +1 -1
- package/dist/Meter.js +4 -4
- package/dist/Meter.js.map +1 -1
- package/dist/MultiSelect/MultiSelectBase.js.map +1 -1
- package/dist/MultiSelect.js.map +1 -1
- package/dist/Popover.d.ts.map +1 -1
- package/dist/Popover.js.map +1 -1
- package/dist/RadialMenu.d.ts.map +1 -1
- package/dist/RadialMenu.js.map +1 -1
- package/dist/RadioButton.js +1 -4
- package/dist/RadioButton.js.map +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.d.ts.map +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.js +2 -5
- package/dist/RadioButtonGroup/RadioButtonGroupBase.js.map +1 -1
- package/dist/RadioButtonGroup.d.ts.map +1 -1
- package/dist/RadioButtonGroup.js.map +1 -1
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +4 -4
- package/dist/RadioGroup.js.map +1 -1
- package/dist/Select.js +2 -2
- package/dist/Select.js.map +1 -1
- package/dist/Skeleton.js.map +1 -1
- package/dist/Slider.js.map +1 -1
- package/dist/Switch/SwitchBase.d.ts.map +1 -1
- package/dist/Switch/SwitchBase.js.map +1 -1
- package/dist/Switch.js.map +1 -1
- package/dist/Tabs/TabsBase.d.ts.map +1 -1
- package/dist/Tabs/TabsBase.js.map +1 -1
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/Tabs.js.map +1 -1
- package/dist/Textarea.js.map +1 -1
- package/dist/Toast.d.ts.map +1 -1
- package/dist/Toast.js +2 -2
- package/dist/Toast.js.map +1 -1
- package/dist/Toggle/ToggleBase.js.map +1 -1
- package/dist/Toggle.d.ts.map +1 -1
- package/dist/Toggle.js +2 -6
- package/dist/Toggle.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupBase.d.ts.map +1 -1
- package/dist/ToggleGroup/ToggleGroupBase.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.js +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js.map +1 -1
- package/dist/ToggleGroup.js +1 -9
- package/dist/ToggleGroup.js.map +1 -1
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip.js +1 -4
- package/dist/Tooltip.js.map +1 -1
- package/dist/Tray.d.ts.map +1 -1
- package/dist/Tray.js +2 -2
- package/dist/Tray.js.map +1 -1
- package/dist/index.d.ts +32 -6
- package/dist/index.js +32 -6
- package/dist/primitives/button.js +1 -1
- package/dist/primitives/button.js.map +1 -1
- package/dist/styles/horizon/base-colors.css +11 -11
- package/dist/styles/horizon/utilities.css +7 -8
- package/dist/styles/spectral.css +1 -1
- package/package.json +2 -2
- package/dist/DataCard/Card.d.ts +0 -38
- package/dist/DataCard/Card.d.ts.map +0 -1
- package/dist/DataCard/Card.js.map +0 -1
- package/dist/DataCard.d.ts +0 -25
- package/dist/DataCard.d.ts.map +0 -1
- package/dist/DataCard.js +0 -37
- package/dist/DataCard.js.map +0 -1
- package/dist/Icons/AnnotationsIcon.d.ts.map +0 -1
- package/dist/Icons/AnnotationsIcon.js.map +0 -1
- package/dist/Icons/PanelIconClose.d.ts.map +0 -1
- package/dist/Icons/PanelIconClose.js +0 -35
- package/dist/Icons/PanelIconClose.js.map +0 -1
- package/dist/Icons/PanelIconOpen.d.ts.map +0 -1
- package/dist/Icons/PanelIconOpen.js +0 -35
- package/dist/Icons/PanelIconOpen.js.map +0 -1
package/dist/ButtonGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonGroup.js","names":[],"sources":["../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import { Separator } from '@components/Separator/Separator'\nimport { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Children, cloneElement, isValidElement, type ComponentProps, type ReactElement } from 'react'\nimport { ButtonGroupButton } from './ButtonGroupButton'\n\ninterface ButtonGroupChildProps {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}\n\nexport type ButtonGroupProps = ComponentProps<typeof ButtonGroup> & VariantProps<typeof buttonGroupVariants>\n\nexport const buttonGroupVariants = cva(\n `has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2 flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10
|
|
1
|
+
{"version":3,"file":"ButtonGroup.js","names":[],"sources":["../src/components/ButtonGroup/ButtonGroup.tsx"],"sourcesContent":["import { Separator } from '@components/Separator/Separator'\nimport { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { Children, cloneElement, isValidElement, type ComponentProps, type ReactElement } from 'react'\nimport { ButtonGroupButton } from './ButtonGroupButton'\n\ninterface ButtonGroupChildProps {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}\n\nexport type ButtonGroupProps = ComponentProps<typeof ButtonGroup> & VariantProps<typeof buttonGroupVariants>\n\nexport const buttonGroupVariants = cva(\n `has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md has-[>[data-slot=button-group]]:gap-2 flex w-fit items-stretch [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 data-[variant='divided']:[&>[data-slot=button-group-item]]:border-y-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]]:border-x-0 data-[variant='divided']:[&>[data-slot=button-group-item]:first-of-type]:border-l-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]:first-of-type]:border-t-0 data-[variant='divided']:[&>[data-slot=button-group-item]:last-of-type]:border-r-0 data-[orientation='vertical']:data-[variant='divided']:[&>[data-slot=button-group-item]:last-of-type]:border-b-0 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1`,\n {\n variants: {\n orientation: {\n horizontal: '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',\n vertical: 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n },\n)\n\nexport const ButtonGroup = ({\n children,\n className,\n orientation = 'horizontal',\n size = 'md',\n variant = 'default',\n ...props\n}: ComponentProps<'div'> &\n VariantProps<typeof buttonGroupVariants> & {\n size?: 'md' | 'sm' | 'lg' | 'icon-md' | 'icon-sm' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n }) => {\n return (\n <div\n aria-label={props['aria-label']}\n className={cn(buttonGroupVariants({ orientation }), className)}\n data-orientation={orientation}\n data-slot='button-group'\n data-testid='spectral-button-group'\n data-variant={variant}\n role='group'\n {...props}\n >\n {Children.map(children, (child) => {\n if (isValidElement<ButtonGroupChildProps>(child) && (child.type === ButtonGroupItem || child.type === ButtonGroupButton)) {\n return cloneElement(child as ReactElement<ButtonGroupChildProps>, {\n variant: child.props.variant ?? variant,\n size: child.props.size ?? size,\n })\n }\n return child\n })}\n </div>\n )\n}\nButtonGroup.displayName = 'ButtonGroup'\n\nexport const ButtonGroupItem = ({\n asChild,\n children,\n className,\n size,\n variant,\n ...props\n}: ComponentProps<'button'> & {\n asChild?: boolean\n size?: 'sm' | 'md' | 'lg' | 'icon-sm' | 'icon-md' | 'icon-lg'\n variant?: 'default' | 'outline' | 'divided'\n}) => {\n return (\n <ButtonGroupButton\n asChild={asChild}\n className={cn(className)}\n data-slot='button-group-item'\n data-testid='spectral-button-group-item'\n data-variant={variant}\n size={size}\n variant={variant}\n {...props}\n >\n {children}\n </ButtonGroupButton>\n )\n}\nButtonGroupItem.displayName = 'ButtonGroupItem'\n\nexport const ButtonGroupText = ({\n asChild = false,\n className,\n ...props\n}: ComponentProps<'div'> & {\n asChild?: boolean\n}) => {\n const Comp = asChild ? Slot : 'div'\n return (\n <Comp\n className={cn(`gap-2 rounded-md px-4 text-sm font-medium shadow-xs [&_svg:not([class*='size-'])]:size-4 flex items-center border [&_svg]:pointer-events-none`, className)}\n data-slot='button-group-text'\n data-testid='spectral-button-group-text'\n {...props}\n />\n )\n}\n\nexport const ButtonGroupSeparator = ({\n className,\n orientation = 'vertical',\n ...props\n}: ComponentProps<typeof Separator> & {\n orientation?: 'vertical' | 'horizontal'\n}) => {\n return (\n <Separator\n className={cn('m-0! relative self-stretch bg-input-primitive-border data-[orientation=vertical]:h-auto', className)}\n data-slot='button-group-separator'\n data-testid='spectral-button-group-separator'\n orientation={orientation}\n {...props}\n />\n )\n}\nButtonGroupSeparator.displayName = 'ButtonGroupSeparator'\n"],"mappings":";;;;;;;;;;AAcA,MAAa,sBAAsB,IACjC,w1BACA;CACE,UAAU,EACR,aAAa;EACX,YAAY;EACZ,UAAU;EACX,EACF;CACD,iBAAiB,EACf,aAAa,cACd;CACF,CACH;AAEA,MAAa,eAAe,EAC1B,UACA,WACA,cAAc,cACd,OAAO,MACP,UAAU,WACV,GAAG,YAKG;AACN,QACE,oBAAC,OAAD;EACE,cAAY,MAAM;EAClB,WAAW,GAAG,oBAAoB,EAAE,aAAa,CAAC,EAAE,UAAU;EAC9D,oBAAkB;EAClB,aAAU;EAEV,gBAAc;EACd,MAAK;EACL,GAAI;YAEH,SAAS,IAAI,WAAW,UAAU;AACjC,OAAI,eAAsC,MAAM,KAAK,MAAM,SAAS,mBAAmB,MAAM,SAAS,mBACpG,QAAO,aAAa,OAA8C;IAChE,SAAS,MAAM,MAAM,WAAW;IAChC,MAAM,MAAM,MAAM,QAAQ;IAC3B,CAAA;AAEH,UAAO;IACP;EACC;;AAGT,YAAY,cAAc;AAE1B,MAAa,mBAAmB,EAC9B,SACA,UACA,WACA,MACA,SACA,GAAG,YAKC;AACJ,QACE,oBAAC,mBAAD;EACW;EACT,WAAW,GAAG,UAAU;EACxB,aAAU;EAEV,gBAAc;EACR;EACG;EACT,GAAI;EAEH;EACgB;;AAGvB,gBAAgB,cAAc;AAE9B,MAAa,mBAAmB,EAC9B,UAAU,OACV,WACA,GAAG,YAGC;AAEJ,QACE,oBAFW,UAAU,OAAO,OAE5B;EACE,WAAW,GAAG,iJAAiJ,UAAU;EACzK,aAAU;EAEV,GAAI;EACL;;AAIL,MAAa,wBAAwB,EACnC,WACA,cAAc,YACd,GAAG,YAGC;AACJ,QACE,oBAAC,WAAD;EACE,WAAW,GAAG,2FAA2F,UAAU;EACnH,aAAU;EAEG;EACb,GAAI;EACL;;AAGL,qBAAqB,cAAc"}
|
package/dist/ButtonIcon.d.ts
CHANGED
|
@@ -8,21 +8,25 @@ interface ButtonIconProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>,
|
|
|
8
8
|
className?: string;
|
|
9
9
|
icon: IconOrSVG;
|
|
10
10
|
isLoading?: boolean;
|
|
11
|
+
isActive?: boolean;
|
|
11
12
|
label: string;
|
|
12
13
|
onClick?: (event: MouseEvent<HTMLButtonElement>) => void;
|
|
13
14
|
shape?: 'circle' | 'square';
|
|
14
15
|
size?: 'sm' | 'md' | 'lg';
|
|
16
|
+
variant?: 'default' | 'active-color';
|
|
15
17
|
}
|
|
16
18
|
declare function ButtonIcon({
|
|
17
19
|
className,
|
|
18
20
|
disabled,
|
|
19
21
|
icon,
|
|
22
|
+
isActive,
|
|
20
23
|
isLoading,
|
|
21
24
|
label,
|
|
22
25
|
onClick,
|
|
23
26
|
ref,
|
|
24
27
|
shape,
|
|
25
28
|
size,
|
|
29
|
+
variant,
|
|
26
30
|
...props
|
|
27
31
|
}: ButtonIconProps & {
|
|
28
32
|
ref?: Ref<HTMLButtonElement>;
|
package/dist/ButtonIcon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonIcon.d.ts","names":[],"sources":["../src/components/ButtonIcon/ButtonIcon.tsx"],"mappings":";;;;;KAIK,SAAA,GAAY,YAAA,UAAsB,YAAA;AAAA,UAEtB,eAAA,SAAwB,IAAA,CAAK,oBAAA,CAAqB,iBAAA;EACjE,SAAA;EACA,IAAA,EAAM,SAAA;EACN,SAAA;EACA,KAAA;EACA,OAAA,IAAW,KAAA,EAAO,UAAA,CAAW,iBAAA;EAC7B,KAAA;EACA,IAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"file":"ButtonIcon.d.ts","names":[],"sources":["../src/components/ButtonIcon/ButtonIcon.tsx"],"mappings":";;;;;KAIK,SAAA,GAAY,YAAA,UAAsB,YAAA;AAAA,UAEtB,eAAA,SAAwB,IAAA,CAAK,oBAAA,CAAqB,iBAAA;EACjE,SAAA;EACA,IAAA,EAAM,SAAA;EACN,SAAA;EACA,QAAA;EACA,KAAA;EACA,OAAA,IAAW,KAAA,EAAO,UAAA,CAAW,iBAAA;EAC7B,KAAA;EACA,IAAA;EACA,OAAA;AAAA;AAAA;EAmBA,SAAA;EACA,QAAA;EACA,IAAA;EACA,QAAA;EACA,SAAA;EACA,KAAA;EACA,OAAA;EACA,GAAA;EACA,KAAA;EACA,IAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,eAAA;EACD,GAAA,GAAM,GAAA,CAAI,iBAAA;AAAA,IACX,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|
package/dist/ButtonIcon.js
CHANGED
|
@@ -8,6 +8,10 @@ import { jsx } from "react/jsx-runtime";
|
|
|
8
8
|
const buttonStyles = `bg-level-two hover:bg-level-four aspect-square text-text-primary inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[background-color,color,transform]
|
|
9
9
|
active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent focus:outline-none cursor-pointer [&_svg]:pointer-events-none [&_svg]:shrink-0 disabled:opacity-50
|
|
10
10
|
disabled:pointer-events-none disabled:text-text-secondary disabled:hover:bg-level-one`;
|
|
11
|
+
const variantConfig = {
|
|
12
|
+
default: "",
|
|
13
|
+
"active-color": "bg-transparent hover:bg-white/6 data-[state=active]:bg-accent/20 data-[state=active]:text-accent data-[state=active]:hover:bg-accent/20"
|
|
14
|
+
};
|
|
11
15
|
const sizeConfig = {
|
|
12
16
|
sm: {
|
|
13
17
|
button: "size-8 min-size-8",
|
|
@@ -22,7 +26,7 @@ const sizeConfig = {
|
|
|
22
26
|
icon: 32
|
|
23
27
|
}
|
|
24
28
|
};
|
|
25
|
-
const ButtonIcon = ({ className, disabled, icon, isLoading = false, label, onClick, ref, shape = "square", size = "md", ...props }) => {
|
|
29
|
+
const ButtonIcon = ({ className, disabled, icon, isActive = false, isLoading = false, label, onClick, ref, shape = "square", size = "md", variant = "default", ...props }) => {
|
|
26
30
|
const handleClick = (event) => onClick?.(event);
|
|
27
31
|
const effectiveLabel = isLoading ? `${label} - Loading` : label;
|
|
28
32
|
const renderIcon = () => {
|
|
@@ -53,7 +57,8 @@ const ButtonIcon = ({ className, disabled, icon, isLoading = false, label, onCli
|
|
|
53
57
|
};
|
|
54
58
|
return /* @__PURE__ */ jsx("button", {
|
|
55
59
|
"aria-label": effectiveLabel,
|
|
56
|
-
className: cn(buttonStyles, shape === "circle" ? "rounded-full" : "rounded-lg", sizeConfig[size].button, isLoading && "cursor-wait", disabled && "cursor-not-allowed opacity-50", className),
|
|
60
|
+
className: cn(buttonStyles, variantConfig[variant], shape === "circle" ? "rounded-full" : "rounded-lg", sizeConfig[size].button, isLoading && "cursor-wait", disabled && "cursor-not-allowed opacity-50", className),
|
|
61
|
+
"data-state": isActive ? "active" : "inactive",
|
|
57
62
|
disabled: disabled ?? isLoading,
|
|
58
63
|
onClick: handleClick,
|
|
59
64
|
ref,
|
package/dist/ButtonIcon.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ButtonIcon.js","names":[],"sources":["../src/components/ButtonIcon/ButtonIcon.tsx"],"sourcesContent":["import { LoaderIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { cloneElement, isValidElement, type ButtonHTMLAttributes, type MouseEvent, type ReactElement, type Ref, type SVGProps } from 'react'\n\ntype IconOrSVG = ReactElement | (() => ReactElement)\n\nexport interface ButtonIconProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n className?: string\n icon: IconOrSVG\n isLoading?: boolean\n label: string\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void\n shape?: 'circle' | 'square'\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst buttonStyles = `bg-level-two hover:bg-level-four aspect-square text-text-primary inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[background-color,color,transform]\n active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent focus:outline-none cursor-pointer [&_svg]:pointer-events-none [&_svg]:shrink-0 disabled:opacity-50\n disabled:pointer-events-none disabled:text-text-secondary disabled:hover:bg-level-one`\n\nconst sizeConfig = {\n sm: { button: 'size-8 min-size-8', icon: 16 },\n md: { button: 'size-10 min-size-10', icon: 24 },\n lg: { button: 'size-12 min-size-12', icon: 32 },\n} as const\n\nexport const ButtonIcon = ({\n className,\n disabled,\n icon,\n isLoading = false,\n label,\n onClick,\n ref,\n shape = 'square',\n size = 'md',\n ...props\n}: ButtonIconProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => onClick?.(event)\n\n const effectiveLabel = isLoading ? `${label} - Loading` : label\n\n const renderIcon = (): ReactElement => {\n if (isLoading) {\n return <LoaderIcon
|
|
1
|
+
{"version":3,"file":"ButtonIcon.js","names":[],"sources":["../src/components/ButtonIcon/ButtonIcon.tsx"],"sourcesContent":["import { LoaderIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { cloneElement, isValidElement, type ButtonHTMLAttributes, type MouseEvent, type ReactElement, type Ref, type SVGProps } from 'react'\n\ntype IconOrSVG = ReactElement | (() => ReactElement)\n\nexport interface ButtonIconProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onClick'> {\n className?: string\n icon: IconOrSVG\n isLoading?: boolean\n isActive?: boolean\n label: string\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void\n shape?: 'circle' | 'square'\n size?: 'sm' | 'md' | 'lg'\n variant?: 'default' | 'active-color'\n}\n\nconst buttonStyles = `bg-level-two hover:bg-level-four aspect-square text-text-primary inline-flex shrink-0 items-center justify-center whitespace-nowrap transition-[background-color,color,transform]\n active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent focus:outline-none cursor-pointer [&_svg]:pointer-events-none [&_svg]:shrink-0 disabled:opacity-50\n disabled:pointer-events-none disabled:text-text-secondary disabled:hover:bg-level-one`\n\nconst variantConfig = {\n default: '',\n 'active-color': 'bg-transparent hover:bg-white/6 data-[state=active]:bg-accent/20 data-[state=active]:text-accent data-[state=active]:hover:bg-accent/20',\n} as const\n\nconst sizeConfig = {\n sm: { button: 'size-8 min-size-8', icon: 16 },\n md: { button: 'size-10 min-size-10', icon: 24 },\n lg: { button: 'size-12 min-size-12', icon: 32 },\n} as const\n\nexport const ButtonIcon = ({\n className,\n disabled,\n icon,\n isActive = false,\n isLoading = false,\n label,\n onClick,\n ref,\n shape = 'square',\n size = 'md',\n variant = 'default',\n ...props\n}: ButtonIconProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => onClick?.(event)\n\n const effectiveLabel = isLoading ? `${label} - Loading` : label\n\n const renderIcon = (): ReactElement => {\n if (isLoading) {\n return (\n <LoaderIcon\n size={sizeConfig[size as keyof typeof sizeConfig].icon}\n aria-hidden='true'\n />\n )\n }\n\n const iconElement = typeof icon === 'function' ? icon() : icon\n\n if (isValidElement(iconElement)) {\n const currentSize = sizeConfig[size as keyof typeof sizeConfig].icon\n\n if (iconElement.type === 'svg') {\n return cloneElement(iconElement as ReactElement<SVGProps<SVGSVGElement>>, {\n className: cn('shrink-0', (iconElement.props as { className?: string }).className),\n height: currentSize,\n width: currentSize,\n 'aria-hidden': 'true',\n })\n }\n\n // For icon components, pass size prop if the element accepts it\n const baseIconProps = {\n 'aria-hidden': 'true',\n className: cn('shrink-0', (iconElement.props as { className?: string }).className),\n }\n\n // Check if this is an icon component that accepts size prop\n // All our icon components accept refs and have displayName containing 'Icon'\n const componentType = iconElement.type as { displayName?: string }\n const isIconComponent = componentType.displayName?.endsWith('Icon') ?? false\n\n if (isIconComponent) {\n const iconPropsWithSize = {\n ...baseIconProps,\n size: currentSize,\n }\n return cloneElement(iconElement, iconPropsWithSize)\n }\n\n return cloneElement(iconElement, baseIconProps)\n }\n\n return iconElement\n }\n\n return (\n <button\n aria-label={effectiveLabel}\n className={cn(buttonStyles, variantConfig[variant], shape === 'circle' ? 'rounded-full' : 'rounded-lg', sizeConfig[size as keyof typeof sizeConfig].button, isLoading && 'cursor-wait', disabled && 'cursor-not-allowed opacity-50', className)}\n data-state={isActive ? 'active' : 'inactive'}\n data-testid='spectral-button-icon'\n disabled={disabled ?? isLoading}\n onClick={handleClick}\n ref={ref}\n type='button'\n {...props}\n >\n {renderIcon()}\n </button>\n )\n}\nButtonIcon.displayName = 'ButtonIcon'\n"],"mappings":";;;;;;;AAkBA,MAAM,eAAe;;;AAIrB,MAAM,gBAAgB;CACpB,SAAS;CACT,gBAAgB;CACjB;AAED,MAAM,aAAa;CACjB,IAAI;EAAE,QAAQ;EAAqB,MAAM;EAAI;CAC7C,IAAI;EAAE,QAAQ;EAAuB,MAAM;EAAI;CAC/C,IAAI;EAAE,QAAQ;EAAuB,MAAM;EAAI;CAChD;AAED,MAAa,cAAc,EACzB,WACA,UACA,MACA,WAAW,OACX,YAAY,OACZ,OACA,SACA,KACA,QAAQ,UACR,OAAO,MACP,UAAU,WACV,GAAG,YAGC;CACJ,MAAM,eAAe,UAAyC,UAAU,MAAK;CAE7E,MAAM,iBAAiB,YAAY,GAAG,MAAM,cAAc;CAE1D,MAAM,mBAAiC;AACrC,MAAI,UACF,QACE,oBAAC,YAAD;GACE,MAAM,WAAW,MAAiC;GAClD,eAAY;GACb;EAIL,MAAM,cAAc,OAAO,SAAS,aAAa,MAAM,GAAG;AAE1D,MAAI,eAAe,YAAY,EAAE;GAC/B,MAAM,cAAc,WAAW,MAAiC;AAEhE,OAAI,YAAY,SAAS,MACvB,QAAO,aAAa,aAAsD;IACxE,WAAW,GAAG,YAAa,YAAY,MAAiC,UAAU;IAClF,QAAQ;IACR,OAAO;IACP,eAAe;IAChB,CAAA;GAIH,MAAM,gBAAgB;IACpB,eAAe;IACf,WAAW,GAAG,YAAa,YAAY,MAAiC,UAAU;IACpF;AAOA,OAHsB,YAAY,KACI,aAAa,SAAS,OAAO,IAAI,MAOrE,QAAO,aAAa,aAAa;IAH/B,GAAG;IACH,MAAM;IAE0C,CAAA;AAGpD,UAAO,aAAa,aAAa,cAAa;;AAGhD,SAAO;;AAGT,QACE,oBAAC,UAAD;EACE,cAAY;EACZ,WAAW,GAAG,cAAc,cAAc,UAAU,UAAU,WAAW,iBAAiB,cAAc,WAAW,MAAiC,QAAQ,aAAa,eAAe,YAAY,iCAAiC,UAAU;EAC/O,cAAY,WAAW,WAAW;EAElC,UAAU,YAAY;EACtB,SAAS;EACJ;EACL,MAAK;EACL,GAAI;YAEH,YAAY;EACP;;AAGZ,WAAW,cAAc"}
|
package/dist/Card.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { ComponentProps } from "react";
|
|
3
|
+
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/components/Card/Card.d.ts
|
|
6
|
+
type CardShadow = 'none' | 'low' | 'medium' | 'high';
|
|
7
|
+
type CardProps = ComponentProps<'div'> & {
|
|
8
|
+
asChild?: boolean;
|
|
9
|
+
shadow?: CardShadow;
|
|
10
|
+
};
|
|
11
|
+
type CardPartProps = ComponentProps<'div'> & {
|
|
12
|
+
asChild?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const Card: ({
|
|
15
|
+
asChild,
|
|
16
|
+
children,
|
|
17
|
+
className,
|
|
18
|
+
shadow,
|
|
19
|
+
...props
|
|
20
|
+
}: CardProps) => _$react_jsx_runtime0.JSX.Element;
|
|
21
|
+
declare const CardHeader: ({
|
|
22
|
+
asChild,
|
|
23
|
+
className,
|
|
24
|
+
...props
|
|
25
|
+
}: CardPartProps) => _$react_jsx_runtime0.JSX.Element;
|
|
26
|
+
declare const CardTitle: ({
|
|
27
|
+
className,
|
|
28
|
+
asChild,
|
|
29
|
+
...props
|
|
30
|
+
}: CardPartProps) => _$react_jsx_runtime0.JSX.Element;
|
|
31
|
+
declare const CardHeaderEndSlot: ({
|
|
32
|
+
className,
|
|
33
|
+
asChild,
|
|
34
|
+
...props
|
|
35
|
+
}: CardPartProps) => _$react_jsx_runtime0.JSX.Element;
|
|
36
|
+
declare const CardContent: ({
|
|
37
|
+
asChild,
|
|
38
|
+
className,
|
|
39
|
+
...props
|
|
40
|
+
}: CardPartProps) => _$react_jsx_runtime0.JSX.Element;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { Card, CardContent, CardHeader, CardHeaderEndSlot, CardPartProps, CardProps, CardShadow, CardTitle };
|
|
43
|
+
//# sourceMappingURL=Card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.d.ts","names":[],"sources":["../src/components/Card/Card.tsx"],"mappings":";;;;;KAIY,UAAA;AAAA,KACA,SAAA,GAAY,cAAA;EAA0B,OAAA;EAAmB,MAAA,GAAS,UAAA;AAAA;AAAA,KAClE,aAAA,GAAgB,cAAA;EAA0B,OAAA;AAAA;AAAA,cAWzC,IAAA;EAAI,OAAA;EAAA,QAAA;EAAA,SAAA;EAAA,MAAA;EAAA,GAAA;AAAA,GAAyE,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAetF,UAAA;EAAU,OAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAA8C,aAAA,KAAa,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAarE,SAAA;EAAS,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAA8C,aAAA,KAAa,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAapE,iBAAA;EAAiB,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAA8C,aAAA,KAAa,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAa5E,WAAA;EAAW,OAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAA8C,aAAA,KAAa,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { cn } from "
|
|
3
|
-
import { Slot } from "
|
|
2
|
+
import { cn } from "./utils/twUtils.js";
|
|
3
|
+
import { Slot } from "./primitives/slot.js";
|
|
4
4
|
import "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
|
|
7
|
-
//#region src/components/
|
|
8
|
-
const cardClasses = "text-text-primary flex flex-col w-full
|
|
9
|
-
const
|
|
10
|
-
|
|
7
|
+
//#region src/components/Card/Card.tsx
|
|
8
|
+
const cardClasses = "text-text-primary flex flex-col w-full p-3 gap-6 rounded-xl";
|
|
9
|
+
const cardShadowClasses = {
|
|
10
|
+
none: "",
|
|
11
|
+
low: "card-effects-small",
|
|
12
|
+
medium: "card-effects-medium",
|
|
13
|
+
high: "card-effects"
|
|
14
|
+
};
|
|
15
|
+
const Card = ({ asChild = false, children, className, shadow = "high", ...props }) => {
|
|
16
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
17
|
+
className: cn(cardClasses, cardShadowClasses[shadow], className),
|
|
11
18
|
"data-slot": "card",
|
|
12
|
-
...props
|
|
19
|
+
...props,
|
|
20
|
+
children
|
|
13
21
|
});
|
|
14
22
|
};
|
|
15
|
-
const CardHeader = ({ className, ...props }) => {
|
|
16
|
-
return /* @__PURE__ */ jsx("div", {
|
|
23
|
+
const CardHeader = ({ asChild = false, className, ...props }) => {
|
|
24
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
17
25
|
className: cn("pb-4 @container/card-header flex items-center justify-between", className),
|
|
18
26
|
"data-slot": "card-header",
|
|
19
27
|
...props
|
|
@@ -33,22 +41,14 @@ const CardHeaderEndSlot = ({ className, asChild = false, ...props }) => {
|
|
|
33
41
|
...props
|
|
34
42
|
});
|
|
35
43
|
};
|
|
36
|
-
const CardContent = ({ className, ...props }) => {
|
|
37
|
-
return /* @__PURE__ */ jsx("div", {
|
|
44
|
+
const CardContent = ({ asChild = false, className, ...props }) => {
|
|
45
|
+
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
38
46
|
className,
|
|
39
47
|
"data-slot": "card-content",
|
|
40
48
|
...props
|
|
41
49
|
});
|
|
42
50
|
};
|
|
43
|
-
const Card = ({ asChild = false, children, className, ...props }) => {
|
|
44
|
-
return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
|
|
45
|
-
className: cn(cardClasses, className),
|
|
46
|
-
"data-slot": "card",
|
|
47
|
-
...props,
|
|
48
|
-
children
|
|
49
|
-
});
|
|
50
|
-
};
|
|
51
51
|
|
|
52
52
|
//#endregion
|
|
53
|
-
export { Card,
|
|
53
|
+
export { Card, CardContent, CardHeader, CardHeaderEndSlot, CardTitle };
|
|
54
54
|
//# sourceMappingURL=Card.js.map
|
package/dist/Card.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.js","names":[],"sources":["../src/components/Card/Card.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\n\nexport type CardShadow = 'none' | 'low' | 'medium' | 'high'\nexport type CardProps = ComponentProps<'div'> & { asChild?: boolean; shadow?: CardShadow }\nexport type CardPartProps = ComponentProps<'div'> & { asChild?: boolean }\n\nconst cardClasses = 'text-text-primary flex flex-col w-full p-3 gap-6 rounded-xl'\n\nconst cardShadowClasses: Record<CardShadow, string> = {\n none: '',\n low: 'card-effects-small',\n medium: 'card-effects-medium',\n high: 'card-effects',\n}\n\nexport const Card = ({ asChild = false, children, className, shadow = 'high', ...props }: CardProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp\n className={cn(cardClasses, cardShadowClasses[shadow], className)}\n data-slot='card'\n data-testid='spectral-card'\n {...props}\n >\n {children}\n </Comp>\n )\n}\n\nexport const CardHeader = ({ asChild = false, className, ...props }: CardPartProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp\n className={cn('pb-4 @container/card-header flex items-center justify-between', className)}\n data-slot='card-header'\n data-testid='spectral-card-header'\n {...props}\n />\n )\n}\n\nexport const CardTitle = ({ className, asChild = false, ...props }: CardPartProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp\n className={cn('font-semibold text-xl', className)}\n data-slot='card-title'\n data-testid='spectral-card-title'\n {...props}\n />\n )\n}\n\nexport const CardHeaderEndSlot = ({ className, asChild = false, ...props }: CardPartProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp\n className={cn('justify-self-end', className)}\n data-slot='card-action'\n data-testid='spectral-card-action'\n {...props}\n />\n )\n}\n\nexport const CardContent = ({ asChild = false, className, ...props }: CardPartProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp\n className={className}\n data-slot='card-content'\n data-testid='spectral-card-content'\n {...props}\n />\n )\n}\n"],"mappings":";;;;;;;AAQA,MAAM,cAAc;AAEpB,MAAM,oBAAgD;CACpD,MAAM;CACN,KAAK;CACL,QAAQ;CACR,MAAM;CACR;AAEA,MAAa,QAAQ,EAAE,UAAU,OAAO,UAAU,WAAW,SAAS,QAAQ,GAAG,YAAuB;AAGtG,QACE,oBAHW,UAAU,OAAO,OAG5B;EACE,WAAW,GAAG,aAAa,kBAAkB,SAAS,UAAU;EAChE,aAAU;EAEV,GAAI;EAEH;EACG;;AAIV,MAAa,cAAc,EAAE,UAAU,OAAO,WAAW,GAAG,YAA2B;AAGrF,QACE,oBAHW,UAAU,OAAO,OAG5B;EACE,WAAW,GAAG,iEAAiE,UAAU;EACzF,aAAU;EAEV,GAAI;EACL;;AAIL,MAAa,aAAa,EAAE,WAAW,UAAU,OAAO,GAAG,YAA2B;AAGpF,QACE,oBAHW,UAAU,OAAO,OAG5B;EACE,WAAW,GAAG,yBAAyB,UAAU;EACjD,aAAU;EAEV,GAAI;EACL;;AAIL,MAAa,qBAAqB,EAAE,WAAW,UAAU,OAAO,GAAG,YAA2B;AAG5F,QACE,oBAHW,UAAU,OAAO,OAG5B;EACE,WAAW,GAAG,oBAAoB,UAAU;EAC5C,aAAU;EAEV,GAAI;EACL;;AAIL,MAAa,eAAe,EAAE,UAAU,OAAO,WAAW,GAAG,YAA2B;AAGtF,QACE,oBAHW,UAAU,OAAO,OAG5B;EACa;EACX,aAAU;EAEV,GAAI;EACL"}
|
|
@@ -76,7 +76,7 @@ const CheckboxBase = ({ asChild, checked, className, defaultChecked = false, dis
|
|
|
76
76
|
children: /* @__PURE__ */ jsxs(Comp, {
|
|
77
77
|
"aria-checked": state === "indeterminate" ? "mixed" : state,
|
|
78
78
|
"aria-disabled": disabled ?? void 0,
|
|
79
|
-
className: cn("inline-flex shrink-0 items-center justify-center border
|
|
79
|
+
className: cn("border-input rounded-sm inline-flex shrink-0 items-center justify-center border bg-background", "focus:outline-none focus-visible:outline focus-visible:outline-offset-2 focus-visible:outline-accent", "data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground disabled:cursor-not-allowed disabled:opacity-50", className),
|
|
80
80
|
"data-indeterminate": state === "indeterminate" ? "" : void 0,
|
|
81
81
|
"data-state": dataState(state),
|
|
82
82
|
disabled,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckboxBase.js","names":[],"sources":["../../src/components/Checkbox/CheckboxBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { Slot, type AsChildProp } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useCallback, useContext, useEffect, useId, useRef, type ButtonHTMLAttributes, type ElementType, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type Ref } from 'react'\n\nexport type CheckedState = boolean | 'indeterminate'\n\ntype BaseButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'>\n\nexport type CheckboxBaseProps = BaseButtonProps &\n AsChildProp & {\n checked?: CheckedState\n defaultChecked?: CheckedState\n form?: string\n name?: string\n onCheckedChange?: (checked: CheckedState) => void\n required?: boolean\n value?: string\n }\n\ninterface Ctx {\n disabled: boolean | undefined\n state: CheckedState\n}\n\nconst CheckboxCtx = createContext<Ctx | null>(null)\n\nconst dataState = (checked: CheckedState): 'checked' | 'unchecked' | 'indeterminate' => {\n if (checked === 'indeterminate') return 'indeterminate'\n return checked ? 'checked' : 'unchecked'\n}\n\nconst getNext = (checked: CheckedState): CheckedState => {\n if (checked === 'indeterminate') return true\n return !checked\n}\n\nexport const CheckboxBase = ({\n asChild,\n checked,\n className,\n defaultChecked = false,\n disabled,\n form,\n id,\n name,\n onCheckedChange,\n onClick,\n onKeyDown,\n ref,\n required,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type,\n value = 'on',\n ...rest\n}: CheckboxBaseProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const autoId = useId()\n const resolvedId = id ?? `chk-${autoId}`\n\n const [state, setState] = useUncontrolledState<CheckedState>({\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n value: checked,\n })\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = state === 'indeterminate'\n }, [state])\n\n useEffect(() => {\n const formEl = inputRef.current?.form ?? null\n if (!formEl) return\n const handleReset = () => {\n setState(defaultChecked)\n }\n formEl.addEventListener('reset', handleReset)\n return () => formEl.removeEventListener('reset', handleReset)\n }, [defaultChecked, setState])\n\n const emitFormChange = useCallback(() => {\n const el = inputRef.current\n if (!el) return\n el.checked = state === true\n el.indeterminate = state === 'indeterminate'\n const event = new Event('change', { bubbles: true })\n el.dispatchEvent(event)\n }, [state])\n\n const handleToggle = useCallback(() => {\n if (disabled) return\n const next = getNext(state)\n setState(next)\n queueMicrotask(() => emitFormChange())\n }, [disabled, emitFormChange, setState, state])\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick],\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(e)\n if (e.defaultPrevented) return\n if (e.key === ' ') {\n e.preventDefault()\n handleToggle()\n }\n },\n [handleToggle, onKeyDown],\n )\n\n const Comp: ElementType = asChild ? Slot : 'button'\n\n return (\n <CheckboxCtx.Provider value={{ state, disabled }}>\n <Comp\n aria-checked={state === 'indeterminate' ? 'mixed' : state}\n aria-disabled={disabled ?? undefined}\n className={cn(\n 'inline-flex shrink-0 items-center justify-center border
|
|
1
|
+
{"version":3,"file":"CheckboxBase.js","names":[],"sources":["../../src/components/Checkbox/CheckboxBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { Slot, type AsChildProp } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useCallback, useContext, useEffect, useId, useRef, type ButtonHTMLAttributes, type ElementType, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type Ref } from 'react'\n\nexport type CheckedState = boolean | 'indeterminate'\n\ntype BaseButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'>\n\nexport type CheckboxBaseProps = BaseButtonProps &\n AsChildProp & {\n checked?: CheckedState\n defaultChecked?: CheckedState\n form?: string\n name?: string\n onCheckedChange?: (checked: CheckedState) => void\n required?: boolean\n value?: string\n }\n\ninterface Ctx {\n disabled: boolean | undefined\n state: CheckedState\n}\n\nconst CheckboxCtx = createContext<Ctx | null>(null)\n\nconst dataState = (checked: CheckedState): 'checked' | 'unchecked' | 'indeterminate' => {\n if (checked === 'indeterminate') return 'indeterminate'\n return checked ? 'checked' : 'unchecked'\n}\n\nconst getNext = (checked: CheckedState): CheckedState => {\n if (checked === 'indeterminate') return true\n return !checked\n}\n\nexport const CheckboxBase = ({\n asChild,\n checked,\n className,\n defaultChecked = false,\n disabled,\n form,\n id,\n name,\n onCheckedChange,\n onClick,\n onKeyDown,\n ref,\n required,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type,\n value = 'on',\n ...rest\n}: CheckboxBaseProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const autoId = useId()\n const resolvedId = id ?? `chk-${autoId}`\n\n const [state, setState] = useUncontrolledState<CheckedState>({\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n value: checked,\n })\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = state === 'indeterminate'\n }, [state])\n\n useEffect(() => {\n const formEl = inputRef.current?.form ?? null\n if (!formEl) return\n const handleReset = () => {\n setState(defaultChecked)\n }\n formEl.addEventListener('reset', handleReset)\n return () => formEl.removeEventListener('reset', handleReset)\n }, [defaultChecked, setState])\n\n const emitFormChange = useCallback(() => {\n const el = inputRef.current\n if (!el) return\n el.checked = state === true\n el.indeterminate = state === 'indeterminate'\n const event = new Event('change', { bubbles: true })\n el.dispatchEvent(event)\n }, [state])\n\n const handleToggle = useCallback(() => {\n if (disabled) return\n const next = getNext(state)\n setState(next)\n queueMicrotask(() => emitFormChange())\n }, [disabled, emitFormChange, setState, state])\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick],\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(e)\n if (e.defaultPrevented) return\n if (e.key === ' ') {\n e.preventDefault()\n handleToggle()\n }\n },\n [handleToggle, onKeyDown],\n )\n\n const Comp: ElementType = asChild ? Slot : 'button'\n\n return (\n <CheckboxCtx.Provider value={{ state, disabled }}>\n <Comp\n aria-checked={state === 'indeterminate' ? 'mixed' : state}\n aria-disabled={disabled ?? undefined}\n className={cn(\n 'border-input rounded-sm inline-flex shrink-0 items-center justify-center border bg-background',\n 'focus:outline-none focus-visible:outline focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n data-indeterminate={state === 'indeterminate' ? '' : undefined}\n data-state={dataState(state)}\n disabled={disabled}\n id={resolvedId}\n ref={ref}\n role='checkbox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role\n type='button'\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {/* hidden input for forms */}\n <input\n aria-hidden='true'\n checked={state === true}\n disabled={disabled}\n form={form}\n name={name}\n readOnly\n ref={inputRef}\n required={required}\n // visually hidden but in the DOM for form submission\n style={{\n position: 'absolute',\n opacity: 0,\n width: 0,\n height: 0,\n pointerEvents: 'none',\n }}\n tabIndex={-1}\n type='checkbox'\n value={value}\n />\n {rest.children}\n </Comp>\n </CheckboxCtx.Provider>\n )\n}\nCheckboxBase.displayName = 'CheckboxBase'\n\nexport type CheckboxIndicatorProps = HTMLAttributes<HTMLSpanElement> &\n AsChildProp & {\n forceMount?: boolean\n }\n\nexport const CheckboxIndicator = ({\n asChild,\n className,\n forceMount,\n ref,\n ...props\n}: CheckboxIndicatorProps & {\n ref?: Ref<HTMLSpanElement>\n}) => {\n const ctx = useContext(CheckboxCtx)\n if (!ctx) return null\n const visible = ctx.state === true || ctx.state === 'indeterminate'\n if (!visible && !forceMount) return null\n\n const Comp: ElementType = asChild ? Slot : 'span'\n\n return (\n <Comp\n className={cn('flex items-center justify-center text-current', className)}\n data-indeterminate={ctx.state === 'indeterminate' ? '' : undefined}\n data-state={dataState(ctx.state)}\n ref={ref}\n {...props}\n />\n )\n}\nCheckboxIndicator.displayName = 'CheckboxIndicator'\n"],"mappings":"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"}
|
package/dist/Checkbox.js
CHANGED
|
@@ -16,7 +16,7 @@ const Checkbox = ({ checked, className, errorMessage, id, label, labelText, mess
|
|
|
16
16
|
const warningMessageId = getWarningMessageId(inputId);
|
|
17
17
|
return /* @__PURE__ */ jsxs("div", { children: [
|
|
18
18
|
/* @__PURE__ */ jsxs("div", {
|
|
19
|
-
className: "gap-2 flex items-start
|
|
19
|
+
className: "gap-2 flex shrink-0 items-start",
|
|
20
20
|
children: [/* @__PURE__ */ jsx(CheckboxBase, {
|
|
21
21
|
"aria-describedby": [state === "error" && errorMessage && errorMessageId ? errorMessageId : state === "warning" && warningMessage && warningMessageId ? warningMessageId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0,
|
|
22
22
|
"aria-invalid": state === "error" ? true : void 0,
|
package/dist/Checkbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckmarkIcon, MinusIcon } from '@components/Icons'\nimport { ErrorMessage, getErrorMessageId, getWarningMessageId, useFormFieldId, WarningMessage, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\nimport { CheckboxBase, CheckboxIndicator } from './CheckboxBase'\n\nexport interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBase>, 'onCheckedChange'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n checked?: boolean | 'indeterminate'\n disabled?: boolean\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n /** @deprecated Use `label` instead. `labelText` will be removed in a future release. */\n labelText?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n onCheckedChange: (value: boolean | 'indeterminate') => void\n required?: boolean\n state?: FormFieldState\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Checkbox = ({\n checked,\n className,\n errorMessage,\n id,\n label,\n labelText,\n messageReserveLines = 1,\n messageReserveSpace = false,\n onCheckedChange,\n ref,\n required,\n state = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n ...props\n}: CheckboxProps & {\n ref?: Ref<ComponentRef<typeof CheckboxBase>>\n}) => {\n const inputId = useFormFieldId(id, props.name)\n const resolvedLabel = label ?? labelText\n const errorMessageId = getErrorMessageId(inputId)\n const warningMessageId = getWarningMessageId(inputId)\n const messageId = state === 'error' && errorMessage && errorMessageId ? errorMessageId : state === 'warning' && warningMessage && warningMessageId ? warningMessageId : undefined\n\n return (\n <div>\n <div className='gap-2 flex items-start
|
|
1
|
+
{"version":3,"file":"Checkbox.js","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckmarkIcon, MinusIcon } from '@components/Icons'\nimport { ErrorMessage, getErrorMessageId, getWarningMessageId, useFormFieldId, WarningMessage, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\nimport { CheckboxBase, CheckboxIndicator } from './CheckboxBase'\n\nexport interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBase>, 'onCheckedChange'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n checked?: boolean | 'indeterminate'\n disabled?: boolean\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n /** @deprecated Use `label` instead. `labelText` will be removed in a future release. */\n labelText?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n onCheckedChange: (value: boolean | 'indeterminate') => void\n required?: boolean\n state?: FormFieldState\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Checkbox = ({\n checked,\n className,\n errorMessage,\n id,\n label,\n labelText,\n messageReserveLines = 1,\n messageReserveSpace = false,\n onCheckedChange,\n ref,\n required,\n state = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n ...props\n}: CheckboxProps & {\n ref?: Ref<ComponentRef<typeof CheckboxBase>>\n}) => {\n const inputId = useFormFieldId(id, props.name)\n const resolvedLabel = label ?? labelText\n const errorMessageId = getErrorMessageId(inputId)\n const warningMessageId = getWarningMessageId(inputId)\n const messageId = state === 'error' && errorMessage && errorMessageId ? errorMessageId : state === 'warning' && warningMessage && warningMessageId ? warningMessageId : undefined\n\n return (\n <div>\n <div className='gap-2 flex shrink-0 items-start'>\n <CheckboxBase\n aria-describedby={[messageId, ariaDescribedBy].filter(Boolean).join(' ') || undefined}\n aria-invalid={state === 'error' ? true : undefined}\n aria-label={ariaLabel ?? (!resolvedLabel ? 'Checkbox' : undefined)}\n aria-required={required ?? undefined}\n checked={checked}\n className={cn('checkbox peer size-5 mt-0.5 border-checkbox-border hover:opacity-80 focus-visible:outline-1 focus-visible:outline-checkbox-border--focus data-[state=checked]:border-checkbox-border--checked', className)}\n data-field-state={state}\n data-testid='spectral-checkbox'\n id={inputId}\n onCheckedChange={onCheckedChange}\n ref={ref}\n {...props}\n >\n <CheckboxIndicator\n data-testid='spectral-checkbox-indicator'\n className={cn('checkbox-indicator flex items-center justify-center text-checkbox-indicator--checked')}\n >\n {checked === 'indeterminate' ? (\n <MinusIcon\n className='checkbox-indeterminate'\n size={16}\n strokeWidth={4}\n />\n ) : (\n <CheckmarkIcon\n className='checkbox-check'\n size={16}\n strokeWidth={4}\n />\n )}\n </CheckboxIndicator>\n </CheckboxBase>\n {resolvedLabel && (\n <label\n className='text-md peer-disabled:text-neutral-400 text-text-primary'\n data-testid='spectral-checkbox-label'\n htmlFor={inputId}\n >\n {resolvedLabel}\n </label>\n )}\n </div>\n <ErrorMessage\n dataTestId='spectral-checkbox-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-checkbox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\n\nCheckbox.displayName = 'Checkbox'\n"],"mappings":";;;;;;;;;;;AA0BA,MAAa,YAAY,EACvB,SACA,WACA,cACA,IACA,OACA,WACA,sBAAsB,GACtB,sBAAsB,OACtB,iBACA,KACA,UACA,QAAQ,WACR,gBACA,oBAAoB,iBACpB,cAAc,WACd,GAAG,YAGC;CACJ,MAAM,UAAU,eAAe,IAAI,MAAM,KAAI;CAC7C,MAAM,gBAAgB,SAAS;CAC/B,MAAM,iBAAiB,kBAAkB,QAAO;CAChD,MAAM,mBAAmB,oBAAoB,QAAO;AAGpD,QACE,qBAAC,OAAD;EACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,cAAD;IACE,oBAAkB,CANR,UAAU,WAAW,gBAAgB,iBAAiB,iBAAiB,UAAU,aAAa,kBAAkB,mBAAmB,mBAAmB,QAMlI,gBAAgB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI;IAC5E,gBAAc,UAAU,UAAU,OAAO;IACzC,cAAY,cAAc,CAAC,gBAAgB,aAAa;IACxD,iBAAe,YAAY;IAClB;IACT,WAAW,GAAG,iMAAiM,UAAU;IACzN,oBAAkB;IAElB,IAAI;IACa;IACZ;IACL,GAAI;cAEJ,oBAAC,mBAAD;KAEE,WAAW,GAAG,uFAAuF;eAEpG,YAAY,kBACX,oBAAC,WAAD;MACE,WAAU;MACV,MAAM;MACN,aAAa;MACd,IAED,oBAAC,eAAD;MACE,WAAU;MACV,MAAM;MACN,aAAa;MACd;KAEc;IACP,GACb,iBACC,oBAAC,SAAD;IACE,WAAU;IAEV,SAAS;cAER;IACI,EAEN;;EACL,oBAAC,cAAD;GACE,YAAW;GACX,IAAI;GACJ,SAAS,UAAU,UAAU,eAAe;GACvB;GACrB,qBAAqB,uBAAuB,UAAU;GACvD;EACD,oBAAC,gBAAD;GACE,YAAW;GACX,IAAI;GACJ,SAAS,UAAU,YAAY,iBAAiB;GAC3B;GACrB,qBAAqB,uBAAuB,UAAU;GACvD;EACE;;AAIT,SAAS,cAAc"}
|
package/dist/Combobox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.js","names":[],"sources":["../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import { Combobox as ComboboxPrimitive } from '@base-ui/react'\nimport { CheckmarkIcon, ChevronDownIcon, LoaderIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { InputGroup, InputGroupAddon } from '@primitives/input-group'\nimport {\n EmptyState,\n ErrorMessage,\n getAriaProps,\n getDropdownWidthStyles,\n getDropdownSurfaceClasses,\n getErrorMessageId,\n getFormFieldCSSProperties,\n getOptionClasses,\n getTriggerClasses,\n getWarningMessageId,\n LoadingState,\n WarningMessage,\n useFormFieldId,\n type BaseFormFieldProps,\n type BaseOption,\n type DropdownWidth,\n type FormFieldState,\n} from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useMemo, useRef, useState, type CSSProperties, type MouseEvent, type Ref } from 'react'\n\nexport type ComboboxOption = BaseOption\n\nexport interface ComboboxProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'> {\n className?: string\n defaultValue?: string\n dropdownWidth?: DropdownWidth\n emptyMessage?: string\n labelClassName?: string\n loadingMessage?: string\n onChange?: (value: string) => void\n /** @deprecated Use `onChange` instead. `onValueChange` will be removed in a future release. */\n onValueChange?: (value: string) => void\n options: ComboboxOption[]\n placeholder?: string\n state?: Exclude<FormFieldState, 'disabled'>\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Combobox = ({\n className,\n disabled,\n defaultValue = '',\n dropdownWidth = 'trigger',\n emptyMessage = 'No options found.',\n errorMessage,\n id,\n label,\n labelClassName,\n loadingMessage = 'Loading…',\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onChange,\n onValueChange,\n options,\n placeholder = 'Search…',\n ref,\n required,\n state = 'default',\n value: valueProp,\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n}: ComboboxProps & { ref?: Ref<HTMLDivElement> }) => {\n if (process.env.NODE_ENV !== 'production' && !label && !ariaLabel) {\n console.warn('Combobox: provide either `label` or `aria-label` for an accessible name.')\n }\n\n const comboboxId = useFormFieldId(id, name)\n const listboxId = `${comboboxId}-listbox`\n const errorMessageId = getErrorMessageId(comboboxId)\n const warningMessageId = getWarningMessageId(comboboxId)\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const isDisabled = Boolean(disabled)\n const isLoading = state === 'loading'\n const isInvalid = state === 'error'\n const ariaProps = getAriaProps(state, ariaDescribedBy, required, messageId)\n\n const [open, setOpen] = useState(false)\n const [inputValue, setInputValue] = useState('')\n const inputRef = useRef<HTMLInputElement>(null)\n const [value, setValue] = useUncontrolledState<string>({\n value: valueProp,\n defaultValue,\n onChange: (nextValue) => {\n if (onChange) {\n onChange(nextValue)\n } else {\n onValueChange?.(nextValue)\n }\n },\n })\n\n const selectedOption = useMemo(() => options.find((o) => o.value === value) ?? null, [options, value])\n const filteredOptions = useMemo(() => {\n const query = inputValue.trim().toLowerCase()\n if (!query) return options\n return options.filter((option) => option.label.toLowerCase().includes(query))\n }, [inputValue, options])\n const showsSelectedValueAsPlaceholder = Boolean(selectedOption && inputValue.length === 0)\n const { dropdownWidthMode, dropdownWidthStyle } = getDropdownWidthStyles({\n dropdownWidth,\n triggerWidth: 'var(--anchor-width)',\n })\n\n const handleValueChange = (nextOption: ComboboxOption | null, eventDetails: { reason?: string }) => {\n const nextValue = nextOption?.value ?? ''\n const shouldClearSelection = eventDetails.reason === 'item-press' && nextValue === value\n setValue(shouldClearSelection ? '' : nextValue)\n setInputValue('')\n setOpen(false)\n }\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (isDisabled || isLoading) {\n setOpen(false)\n return\n }\n\n if (!nextOpen) {\n setInputValue('')\n }\n\n setOpen(nextOpen)\n }\n\n const handleTriggerContainerClick = (event: MouseEvent<HTMLDivElement>) => {\n if (isDisabled || isLoading) return\n\n const target = event.target as HTMLElement\n if (target === inputRef.current) return\n if (target.closest('[data-slot=combobox-trigger-button]')) return\n inputRef.current?.focus()\n setOpen(true)\n }\n\n return (\n <div className='w-full' ref={ref}>\n {label && (\n <Label className={cn('mb-2 block text-text-primary', labelClassName, isDisabled && 'text-text-secondary')} data-testid='spectral-combobox-label' htmlFor={comboboxId}>\n {label}\n </Label>\n )}\n\n <ComboboxPrimitive.Root\n autoHighlight\n disabled={isDisabled || isLoading}\n filter={null}\n inputValue={inputValue}\n itemToStringLabel={(option: ComboboxOption) => option.label}\n itemToStringValue={(option: ComboboxOption) => option.value}\n openOnInputClick\n onInputValueChange={(nextInputValue, eventDetails) => {\n if (eventDetails.reason !== 'input-change' && eventDetails.reason !== 'input-clear') return\n setInputValue(nextInputValue)\n }}\n name={name}\n onOpenChange={handleOpenChange}\n onValueChange={handleValueChange}\n open={open}\n required={required}\n value={selectedOption}\n >\n <ComboboxPrimitive.InputGroup\n render={\n <InputGroup\n data-slot='combobox-content'\n data-state={state}\n data-testid='spectral-combobox-trigger'\n className={cn(getTriggerClasses(open, state), 'ring-0! outline-none focus-within:outline-none has-[[data-slot=input-group-control]:focus-visible]:outline-0', isDisabled && 'pointer-events-none cursor-not-allowed', className)}\n onClick={handleTriggerContainerClick}\n style={getFormFieldCSSProperties() as CSSProperties}\n />\n }\n >\n <ComboboxPrimitive.Input\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel ?? label}\n autoComplete='off'\n className={cn(\n 'min-w-0 text-base flex-1 truncate overflow-hidden border-0 bg-transparent whitespace-nowrap text-input-text outline-hidden outline-0 placeholder:opacity-100 focus-visible:ring-0 focus-visible:outline-none',\n showsSelectedValueAsPlaceholder ? 'placeholder:text-input-text!' : 'placeholder:text-input-text-placeholder!',\n )}\n data-slot='input-group-control'\n id={comboboxId}\n ref={inputRef}\n placeholder={selectedOption?.label ?? placeholder}\n {...ariaProps}\n />\n <InputGroupAddon align='inline-end' className='cursor-pointer'>\n <ComboboxPrimitive.Trigger\n aria-label='Toggle options'\n className='cursor-pointer'\n data-slot='combobox-trigger-button'\n >\n {isLoading ? <LoaderIcon className='size-5 motion-safe:animate-spin' /> : <ChevronDownIcon className={cn('size-5 shrink-0 transition-transform duration-200', open && 'rotate-180')} />}\n </ComboboxPrimitive.Trigger>\n </InputGroupAddon>\n </ComboboxPrimitive.InputGroup>\n\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Positioner align='start' className='isolate z-50' sideOffset={4}>\n <ComboboxPrimitive.Popup\n className={cn(\n 'p-1 z-50 motion-safe:data-closed:animate-out motion-safe:data-open:animate-in',\n getDropdownSurfaceClasses(),\n 'motion-safe:data-closed:fade-out-0 motion-safe:data-closed:zoom-out-95 motion-safe:data-open:fade-in-0 motion-safe:data-open:zoom-in-95',\n 'max-h-[min(var(--available-height),18rem)] motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=top]:slide-in-from-bottom-2',\n // Keep a single scroll container (the list) to avoid dual scrollbar styles.\n 'min-w-32 origin-(--transform-origin) overflow-hidden',\n )}\n data-dropdown-width-mode={dropdownWidthMode}\n data-dropdown-width-value={dropdownWidthMode === 'custom' ? dropdownWidth : undefined}\n data-testid='spectral-combobox-content'\n style={dropdownWidthStyle}\n >\n {isLoading ? (\n <LoadingState message={loadingMessage} />\n ) : filteredOptions.length === 0 ? (\n <EmptyState message={emptyMessage} />\n ) : (\n <ComboboxPrimitive.List className='max-h-[min(var(--available-height),18rem)] overflow-y-auto' id={listboxId}>\n {filteredOptions.map((option) => (\n <ComboboxPrimitive.Item\n className={cn(getOptionClasses(!!option.disabled, false, value === option.value), 'group/command-item relative flex w-full items-center data-highlighted:bg-input-bg--hover')}\n data-testid='spectral-combobox-item'\n disabled={option.disabled}\n key={option.value}\n value={option}\n >\n <span className='min-w-0 flex-1 truncate whitespace-nowrap'>{option.label}</span>\n <ComboboxPrimitive.ItemIndicator\n render={\n <span className='right-2 h-4 w-4 absolute flex items-center justify-center'>\n <CheckmarkIcon size={16} />\n </span>\n }\n />\n </ComboboxPrimitive.Item>\n ))}\n </ComboboxPrimitive.List>\n )}\n </ComboboxPrimitive.Popup>\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n </ComboboxPrimitive.Root>\n\n <ErrorMessage\n dataTestId='spectral-combobox-error-message'\n id={errorMessageId}\n message={isInvalid ? (errorMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-combobox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? (warningMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nCombobox.displayName = 'Combobox'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Combobox.js","names":[],"sources":["../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import { Combobox as ComboboxPrimitive } from '@base-ui/react'\nimport { CheckmarkIcon, ChevronDownIcon, LoaderIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { InputGroup, InputGroupAddon } from '@primitives/input-group'\nimport {\n EmptyState,\n ErrorMessage,\n getAriaProps,\n getDropdownWidthStyles,\n getDropdownSurfaceClasses,\n getErrorMessageId,\n getFormFieldCSSProperties,\n getOptionClasses,\n getTriggerClasses,\n getWarningMessageId,\n LoadingState,\n WarningMessage,\n useFormFieldId,\n type BaseFormFieldProps,\n type BaseOption,\n type DropdownWidth,\n type FormFieldState,\n} from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useMemo, useRef, useState, type CSSProperties, type MouseEvent, type Ref } from 'react'\n\nexport type ComboboxOption = BaseOption\n\nexport interface ComboboxProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'> {\n className?: string\n defaultValue?: string\n dropdownWidth?: DropdownWidth\n emptyMessage?: string\n labelClassName?: string\n loadingMessage?: string\n onChange?: (value: string) => void\n /** @deprecated Use `onChange` instead. `onValueChange` will be removed in a future release. */\n onValueChange?: (value: string) => void\n options: ComboboxOption[]\n placeholder?: string\n state?: Exclude<FormFieldState, 'disabled'>\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Combobox = ({\n className,\n disabled,\n defaultValue = '',\n dropdownWidth = 'trigger',\n emptyMessage = 'No options found.',\n errorMessage,\n id,\n label,\n labelClassName,\n loadingMessage = 'Loading…',\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onChange,\n onValueChange,\n options,\n placeholder = 'Search…',\n ref,\n required,\n state = 'default',\n value: valueProp,\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n}: ComboboxProps & { ref?: Ref<HTMLDivElement> }) => {\n if (process.env.NODE_ENV !== 'production' && !label && !ariaLabel) {\n console.warn('Combobox: provide either `label` or `aria-label` for an accessible name.')\n }\n\n const comboboxId = useFormFieldId(id, name)\n const listboxId = `${comboboxId}-listbox`\n const errorMessageId = getErrorMessageId(comboboxId)\n const warningMessageId = getWarningMessageId(comboboxId)\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const isDisabled = Boolean(disabled)\n const isLoading = state === 'loading'\n const isInvalid = state === 'error'\n const ariaProps = getAriaProps(state, ariaDescribedBy, required, messageId)\n\n const [open, setOpen] = useState(false)\n const [inputValue, setInputValue] = useState('')\n const inputRef = useRef<HTMLInputElement>(null)\n const [value, setValue] = useUncontrolledState<string>({\n value: valueProp,\n defaultValue,\n onChange: (nextValue) => {\n if (onChange) {\n onChange(nextValue)\n } else {\n onValueChange?.(nextValue)\n }\n },\n })\n\n const selectedOption = useMemo(() => options.find((o) => o.value === value) ?? null, [options, value])\n const filteredOptions = useMemo(() => {\n const query = inputValue.trim().toLowerCase()\n if (!query) return options\n return options.filter((option) => option.label.toLowerCase().includes(query))\n }, [inputValue, options])\n const showsSelectedValueAsPlaceholder = Boolean(selectedOption && inputValue.length === 0)\n const { dropdownWidthMode, dropdownWidthStyle } = getDropdownWidthStyles({\n dropdownWidth,\n triggerWidth: 'var(--anchor-width)',\n })\n\n const handleValueChange = (nextOption: ComboboxOption | null, eventDetails: { reason?: string }) => {\n const nextValue = nextOption?.value ?? ''\n const shouldClearSelection = eventDetails.reason === 'item-press' && nextValue === value\n setValue(shouldClearSelection ? '' : nextValue)\n setInputValue('')\n setOpen(false)\n }\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (isDisabled || isLoading) {\n setOpen(false)\n return\n }\n\n if (!nextOpen) {\n setInputValue('')\n }\n\n setOpen(nextOpen)\n }\n\n const handleTriggerContainerClick = (event: MouseEvent<HTMLDivElement>) => {\n if (isDisabled || isLoading) return\n\n const target = event.target as HTMLElement\n if (target === inputRef.current) return\n if (target.closest('[data-slot=combobox-trigger-button]')) return\n inputRef.current?.focus()\n setOpen(true)\n }\n\n return (\n <div\n className='w-full'\n ref={ref}\n >\n {label && (\n <Label\n className={cn('mb-2 block text-text-primary', labelClassName, isDisabled && 'text-text-secondary')}\n data-testid='spectral-combobox-label'\n htmlFor={comboboxId}\n >\n {label}\n </Label>\n )}\n\n <ComboboxPrimitive.Root\n autoHighlight\n disabled={isDisabled || isLoading}\n filter={null}\n inputValue={inputValue}\n itemToStringLabel={(option: ComboboxOption) => option.label}\n itemToStringValue={(option: ComboboxOption) => option.value}\n openOnInputClick\n onInputValueChange={(nextInputValue, eventDetails) => {\n if (eventDetails.reason !== 'input-change' && eventDetails.reason !== 'input-clear') return\n setInputValue(nextInputValue)\n }}\n name={name}\n onOpenChange={handleOpenChange}\n onValueChange={handleValueChange}\n open={open}\n required={required}\n value={selectedOption}\n >\n <ComboboxPrimitive.InputGroup\n render={\n <InputGroup\n data-slot='combobox-content'\n data-state={state}\n data-testid='spectral-combobox-trigger'\n className={cn(getTriggerClasses(open, state), 'ring-0! outline-none focus-within:outline-none has-[[data-slot=input-group-control]:focus-visible]:outline-0', isDisabled && 'pointer-events-none cursor-not-allowed', className)}\n onClick={handleTriggerContainerClick}\n style={getFormFieldCSSProperties() as CSSProperties}\n />\n }\n >\n <ComboboxPrimitive.Input\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel ?? label}\n autoComplete='off'\n className={cn(\n 'min-w-0 text-base flex-1 truncate overflow-hidden border-0 bg-transparent whitespace-nowrap text-input-text outline-hidden outline-0 placeholder:opacity-100 focus-visible:ring-0 focus-visible:outline-none',\n showsSelectedValueAsPlaceholder ? 'placeholder:text-input-text!' : 'placeholder:text-input-text-placeholder!',\n )}\n data-slot='input-group-control'\n id={comboboxId}\n ref={inputRef}\n placeholder={selectedOption?.label ?? placeholder}\n {...ariaProps}\n />\n <InputGroupAddon\n align='inline-end'\n className='cursor-pointer'\n >\n <ComboboxPrimitive.Trigger\n aria-label='Toggle options'\n className='cursor-pointer'\n data-slot='combobox-trigger-button'\n >\n {isLoading ? <LoaderIcon className='size-5 motion-safe:animate-spin' /> : <ChevronDownIcon className={cn('size-5 shrink-0 transition-transform duration-200', open && 'rotate-180')} />}\n </ComboboxPrimitive.Trigger>\n </InputGroupAddon>\n </ComboboxPrimitive.InputGroup>\n\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Positioner\n align='start'\n className='isolate z-50'\n sideOffset={4}\n >\n <ComboboxPrimitive.Popup\n className={cn(\n 'p-1 z-50 motion-safe:data-closed:animate-out motion-safe:data-open:animate-in',\n getDropdownSurfaceClasses(),\n 'motion-safe:data-closed:fade-out-0 motion-safe:data-closed:zoom-out-95 motion-safe:data-open:fade-in-0 motion-safe:data-open:zoom-in-95',\n 'max-h-[min(var(--available-height),18rem)] motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=top]:slide-in-from-bottom-2',\n // Keep a single scroll container (the list) to avoid dual scrollbar styles.\n 'min-w-32 origin-(--transform-origin) overflow-hidden',\n )}\n data-dropdown-width-mode={dropdownWidthMode}\n data-dropdown-width-value={dropdownWidthMode === 'custom' ? dropdownWidth : undefined}\n data-testid='spectral-combobox-content'\n style={dropdownWidthStyle}\n >\n {isLoading ? (\n <LoadingState message={loadingMessage} />\n ) : filteredOptions.length === 0 ? (\n <EmptyState message={emptyMessage} />\n ) : (\n <ComboboxPrimitive.List\n className='max-h-[min(var(--available-height),18rem)] overflow-y-auto'\n id={listboxId}\n >\n {filteredOptions.map((option) => (\n <ComboboxPrimitive.Item\n className={cn(getOptionClasses(!!option.disabled, false, value === option.value), 'group/command-item relative flex w-full items-center data-highlighted:bg-input-bg--hover')}\n data-testid='spectral-combobox-item'\n disabled={option.disabled}\n key={option.value}\n value={option}\n >\n <span className='min-w-0 flex-1 truncate whitespace-nowrap'>{option.label}</span>\n <ComboboxPrimitive.ItemIndicator\n render={\n <span className='right-2 h-4 w-4 absolute flex items-center justify-center'>\n <CheckmarkIcon size={16} />\n </span>\n }\n />\n </ComboboxPrimitive.Item>\n ))}\n </ComboboxPrimitive.List>\n )}\n </ComboboxPrimitive.Popup>\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n </ComboboxPrimitive.Root>\n\n <ErrorMessage\n dataTestId='spectral-combobox-error-message'\n id={errorMessageId}\n message={isInvalid ? (errorMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-combobox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? (warningMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nCombobox.displayName = 'Combobox'\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroupSelect.js","names":[],"sources":["../../src/components/ControlGroup/ControlGroupSelect.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { Input } from '@primitives/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@primitives/select'\nimport { getStateClasses, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useId, type ComponentProps } from 'react'\nimport { ControlGroup, ControlGroupItem, useControlGroup, type ControlGroupProps } from './ControlGroup'\n\nconst numberInputNoSpinner = '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'\nconst defaultInputLabel = 'Amount'\nconst defaultSelectLabel = 'Select an option'\n\nexport interface SelectOptionType {\n disabled?: boolean\n label: string\n value: string\n}\n\n/** `inline`: `inputPlaceholder` / `selectPlaceholder` show inside the fields. `above`: same strings render as labels above each control (no inner placeholders). */\nexport type ControlGroupSelectCaptionLayout = 'above' | 'inline'\n\ntype ControlGroupSelectInputControlProps =\n | {\n inputValue: ComponentProps<typeof Input>['value']\n onInputChange: ComponentProps<typeof Input>['onChange']\n }\n | {\n inputValue?: undefined\n onInputChange?: undefined\n }\n\ntype ControlGroupSelectBaseProps = ComponentProps<typeof Select> &\n Pick<ControlGroupProps, 'orientation'> & {\n amountStep?: number\n /** Accessible name for the group wrapper (use when there is no visible group heading). */\n ariaLabel?: string\n captionLayout?: ControlGroupSelectCaptionLayout\n className?: string\n dataTestId?: string\n disabled?: boolean\n dropdownWidth?: DropdownWidth\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n /** Class applied to the input `ControlGroupItem` segment for width/split composition. */\n inputItemClassName?: string\n /** When `captionLayout` is `inline`, overrides the input's accessible name (defaults to `inputPlaceholder` when set). */\n inputAriaLabel?: string\n inputPlaceholder?: string\n maxAmount?: number\n /** Number of message lines to reserve (default: 1). */\n messageReserveLines?: number\n /** Whether to keep message space reserved when hidden (default: false). */\n messageReserveSpace?: boolean\n minAmount?: number\n selectPlaceholder?: string\n /** When `captionLayout` is `inline` and `selectPlaceholder` is empty, sets the select trigger's accessible name. */\n selectAriaLabel?: string\n /** Class applied to the select `ControlGroupItem` segment for width/split composition. */\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n state?: Exclude<FormFieldState, 'disabled'>\n type?: 'number' | 'text'\n warningMessage?: string | string[] | Record<string, unknown> | null\n }\n\nexport type ControlGroupSelectProps = ControlGroupSelectBaseProps & ControlGroupSelectInputControlProps\n\nconst fieldStackClass = 'flex w-full min-w-0 flex-col gap-1.5'\nconst groupedFieldBaseClasses =\n 'h-12! min-h-12! border-2! border-input-border bg-input-bg text-base text-input-text transition duration-200 placeholder:text-input-text-placeholder hover:border-input-border--hover focus-visible:border-input-border--focus focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus disabled:pointer-events-none disabled:border-input-border--disabled disabled:bg-input-bg--disabled disabled:text-input-text--disabled'\n\nconst getFieldMinWidth = (caption?: string, extraCharacters: number = 0): string | undefined => {\n const normalizedCaption = caption?.trim()\n if (!normalizedCaption) return undefined\n return `${Math.max(normalizedCaption.length + extraCharacters, 8)}ch`\n}\n\nconst getReadableLabel = (label: string | undefined, fallback: string): string => {\n const normalizedLabel = label?.trim()\n return normalizedLabel && normalizedLabel.length > 0 ? normalizedLabel : fallback\n}\n\nexport const ControlGroupSelect = ({\n amountStep,\n ariaLabel,\n captionLayout = 'inline',\n className,\n dataTestId = 'spectral-control-group-select',\n disabled,\n errorMessage,\n id,\n dropdownWidth = 'trigger',\n inputAriaLabel,\n inputPlaceholder,\n inputItemClassName,\n inputValue,\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxAmount = 1000000,\n minAmount = 0,\n onInputChange,\n orientation = 'horizontal',\n selectAriaLabel,\n selectItemClassName,\n selectOptions,\n selectPlaceholder,\n state = 'default',\n type = 'number',\n warningMessage,\n ...selectProps\n}: ControlGroupSelectProps) => {\n const baseId = useId()\n const idPrefix = id ?? baseId\n const inputId = `${idPrefix}-amount`\n const selectTriggerId = `${idPrefix}-select`\n const inputLabelId = `${inputId}-label`\n const selectLabelId = `${selectTriggerId}-label`\n\n const useAboveLabels = captionLayout === 'above'\n const inputCaption = useAboveLabels ? undefined : inputPlaceholder\n const selectCaption = useAboveLabels ? undefined : selectPlaceholder\n const inputLabelText = getReadableLabel(inputPlaceholder, defaultInputLabel)\n const selectLabelText = getReadableLabel(selectPlaceholder, defaultSelectLabel)\n\n const inputAccessibleName = inputAriaLabel ?? (useAboveLabels ? undefined : inputLabelText)\n const selectTriggerAriaLabel = selectAriaLabel ?? (useAboveLabels ? undefined : selectLabelText)\n const inputMinWidth = getFieldMinWidth(inputPlaceholder, 3)\n const selectTriggerMinWidth = getFieldMinWidth(selectPlaceholder, 5)\n const groupAriaLabel = ariaLabel ?? `${inputLabelText} and ${selectLabelText}`\n\n const isDisabled = !!disabled\n const isInputControlled = inputValue !== undefined && onInputChange !== undefined\n\n return (\n <ControlGroup\n aria-label={groupAriaLabel}\n className={className}\n data-testid={dataTestId}\n disabled={disabled}\n errorMessage={errorMessage}\n id={idPrefix}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n orientation={orientation}\n state={state}\n warningMessage={warningMessage}\n >\n <ControlGroupSelectInner\n amountStep={amountStep}\n dataTestId={dataTestId}\n inputAccessibleName={inputAccessibleName}\n inputCaption={inputCaption}\n inputId={inputId}\n inputLabelId={inputLabelId}\n inputLabelText={inputLabelText}\n inputItemClassName={inputItemClassName}\n inputMinWidth={inputMinWidth}\n inputValue={isInputControlled ? inputValue : undefined}\n isDisabled={isDisabled}\n maxAmount={maxAmount}\n minAmount={minAmount}\n onInputChange={isInputControlled ? onInputChange : undefined}\n dropdownWidth={dropdownWidth}\n selectCaption={selectCaption}\n selectOptions={selectOptions}\n selectLabelId={selectLabelId}\n selectLabelText={selectLabelText}\n selectItemClassName={selectItemClassName}\n selectProps={selectProps}\n selectTriggerAriaLabel={selectTriggerAriaLabel}\n selectTriggerId={selectTriggerId}\n selectTriggerMinWidth={selectTriggerMinWidth}\n type={type}\n useAboveLabels={useAboveLabels}\n />\n </ControlGroup>\n )\n}\n\ninterface ControlGroupSelectInnerProps {\n amountStep?: number\n dataTestId: string\n dropdownWidth: DropdownWidth\n inputAccessibleName?: string\n inputCaption?: string\n inputId: string\n inputLabelId: string\n inputLabelText: string\n inputItemClassName?: string\n inputMinWidth?: string\n inputValue?: ComponentProps<typeof Input>['value']\n isDisabled: boolean\n maxAmount: number\n minAmount: number\n onInputChange?: ComponentProps<typeof Input>['onChange']\n selectCaption?: string\n selectLabelId: string\n selectLabelText: string\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n selectProps: Omit<ComponentProps<typeof Select>, 'children'>\n selectTriggerAriaLabel?: string\n selectTriggerId: string\n selectTriggerMinWidth?: string\n type: 'number' | 'text'\n useAboveLabels: boolean\n}\n\nconst ControlGroupSelectInner = ({\n amountStep,\n dataTestId,\n dropdownWidth,\n inputAccessibleName,\n inputCaption,\n inputId,\n inputLabelId,\n inputLabelText,\n inputItemClassName,\n inputMinWidth,\n inputValue,\n isDisabled,\n maxAmount,\n minAmount,\n onInputChange,\n selectCaption,\n selectLabelId,\n selectLabelText,\n selectItemClassName,\n selectOptions,\n selectProps,\n selectTriggerAriaLabel,\n selectTriggerId,\n selectTriggerMinWidth,\n type,\n useAboveLabels,\n}: ControlGroupSelectInnerProps) => {\n const { messageId, orientation, state } = useControlGroup()\n const isSelectOpenControlled = selectProps.open !== undefined\n const handleSelectOpenChange: NonNullable<ComponentProps<typeof Select>['onOpenChange']> = (nextOpen) => {\n selectProps.onOpenChange?.(nextOpen)\n }\n\n const inputRadiusClasses = orientation === 'horizontal' ? 'rounded-s-md rounded-e-none' : 'rounded-ss-md rounded-se-md rounded-es-none rounded-ee-none'\n const selectRadiusClasses = orientation === 'horizontal' ? 'rounded-s-none rounded-e-md' : 'rounded-ss-none rounded-se-none rounded-es-md rounded-ee-md'\n const firstItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0' : 'mbe-0'\n const secondItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0 [&>*:last-child]:-ms-0.5' : 'mbe-0 [&>*:last-child]:-mt-0.5'\n\n const inputElement = (\n <Input\n aria-describedby={messageId}\n aria-label={inputAccessibleName}\n aria-labelledby={useAboveLabels ? inputLabelId : undefined}\n className={cn(groupedFieldBaseClasses, inputRadiusClasses, getStateClasses(state), type === 'number' && numberInputNoSpinner, type === 'number' && 'tabular-nums')}\n data-testid={`${dataTestId}-input`}\n disabled={isDisabled}\n id={useAboveLabels ? inputId : undefined}\n type={type === 'number' ? 'number' : 'text'}\n placeholder={inputCaption}\n style={inputMinWidth ? { minWidth: inputMinWidth } : undefined}\n min={minAmount ?? 0}\n max={maxAmount ?? 1000000}\n {...(inputValue !== undefined && onInputChange !== undefined ? { value: inputValue, onChange: onInputChange } : {})}\n step={amountStep ?? 1}\n />\n )\n\n const selectTriggerElement = (\n <SelectTrigger\n aria-describedby={messageId}\n aria-label={selectTriggerAriaLabel}\n aria-labelledby={useAboveLabels ? selectLabelId : undefined}\n className={cn(\n 'text-input-text data-placeholder:text-input-text-placeholder!',\n selectRadiusClasses,\n 'px-4 w-full justify-between focus-visible:border-input-border--focus focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus',\n getStateClasses(state),\n )}\n data-testid={`${dataTestId}-select-trigger`}\n disabled={isDisabled}\n id={useAboveLabels ? selectTriggerId : undefined}\n style={selectTriggerMinWidth ? { minWidth: selectTriggerMinWidth } : undefined}\n >\n <SelectValue className='min-w-0 block max-w-full truncate text-left whitespace-nowrap text-input-text! data-placeholder:text-input-text-placeholder!' placeholder={selectCaption} />\n </SelectTrigger>\n )\n\n return (\n <>\n <ControlGroupItem className={cn(useAboveLabels ? firstItemAboveLabelClasses : undefined, inputItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={inputId} id={inputLabelId}>\n {inputLabelText}\n </Label>\n {inputElement}\n </div>\n ) : (\n inputElement\n )}\n </ControlGroupItem>\n <Select {...selectProps} data-testid={`${dataTestId}-select-root`} disabled={isDisabled} {...(isSelectOpenControlled ? { open: selectProps.open } : {})} onOpenChange={handleSelectOpenChange}>\n <ControlGroupItem className={cn(useAboveLabels ? secondItemAboveLabelClasses : undefined, selectItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={selectTriggerId} id={selectLabelId}>\n {selectLabelText}\n </Label>\n {selectTriggerElement}\n </div>\n ) : (\n selectTriggerElement\n )}\n </ControlGroupItem>\n <SelectContent data-testid={`${dataTestId}-select-content`} dropdownWidth={dropdownWidth}>\n {selectOptions.map((option) => (\n <SelectItem disabled={option.disabled} key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ControlGroupSelect.js","names":[],"sources":["../../src/components/ControlGroup/ControlGroupSelect.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { Input } from '@primitives/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@primitives/select'\nimport { getStateClasses, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useId, type ComponentProps } from 'react'\nimport { ControlGroup, ControlGroupItem, useControlGroup, type ControlGroupProps } from './ControlGroup'\n\nconst numberInputNoSpinner = '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'\nconst defaultInputLabel = 'Amount'\nconst defaultSelectLabel = 'Select an option'\n\nexport interface SelectOptionType {\n disabled?: boolean\n label: string\n value: string\n}\n\n/** `inline`: `inputPlaceholder` / `selectPlaceholder` show inside the fields. `above`: same strings render as labels above each control (no inner placeholders). */\nexport type ControlGroupSelectCaptionLayout = 'above' | 'inline'\n\ntype ControlGroupSelectInputControlProps =\n | {\n inputValue: ComponentProps<typeof Input>['value']\n onInputChange: ComponentProps<typeof Input>['onChange']\n }\n | {\n inputValue?: undefined\n onInputChange?: undefined\n }\n\ntype ControlGroupSelectBaseProps = ComponentProps<typeof Select> &\n Pick<ControlGroupProps, 'orientation'> & {\n amountStep?: number\n /** Accessible name for the group wrapper (use when there is no visible group heading). */\n ariaLabel?: string\n captionLayout?: ControlGroupSelectCaptionLayout\n className?: string\n dataTestId?: string\n disabled?: boolean\n dropdownWidth?: DropdownWidth\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n /** Class applied to the input `ControlGroupItem` segment for width/split composition. */\n inputItemClassName?: string\n /** When `captionLayout` is `inline`, overrides the input's accessible name (defaults to `inputPlaceholder` when set). */\n inputAriaLabel?: string\n inputPlaceholder?: string\n maxAmount?: number\n /** Number of message lines to reserve (default: 1). */\n messageReserveLines?: number\n /** Whether to keep message space reserved when hidden (default: false). */\n messageReserveSpace?: boolean\n minAmount?: number\n selectPlaceholder?: string\n /** When `captionLayout` is `inline` and `selectPlaceholder` is empty, sets the select trigger's accessible name. */\n selectAriaLabel?: string\n /** Class applied to the select `ControlGroupItem` segment for width/split composition. */\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n state?: Exclude<FormFieldState, 'disabled'>\n type?: 'number' | 'text'\n warningMessage?: string | string[] | Record<string, unknown> | null\n }\n\nexport type ControlGroupSelectProps = ControlGroupSelectBaseProps & ControlGroupSelectInputControlProps\n\nconst fieldStackClass = 'flex w-full min-w-0 flex-col gap-1.5'\nconst groupedFieldBaseClasses =\n 'h-12! min-h-12! border-2! border-input-border bg-input-bg text-base text-input-text transition duration-200 placeholder:text-input-text-placeholder hover:border-input-border--hover focus-visible:border-input-border--focus focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus disabled:pointer-events-none disabled:border-input-border--disabled disabled:bg-input-bg--disabled disabled:text-input-text--disabled'\n\nconst getFieldMinWidth = (caption?: string, extraCharacters: number = 0): string | undefined => {\n const normalizedCaption = caption?.trim()\n if (!normalizedCaption) return undefined\n return `${Math.max(normalizedCaption.length + extraCharacters, 8)}ch`\n}\n\nconst getReadableLabel = (label: string | undefined, fallback: string): string => {\n const normalizedLabel = label?.trim()\n return normalizedLabel && normalizedLabel.length > 0 ? normalizedLabel : fallback\n}\n\nexport const ControlGroupSelect = ({\n amountStep,\n ariaLabel,\n captionLayout = 'inline',\n className,\n dataTestId = 'spectral-control-group-select',\n disabled,\n errorMessage,\n id,\n dropdownWidth = 'trigger',\n inputAriaLabel,\n inputPlaceholder,\n inputItemClassName,\n inputValue,\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxAmount = 1000000,\n minAmount = 0,\n onInputChange,\n orientation = 'horizontal',\n selectAriaLabel,\n selectItemClassName,\n selectOptions,\n selectPlaceholder,\n state = 'default',\n type = 'number',\n warningMessage,\n ...selectProps\n}: ControlGroupSelectProps) => {\n const baseId = useId()\n const idPrefix = id ?? baseId\n const inputId = `${idPrefix}-amount`\n const selectTriggerId = `${idPrefix}-select`\n const inputLabelId = `${inputId}-label`\n const selectLabelId = `${selectTriggerId}-label`\n\n const useAboveLabels = captionLayout === 'above'\n const inputCaption = useAboveLabels ? undefined : inputPlaceholder\n const selectCaption = useAboveLabels ? undefined : selectPlaceholder\n const inputLabelText = getReadableLabel(inputPlaceholder, defaultInputLabel)\n const selectLabelText = getReadableLabel(selectPlaceholder, defaultSelectLabel)\n\n const inputAccessibleName = inputAriaLabel ?? (useAboveLabels ? undefined : inputLabelText)\n const selectTriggerAriaLabel = selectAriaLabel ?? (useAboveLabels ? undefined : selectLabelText)\n const inputMinWidth = getFieldMinWidth(inputPlaceholder, 3)\n const selectTriggerMinWidth = getFieldMinWidth(selectPlaceholder, 5)\n const groupAriaLabel = ariaLabel ?? `${inputLabelText} and ${selectLabelText}`\n\n const isDisabled = !!disabled\n const isInputControlled = inputValue !== undefined && onInputChange !== undefined\n\n return (\n <ControlGroup\n aria-label={groupAriaLabel}\n className={className}\n data-testid={dataTestId}\n disabled={disabled}\n errorMessage={errorMessage}\n id={idPrefix}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n orientation={orientation}\n state={state}\n warningMessage={warningMessage}\n >\n <ControlGroupSelectInner\n amountStep={amountStep}\n dataTestId={dataTestId}\n inputAccessibleName={inputAccessibleName}\n inputCaption={inputCaption}\n inputId={inputId}\n inputLabelId={inputLabelId}\n inputLabelText={inputLabelText}\n inputItemClassName={inputItemClassName}\n inputMinWidth={inputMinWidth}\n inputValue={isInputControlled ? inputValue : undefined}\n isDisabled={isDisabled}\n maxAmount={maxAmount}\n minAmount={minAmount}\n onInputChange={isInputControlled ? onInputChange : undefined}\n dropdownWidth={dropdownWidth}\n selectCaption={selectCaption}\n selectOptions={selectOptions}\n selectLabelId={selectLabelId}\n selectLabelText={selectLabelText}\n selectItemClassName={selectItemClassName}\n selectProps={selectProps}\n selectTriggerAriaLabel={selectTriggerAriaLabel}\n selectTriggerId={selectTriggerId}\n selectTriggerMinWidth={selectTriggerMinWidth}\n type={type}\n useAboveLabels={useAboveLabels}\n />\n </ControlGroup>\n )\n}\n\ninterface ControlGroupSelectInnerProps {\n amountStep?: number\n dataTestId: string\n dropdownWidth: DropdownWidth\n inputAccessibleName?: string\n inputCaption?: string\n inputId: string\n inputLabelId: string\n inputLabelText: string\n inputItemClassName?: string\n inputMinWidth?: string\n inputValue?: ComponentProps<typeof Input>['value']\n isDisabled: boolean\n maxAmount: number\n minAmount: number\n onInputChange?: ComponentProps<typeof Input>['onChange']\n selectCaption?: string\n selectLabelId: string\n selectLabelText: string\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n selectProps: Omit<ComponentProps<typeof Select>, 'children'>\n selectTriggerAriaLabel?: string\n selectTriggerId: string\n selectTriggerMinWidth?: string\n type: 'number' | 'text'\n useAboveLabels: boolean\n}\n\nconst ControlGroupSelectInner = ({\n amountStep,\n dataTestId,\n dropdownWidth,\n inputAccessibleName,\n inputCaption,\n inputId,\n inputLabelId,\n inputLabelText,\n inputItemClassName,\n inputMinWidth,\n inputValue,\n isDisabled,\n maxAmount,\n minAmount,\n onInputChange,\n selectCaption,\n selectLabelId,\n selectLabelText,\n selectItemClassName,\n selectOptions,\n selectProps,\n selectTriggerAriaLabel,\n selectTriggerId,\n selectTriggerMinWidth,\n type,\n useAboveLabels,\n}: ControlGroupSelectInnerProps) => {\n const { messageId, orientation, state } = useControlGroup()\n const isSelectOpenControlled = selectProps.open !== undefined\n const handleSelectOpenChange: NonNullable<ComponentProps<typeof Select>['onOpenChange']> = (nextOpen) => {\n selectProps.onOpenChange?.(nextOpen)\n }\n\n const inputRadiusClasses = orientation === 'horizontal' ? 'rounded-s-md rounded-e-none' : 'rounded-ss-md rounded-se-md rounded-es-none rounded-ee-none'\n const selectRadiusClasses = orientation === 'horizontal' ? 'rounded-s-none rounded-e-md' : 'rounded-ss-none rounded-se-none rounded-es-md rounded-ee-md'\n const firstItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0' : 'mbe-0'\n const secondItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0 [&>*:last-child]:-ms-0.5' : 'mbe-0 [&>*:last-child]:-mt-0.5'\n\n const inputElement = (\n <Input\n aria-describedby={messageId}\n aria-label={inputAccessibleName}\n aria-labelledby={useAboveLabels ? inputLabelId : undefined}\n className={cn(groupedFieldBaseClasses, inputRadiusClasses, getStateClasses(state), type === 'number' && numberInputNoSpinner, type === 'number' && 'tabular-nums')}\n data-testid={`${dataTestId}-input`}\n disabled={isDisabled}\n id={useAboveLabels ? inputId : undefined}\n type={type === 'number' ? 'number' : 'text'}\n placeholder={inputCaption}\n style={inputMinWidth ? { minWidth: inputMinWidth } : undefined}\n min={minAmount ?? 0}\n max={maxAmount ?? 1000000}\n {...(inputValue !== undefined && onInputChange !== undefined ? { value: inputValue, onChange: onInputChange } : {})}\n step={amountStep ?? 1}\n />\n )\n\n const selectTriggerElement = (\n <SelectTrigger\n aria-describedby={messageId}\n aria-label={selectTriggerAriaLabel}\n aria-labelledby={useAboveLabels ? selectLabelId : undefined}\n className={cn(\n 'text-input-text data-placeholder:text-input-text-placeholder!',\n selectRadiusClasses,\n 'px-4 w-full justify-between focus-visible:border-input-border--focus focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus',\n getStateClasses(state),\n )}\n data-testid={`${dataTestId}-select-trigger`}\n disabled={isDisabled}\n id={useAboveLabels ? selectTriggerId : undefined}\n style={selectTriggerMinWidth ? { minWidth: selectTriggerMinWidth } : undefined}\n >\n <SelectValue\n className='min-w-0 block max-w-full truncate text-left whitespace-nowrap text-input-text! data-placeholder:text-input-text-placeholder!'\n placeholder={selectCaption}\n />\n </SelectTrigger>\n )\n\n return (\n <>\n <ControlGroupItem className={cn(useAboveLabels ? firstItemAboveLabelClasses : undefined, inputItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label\n className='text-text-primary'\n htmlFor={inputId}\n id={inputLabelId}\n >\n {inputLabelText}\n </Label>\n {inputElement}\n </div>\n ) : (\n inputElement\n )}\n </ControlGroupItem>\n <Select\n {...selectProps}\n data-testid={`${dataTestId}-select-root`}\n disabled={isDisabled}\n {...(isSelectOpenControlled ? { open: selectProps.open } : {})}\n onOpenChange={handleSelectOpenChange}\n >\n <ControlGroupItem className={cn(useAboveLabels ? secondItemAboveLabelClasses : undefined, selectItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label\n className='text-text-primary'\n htmlFor={selectTriggerId}\n id={selectLabelId}\n >\n {selectLabelText}\n </Label>\n {selectTriggerElement}\n </div>\n ) : (\n selectTriggerElement\n )}\n </ControlGroupItem>\n <SelectContent\n data-testid={`${dataTestId}-select-content`}\n dropdownWidth={dropdownWidth}\n >\n {selectOptions.map((option) => (\n <SelectItem\n disabled={option.disabled}\n key={option.value}\n value={option.value}\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroup.d.ts","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"mappings":";;;;;;;UAKU,wBAAA;EACR,SAAA;EACA,UAAA;EACA,SAAA;EACA,SAAA;EACA,WAAA;EACA,KAAA,EAAO,cAAA;AAAA;AAAA,cAKI,eAAA,QAAe,wBAAA;AAAA,UAQX,iBAAA,SAA0B,cAAA;EACzC,QAAA;EACA,YAAA,uBAAmC,MAAA;EACnC,EAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,WAAA;EACA,KAAA,GAAQ,cAAA;EACR,cAAA,uBAAqC,MAAA;AAAA;AAAA,cAG1B,YAAA;EAAY,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,EAAA;EAAA,mBAAA;EAAA,mBAAA;EAAA,IAAA;EAAA,WAAA;EAAA,KAAA;EAAA,cAAA;EAAA,GAAA;AAAA,GAAoL,iBAAA,KAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"ControlGroup.d.ts","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"mappings":";;;;;;;UAKU,wBAAA;EACR,SAAA;EACA,UAAA;EACA,SAAA;EACA,SAAA;EACA,WAAA;EACA,KAAA,EAAO,cAAA;AAAA;AAAA,cAKI,eAAA,QAAe,wBAAA;AAAA,UAQX,iBAAA,SAA0B,cAAA;EACzC,QAAA;EACA,YAAA,uBAAmC,MAAA;EACnC,EAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,WAAA;EACA,KAAA,GAAQ,cAAA;EACR,cAAA,uBAAqC,MAAA;AAAA;AAAA,cAG1B,YAAA;EAAY,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,EAAA;EAAA,mBAAA;EAAA,mBAAA;EAAA,IAAA;EAAA,WAAA;EAAA,KAAA;EAAA,cAAA;EAAA,GAAA;AAAA,GAAoL,iBAAA,KAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cA0CjN,gBAAA;EAAgB,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,QAAsB,IAAA,MAAK,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/ControlGroup.js
CHANGED
|
@@ -30,7 +30,7 @@ const ControlGroup = ({ className, disabled, errorMessage, id, messageReserveLin
|
|
|
30
30
|
},
|
|
31
31
|
children: /* @__PURE__ */ jsxs("div", {
|
|
32
32
|
"data-slot": "control-group-field",
|
|
33
|
-
className: "flex w-full flex-col
|
|
33
|
+
className: "gap-1.5 flex w-full flex-col",
|
|
34
34
|
children: [
|
|
35
35
|
/* @__PURE__ */ jsx("div", {
|
|
36
36
|
"data-slot": "control-group",
|
package/dist/ControlGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroup.js","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId, useFormFieldState, WarningMessage, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useContext, type ComponentProps } from 'react'\n\ninterface ControlGroupContextValue {\n messageId?: string\n isDisabled: boolean\n isInvalid: boolean\n isLoading: boolean\n orientation: 'horizontal' | 'vertical'\n state: FormFieldState\n}\n\nconst ControlGroupContext = createContext<ControlGroupContextValue | null>(null)\n\nexport const useControlGroup = () => {\n const context = useContext(ControlGroupContext)\n if (context === null) {\n throw new Error('useControlGroup must be used within a ControlGroup')\n }\n return context\n}\n\nexport interface ControlGroupProps extends ComponentProps<'div'> {\n disabled?: boolean\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n orientation?: 'horizontal' | 'vertical'\n state?: FormFieldState\n warningMessage?: string | string[] | Record<string, unknown> | null\n}\n\nexport const ControlGroup = ({ className, disabled, errorMessage, id, messageReserveLines = 1, messageReserveSpace = false, name, orientation = 'horizontal', state = 'default', warningMessage, ...props }: ControlGroupProps) => {\n const groupId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(groupId)\n const warningMessageId = `${groupId}-warning`\n const { isDisabled, isLoading, isInvalid } = useFormFieldState(disabled, state)\n const messageId = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n\n return (\n <ControlGroupContext.Provider value={{ messageId, isDisabled, isInvalid, isLoading, orientation, state }}>\n <div
|
|
1
|
+
{"version":3,"file":"ControlGroup.js","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId, useFormFieldState, WarningMessage, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useContext, type ComponentProps } from 'react'\n\ninterface ControlGroupContextValue {\n messageId?: string\n isDisabled: boolean\n isInvalid: boolean\n isLoading: boolean\n orientation: 'horizontal' | 'vertical'\n state: FormFieldState\n}\n\nconst ControlGroupContext = createContext<ControlGroupContextValue | null>(null)\n\nexport const useControlGroup = () => {\n const context = useContext(ControlGroupContext)\n if (context === null) {\n throw new Error('useControlGroup must be used within a ControlGroup')\n }\n return context\n}\n\nexport interface ControlGroupProps extends ComponentProps<'div'> {\n disabled?: boolean\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n orientation?: 'horizontal' | 'vertical'\n state?: FormFieldState\n warningMessage?: string | string[] | Record<string, unknown> | null\n}\n\nexport const ControlGroup = ({ className, disabled, errorMessage, id, messageReserveLines = 1, messageReserveSpace = false, name, orientation = 'horizontal', state = 'default', warningMessage, ...props }: ControlGroupProps) => {\n const groupId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(groupId)\n const warningMessageId = `${groupId}-warning`\n const { isDisabled, isLoading, isInvalid } = useFormFieldState(disabled, state)\n const messageId = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n\n return (\n <ControlGroupContext.Provider value={{ messageId, isDisabled, isInvalid, isLoading, orientation, state }}>\n <div\n data-slot='control-group-field'\n className='gap-1.5 flex w-full flex-col'\n >\n <div\n data-slot='control-group'\n data-orientation={orientation}\n data-state={state}\n id={groupId}\n role='group'\n aria-describedby={messageId}\n className={cn('group flex w-full', orientation === 'vertical' && 'flex-col', isDisabled && 'pointer-events-none opacity-50', className)}\n {...props}\n />\n <ErrorMessage\n dataTestId='spectral-control-group-error-message'\n id={errorMessageId}\n message={isInvalid ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-control-group-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n </ControlGroupContext.Provider>\n )\n}\n\nexport const ControlGroupItem = ({ className, ...props }: ComponentProps<typeof Slot>) => {\n const { orientation } = useControlGroup()\n\n return (\n <Slot\n data-slot='control-group-item'\n className={cn(\n 'rounded-none focus-within:z-10 hover:z-10',\n orientation === 'horizontal' && 'first:rounded-s-md last:me-0 last:rounded-e-md -me-0.5 h-auto',\n orientation === 'vertical' && 'first:rounded-ss-md first:rounded-se-md last:rounded-ee-md last:rounded-es-md last:mbe-0 -mbe-0.5 w-auto',\n className,\n )}\n {...props}\n />\n )\n}\n"],"mappings":";;;;;;;;;AAcA,MAAM,sBAAsB,cAA+C,KAAK;AAEhF,MAAa,wBAAwB;CACnC,MAAM,UAAU,WAAW,oBAAoB;AAC/C,KAAI,YAAY,KACd,OAAM,IAAI,MAAM,qDAAqD;AAEvE,QAAO;;AAeT,MAAa,gBAAgB,EAAE,WAAW,UAAU,cAAc,IAAI,sBAAsB,GAAG,sBAAsB,OAAO,MAAM,cAAc,cAAc,QAAQ,WAAW,gBAAgB,GAAG,YAA+B;CACjO,MAAM,UAAU,eAAe,IAAI,KAAK;CACxC,MAAM,iBAAiB,kBAAkB,QAAQ;CACjD,MAAM,mBAAmB,GAAG,QAAQ;CACpC,MAAM,EAAE,YAAY,WAAW,cAAc,kBAAkB,UAAU,MAAM;CAC/E,MAAM,YAAY,UAAU,WAAW,eAAe,iBAAiB,UAAU,aAAa,iBAAiB,mBAAmB;AAElI,QACE,oBAAC,oBAAoB,UAArB;EAA8B,OAAO;GAAE;GAAW;GAAY;GAAW;GAAW;GAAa;GAAO;YACtG,qBAAC,OAAD;GACE,aAAU;GACV,WAAU;aAFZ;IAIE,oBAAC,OAAD;KACE,aAAU;KACV,oBAAkB;KAClB,cAAY;KACZ,IAAI;KACJ,MAAK;KACL,oBAAkB;KAClB,WAAW,GAAG,qBAAqB,gBAAgB,cAAc,YAAY,cAAc,kCAAkC,UAAU;KACvI,GAAI;KACJ;IACF,oBAAC,cAAD;KACE,YAAW;KACX,IAAI;KACJ,SAAS,YAAY,eAAe;KACf;KACrB,qBAAqB,uBAAuB,UAAU;KACtD;IACF,oBAAC,gBAAD;KACE,YAAW;KACX,IAAI;KACJ,SAAS,UAAU,YAAY,iBAAiB;KAC3B;KACrB,qBAAqB,uBAAuB,UAAU;KACtD;IACE;;EACuB;;AAInC,MAAa,oBAAoB,EAAE,WAAW,GAAG,YAAyC;CACxF,MAAM,EAAE,gBAAgB,iBAAiB;AAEzC,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,6CACA,gBAAgB,gBAAgB,iEAChC,gBAAgB,cAAc,4GAC9B,UACD;EACD,GAAI;EACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.js","names":[],"sources":["../../src/components/DateTimePicker/Calendar.tsx"],"sourcesContent":["import { ChevronDownIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { useMemo } from 'react'\nimport { DayPicker, type DayPickerProps, type Matcher, type Locale } from 'react-day-picker'\n\nexport type CalendarProps = DayPickerProps & {\n disabled?: Matcher | Matcher[]\n disablePastDates?: boolean\n fixedWeeks?: boolean\n /** The locale object used to localize dates. Import from 'react-day-picker/locale'. */\n locale?: Partial<Locale>\n /** The earliest selectable date (inclusive). Dates before this are disabled. */\n minDate?: Date\n /** The latest selectable date (inclusive). Dates after this are disabled. */\n maxDate?: Date\n /**\n * The date treated as \"today\". Receives the `rdp-today` styling and is used as the reference\n * for `disablePastDates`. When `defaultMonth` is not set, the calendar also opens to this date's\n * month. Defaults to the current date. Useful when picking dates around historical data.\n */\n today?: Date\n}\n\nexport const Calendar = ({ classNames, defaultMonth, disabled, disablePastDates = true, fixedWeeks, locale, maxDate, minDate, showOutsideDays = true, today, ...props }: CalendarProps) => {\n // Reference date for the `today` modifier and past-date disabling. Defaults to the current date.\n const referenceDate = useMemo(() => today ?? new Date(), [today])\n\n // Combine user-provided disabled dates with the past-date, min, and max constraints\n const combinedDisabled: Matcher[] = [
|
|
1
|
+
{"version":3,"file":"Calendar.js","names":[],"sources":["../../src/components/DateTimePicker/Calendar.tsx"],"sourcesContent":["import { ChevronDownIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { useMemo } from 'react'\nimport { DayPicker, type DayPickerProps, type Matcher, type Locale } from 'react-day-picker'\n\nexport type CalendarProps = DayPickerProps & {\n disabled?: Matcher | Matcher[]\n disablePastDates?: boolean\n fixedWeeks?: boolean\n /** The locale object used to localize dates. Import from 'react-day-picker/locale'. */\n locale?: Partial<Locale>\n /** The earliest selectable date (inclusive). Dates before this are disabled. */\n minDate?: Date\n /** The latest selectable date (inclusive). Dates after this are disabled. */\n maxDate?: Date\n /**\n * The date treated as \"today\". Receives the `rdp-today` styling and is used as the reference\n * for `disablePastDates`. When `defaultMonth` is not set, the calendar also opens to this date's\n * month. Defaults to the current date. Useful when picking dates around historical data.\n */\n today?: Date\n}\n\nexport const Calendar = ({ classNames, defaultMonth, disabled, disablePastDates = true, fixedWeeks, locale, maxDate, minDate, showOutsideDays = true, today, ...props }: CalendarProps) => {\n // Reference date for the `today` modifier and past-date disabling. Defaults to the current date.\n const referenceDate = useMemo(() => today ?? new Date(), [today])\n\n // Combine user-provided disabled dates with the past-date, min, and max constraints\n const combinedDisabled: Matcher[] = [...(disablePastDates ? [{ before: referenceDate }] : []), ...(minDate ? [{ before: minDate }] : []), ...(maxDate ? [{ after: maxDate }] : []), ...(Array.isArray(disabled) ? disabled : disabled ? [disabled] : [])]\n\n return (\n <DayPicker\n {...props}\n classNames={{\n months: cn('months relative flex'),\n month: cn('month'),\n caption: cn('calendar-header'),\n caption_label: cn('month-title'),\n nav: cn('rdp-nav flex w-full items-center'),\n nav_button: cn('nav-button h-7 w-7 p-0 bg-transparent opacity-50 hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent'),\n button_previous: cn('nav-prev left-1 top-0 absolute'),\n button_next: cn('nav-next right-1 top-0 absolute'),\n table: cn('table w-full border-collapse'),\n head_row: cn('day-head-row flex'),\n head_cell: cn('days-of-week'),\n row: cn('day-row mt-2 flex w-full'),\n cell: cn('day-cell'),\n day: cn('day'),\n day_range_start: cn('day-range-start'),\n day_range_middle: cn('day-range-middle'),\n day_range_end: cn('day-range-end'),\n day_selected: cn('day-selected'),\n day_outside: cn('day-outside'),\n day_disabled: cn('day-disabled'),\n hidden: cn('hidden'),\n ...classNames,\n }}\n components={{\n Chevron: ({ orientation }) => (\n <ChevronDownIcon\n aria-hidden='true'\n className={cn('size-4', orientation === 'left' && 'rotate-90', orientation === 'right' && '-rotate-90')}\n />\n ),\n }}\n data-slot='calendar'\n data-testid='spectral-calendar'\n defaultMonth={defaultMonth ?? referenceDate}\n disabled={combinedDisabled.length > 0 ? combinedDisabled : undefined}\n fixedWeeks={fixedWeeks}\n locale={locale}\n showOutsideDays={showOutsideDays}\n today={referenceDate}\n />\n )\n}\n\nCalendar.displayName = 'Calendar'\n"],"mappings":";;;;;;;;AAuBA,MAAa,YAAY,EAAE,YAAY,cAAc,UAAU,mBAAmB,MAAM,YAAY,QAAQ,SAAS,SAAS,kBAAkB,MAAM,OAAO,GAAG,YAA2B;CAEzL,MAAM,gBAAgB,cAAc,yBAAS,IAAI,MAAM,EAAE,CAAC,MAAM,CAAA;CAGhE,MAAM,mBAA8B;EAAC,GAAI,mBAAmB,CAAC,EAAE,QAAQ,eAAe,CAAC,GAAG,EAAE;EAAG,GAAI,UAAU,CAAC,EAAE,QAAQ,SAAS,CAAC,GAAG,EAAE;EAAG,GAAI,UAAU,CAAC,EAAE,OAAO,SAAS,CAAC,GAAG,EAAE;EAAG,GAAI,MAAM,QAAQ,SAAS,GAAG,WAAW,WAAW,CAAC,SAAS,GAAG,EAAE;EAAC;AAExP,QACE,oBAAC,WAAD;EACE,GAAI;EACJ,YAAY;GACV,QAAQ,GAAG,uBAAuB;GAClC,OAAO,GAAG,QAAQ;GAClB,SAAS,GAAG,kBAAkB;GAC9B,eAAe,GAAG,cAAc;GAChC,KAAK,GAAG,mCAAmC;GAC3C,YAAY,GAAG,mLAAmL;GAClM,iBAAiB,GAAG,iCAAiC;GACrD,aAAa,GAAG,kCAAkC;GAClD,OAAO,GAAG,+BAA+B;GACzC,UAAU,GAAG,oBAAoB;GACjC,WAAW,GAAG,eAAe;GAC7B,KAAK,GAAG,2BAA2B;GACnC,MAAM,GAAG,WAAW;GACpB,KAAK,GAAG,MAAM;GACd,iBAAiB,GAAG,kBAAkB;GACtC,kBAAkB,GAAG,mBAAmB;GACxC,eAAe,GAAG,gBAAgB;GAClC,cAAc,GAAG,eAAe;GAChC,aAAa,GAAG,cAAc;GAC9B,cAAc,GAAG,eAAe;GAChC,QAAQ,GAAG,SAAS;GACpB,GAAG;GACJ;EACD,YAAY,EACV,UAAU,EAAE,kBACV,oBAAC,iBAAD;GACE,eAAY;GACZ,WAAW,GAAG,UAAU,gBAAgB,UAAU,aAAa,gBAAgB,WAAW,aAAa;GACxG,GAEJ;EACD,aAAU;EAEV,cAAc,gBAAgB;EAC9B,UAAU,iBAAiB,SAAS,IAAI,mBAAmB;EAC/C;EACJ;EACS;EACjB,OAAO;EACR;;AAIL,SAAS,cAAc"}
|