@spear-ai/spectral 1.15.0 → 1.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Accordion.d.ts.map +1 -1
- package/dist/Accordion.js.map +1 -1
- package/dist/Alert/AlertBase.d.ts.map +1 -1
- package/dist/Alert/AlertBase.js.map +1 -1
- package/dist/Alert.js.map +1 -1
- package/dist/Avatar.js.map +1 -1
- package/dist/Badge.d.ts.map +1 -1
- package/dist/Badge.js +3 -3
- package/dist/Badge.js.map +1 -1
- package/dist/Button.js.map +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.js.map +1 -1
- package/dist/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup.js.map +1 -1
- package/dist/ButtonIcon.js.map +1 -1
- package/dist/Checkbox/CheckboxBase.js.map +1 -1
- package/dist/Checkbox.js.map +1 -1
- package/dist/Combobox.js +0 -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.map +1 -1
- package/dist/DataCard/Card.d.ts.map +1 -1
- package/dist/DataCard/Card.js.map +1 -1
- package/dist/DataCard.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.map +1 -1
- package/dist/DateTimePicker/TimePicker.js.map +1 -1
- package/dist/DateTimePicker.js.map +1 -1
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js.map +1 -1
- package/dist/Drawer.js.map +1 -1
- package/dist/DropdownMenu.js.map +1 -1
- package/dist/FormFieldMessage.d.ts.map +1 -1
- package/dist/FormFieldMessage.js +2 -2
- package/dist/FormFieldMessage.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.map +1 -1
- package/dist/Icons/AnalyzeIcon.d.ts.map +1 -1
- package/dist/Icons/AnalyzeIcon.js.map +1 -1
- package/dist/Icons/AnnotationsIcon.d.ts.map +1 -1
- package/dist/Icons/AnnotationsIcon.js.map +1 -1
- package/dist/Icons/ApprovedIcon.d.ts.map +1 -1
- package/dist/Icons/ApprovedIcon.js.map +1 -1
- package/dist/Icons/ArrowDownIcon.d.ts.map +1 -1
- package/dist/Icons/ArrowDownIcon.js.map +1 -1
- package/dist/Icons/ArrowUpIcon.d.ts.map +1 -1
- package/dist/Icons/ArrowUpIcon.js.map +1 -1
- package/dist/Icons/BoxToolIcon.d.ts.map +1 -1
- package/dist/Icons/BoxToolIcon.js.map +1 -1
- package/dist/Icons/CalendarIcon.d.ts.map +1 -1
- package/dist/Icons/CalendarIcon.js.map +1 -1
- package/dist/Icons/CheckCircleIcon.d.ts.map +1 -1
- package/dist/Icons/CheckCircleIcon.js.map +1 -1
- package/dist/Icons/CheckSquareIcon.d.ts.map +1 -1
- package/dist/Icons/CheckSquareIcon.js.map +1 -1
- package/dist/Icons/CheckmarkIcon.d.ts.map +1 -1
- package/dist/Icons/CheckmarkIcon.js.map +1 -1
- package/dist/Icons/ChevronDownIcon.d.ts.map +1 -1
- package/dist/Icons/ChevronDownIcon.js.map +1 -1
- package/dist/Icons/ChevronUpIcon.d.ts.map +1 -1
- package/dist/Icons/ChevronUpIcon.js.map +1 -1
- package/dist/Icons/ClockIcon.d.ts.map +1 -1
- package/dist/Icons/ClockIcon.js.map +1 -1
- package/dist/Icons/CloseCircleIcon.d.ts.map +1 -1
- package/dist/Icons/CloseCircleIcon.js.map +1 -1
- package/dist/Icons/CloseIcon.d.ts.map +1 -1
- package/dist/Icons/CloseIcon.js.map +1 -1
- package/dist/Icons/Crosshairs2Icon.d.ts.map +1 -1
- package/dist/Icons/Crosshairs2Icon.js.map +1 -1
- package/dist/Icons/CrosshairsIcon.d.ts.map +1 -1
- package/dist/Icons/CrosshairsIcon.js.map +1 -1
- package/dist/Icons/DashboardIcon.d.ts.map +1 -1
- package/dist/Icons/DashboardIcon.js.map +1 -1
- package/dist/Icons/DatabaseIcon.d.ts.map +1 -1
- package/dist/Icons/DatabaseIcon.js.map +1 -1
- package/dist/Icons/DeleteIcon.d.ts.map +1 -1
- package/dist/Icons/DeleteIcon.js.map +1 -1
- package/dist/Icons/DurationIcon.d.ts.map +1 -1
- package/dist/Icons/DurationIcon.js.map +1 -1
- package/dist/Icons/EditIcon.d.ts.map +1 -1
- package/dist/Icons/EditIcon.js.map +1 -1
- package/dist/Icons/EmailIcon.d.ts.map +1 -1
- package/dist/Icons/EmailIcon.js.map +1 -1
- package/dist/Icons/EraserIcon.d.ts.map +1 -1
- package/dist/Icons/EraserIcon.js.map +1 -1
- package/dist/Icons/ErrorIcon.d.ts.map +1 -1
- package/dist/Icons/ErrorIcon.js.map +1 -1
- package/dist/Icons/EyeClosedIcon.d.ts.map +1 -1
- package/dist/Icons/EyeClosedIcon.js.map +1 -1
- package/dist/Icons/EyeClosedIcon2.d.ts.map +1 -1
- package/dist/Icons/EyeClosedIcon2.js.map +1 -1
- package/dist/Icons/EyeOpenIcon.d.ts.map +1 -1
- package/dist/Icons/EyeOpenIcon.js.map +1 -1
- package/dist/Icons/FileDownloadIcon.d.ts.map +1 -1
- package/dist/Icons/FileDownloadIcon.js.map +1 -1
- package/dist/Icons/GoToFirstIcon.d.ts.map +1 -1
- package/dist/Icons/GoToFirstIcon.js.map +1 -1
- package/dist/Icons/GoToLastIcon.d.ts.map +1 -1
- package/dist/Icons/GoToLastIcon.js.map +1 -1
- package/dist/Icons/HarmonicCursorsIcon.d.ts.map +1 -1
- package/dist/Icons/HarmonicCursorsIcon.js.map +1 -1
- package/dist/Icons/InfoIcon.d.ts.map +1 -1
- package/dist/Icons/InfoIcon.js.map +1 -1
- package/dist/Icons/KeyboardIcon.d.ts.map +1 -1
- package/dist/Icons/KeyboardIcon.js.map +1 -1
- package/dist/Icons/LabelIcon.d.ts.map +1 -1
- package/dist/Icons/LabelIcon.js.map +1 -1
- package/dist/Icons/LassoIcon.d.ts.map +1 -1
- package/dist/Icons/LassoIcon.js.map +1 -1
- package/dist/Icons/LineToolIcon.d.ts.map +1 -1
- package/dist/Icons/LineToolIcon.js.map +1 -1
- package/dist/Icons/LiveViewIcon.d.ts.map +1 -1
- package/dist/Icons/LiveViewIcon.js.map +1 -1
- package/dist/Icons/LoaderIcon.d.ts.map +1 -1
- package/dist/Icons/LoaderIcon.js.map +1 -1
- package/dist/Icons/LocationIcon.d.ts.map +1 -1
- package/dist/Icons/LocationIcon.js.map +1 -1
- package/dist/Icons/LogoutIcon.d.ts.map +1 -1
- package/dist/Icons/LogoutIcon.js.map +1 -1
- package/dist/Icons/MaximizeIcon.d.ts.map +1 -1
- package/dist/Icons/MaximizeIcon.js.map +1 -1
- package/dist/Icons/MeasureIcon.d.ts.map +1 -1
- package/dist/Icons/MeasureIcon.js.map +1 -1
- package/dist/Icons/MenuDotsIcon.d.ts.map +1 -1
- package/dist/Icons/MenuDotsIcon.js.map +1 -1
- package/dist/Icons/MenuIcon.d.ts.map +1 -1
- package/dist/Icons/MenuIcon.js.map +1 -1
- package/dist/Icons/MessagesIcon.d.ts.map +1 -1
- package/dist/Icons/MessagesIcon.js.map +1 -1
- package/dist/Icons/MetadataIcon.d.ts.map +1 -1
- package/dist/Icons/MetadataIcon.js.map +1 -1
- package/dist/Icons/MinimizeIcon.d.ts.map +1 -1
- package/dist/Icons/MinimizeIcon.js.map +1 -1
- package/dist/Icons/MinusIcon.d.ts.map +1 -1
- package/dist/Icons/MinusIcon.js.map +1 -1
- package/dist/Icons/OntologyIcon.d.ts.map +1 -1
- package/dist/Icons/OntologyIcon.js.map +1 -1
- package/dist/Icons/PanelIconClose.d.ts.map +1 -1
- package/dist/Icons/PanelIconClose.js.map +1 -1
- package/dist/Icons/PanelIconOpen.d.ts.map +1 -1
- package/dist/Icons/PanelIconOpen.js.map +1 -1
- package/dist/Icons/PauseIcon.d.ts.map +1 -1
- package/dist/Icons/PauseIcon.js.map +1 -1
- package/dist/Icons/PlayIcon.d.ts.map +1 -1
- package/dist/Icons/PlayIcon.js.map +1 -1
- package/dist/Icons/PlusIcon.d.ts.map +1 -1
- package/dist/Icons/PlusIcon.js.map +1 -1
- package/dist/Icons/PolygonIcon.d.ts.map +1 -1
- package/dist/Icons/PolygonIcon.js.map +1 -1
- package/dist/Icons/PrinterIcon.d.ts.map +1 -1
- package/dist/Icons/PrinterIcon.js.map +1 -1
- package/dist/Icons/ProgressCheckIcon.d.ts.map +1 -1
- package/dist/Icons/ProgressCheckIcon.js.map +1 -1
- package/dist/Icons/ResetIcon.d.ts.map +1 -1
- package/dist/Icons/ResetIcon.js.map +1 -1
- package/dist/Icons/ReviewedIcon.d.ts.map +1 -1
- package/dist/Icons/ReviewedIcon.js.map +1 -1
- package/dist/Icons/ScissorsIcon.d.ts.map +1 -1
- package/dist/Icons/ScissorsIcon.js.map +1 -1
- package/dist/Icons/SearchIcon.d.ts.map +1 -1
- package/dist/Icons/SearchIcon.js.map +1 -1
- package/dist/Icons/SettingsIcon.d.ts.map +1 -1
- package/dist/Icons/SettingsIcon.js.map +1 -1
- package/dist/Icons/SortAscendingIcon.d.ts.map +1 -1
- package/dist/Icons/SortAscendingIcon.js.map +1 -1
- package/dist/Icons/SortAtoZIcon.d.ts.map +1 -1
- package/dist/Icons/SortAtoZIcon.js.map +1 -1
- package/dist/Icons/SortDescendingIcon.d.ts.map +1 -1
- package/dist/Icons/SortDescendingIcon.js.map +1 -1
- package/dist/Icons/SortZtoAIcon.d.ts.map +1 -1
- package/dist/Icons/SortZtoAIcon.js.map +1 -1
- package/dist/Icons/SparklesIcon.d.ts.map +1 -1
- package/dist/Icons/SparklesIcon.js.map +1 -1
- package/dist/Icons/StackIcon.d.ts.map +1 -1
- package/dist/Icons/StackIcon.js.map +1 -1
- package/dist/Icons/StarIcon.d.ts.map +1 -1
- package/dist/Icons/StarIcon.js.map +1 -1
- package/dist/Icons/TrashIcon.d.ts.map +1 -1
- package/dist/Icons/TrashIcon.js.map +1 -1
- package/dist/Icons/UndoIcon.d.ts.map +1 -1
- package/dist/Icons/UndoIcon.js.map +1 -1
- package/dist/Icons/UploadIcon.d.ts.map +1 -1
- package/dist/Icons/UploadIcon.js.map +1 -1
- package/dist/Icons/User2Icon.d.ts.map +1 -1
- package/dist/Icons/User2Icon.js.map +1 -1
- package/dist/Icons/UserIcon.d.ts.map +1 -1
- package/dist/Icons/UserIcon.js.map +1 -1
- package/dist/Icons/WarningIcon.d.ts.map +1 -1
- package/dist/Icons/WarningIcon.js.map +1 -1
- package/dist/Icons/ZoomAllIcon.d.ts.map +1 -1
- package/dist/Icons/ZoomAllIcon.js.map +1 -1
- package/dist/Icons/ZoomXIcon.d.ts.map +1 -1
- package/dist/Icons/ZoomXIcon.js.map +1 -1
- package/dist/Icons/ZoomYIcon.d.ts.map +1 -1
- package/dist/Icons/ZoomYIcon.js.map +1 -1
- package/dist/IconsAnimated/PanelLeftCloseIcon.js.map +1 -1
- package/dist/IconsAnimated/PanelLeftOpenIcon.js.map +1 -1
- package/dist/Input.js.map +1 -1
- package/dist/InputNumeric.js +0 -6
- package/dist/InputNumeric.js.map +1 -1
- package/dist/InputOTP.d.ts.map +1 -1
- package/dist/InputOTP.js +0 -1
- package/dist/InputOTP.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/MultiSelect/MultiSelectBase.js +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/RadioButton.d.ts +6 -0
- package/dist/RadioButton.d.ts.map +1 -1
- package/dist/RadioButton.js +7 -2
- package/dist/RadioButton.js.map +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.d.ts +15 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.d.ts.map +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.js +166 -15
- package/dist/RadioButtonGroup/RadioButtonGroupBase.js.map +1 -1
- package/dist/RadioButtonGroup.d.ts +4 -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.map +1 -1
- package/dist/Select.js +1 -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 +1 -0
- 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.map +1 -1
- package/dist/Toggle/ToggleBase.js.map +1 -1
- package/dist/Toggle.d.ts +5 -6
- package/dist/Toggle.d.ts.map +1 -1
- package/dist/Toggle.js +4 -19
- 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.d.ts +3 -2
- package/dist/ToggleGroup/ToggleGroupItem.d.ts.map +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.js +3 -2
- package/dist/ToggleGroup/ToggleGroupItem.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.d.ts.map +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js +3 -2
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js.map +1 -1
- package/dist/ToggleGroup.d.ts +3 -2
- package/dist/ToggleGroup.d.ts.map +1 -1
- package/dist/ToggleGroup.js +1 -1
- package/dist/ToggleGroup.js.map +1 -1
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip.js.map +1 -1
- package/dist/Tray.d.ts.map +1 -1
- package/dist/Tray.js.map +1 -1
- package/dist/components/ToggleGroup/ToggleGroup.context.js.map +1 -1
- package/dist/styles/horizon/colors.css +9 -16
- package/dist/styles/spectral.css +2 -2
- package/dist/utils/activeColorStyle.d.ts +11 -0
- package/dist/utils/activeColorStyle.d.ts.map +1 -0
- package/dist/utils/activeColorStyle.js +41 -0
- package/dist/utils/activeColorStyle.js.map +1 -0
- package/package.json +25 -20
package/dist/Tabs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.js","names":[],"sources":["../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ReactNode } from 'react'\nimport { TabsBase, TabsContent, TabsContentContainer, TabsList, TabsTrigger, type TabsBaseProps } from './TabsBase'\nimport { getTabKeys, validateTabValues } from './tabsUtils'\n\nexport interface TabValue {\n children: ReactNode\n disabled?: boolean | undefined\n key: string | undefined\n label: ReactNode\n 'aria-label'?: string | undefined\n 'aria-describedby'?: string | undefined\n}\n\nexport interface TabsProps extends Omit<TabsBaseProps, 'children' | 'defaultValue' | 'onError' | 'disabled' | 'value'> {\n activationMode?: 'automatic' | 'manual' | undefined\n ariaLabel?: string | undefined\n className?: string | undefined\n /** Hide the content panel, useful when managing content display externally */\n hideContent?: boolean | undefined\n onBeforeChange?: (newValue: string, oldValue: string) => boolean | Promise<boolean> | undefined\n onError?: ((error: Error) => void) | undefined\n loading?: boolean | undefined\n openOnLoad?: string | undefined\n rightSlot?: ReactNode | undefined\n tabValues: TabValue[] | undefined\n /**\n * Controlled value - the currently active tab key.\n * When provided, the component operates in controlled mode and the parent\n * must manage the active tab state via `onValueChange`.\n * Mutually exclusive with `openOnLoad` - use one or the other.\n */\n value?: string | undefined\n variant?: 'enclosed' | 'default'\n}\n\nexport const Tabs = ({\n activationMode = 'automatic',\n ariaLabel,\n className,\n hideContent = false,\n loading = false,\n onBeforeChange,\n onError,\n onValueChange,\n openOnLoad,\n orientation = 'horizontal',\n rightSlot,\n tabValues = [],\n value: controlledValue,\n variant = 'default',\n ...props\n}: TabsProps) => {\n if (loading) {\n return (\n <div className='p-4 relative flex w-full flex-col text-center text-text-secondary' role='status' aria-live='polite'>\n <p>Loading tabs…</p>\n </div>\n )\n }\n\n const validTabs = tabValues.filter((tab): tab is TabValue & { key: string } => tab.key !== undefined)\n const isControlled = controlledValue !== undefined\n\n if (!validateTabValues(validTabs as { key: string; label: unknown; children: unknown; [K: string]: unknown }[])) {\n const error = new Error('Invalid tabValues provided to Tabs component')\n onError?.(error)\n\n return (\n <div className='p-4 text-gray-500 relative flex w-full flex-col text-center' role='alert' aria-live='polite'>\n <p>No valid tabs provided</p>\n </div>\n )\n }\n\n const validKeys = getTabKeys(validTabs)\n\n // Compute effective value for controlled mode (fallback if invalid)\n let effectiveValue: string | undefined\n if (isControlled) {\n if (validKeys.includes(controlledValue)) {\n effectiveValue = controlledValue\n } else {\n console.warn(`Tabs: value '${controlledValue}' is not a valid tab key, falling back to first tab`)\n effectiveValue = validKeys[0]\n }\n }\n\n // For uncontrolled mode, determine the default value\n let defaultValue: string | undefined\n if (!isControlled) {\n defaultValue = openOnLoad ?? validKeys[0]\n\n if (openOnLoad && !validKeys.includes(openOnLoad)) {\n console.warn(`Tabs: openOnLoad value '${openOnLoad}' is not a valid tab key`)\n defaultValue = validKeys[0]\n }\n\n if (!defaultValue) {\n const error = new Error('No valid default tab available')\n onError?.(error)\n return (\n <div className='p-4 relative flex w-full flex-col text-center text-text-secondary' role='alert' aria-live='polite'>\n <p>Unable to render tabs</p>\n </div>\n )\n }\n }\n\n const handleValueChange = async (newValue: string) => {\n if (onBeforeChange && onValueChange) {\n const currentValue = isControlled ? (effectiveValue ?? '') : (defaultValue ?? '')\n try {\n const canChange = await onBeforeChange(newValue, currentValue)\n if (canChange === false) return\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error('Before change callback failed'))\n return\n }\n }\n\n onValueChange?.(newValue)\n }\n\n return (\n <div className='relative flex w-full flex-col'>\n <TabsBase\n aria-label={ariaLabel}\n className={cn('relative w-full data-[orientation=vertical]:flex', variant, className)}\n {...(isControlled ? { value: effectiveValue } : { defaultValue })}\n orientation={orientation}\n activationMode={activationMode}\n onValueChange={handleValueChange}\n {...props}\n >\n <TabsList\n className={cn(\n 'inline-flex w-full items-center justify-between',\n orientation === 'horizontal' && variant === 'default' && 'border-b border-tabs-border',\n orientation === 'vertical' && variant === 'default' && 'm-0 py-1 relative h-auto w-auto flex-col items-stretch border-r border-tabs-border',\n orientation === 'horizontal' && variant === 'enclosed' && 'rounded-lg p-1 relative border-0 bg-tabs-group-bg',\n orientation === 'vertical' && variant === 'enclosed' && 'rounded-lg p-1 w-auto flex-col border-0 bg-tabs-group-bg',\n )}\n rightSlot={rightSlot}\n >\n {validTabs.map((tab) => (\n <TabsTrigger\n key={tab.key}\n value={tab.key}\n disabled={tab.disabled}\n aria-label={tab['aria-label']}\n aria-describedby={tab['aria-describedby']}\n className={cn(\n 'font-semibold relative whitespace-nowrap transition-all duration-500 ease-in-out focus:outline-none focus-visible:outline-none',\n orientation === 'horizontal' && variant === 'default' && 'py-2 px-4 hover:bg-tabs-bg--hover text-text-primary hover:text-accent',\n orientation === 'vertical' && variant === 'default' && 'h-10 px-4 py-2 hover:bg-tabs-bg--hover flex items-center text-text-primary hover:text-accent data-[state=active]:text-accent',\n orientation === 'horizontal' && variant === 'enclosed' && 'px-4 py-2 hover:bg-tabs-bg--hover z-[1] inline-flex items-center justify-center text-text-primary hover:text-accent data-[state=active]:text-accent',\n orientation === 'vertical' && variant === 'enclosed' && 'px-4 py-2 hover:bg-tabs-bg--hover z-1 text-text-primary hover:text-accent data-[state=active]:text-accent',\n 'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-text-primary',\n )}\n >\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {!hideContent && (\n <TabsContentContainer className={cn(orientation === 'vertical' && 'flex-1')}>\n {validTabs.map((tab) => (\n <TabsContent key={tab.key} value={tab.key} className={cn('text-text-primary focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent', orientation === 'horizontal' && 'pb-4', orientation === 'vertical' && 'py-2 px-4')}>\n {tab.children}\n </TabsContent>\n ))}\n </TabsContentContainer>\n )}\n </TabsBase>\n </div>\n )\n}\n\nexport { TabsContent, TabsContentContainer, TabsList, TabsBase as TabsRoot, TabsTrigger }\n\nexport type { TabsBaseProps, TabsContentContainerProps, TabsContentProps, TabsListProps, TabsTriggerProps } from './TabsBase'\n\nexport type TabKeys<T extends TabValue[]> = T[number]['key']\nexport type TabValueWithKey<TKey extends string> = TabValue & { key: TKey }\n"],"mappings":";;;;;;;;AAoCA,MAAa,QAAQ,EACnB,iBAAiB,aACjB,WACA,WACA,cAAc,OACd,UAAU,OACV,gBACA,SACA,eACA,YACA,cAAc,cACd,WACA,YAAY,EAAE,EACd,OAAO,iBACP,UAAU,WACV,GAAG,YACY;AACf,KAAI,QACF,QACE,oBAAC,OAAD;EAAK,WAAU;EAAoE,MAAK;EAAS,aAAU;YACzG,oBAAC,KAAD,YAAG,iBAAiB;EAChB;CAIV,MAAM,YAAY,UAAU,QAAQ,QAA2C,IAAI,QAAQ,OAAU;CACrG,MAAM,eAAe,oBAAoB;AAEzC,KAAI,CAAC,kBAAkB,UAAwF,EAAE;AAE/G,4BAAU,IADQ,MAAM,+CACT,CAAC;AAEhB,SACE,oBAAC,OAAD;GAAK,WAAU;GAA8D,MAAK;GAAQ,aAAU;aAClG,oBAAC,KAAD,YAAG,0BAA0B;GACzB;;CAIV,MAAM,YAAY,WAAW,UAAU;CAGvC,IAAI;AACJ,KAAI,aACF,KAAI,UAAU,SAAS,gBAAgB,CACrC,kBAAiB;MACZ;AACL,UAAQ,KAAK,gBAAgB,gBAAgB,qDAAqD;AAClG,mBAAiB,UAAU;;CAK/B,IAAI;AACJ,KAAI,CAAC,cAAc;AACjB,iBAAe,cAAc,UAAU;AAEvC,MAAI,cAAc,CAAC,UAAU,SAAS,WAAW,EAAE;AACjD,WAAQ,KAAK,2BAA2B,WAAW,0BAA0B;AAC7E,kBAAe,UAAU;;AAG3B,MAAI,CAAC,cAAc;AAEjB,6BAAU,IADQ,MAAM,iCACT,CAAC;AAChB,UACE,oBAAC,OAAD;IAAK,WAAU;IAAoE,MAAK;IAAQ,aAAU;cACxG,oBAAC,KAAD,YAAG,yBAAyB;IACxB;;;CAKZ,MAAM,oBAAoB,OAAO,aAAqB;AACpD,MAAI,kBAAkB,eAAe;GACnC,MAAM,eAAe,eAAgB,kBAAkB,KAAO,gBAAgB;AAC9E,OAAI;AAEF,QAAI,MADoB,eAAe,UAAU,aAAa,KAC5C,MAAO;YAClB,OAAO;AACd,cAAU,iBAAiB,QAAQ,wBAAQ,IAAI,MAAM,gCAAgC,CAAC;AACtF;;;AAIJ,kBAAgB,SAAS;;AAG3B,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,UAAD;GACE,cAAY;GACZ,WAAW,GAAG,oDAAoD,SAAS,UAAU;GACrF,GAAK,eAAe,EAAE,OAAO,gBAAgB,GAAG,EAAE,cAAc;GACnD;GACG;GAChB,eAAe;GACf,GAAI;aAPN,CASE,oBAAC,UAAD;IACE,WAAW,GACT,mDACA,gBAAgB,gBAAgB,YAAY,aAAa,+BACzD,gBAAgB,cAAc,YAAY,aAAa,sFACvD,gBAAgB,gBAAgB,YAAY,cAAc,qDAC1D,gBAAgB,cAAc,YAAY,cAAc,2DACzD;IACU;cAEV,UAAU,KAAK,QACd,oBAAC,aAAD;KAEE,OAAO,IAAI;KACX,UAAU,IAAI;KACd,cAAY,IAAI;KAChB,oBAAkB,IAAI;KACtB,WAAW,GACT,kIACA,gBAAgB,gBAAgB,YAAY,aAAa,yEACzD,gBAAgB,cAAc,YAAY,aAAa,gIACvD,gBAAgB,gBAAgB,YAAY,cAAc,uJAC1D,gBAAgB,cAAc,YAAY,cAAc,6GACxD,iHACD;eAEA,IAAI;KACO,EAfP,IAAI,IAeG,CACd;IACO,GACV,CAAC,eACA,oBAAC,sBAAD;IAAsB,WAAW,GAAG,gBAAgB,cAAc,SAAS;cACxE,UAAU,KAAK,QACd,oBAAC,aAAD;KAA2B,OAAO,IAAI;KAAK,WAAW,GAAG,4HAA4H,gBAAgB,gBAAgB,QAAQ,gBAAgB,cAAc,YAAY;eACpQ,IAAI;KACO,EAFI,IAAI,IAER,CACd;IACmB,EAEhB;;EACP"}
|
|
1
|
+
{"version":3,"file":"Tabs.js","names":[],"sources":["../src/components/Tabs/Tabs.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ReactNode } from 'react'\nimport { TabsBase, TabsContent, TabsContentContainer, TabsList, TabsTrigger, type TabsBaseProps } from './TabsBase'\nimport { getTabKeys, validateTabValues } from './tabsUtils'\n\nexport interface TabValue {\n children: ReactNode\n disabled?: boolean | undefined\n key: string | undefined\n label: ReactNode\n 'aria-label'?: string | undefined\n 'aria-describedby'?: string | undefined\n}\n\nexport interface TabsProps extends Omit<TabsBaseProps, 'children' | 'defaultValue' | 'onError' | 'disabled' | 'value'> {\n activationMode?: 'automatic' | 'manual' | undefined\n ariaLabel?: string | undefined\n className?: string | undefined\n /** Hide the content panel, useful when managing content display externally */\n hideContent?: boolean | undefined\n onBeforeChange?: (newValue: string, oldValue: string) => boolean | Promise<boolean> | undefined\n onError?: ((error: Error) => void) | undefined\n loading?: boolean | undefined\n openOnLoad?: string | undefined\n rightSlot?: ReactNode | undefined\n tabValues: TabValue[] | undefined\n /**\n * Controlled value - the currently active tab key.\n * When provided, the component operates in controlled mode and the parent\n * must manage the active tab state via `onValueChange`.\n * Mutually exclusive with `openOnLoad` - use one or the other.\n */\n value?: string | undefined\n variant?: 'enclosed' | 'default'\n}\n\nexport const Tabs = ({\n activationMode = 'automatic',\n ariaLabel,\n className,\n hideContent = false,\n loading = false,\n onBeforeChange,\n onError,\n onValueChange,\n openOnLoad,\n orientation = 'horizontal',\n rightSlot,\n tabValues = [],\n value: controlledValue,\n variant = 'default',\n ...props\n}: TabsProps) => {\n if (loading) {\n return (\n <div\n className='p-4 relative flex w-full flex-col text-center text-text-secondary'\n role='status'\n aria-live='polite'\n >\n <p>Loading tabs…</p>\n </div>\n )\n }\n\n const validTabs = tabValues.filter((tab): tab is TabValue & { key: string } => tab.key !== undefined)\n const isControlled = controlledValue !== undefined\n\n if (!validateTabValues(validTabs as { key: string; label: unknown; children: unknown; [K: string]: unknown }[])) {\n const error = new Error('Invalid tabValues provided to Tabs component')\n onError?.(error)\n\n return (\n <div\n className='p-4 text-gray-500 relative flex w-full flex-col text-center'\n role='alert'\n aria-live='polite'\n >\n <p>No valid tabs provided</p>\n </div>\n )\n }\n\n const validKeys = getTabKeys(validTabs)\n\n // Compute effective value for controlled mode (fallback if invalid)\n let effectiveValue: string | undefined\n if (isControlled) {\n if (validKeys.includes(controlledValue)) {\n effectiveValue = controlledValue\n } else {\n console.warn(`Tabs: value '${controlledValue}' is not a valid tab key, falling back to first tab`)\n effectiveValue = validKeys[0]\n }\n }\n\n // For uncontrolled mode, determine the default value\n let defaultValue: string | undefined\n if (!isControlled) {\n defaultValue = openOnLoad ?? validKeys[0]\n\n if (openOnLoad && !validKeys.includes(openOnLoad)) {\n console.warn(`Tabs: openOnLoad value '${openOnLoad}' is not a valid tab key`)\n defaultValue = validKeys[0]\n }\n\n if (!defaultValue) {\n const error = new Error('No valid default tab available')\n onError?.(error)\n return (\n <div\n className='p-4 relative flex w-full flex-col text-center text-text-secondary'\n role='alert'\n aria-live='polite'\n >\n <p>Unable to render tabs</p>\n </div>\n )\n }\n }\n\n const handleValueChange = async (newValue: string) => {\n if (onBeforeChange && onValueChange) {\n const currentValue = isControlled ? (effectiveValue ?? '') : (defaultValue ?? '')\n try {\n const canChange = await onBeforeChange(newValue, currentValue)\n if (canChange === false) return\n } catch (error) {\n onError?.(error instanceof Error ? error : new Error('Before change callback failed'))\n return\n }\n }\n\n onValueChange?.(newValue)\n }\n\n return (\n <div className='relative flex w-full flex-col'>\n <TabsBase\n aria-label={ariaLabel}\n className={cn('relative w-full data-[orientation=vertical]:flex', variant, className)}\n {...(isControlled ? { value: effectiveValue } : { defaultValue })}\n orientation={orientation}\n activationMode={activationMode}\n onValueChange={handleValueChange}\n {...props}\n >\n <TabsList\n className={cn(\n 'inline-flex w-full items-center justify-between',\n orientation === 'horizontal' && variant === 'default' && 'border-b border-tabs-border',\n orientation === 'vertical' && variant === 'default' && 'm-0 py-1 relative h-auto w-auto flex-col items-stretch border-r border-tabs-border',\n orientation === 'horizontal' && variant === 'enclosed' && 'rounded-lg p-1 relative border-0 bg-tabs-group-bg',\n orientation === 'vertical' && variant === 'enclosed' && 'rounded-lg p-1 w-auto flex-col border-0 bg-tabs-group-bg',\n )}\n rightSlot={rightSlot}\n >\n {validTabs.map((tab) => (\n <TabsTrigger\n key={tab.key}\n value={tab.key}\n disabled={tab.disabled}\n aria-label={tab['aria-label']}\n aria-describedby={tab['aria-describedby']}\n className={cn(\n 'font-semibold relative whitespace-nowrap transition-all duration-500 ease-in-out focus:outline-none focus-visible:outline-none',\n orientation === 'horizontal' && variant === 'default' && 'py-2 px-4 hover:bg-tabs-bg--hover text-text-primary hover:text-accent',\n orientation === 'vertical' && variant === 'default' && 'h-10 px-4 py-2 hover:bg-tabs-bg--hover flex items-center text-text-primary hover:text-accent data-[state=active]:text-accent',\n orientation === 'horizontal' && variant === 'enclosed' && 'px-4 py-2 hover:bg-tabs-bg--hover z-[1] inline-flex items-center justify-center text-text-primary hover:text-accent data-[state=active]:text-accent',\n orientation === 'vertical' && variant === 'enclosed' && 'px-4 py-2 hover:bg-tabs-bg--hover z-1 text-text-primary hover:text-accent data-[state=active]:text-accent',\n 'disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-transparent disabled:hover:text-text-primary',\n )}\n >\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n {!hideContent && (\n <TabsContentContainer className={cn(orientation === 'vertical' && 'flex-1')}>\n {validTabs.map((tab) => (\n <TabsContent\n key={tab.key}\n value={tab.key}\n className={cn('text-text-primary focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent', orientation === 'horizontal' && 'pb-4', orientation === 'vertical' && 'py-2 px-4')}\n >\n {tab.children}\n </TabsContent>\n ))}\n </TabsContentContainer>\n )}\n </TabsBase>\n </div>\n )\n}\n\nexport { TabsContent, TabsContentContainer, TabsList, TabsBase as TabsRoot, TabsTrigger }\n\nexport type { TabsBaseProps, TabsContentContainerProps, TabsContentProps, TabsListProps, TabsTriggerProps } from './TabsBase'\n\nexport type TabKeys<T extends TabValue[]> = T[number]['key']\nexport type TabValueWithKey<TKey extends string> = TabValue & { key: TKey }\n"],"mappings":";;;;;;;;AAoCA,MAAa,QAAQ,EACnB,iBAAiB,aACjB,WACA,WACA,cAAc,OACd,UAAU,OACV,gBACA,SACA,eACA,YACA,cAAc,cACd,WACA,YAAY,EAAE,EACd,OAAO,iBACP,UAAU,WACV,GAAG,YACY;AACf,KAAI,QACF,QACE,oBAAC,OAAD;EACE,WAAU;EACV,MAAK;EACL,aAAU;YAEV,oBAAC,KAAD,YAAG,iBAAiB;EAChB;CAIV,MAAM,YAAY,UAAU,QAAQ,QAA2C,IAAI,QAAQ,OAAU;CACrG,MAAM,eAAe,oBAAoB;AAEzC,KAAI,CAAC,kBAAkB,UAAwF,EAAE;AAE/G,4BAAU,IADQ,MAAM,+CACT,CAAC;AAEhB,SACE,oBAAC,OAAD;GACE,WAAU;GACV,MAAK;GACL,aAAU;aAEV,oBAAC,KAAD,YAAG,0BAA0B;GACzB;;CAIV,MAAM,YAAY,WAAW,UAAU;CAGvC,IAAI;AACJ,KAAI,aACF,KAAI,UAAU,SAAS,gBAAgB,CACrC,kBAAiB;MACZ;AACL,UAAQ,KAAK,gBAAgB,gBAAgB,qDAAqD;AAClG,mBAAiB,UAAU;;CAK/B,IAAI;AACJ,KAAI,CAAC,cAAc;AACjB,iBAAe,cAAc,UAAU;AAEvC,MAAI,cAAc,CAAC,UAAU,SAAS,WAAW,EAAE;AACjD,WAAQ,KAAK,2BAA2B,WAAW,0BAA0B;AAC7E,kBAAe,UAAU;;AAG3B,MAAI,CAAC,cAAc;AAEjB,6BAAU,IADQ,MAAM,iCACT,CAAC;AAChB,UACE,oBAAC,OAAD;IACE,WAAU;IACV,MAAK;IACL,aAAU;cAEV,oBAAC,KAAD,YAAG,yBAAyB;IACxB;;;CAKZ,MAAM,oBAAoB,OAAO,aAAqB;AACpD,MAAI,kBAAkB,eAAe;GACnC,MAAM,eAAe,eAAgB,kBAAkB,KAAO,gBAAgB;AAC9E,OAAI;AAEF,QAAI,MADoB,eAAe,UAAU,aAAa,KAC5C,MAAO;YAClB,OAAO;AACd,cAAU,iBAAiB,QAAQ,wBAAQ,IAAI,MAAM,gCAAgC,CAAC;AACtF;;;AAIJ,kBAAgB,SAAS;;AAG3B,QACE,oBAAC,OAAD;EAAK,WAAU;YACb,qBAAC,UAAD;GACE,cAAY;GACZ,WAAW,GAAG,oDAAoD,SAAS,UAAU;GACrF,GAAK,eAAe,EAAE,OAAO,gBAAgB,GAAG,EAAE,cAAc;GACnD;GACG;GAChB,eAAe;GACf,GAAI;aAPN,CASE,oBAAC,UAAD;IACE,WAAW,GACT,mDACA,gBAAgB,gBAAgB,YAAY,aAAa,+BACzD,gBAAgB,cAAc,YAAY,aAAa,sFACvD,gBAAgB,gBAAgB,YAAY,cAAc,qDAC1D,gBAAgB,cAAc,YAAY,cAAc,2DACzD;IACU;cAEV,UAAU,KAAK,QACd,oBAAC,aAAD;KAEE,OAAO,IAAI;KACX,UAAU,IAAI;KACd,cAAY,IAAI;KAChB,oBAAkB,IAAI;KACtB,WAAW,GACT,kIACA,gBAAgB,gBAAgB,YAAY,aAAa,yEACzD,gBAAgB,cAAc,YAAY,aAAa,gIACvD,gBAAgB,gBAAgB,YAAY,cAAc,uJAC1D,gBAAgB,cAAc,YAAY,cAAc,6GACxD,iHACD;eAEA,IAAI;KACO,EAfP,IAAI,IAeG,CACd;IACO,GACV,CAAC,eACA,oBAAC,sBAAD;IAAsB,WAAW,GAAG,gBAAgB,cAAc,SAAS;cACxE,UAAU,KAAK,QACd,oBAAC,aAAD;KAEE,OAAO,IAAI;KACX,WAAW,GAAG,4HAA4H,gBAAgB,gBAAgB,QAAQ,gBAAgB,cAAc,YAAY;eAE3N,IAAI;KACO,EALP,IAAI,IAKG,CACd;IACmB,EAEhB;;EACP"}
|
package/dist/Textarea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Textarea.js","names":[],"sources":["../src/components/Textarea/Textarea.tsx"],"sourcesContent":["import { LoaderIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { ErrorMessage, getAriaProps, getErrorMessageId, getTextareaClasses, useFormFieldId, useFormFieldState, WarningMessage, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useRef, type ComponentProps, type CSSProperties, type FocusEvent, type Ref } from 'react'\nimport { useTextarea } from './TextareaUtils'\n\nexport type TextareaState = FormFieldState\n\ntype AutoCompleteValue = 'on' | 'off' | 'name' | 'email' | 'username' | 'street-address' | (string & {})\n\nexport type TextareaProps = Omit<ComponentProps<'textarea'>, 'onChange'> & {\n className?: string | undefined\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string | undefined\n label: string\n labelClassName?: string\n maxLength?: number | undefined\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 name: string\n onBlur?: (e: FocusEvent<HTMLTextAreaElement>) => void\n onChange?: (value: string) => void\n onFocus?: (e: FocusEvent<HTMLTextAreaElement>) => void\n placeholder?: string | undefined\n required?: boolean\n state?: TextareaState\n value?: string | undefined\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nconst LOADING_ICON_CLASSES = 'absolute right-4 top-4'\n\nconst getAutoCompleteValue = (autoComplete?: string): AutoCompleteValue => {\n if (autoComplete) return autoComplete\n return 'off'\n}\n\nconst getCounterClasses = (currentLength: number, maxLength: number): string => {\n const baseClasses = 'absolute bottom-2 right-3 text-xs pointer-events-none z-10 tabular-nums'\n const colorClass = currentLength >= maxLength ? 'text-danger-400' : 'text-text-secondary'\n return cn(baseClasses, colorClass)\n}\n\nexport const Textarea = (\n allProps: TextareaProps & {\n ref?: Ref<HTMLTextAreaElement>\n },\n) => {\n const {\n ref,\n autoComplete,\n className,\n defaultValue,\n disabled,\n errorMessage,\n id,\n label,\n labelClassName,\n maxLength = 280,\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onBlur,\n onChange,\n onFocus,\n placeholder,\n required,\n state = 'default',\n value: valueProp,\n warningMessage,\n ...props\n } = allProps\n const textareaId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(textareaId)\n const warningMessageId = `${textareaId}-warning`\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const internalRef = useRef<HTMLTextAreaElement>(null)\n const textareaRef = ref ?? internalRef\n const normalizedDefaultValue = typeof defaultValue === 'string' ? defaultValue : defaultValue !== undefined && defaultValue !== null ? String(defaultValue) : ''\n const [value, setValue] = useUncontrolledState<string>({\n value: valueProp,\n defaultValue: normalizedDefaultValue,\n onChange,\n })\n\n const { handleFocus, handleBlur, handleChange, handlePaste } = useTextarea({\n maxLength,\n value,\n onChange: setValue,\n onFocus,\n onBlur,\n })\n\n const { isDisabled, isLoading } = useFormFieldState(disabled, state)\n const ariaProps = getAriaProps(state, props['aria-describedby'], required, messageId)\n const currentLength = value?.length || 0\n const textareaClasses = getTextareaClasses(state, className)\n\n const getCSSCustomProperties = () => ({\n '--textarea-min-height': '6rem',\n '--textarea-max-height': '12rem',\n '--textarea-border-radius': '0.5rem',\n })\n\n return (\n <div className='w-full'>\n {label && (\n <Label
|
|
1
|
+
{"version":3,"file":"Textarea.js","names":[],"sources":["../src/components/Textarea/Textarea.tsx"],"sourcesContent":["import { LoaderIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { ErrorMessage, getAriaProps, getErrorMessageId, getTextareaClasses, useFormFieldId, useFormFieldState, WarningMessage, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useRef, type ComponentProps, type CSSProperties, type FocusEvent, type Ref } from 'react'\nimport { useTextarea } from './TextareaUtils'\n\nexport type TextareaState = FormFieldState\n\ntype AutoCompleteValue = 'on' | 'off' | 'name' | 'email' | 'username' | 'street-address' | (string & {})\n\nexport type TextareaProps = Omit<ComponentProps<'textarea'>, 'onChange'> & {\n className?: string | undefined\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string | undefined\n label: string\n labelClassName?: string\n maxLength?: number | undefined\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 name: string\n onBlur?: (e: FocusEvent<HTMLTextAreaElement>) => void\n onChange?: (value: string) => void\n onFocus?: (e: FocusEvent<HTMLTextAreaElement>) => void\n placeholder?: string | undefined\n required?: boolean\n state?: TextareaState\n value?: string | undefined\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nconst LOADING_ICON_CLASSES = 'absolute right-4 top-4'\n\nconst getAutoCompleteValue = (autoComplete?: string): AutoCompleteValue => {\n if (autoComplete) return autoComplete\n return 'off'\n}\n\nconst getCounterClasses = (currentLength: number, maxLength: number): string => {\n const baseClasses = 'absolute bottom-2 right-3 text-xs pointer-events-none z-10 tabular-nums'\n const colorClass = currentLength >= maxLength ? 'text-danger-400' : 'text-text-secondary'\n return cn(baseClasses, colorClass)\n}\n\nexport const Textarea = (\n allProps: TextareaProps & {\n ref?: Ref<HTMLTextAreaElement>\n },\n) => {\n const {\n ref,\n autoComplete,\n className,\n defaultValue,\n disabled,\n errorMessage,\n id,\n label,\n labelClassName,\n maxLength = 280,\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onBlur,\n onChange,\n onFocus,\n placeholder,\n required,\n state = 'default',\n value: valueProp,\n warningMessage,\n ...props\n } = allProps\n const textareaId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(textareaId)\n const warningMessageId = `${textareaId}-warning`\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const internalRef = useRef<HTMLTextAreaElement>(null)\n const textareaRef = ref ?? internalRef\n const normalizedDefaultValue = typeof defaultValue === 'string' ? defaultValue : defaultValue !== undefined && defaultValue !== null ? String(defaultValue) : ''\n const [value, setValue] = useUncontrolledState<string>({\n value: valueProp,\n defaultValue: normalizedDefaultValue,\n onChange,\n })\n\n const { handleFocus, handleBlur, handleChange, handlePaste } = useTextarea({\n maxLength,\n value,\n onChange: setValue,\n onFocus,\n onBlur,\n })\n\n const { isDisabled, isLoading } = useFormFieldState(disabled, state)\n const ariaProps = getAriaProps(state, props['aria-describedby'], required, messageId)\n const currentLength = value?.length || 0\n const textareaClasses = getTextareaClasses(state, className)\n\n const getCSSCustomProperties = () => ({\n '--textarea-min-height': '6rem',\n '--textarea-max-height': '12rem',\n '--textarea-border-radius': '0.5rem',\n })\n\n return (\n <div className='w-full'>\n {label && (\n <Label\n data-testid='spectral-textarea-label'\n htmlFor={textareaId}\n className={cn('mb-2 block', isDisabled && 'cursor-not-allowed opacity-50', labelClassName)}\n >\n {label}\n </Label>\n )}\n <div className='relative'>\n <textarea\n aria-multiline='true'\n autoComplete={getAutoCompleteValue(autoComplete)}\n className={textareaClasses}\n data-state={state}\n data-testid='spectral-textarea'\n disabled={isDisabled}\n id={textareaId}\n name={name}\n onBlur={handleBlur}\n onChange={handleChange}\n onFocus={handleFocus}\n onPaste={handlePaste}\n placeholder={placeholder}\n ref={textareaRef}\n required={required}\n spellCheck='true'\n style={getCSSCustomProperties() as CSSProperties}\n value={value}\n {...ariaProps}\n {...props}\n />\n\n {isLoading && (\n <div\n className={LOADING_ICON_CLASSES}\n data-testid='spectral-textarea-loading-icon'\n >\n <LoaderIcon size={24} />\n </div>\n )}\n\n <div\n // oxlint will throw an error when passing ternaries in for aria-label\n aria-label={currentLength + ' of ' + maxLength + ' characters used'}\n aria-live='polite'\n className={getCounterClasses(currentLength, maxLength)}\n data-testid='spectral-textarea-counter'\n role='status'\n >\n {currentLength}/{maxLength}\n </div>\n </div>\n\n <ErrorMessage\n dataTestId='spectral-textarea-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-textarea-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nTextarea.displayName = 'Textarea'\n"],"mappings":";;;;;;;;;;;;AAkCA,MAAM,uBAAuB;AAE7B,MAAM,wBAAwB,iBAA6C;AACzE,KAAI,aAAc,QAAO;AACzB,QAAO;;AAGT,MAAM,qBAAqB,eAAuB,cAA8B;AAG9E,QAAO,GAAG,2EADS,iBAAiB,YAAY,oBAAoB,sBAClC;;AAGpC,MAAa,YACX,aAGG;CACH,MAAM,EACJ,KACA,cACA,WACA,cACA,UACA,cACA,IACA,OACA,gBACA,YAAY,KACZ,sBAAsB,GACtB,sBAAsB,OACtB,MACA,QACA,UACA,SACA,aACA,UACA,QAAQ,WACR,OAAO,WACP,gBACA,GAAG,UACD;CACJ,MAAM,aAAa,eAAe,IAAI,KAAK;CAC3C,MAAM,iBAAiB,kBAAkB,WAAW;CACpD,MAAM,mBAAmB,GAAG,WAAW;CACvC,MAAM,YAAY,UAAU,UAAU,iBAAiB,UAAU,aAAa,iBAAiB,mBAAmB;CAClH,MAAM,cAAc,OAA4B,KAAK;CACrD,MAAM,cAAc,OAAO;CAE3B,MAAM,CAAC,OAAO,YAAY,qBAA6B;EACrD,OAAO;EACP,cAH6B,OAAO,iBAAiB,WAAW,eAAe,iBAAiB,UAAa,iBAAiB,OAAO,OAAO,aAAa,GAAG;EAI5J;EACD,CAAC;CAEF,MAAM,EAAE,aAAa,YAAY,cAAc,gBAAgB,YAAY;EACzE;EACA;EACA,UAAU;EACV;EACA;EACD,CAAC;CAEF,MAAM,EAAE,YAAY,cAAc,kBAAkB,UAAU,MAAM;CACpE,MAAM,YAAY,aAAa,OAAO,MAAM,qBAAqB,UAAU,UAAU;CACrF,MAAM,gBAAgB,OAAO,UAAU;CACvC,MAAM,kBAAkB,mBAAmB,OAAO,UAAU;CAE5D,MAAM,gCAAgC;EACpC,yBAAyB;EACzB,yBAAyB;EACzB,4BAA4B;EAC7B;AAED,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACG,SACC,oBAAC,OAAD;IACE,eAAY;IACZ,SAAS;IACT,WAAW,GAAG,cAAc,cAAc,iCAAiC,eAAe;cAEzF;IACK;GAEV,qBAAC,OAAD;IAAK,WAAU;cAAf;KACE,oBAAC,YAAD;MACE,kBAAe;MACf,cAAc,qBAAqB,aAAa;MAChD,WAAW;MACX,cAAY;MACZ,eAAY;MACZ,UAAU;MACV,IAAI;MACE;MACN,QAAQ;MACR,UAAU;MACV,SAAS;MACT,SAAS;MACI;MACb,KAAK;MACK;MACV,YAAW;MACX,OAAO,wBAAwB;MACxB;MACP,GAAI;MACJ,GAAI;MACJ;KAED,aACC,oBAAC,OAAD;MACE,WAAW;MACX,eAAY;gBAEZ,oBAAC,YAAD,EAAY,MAAM,IAAM;MACpB;KAGR,qBAAC,OAAD;MAEE,cAAY,gBAAgB,SAAS,YAAY;MACjD,aAAU;MACV,WAAW,kBAAkB,eAAe,UAAU;MACtD,eAAY;MACZ,MAAK;gBANP;OAQG;OAAc;OAAE;OACb;;KACF;;GAEN,oBAAC,cAAD;IACE,YAAW;IACX,IAAI;IACJ,SAAS,UAAU,UAAU,eAAe;IACvB;IACrB,qBAAqB,uBAAuB,UAAU;IACtD;GACF,oBAAC,gBAAD;IACE,YAAW;IACX,IAAI;IACJ,SAAS,UAAU,YAAY,iBAAiB;IAC3B;IACrB,qBAAqB,uBAAuB,UAAU;IACtD;GACE;;;AAGV,SAAS,cAAc"}
|
package/dist/Toast.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.d.ts","names":[],"sources":["../src/components/Toast/Toast.tsx"],"mappings":";;;;;;;;KAMK,YAAA;AAAA,KACA,aAAA;AAAA,UAEY,UAAA,SAAmB,YAAA,QAAoB,aAAA;EACtD,SAAA;EACA,kBAAA;EACA,UAAA;EACA,OAAA,YAAmB,SAAA;EACnB,QAAA;EACA,IAAA,GAAO,SAAA;EACP,EAAA;EACA,WAAA;EACA,QAAA,GAAW,aAAA;EACX,OAAA,GAAU,YAAA;AAAA;AAAA,UAGK,YAAA,SAAqB,IAAA,CAAK,cAAA;EACzC,GAAA;EACA,MAAA;EACA,QAAA,GAAW,aAAA;EACX,aAAA;AAAA;AAAA,cAGI,aAAA,GAAa,KAAA;;IAajB,iCAAA,CAAA,SAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"Toast.d.ts","names":[],"sources":["../src/components/Toast/Toast.tsx"],"mappings":";;;;;;;;KAMK,YAAA;AAAA,KACA,aAAA;AAAA,UAEY,UAAA,SAAmB,YAAA,QAAoB,aAAA;EACtD,SAAA;EACA,kBAAA;EACA,UAAA;EACA,OAAA,YAAmB,SAAA;EACnB,QAAA;EACA,IAAA,GAAO,SAAA;EACP,EAAA;EACA,WAAA;EACA,QAAA,GAAW,aAAA;EACX,OAAA,GAAU,YAAA;AAAA;AAAA,UAGK,YAAA,SAAqB,IAAA,CAAK,cAAA;EACzC,GAAA;EACA,MAAA;EACA,QAAA,GAAW,aAAA;EACX,aAAA;AAAA;AAAA,cAGI,aAAA,GAAa,KAAA;;IAajB,iCAAA,CAAA,SAAA;AAAA,cA8FW,KAAA;EAAA;;;;;;;KAlD+G,UAAA,GAAU,oBAAA,CAAA,GAAA,CAAA,OAAA;;;;;;;;;;OAnB5B,YAAA,GAAY,oBAAA,CAAA,GAAA,CAAA,OAAA;;;;cAyEzG,KAAA;EAAK,SAAA;EAAA,kBAAA;EAAA,UAAA;EAAA,QAAA;EAAA,IAAA;EAAA,OAAA;EAAA,WAAA;EAAA,QAAA;EAAA;AAAA,GAzB4H,UAAA;qBA0BzH,IAAA,CAAK,UAAA;mBACP,IAAA,CAAK,UAAA;kBACN,IAAA,CAAK,UAAA;qBACF,IAAA,CAAK,UAAA;AAAA"}
|
package/dist/Toast.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.js","names":["SonnerToaster","sonnerToast"],"sources":["../src/components/Toast/Toast.tsx"],"sourcesContent":["import { CheckSquareIcon, CloseCircleIcon, InfoIcon, WarningIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ReactNode } from 'react'\nimport { toast as sonnerToast, Toaster as SonnerToaster, type ToasterProps as SonnerToasterProps } from 'sonner'\n\ntype ToastVariant = 'default' | 'success' | 'error' | 'info' | 'warning'\ntype ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'\n\nexport interface ToastProps extends VariantProps<typeof toastVariants> {\n className?: string\n containerAriaLabel?: string\n dataTestId?: string\n message?: string | ReactNode\n duration?: number\n icon?: ReactNode\n id?: string | number\n onAutoClose?: () => void\n position?: ToastPosition\n variant?: ToastVariant\n}\n\nexport interface ToasterProps extends Omit<SonnerToasterProps, 'toastOptions'> {\n gap?: number\n offset?: number | string\n position?: ToastPosition\n visibleToasts?: number\n}\n\nconst toastVariants = cva('rounded-md px-4 py-3 text-sm gap-3 shadow-lg flex max-w-[420px] min-w-[300px] items-start border', {\n variants: {\n variant: {\n default: 'border-toast-border bg-toast-bg text-toast-text',\n success: 'border-toast-success-border bg-toast-success-bg text-toast-success-text',\n error: 'border-toast-danger-border bg-toast-danger-bg text-toast-danger-text',\n info: 'border-toast-info-border bg-toast-info-bg text-toast-info-text',\n warning: 'border-toast-warning-border bg-toast-warning-bg text-toast-warning-text',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nconst messageVariants = cva('mt-1 text-sm opacity-90', {\n variants: {\n variant: {\n default: 'text-toast-text',\n success: 'text-toast-success-text',\n error: 'text-toast-danger-text',\n info: 'text-toast-info-text',\n warning: 'text-toast-warning-text',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nconst variantIcons: Record<ToastVariant, ReactNode> = {\n default: null,\n success: <CheckSquareIcon className='size-5 shrink-0 text-toast-success-icon' />,\n info: <InfoIcon className='size-5 shrink-0 text-toast-info-icon' />,\n warning: <WarningIcon className='size-5 shrink-0 text-toast-warning-icon' />,\n error: <CloseCircleIcon className='size-5 shrink-0 text-toast-danger-icon' />,\n}\n\nconst ToastProvider = ({ gap = 14, offset = 32, position = 'bottom-right', visibleToasts = 3, ...props }: ToasterProps) => {\n return (\n <SonnerToaster\n position={position}\n visibleToasts={visibleToasts}\n offset={offset}\n gap={gap}\n toastOptions={{\n unstyled: true,\n classNames: {\n toast: 'spectral-toast',\n },\n }}\n {...props}\n />\n )\n}\nToastProvider.displayName = 'Toast.Provider'\n\nconst ToastComponent = ({ className, containerAriaLabel = 'Notification', dataTestId, icon, message, variant = 'default' }: ToastProps) => {\n const resolvedVariant = variant ?? 'default'\n const displayIcon = icon ?? variantIcons[resolvedVariant]\n\n return (\n <div
|
|
1
|
+
{"version":3,"file":"Toast.js","names":["SonnerToaster","sonnerToast"],"sources":["../src/components/Toast/Toast.tsx"],"sourcesContent":["import { CheckSquareIcon, CloseCircleIcon, InfoIcon, WarningIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ReactNode } from 'react'\nimport { toast as sonnerToast, Toaster as SonnerToaster, type ToasterProps as SonnerToasterProps } from 'sonner'\n\ntype ToastVariant = 'default' | 'success' | 'error' | 'info' | 'warning'\ntype ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right'\n\nexport interface ToastProps extends VariantProps<typeof toastVariants> {\n className?: string\n containerAriaLabel?: string\n dataTestId?: string\n message?: string | ReactNode\n duration?: number\n icon?: ReactNode\n id?: string | number\n onAutoClose?: () => void\n position?: ToastPosition\n variant?: ToastVariant\n}\n\nexport interface ToasterProps extends Omit<SonnerToasterProps, 'toastOptions'> {\n gap?: number\n offset?: number | string\n position?: ToastPosition\n visibleToasts?: number\n}\n\nconst toastVariants = cva('rounded-md px-4 py-3 text-sm gap-3 shadow-lg flex max-w-[420px] min-w-[300px] items-start border', {\n variants: {\n variant: {\n default: 'border-toast-border bg-toast-bg text-toast-text',\n success: 'border-toast-success-border bg-toast-success-bg text-toast-success-text',\n error: 'border-toast-danger-border bg-toast-danger-bg text-toast-danger-text',\n info: 'border-toast-info-border bg-toast-info-bg text-toast-info-text',\n warning: 'border-toast-warning-border bg-toast-warning-bg text-toast-warning-text',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nconst messageVariants = cva('mt-1 text-sm opacity-90', {\n variants: {\n variant: {\n default: 'text-toast-text',\n success: 'text-toast-success-text',\n error: 'text-toast-danger-text',\n info: 'text-toast-info-text',\n warning: 'text-toast-warning-text',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nconst variantIcons: Record<ToastVariant, ReactNode> = {\n default: null,\n success: <CheckSquareIcon className='size-5 shrink-0 text-toast-success-icon' />,\n info: <InfoIcon className='size-5 shrink-0 text-toast-info-icon' />,\n warning: <WarningIcon className='size-5 shrink-0 text-toast-warning-icon' />,\n error: <CloseCircleIcon className='size-5 shrink-0 text-toast-danger-icon' />,\n}\n\nconst ToastProvider = ({ gap = 14, offset = 32, position = 'bottom-right', visibleToasts = 3, ...props }: ToasterProps) => {\n return (\n <SonnerToaster\n position={position}\n visibleToasts={visibleToasts}\n offset={offset}\n gap={gap}\n toastOptions={{\n unstyled: true,\n classNames: {\n toast: 'spectral-toast',\n },\n }}\n {...props}\n />\n )\n}\nToastProvider.displayName = 'Toast.Provider'\n\nconst ToastComponent = ({ className, containerAriaLabel = 'Notification', dataTestId, icon, message, variant = 'default' }: ToastProps) => {\n const resolvedVariant = variant ?? 'default'\n const displayIcon = icon ?? variantIcons[resolvedVariant]\n\n return (\n <div\n aria-label={containerAriaLabel}\n className={cn(toastVariants({ variant: resolvedVariant }), className)}\n data-variant={resolvedVariant}\n data-testid={dataTestId ?? `spectral-toast-${resolvedVariant}`}\n role='status'\n aria-live='polite'\n >\n {displayIcon && (\n <div\n className='mt-0.5'\n aria-hidden='true'\n >\n {displayIcon}\n </div>\n )}\n <div className='flex flex-col'>\n <p className={messageVariants({ variant: resolvedVariant })}>{message}</p>\n </div>\n </div>\n )\n}\nToastComponent.displayName = 'Toast'\n\nconst showToast = ({ className, containerAriaLabel, dataTestId, duration = 4000, icon, message, onAutoClose, position, variant = 'default' }: ToastProps) => {\n return sonnerToast.custom(\n (id) => (\n <ToastComponent\n className={className}\n containerAriaLabel={containerAriaLabel}\n dataTestId={dataTestId}\n icon={icon}\n id={id}\n message={message}\n variant={variant}\n />\n ),\n {\n duration,\n onAutoClose,\n position,\n },\n )\n}\n\nexport const Toast = Object.assign(ToastComponent, {\n Provider: ToastProvider,\n})\n\nexport const toast = Object.assign(showToast, {\n success: (options: Omit<ToastProps, 'variant'>) => showToast({ ...options, variant: 'success' }),\n error: (options: Omit<ToastProps, 'variant'>) => showToast({ ...options, variant: 'error' }),\n info: (options: Omit<ToastProps, 'variant'>) => showToast({ ...options, variant: 'info' }),\n warning: (options: Omit<ToastProps, 'variant'>) => showToast({ ...options, variant: 'warning' }),\n})\n"],"mappings":";;;;;;;;;;;;AA6BA,MAAM,gBAAgB,IAAI,oGAAoG;CAC5H,UAAU,EACR,SAAS;EACP,SAAS;EACT,SAAS;EACT,OAAO;EACP,MAAM;EACN,SAAS;EACV,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CAAC;AAEF,MAAM,kBAAkB,IAAI,2BAA2B;CACrD,UAAU,EACR,SAAS;EACP,SAAS;EACT,SAAS;EACT,OAAO;EACP,MAAM;EACN,SAAS;EACV,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CAAC;AAEF,MAAM,eAAgD;CACpD,SAAS;CACT,SAAS,oBAAC,iBAAD,EAAiB,WAAU,2CAA4C;CAChF,MAAM,oBAAC,UAAD,EAAU,WAAU,wCAAyC;CACnE,SAAS,oBAAC,aAAD,EAAa,WAAU,2CAA4C;CAC5E,OAAO,oBAAC,iBAAD,EAAiB,WAAU,0CAA2C;CAC9E;AAED,MAAM,iBAAiB,EAAE,MAAM,IAAI,SAAS,IAAI,WAAW,gBAAgB,gBAAgB,GAAG,GAAG,YAA0B;AACzH,QACE,oBAACA,SAAD;EACY;EACK;EACP;EACH;EACL,cAAc;GACZ,UAAU;GACV,YAAY,EACV,OAAO,kBACR;GACF;EACD,GAAI;EACJ;;AAGN,cAAc,cAAc;AAE5B,MAAM,kBAAkB,EAAE,WAAW,qBAAqB,gBAAgB,YAAY,MAAM,SAAS,UAAU,gBAA4B;CACzI,MAAM,kBAAkB,WAAW;CACnC,MAAM,cAAc,QAAQ,aAAa;AAEzC,QACE,qBAAC,OAAD;EACE,cAAY;EACZ,WAAW,GAAG,cAAc,EAAE,SAAS,iBAAiB,CAAC,EAAE,UAAU;EACrE,gBAAc;EACd,eAAa,cAAc,kBAAkB;EAC7C,MAAK;EACL,aAAU;YANZ,CAQG,eACC,oBAAC,OAAD;GACE,WAAU;GACV,eAAY;aAEX;GACG,GAER,oBAAC,OAAD;GAAK,WAAU;aACb,oBAAC,KAAD;IAAG,WAAW,gBAAgB,EAAE,SAAS,iBAAiB,CAAC;cAAG;IAAY;GACtE,EACF;;;AAGV,eAAe,cAAc;AAE7B,MAAM,aAAa,EAAE,WAAW,oBAAoB,YAAY,WAAW,KAAM,MAAM,SAAS,aAAa,UAAU,UAAU,gBAA4B;AAC3J,QAAOC,QAAY,QAChB,OACC,oBAAC,gBAAD;EACa;EACS;EACR;EACN;EACF;EACK;EACA;EACT,GAEJ;EACE;EACA;EACA;EACD,CACF;;AAGH,MAAa,QAAQ,OAAO,OAAO,gBAAgB,EACjD,UAAU,eACX,CAAC;AAEF,MAAa,QAAQ,OAAO,OAAO,WAAW;CAC5C,UAAU,YAAyC,UAAU;EAAE,GAAG;EAAS,SAAS;EAAW,CAAC;CAChG,QAAQ,YAAyC,UAAU;EAAE,GAAG;EAAS,SAAS;EAAS,CAAC;CAC5F,OAAO,YAAyC,UAAU;EAAE,GAAG;EAAS,SAAS;EAAQ,CAAC;CAC1F,UAAU,YAAyC,UAAU;EAAE,GAAG;EAAS,SAAS;EAAW,CAAC;CACjG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleBase.js","names":[],"sources":["../../src/components/Toggle/ToggleBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { Slot, type AsChildProp } from '@primitives/slot'\nimport { useCallback, type ButtonHTMLAttributes, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type Ref } from 'react'\n\nexport type ToggleProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> &\n Omit<AsChildProp, 'asChild'> & {\n asChild?: boolean\n defaultPressed?: boolean\n disabled?: boolean\n onPressedChange?: (pressed: boolean) => void\n pressed?: boolean\n }\n\nexport const ToggleBase = function Toggle({\n asChild = false,\n children,\n className,\n defaultPressed = false,\n disabled,\n onClick,\n onKeyDown,\n onPressedChange,\n pressed: pressedProp,\n ref,\n ...rest\n}: ToggleProps & {\n ref?: Ref<HTMLButtonElement>\n}) {\n const [pressed, setPressed] = useUncontrolledState<boolean>({\n defaultValue: defaultPressed,\n onChange: onPressedChange,\n value: pressedProp,\n })\n\n const handleToggle = useCallback(() => {\n if (disabled) return\n setPressed(!pressed)\n }, [disabled, pressed, setPressed])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement | HTMLDivElement>) => {\n if (onKeyDown) onKeyDown(e as KeyboardEvent<HTMLButtonElement>)\n if (e.defaultPrevented) return\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n handleToggle()\n }\n },\n [handleToggle, onKeyDown],\n )\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement | HTMLDivElement>) => {\n if (onClick) onClick(e as MouseEvent<HTMLButtonElement>)\n if (e.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick],\n )\n\n const sharedProps = {\n className,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n 'aria-disabled': disabled ? true : undefined,\n 'aria-pressed': pressed,\n 'data-state': pressed ? 'on' : 'off',\n 'data-disabled': disabled ? true : undefined,\n }\n\n if (asChild) {\n return (\n <div\n ref={ref as Ref<HTMLDivElement>}\n // eslint-disable-next-line jsx-a11y/prefer-tag-over-role -- div wrapper required for Slot primitive to merge props with child\n role='button'\n tabIndex={disabled ? -1 : 0}\n {...(rest as HTMLAttributes<HTMLDivElement>)}\n {...sharedProps}\n >\n <Slot>{children}</Slot>\n </div>\n )\n }\n\n return (\n <button
|
|
1
|
+
{"version":3,"file":"ToggleBase.js","names":[],"sources":["../../src/components/Toggle/ToggleBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { Slot, type AsChildProp } from '@primitives/slot'\nimport { useCallback, type ButtonHTMLAttributes, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type Ref } from 'react'\n\nexport type ToggleProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange'> &\n Omit<AsChildProp, 'asChild'> & {\n asChild?: boolean\n defaultPressed?: boolean\n disabled?: boolean\n onPressedChange?: (pressed: boolean) => void\n pressed?: boolean\n }\n\nexport const ToggleBase = function Toggle({\n asChild = false,\n children,\n className,\n defaultPressed = false,\n disabled,\n onClick,\n onKeyDown,\n onPressedChange,\n pressed: pressedProp,\n ref,\n ...rest\n}: ToggleProps & {\n ref?: Ref<HTMLButtonElement>\n}) {\n const [pressed, setPressed] = useUncontrolledState<boolean>({\n defaultValue: defaultPressed,\n onChange: onPressedChange,\n value: pressedProp,\n })\n\n const handleToggle = useCallback(() => {\n if (disabled) return\n setPressed(!pressed)\n }, [disabled, pressed, setPressed])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement | HTMLDivElement>) => {\n if (onKeyDown) onKeyDown(e as KeyboardEvent<HTMLButtonElement>)\n if (e.defaultPrevented) return\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n handleToggle()\n }\n },\n [handleToggle, onKeyDown],\n )\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement | HTMLDivElement>) => {\n if (onClick) onClick(e as MouseEvent<HTMLButtonElement>)\n if (e.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick],\n )\n\n const sharedProps = {\n className,\n onClick: handleClick,\n onKeyDown: handleKeyDown,\n 'aria-disabled': disabled ? true : undefined,\n 'aria-pressed': pressed,\n 'data-state': pressed ? 'on' : 'off',\n 'data-disabled': disabled ? true : undefined,\n }\n\n if (asChild) {\n return (\n <div\n ref={ref as Ref<HTMLDivElement>}\n // eslint-disable-next-line jsx-a11y/prefer-tag-over-role -- div wrapper required for Slot primitive to merge props with child\n role='button'\n tabIndex={disabled ? -1 : 0}\n {...(rest as HTMLAttributes<HTMLDivElement>)}\n {...sharedProps}\n >\n <Slot>{children}</Slot>\n </div>\n )\n }\n\n return (\n <button\n {...rest}\n {...sharedProps}\n disabled={disabled}\n ref={ref as Ref<HTMLButtonElement>}\n type='button'\n >\n {children}\n </button>\n )\n}\n"],"mappings":";;;;;;;AAaA,MAAa,aAAa,SAAS,OAAO,EACxC,UAAU,OACV,UACA,WACA,iBAAiB,OACjB,UACA,SACA,WACA,iBACA,SAAS,aACT,KACA,GAAG,QAGF;CACD,MAAM,CAAC,SAAS,cAAc,qBAA8B;EAC1D,cAAc;EACd,UAAU;EACV,OAAO;EACR,CAAC;CAEF,MAAM,eAAe,kBAAkB;AACrC,MAAI,SAAU;AACd,aAAW,CAAC,QAAQ;IACnB;EAAC;EAAU;EAAS;EAAW,CAAC;CAEnC,MAAM,gBAAgB,aACnB,MAAyD;AACxD,MAAI,UAAW,WAAU,EAAsC;AAC/D,MAAI,EAAE,iBAAkB;AACxB,MAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,SAAS;AACtC,KAAE,gBAAgB;AAClB,iBAAc;;IAGlB,CAAC,cAAc,UAAU,CAC1B;CAWD,MAAM,cAAc;EAClB;EACA,SAXkB,aACjB,MAAsD;AACrD,OAAI,QAAS,SAAQ,EAAmC;AACxD,OAAI,EAAE,iBAAkB;AACxB,iBAAc;KAEhB,CAAC,cAAc,QAAQ,CAKH;EACpB,WAAW;EACX,iBAAiB,WAAW,OAAO;EACnC,gBAAgB;EAChB,cAAc,UAAU,OAAO;EAC/B,iBAAiB,WAAW,OAAO;EACpC;AAED,KAAI,QACF,QACE,oBAAC,OAAD;EACO;EAEL,MAAK;EACL,UAAU,WAAW,KAAK;EAC1B,GAAK;EACL,GAAI;YAEJ,oBAAC,MAAD,EAAO,UAAgB;EACnB;AAIV,QACE,oBAAC,UAAD;EACE,GAAI;EACJ,GAAI;EACM;EACL;EACL,MAAK;EAEJ;EACM"}
|
package/dist/Toggle.d.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
|
+
import { ActiveColor, ActiveTextColor, getActiveColorStyle } from "./utils/activeColorStyle.js";
|
|
2
3
|
import { ToggleBase } from "./Toggle/ToggleBase.js";
|
|
3
|
-
import {
|
|
4
|
+
import { ComponentProps, Ref } from "react";
|
|
4
5
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
5
6
|
import { VariantProps } from "class-variance-authority";
|
|
6
7
|
import * as _$class_variance_authority_types0 from "class-variance-authority/types";
|
|
7
8
|
|
|
8
9
|
//#region src/components/Toggle/Toggle.d.ts
|
|
9
|
-
type ActiveColor = string;
|
|
10
|
-
declare const getActiveColorStyle: (activeColor: ActiveColor | undefined, activeTextColor?: ActiveColor) => CSSProperties | undefined;
|
|
11
10
|
type ToggleProps = ComponentProps<typeof ToggleBase> & VariantProps<typeof toggleVariants> & {
|
|
12
11
|
activeColor?: ActiveColor;
|
|
13
|
-
activeTextColor?:
|
|
12
|
+
activeTextColor?: ActiveTextColor;
|
|
14
13
|
};
|
|
15
14
|
declare const toggleVariants: (props?: ({
|
|
16
|
-
variant?: "default" | "outline" | null | undefined;
|
|
15
|
+
variant?: "default" | "outline" | "separated" | null | undefined;
|
|
17
16
|
size?: "default" | "lg" | "sm" | null | undefined;
|
|
18
17
|
layout?: "default" | "expanded" | null | undefined;
|
|
19
18
|
} & _$class_variance_authority_types0.ClassProp) | undefined) => string;
|
|
@@ -32,5 +31,5 @@ declare const Toggle: ({
|
|
|
32
31
|
ref?: Ref<HTMLButtonElement>;
|
|
33
32
|
}) => _$react_jsx_runtime0.JSX.Element;
|
|
34
33
|
//#endregion
|
|
35
|
-
export { ActiveColor, Toggle, ToggleProps, getActiveColorStyle, toggleVariants };
|
|
34
|
+
export { type ActiveColor, type ActiveTextColor, Toggle, ToggleProps, getActiveColorStyle, toggleVariants };
|
|
36
35
|
//# sourceMappingURL=Toggle.d.ts.map
|
package/dist/Toggle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toggle.d.ts","names":[],"sources":["../src/components/Toggle/Toggle.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Toggle.d.ts","names":[],"sources":["../src/components/Toggle/Toggle.tsx"],"mappings":";;;;;;;;;KASY,WAAA,GAAc,cAAA,QAAsB,UAAA,IAC9C,YAAA,QAAoB,cAAA;EAClB,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;AAAA;AAAA,cAGT,cAAA,GAAc,KAAA;;;;IAyB1B,iCAAA,CAAA,SAAA;AAAA,cAEY,MAAA;EAAM,GAAA;EAAA,SAAA;EAAA,OAAA;EAAA,IAAA;EAAA,MAAA;EAAA,QAAA;EAAA,WAAA;EAAA,eAAA;EAAA,KAAA;EAAA,GAAA;AAAA,GAWhB,WAAA;EACD,GAAA,GAAM,GAAA,CAAI,iBAAA;AAAA,MACX,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/Toggle.js
CHANGED
|
@@ -1,33 +1,18 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { cn } from "./utils/twUtils.js";
|
|
3
|
+
import { getActiveColorStyle } from "./utils/activeColorStyle.js";
|
|
3
4
|
import { ToggleBase } from "./Toggle/ToggleBase.js";
|
|
4
5
|
import "react";
|
|
5
6
|
import { jsx } from "react/jsx-runtime";
|
|
6
7
|
import { cva } from "class-variance-authority";
|
|
7
8
|
|
|
8
9
|
//#region src/components/Toggle/Toggle.tsx
|
|
9
|
-
const RAW_COLOR_PATTERN = /^(#|rgb|hsl|oklch|oklab|lab|lch|color|var\(|transparent|currentcolor)/i;
|
|
10
|
-
const BASE_COLOR_PATTERN = /^(success|warning|danger|primary|neutral|secondary)-\d+$/;
|
|
11
|
-
const resolveColor = (color) => {
|
|
12
|
-
if (RAW_COLOR_PATTERN.test(color)) return color;
|
|
13
|
-
if (BASE_COLOR_PATTERN.test(color)) return `var(--horizon-color-${color})`;
|
|
14
|
-
return `var(--color-${color})`;
|
|
15
|
-
};
|
|
16
|
-
const getActiveColorStyle = (activeColor, activeTextColor) => {
|
|
17
|
-
if (!activeColor && !activeTextColor) return void 0;
|
|
18
|
-
return {
|
|
19
|
-
...activeColor && {
|
|
20
|
-
"--color-toggle-bg--active": resolveColor(activeColor),
|
|
21
|
-
"--color-toggle-border--active": resolveColor(activeColor)
|
|
22
|
-
},
|
|
23
|
-
...activeTextColor && { "--color-toggle-text--active": resolveColor(activeTextColor) }
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
10
|
const toggleVariants = cva(`gap-2 rounded-md text-sm shadow-sm font-medium inline-flex w-fit items-center justify-center border bg-toggle-bg whitespace-nowrap text-toggle-text transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:bg-toggle-bg--active aria-invalid:border-danger-200 aria-invalid:outline-danger-200/20 aria-pressed:border-toggle-border--active aria-pressed:bg-toggle-bg--active aria-pressed:text-toggle-text--active data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active [&_svg]:pointer-events-none [&_svg]:shrink-0`, {
|
|
27
11
|
variants: {
|
|
28
12
|
variant: {
|
|
29
13
|
default: "border-toggle-border hover:border-toggle-border--hover",
|
|
30
|
-
outline: "border-toggle-outline-border hover:border-toggle-outline-border--hover hover:bg-toggle-bg--hover"
|
|
14
|
+
outline: "border-toggle-outline-border hover:border-toggle-outline-border--hover hover:bg-toggle-bg--hover",
|
|
15
|
+
separated: "border-toggle-border hover:border-toggle-border--hover aria-pressed:border-toggle-border--active aria-pressed:bg-toggle-bg--active data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active"
|
|
31
16
|
},
|
|
32
17
|
size: {
|
|
33
18
|
default: `h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4`,
|
|
@@ -45,7 +30,7 @@ const toggleVariants = cva(`gap-2 rounded-md text-sm shadow-sm font-medium inlin
|
|
|
45
30
|
layout: "default"
|
|
46
31
|
}
|
|
47
32
|
});
|
|
48
|
-
const Toggle = ({ ref, className, variant, size, layout, disabled, activeColor, activeTextColor, style, ...props }) => {
|
|
33
|
+
const Toggle = ({ ref, className, variant, size, layout, disabled, activeColor = "default", activeTextColor, style, ...props }) => {
|
|
49
34
|
return /* @__PURE__ */ jsx(ToggleBase, {
|
|
50
35
|
ref,
|
|
51
36
|
disabled,
|
package/dist/Toggle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toggle.js","names":[],"sources":["../src/components/Toggle/Toggle.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps, type
|
|
1
|
+
{"version":3,"file":"Toggle.js","names":[],"sources":["../src/components/Toggle/Toggle.tsx"],"sourcesContent":["import { getActiveColorStyle, type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps, type Ref } from 'react'\nimport { ToggleBase } from './ToggleBase'\n\nexport { getActiveColorStyle }\nexport type { ActiveColor, ActiveTextColor }\n\nexport type ToggleProps = ComponentProps<typeof ToggleBase> &\n VariantProps<typeof toggleVariants> & {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n }\n\nexport const toggleVariants = cva(\n `gap-2 rounded-md text-sm shadow-sm font-medium inline-flex w-fit items-center justify-center border bg-toggle-bg whitespace-nowrap text-toggle-text transition-colors hover:cursor-pointer hover:border-toggle-border--hover hover:bg-toggle-bg--hover hover:text-toggle-text--hover focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent active:bg-toggle-bg--active aria-invalid:border-danger-200 aria-invalid:outline-danger-200/20 aria-pressed:border-toggle-border--active aria-pressed:bg-toggle-bg--active aria-pressed:text-toggle-text--active data-[disabled]:pointer-events-none data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50 data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active data-[state=on]:text-toggle-text--active [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n {\n variants: {\n variant: {\n default: 'border-toggle-border hover:border-toggle-border--hover',\n outline: 'border-toggle-outline-border hover:border-toggle-outline-border--hover hover:bg-toggle-bg--hover',\n separated: 'border-toggle-border hover:border-toggle-border--hover aria-pressed:border-toggle-border--active aria-pressed:bg-toggle-bg--active data-[state=on]:border-toggle-border--active data-[state=on]:bg-toggle-bg--active',\n },\n size: {\n default: `h-9 px-3 min-w-9 [&_svg:not([class*='size-']):not([width]):not([height])]:size-4`,\n sm: `h-8 px-1.5 min-w-8 [&_svg:not([class*='size-']):not([width]):not([height])]:size-3`,\n lg: `h-10 px-2.5 min-w-10 [&_svg:not([class*='size-']):not([width]):not([height])]:size-5`,\n },\n layout: {\n default: 'w-fit',\n expanded: 'w-full',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n layout: 'default',\n },\n },\n)\n\nexport const Toggle = ({\n ref,\n className,\n variant,\n size,\n layout,\n disabled,\n activeColor = 'default',\n activeTextColor,\n style,\n ...props\n}: ToggleProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n return (\n <ToggleBase\n ref={ref}\n disabled={disabled}\n data-slot='toggle'\n data-testid='spectral-toggle'\n className={cn(toggleVariants({ variant, size, layout }), className)}\n style={{ ...getActiveColorStyle(activeColor, activeTextColor), ...style }}\n {...props}\n />\n )\n}\n"],"mappings":";;;;;;;;;AAeA,MAAa,iBAAiB,IAC5B,s0BACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,SAAS;GACT,WAAW;GACZ;EACD,MAAM;GACJ,SAAS;GACT,IAAI;GACJ,IAAI;GACL;EACD,QAAQ;GACN,SAAS;GACT,UAAU;GACX;EACF;CACD,iBAAiB;EACf,SAAS;EACT,MAAM;EACN,QAAQ;EACT;CACF,CACF;AAED,MAAa,UAAU,EACrB,KACA,WACA,SACA,MACA,QACA,UACA,cAAc,WACd,iBACA,OACA,GAAG,YAGC;AACJ,QACE,oBAAC,YAAD;EACO;EACK;EACV,aAAU;EACV,eAAY;EACZ,WAAW,GAAG,eAAe;GAAE;GAAS;GAAM;GAAQ,CAAC,EAAE,UAAU;EACnE,OAAO;GAAE,GAAG,oBAAoB,aAAa,gBAAgB;GAAE,GAAG;GAAO;EACzE,GAAI;EACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupBase.d.ts","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupBase.tsx"],"mappings":";;;;;KAKK,WAAA;AAAA,UAEY,gBAAA;EACf,SAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA;EACA,WAAA,GAAc,WAAA;AAAA;AAAA,KAGJ,WAAA,GAAc,gBAAA;EACxB,YAAA;EACA,aAAA,IAAiB,CAAA;EACjB,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,aAAA,GAAgB,gBAAA;EAC1B,YAAA;EACA,aAAA,IAAiB,CAAA;EACjB,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,gBAAA,IAAoB,WAAA,GAAc,aAAA,IAAiB,IAAA,CAAK,cAAA,CAAe,cAAA;AAAA,UAElE,eAAA;EACf,QAAA,GAAW,SAAA;EACX,SAAA;EACA,QAAA;EACA,KAAA;AAAA;AAAA,cAiBW,eAAA,GAAe,KAAA,EAAW,gBAAA,GAAmB,MAAA,gCAAiC,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"ToggleGroupBase.d.ts","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupBase.tsx"],"mappings":";;;;;KAKK,WAAA;AAAA,UAEY,gBAAA;EACf,SAAA;EACA,QAAA;EACA,IAAA;EACA,IAAA;EACA,WAAA,GAAc,WAAA;AAAA;AAAA,KAGJ,WAAA,GAAc,gBAAA;EACxB,YAAA;EACA,aAAA,IAAiB,CAAA;EACjB,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,aAAA,GAAgB,gBAAA;EAC1B,YAAA;EACA,aAAA,IAAiB,CAAA;EACjB,IAAA;EACA,KAAA;AAAA;AAAA,KAGU,gBAAA,IAAoB,WAAA,GAAc,aAAA,IAAiB,IAAA,CAAK,cAAA,CAAe,cAAA;AAAA,UAElE,eAAA;EACf,QAAA,GAAW,SAAA;EACX,SAAA;EACA,QAAA;EACA,KAAA;AAAA;AAAA,cAiBW,eAAA,GAAe,KAAA,EAAW,gBAAA,GAAmB,MAAA,gCAAiC,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,KAiI/E,oBAAA,GAAuB,IAAA,CAAK,oBAAA,CAAqB,iBAAA,oEAC3D,eAAA;EAnKA,iFAqKE,OAAA,YArKG;EAuKH,cAAA;AAAA;AAAA,cAGS,mBAAA;EAAmB,GAAA;EAAA,KAAA;EAAA,QAAA;EAAA,SAAA;EAAA,QAAA;EAAA,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAS7B,oBAAA;EACD,GAAA,GAAM,GAAA,CAAI,iBAAA;AAAA,MACX,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupBase.js","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { clamp } from '@utils/sharedUtils'\nimport { createContext, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, type ButtonHTMLAttributes, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type ReactNode, type Ref } from 'react'\n\ntype VoidFn = () => void\ntype Orientation = 'horizontal' | 'vertical'\n\nexport interface CommonGroupProps {\n className?: string\n disabled?: boolean\n loop?: boolean\n name?: string\n orientation?: Orientation\n}\n\nexport type SingleProps = CommonGroupProps & {\n defaultValue?: string\n onValueChange?: (v: string) => void\n type?: 'single'\n value?: string\n}\n\nexport type MultipleProps = CommonGroupProps & {\n defaultValue?: string[]\n onValueChange?: (v: string[]) => void\n type: 'multiple'\n value?: string[]\n}\n\nexport type ToggleGroupProps = (SingleProps | MultipleProps) & Omit<HTMLAttributes<HTMLDivElement>, 'onChange'>\n\nexport interface ItemRenderProps {\n children?: ReactNode\n className?: string\n disabled?: boolean\n value: string\n}\n\nconst GroupContext = createContext<{\n focusItemByIndex: (index: number) => void\n groupDisabled: boolean\n loop: boolean\n isItemPressed: (val: string) => boolean\n itemsSnapshot: () => { val: string; el: HTMLButtonElement | null; disabled: boolean }[]\n name?: string\n orientation: Orientation\n register: (val: string, el: HTMLButtonElement | null) => VoidFn\n setValue: (next: string | string[]) => void\n type: 'single' | 'multiple'\n value: string | string[]\n} | null>(null)\n\nexport const ToggleGroupBase = (props: ToggleGroupProps & Record<`data-${string}`, unknown>) => {\n const {\n className,\n defaultValue,\n disabled: groupDisabled = false,\n loop = true,\n name,\n onValueChange,\n orientation = 'horizontal',\n type = 'single',\n value: valueProp,\n 'data-variant': dataVariant,\n 'data-size': dataSize,\n 'data-slot': dataSlot,\n 'data-layout': dataLayout,\n ...rest\n } = props\n\n const isMultiple = type === 'multiple'\n\n const handleValueChange = useCallback(\n (next: string | string[]) => {\n if (!onValueChange) return\n if (isMultiple) {\n const onValueChangeMultiple = onValueChange as (v: string[]) => void\n onValueChangeMultiple(next as string[])\n return\n }\n const onValueChangeSingle = onValueChange as (v: string) => void\n onValueChangeSingle(next as string)\n },\n [isMultiple, onValueChange],\n )\n\n const [value, setValue] = useUncontrolledState<string | string[]>({\n defaultValue: typeof defaultValue !== 'undefined' ? defaultValue : isMultiple ? [] : '',\n onChange: handleValueChange,\n value: valueProp,\n })\n\n const registry = useRef<{ val: string; el: HTMLButtonElement | null; disabled: boolean }[]>([])\n\n const register = useCallback((val: string, el: HTMLButtonElement | null) => {\n const entry = { val, el, disabled: !!el?.disabled }\n registry.current = [...registry.current.filter((i) => i.val !== val), entry]\n return () => {\n registry.current = registry.current.filter((i) => i.val !== val)\n }\n }, [])\n\n const itemsSnapshot = useCallback(() => registry.current.slice(), [])\n\n const isItemPressed = useCallback(\n (val: string) => {\n if (isMultiple) return Array.isArray(value) && value.includes(val)\n return value === val\n },\n [isMultiple, value],\n )\n\n const setValueSafe = useCallback((next: string | string[]) => setValue(next), [setValue])\n\n const focusItemByIndex = useCallback(\n (index: number) => {\n const items = registry.current\n if (items.length === 0) return\n const last = items.length - 1\n const clamped = loop ? ((index % items.length) + items.length) % items.length : clamp(index, 0, last)\n const target = items[clamped]\n target?.el?.focus()\n },\n [loop],\n )\n\n const ctx = useMemo(\n () => ({\n focusItemByIndex,\n groupDisabled,\n isItemPressed,\n itemsSnapshot,\n loop,\n name,\n orientation,\n register,\n setValue: setValueSafe,\n type,\n value,\n }),\n [focusItemByIndex, groupDisabled, isItemPressed, itemsSnapshot, loop, name, orientation, register, setValueSafe, type, value],\n )\n\n const hiddenName = name\n\n return (\n <div className={className} data-disabled={groupDisabled ? '' : undefined} data-layout={dataLayout} data-orientation={orientation} data-size={dataSize} data-slot={dataSlot} data-variant={dataVariant} role='group' {...rest}>\n <GroupContext.Provider value={ctx}>{props.children}</GroupContext.Provider>\n\n {hiddenName && type === 'single' && typeof value === 'string' ? <input type='hidden' name={hiddenName} value={value} /> : null}\n\n {hiddenName && type === 'multiple' && Array.isArray(value) ? value.map((v) => <input key={v} type='hidden' name={hiddenName + '[]'} value={v} />) : null}\n </div>\n )\n}\n\nexport type ToggleGroupItemProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'onPressedChange' | 'pressed' | 'defaultPressed'> &\n ItemRenderProps & {\n /** @deprecated This prop is ignored - pressed state is managed by ToggleGroup */\n pressed?: boolean\n /** @deprecated This prop is ignored - pressed state is managed by ToggleGroup */\n defaultPressed?: boolean\n }\n\nexport const ToggleGroupItemBase = function ToggleGroupItem({\n ref,\n value,\n disabled,\n className,\n children,\n onKeyDown,\n onClick,\n ...rest\n}: ToggleGroupItemProps & {\n ref?: Ref<HTMLButtonElement>\n}) {\n const ctx = useContext(GroupContext)\n if (!ctx) throw new Error('ToggleGroupItem must be used within ToggleGroup')\n\n const { type, orientation, groupDisabled, setValue, isItemPressed, itemsSnapshot, register } = ctx\n\n const btnRef = useRef<HTMLButtonElement | null>(null)\n useImperativeHandle(ref, () => {\n if (!btnRef.current) {\n throw new Error('ToggleGroupItem button ref is not set')\n }\n return btnRef.current\n })\n\n useEffect(() => register(value, btnRef.current), [register, value])\n\n const pressed = isItemPressed(value)\n\n const toggleMe = useCallback(() => {\n if (groupDisabled || disabled) return\n if (type === 'single') setValue(pressed ? '' : value)\n else {\n const current = ctx.value as string[]\n const next = pressed ? current.filter((v) => v !== value) : [...current, value]\n setValue(next)\n }\n }, [ctx.value, disabled, groupDisabled, pressed, setValue, type, value])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (onKeyDown) onKeyDown(e)\n if (e.defaultPrevented) return\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n toggleMe()\n return\n }\n const items = itemsSnapshot()\n const index = items.findIndex((i) => i.val === value)\n const prevKey = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp'\n const nextKey = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown'\n if (e.key === prevKey) {\n e.preventDefault()\n ctx.focusItemByIndex(index - 1)\n } else if (e.key === nextKey) {\n e.preventDefault()\n ctx.focusItemByIndex(index + 1)\n } else if (e.key === 'Home') {\n e.preventDefault()\n ctx.focusItemByIndex(0)\n } else if (e.key === 'End') {\n e.preventDefault()\n ctx.focusItemByIndex(items.length - 1)\n }\n },\n [ctx, itemsSnapshot, onKeyDown, orientation, toggleMe, value],\n )\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n if (onClick) onClick(e)\n if (e.defaultPrevented) return\n toggleMe()\n },\n [onClick, toggleMe],\n )\n\n return (\n <button aria-pressed={pressed} className={className} data-disabled={groupDisabled || disabled ? '' : undefined} data-state={pressed ? 'on' : 'off'} disabled={groupDisabled || disabled} onClick={handleClick} onKeyDown={handleKeyDown} ref={btnRef} type='button' {...rest}>\n {children}\n </button>\n )\n}\n"],"mappings":";;;;;;;AAsCA,MAAM,eAAe,cAYX,KAAK;AAEf,MAAa,mBAAmB,UAAgE;CAC9F,MAAM,EACJ,WACA,cACA,UAAU,gBAAgB,OAC1B,OAAO,MACP,MACA,eACA,cAAc,cACd,OAAO,UACP,OAAO,WACP,gBAAgB,aAChB,aAAa,UACb,aAAa,UACb,eAAe,YACf,GAAG,SACD;CAEJ,MAAM,aAAa,SAAS;CAE5B,MAAM,oBAAoB,aACvB,SAA4B;AAC3B,MAAI,CAAC,cAAe;AACpB,MAAI,YAAY;AAEd,iBAAsB,KAAiB;AACvC;;AAGF,gBAAoB,KAAe;IAErC,CAAC,YAAY,cAAc,CAC5B;CAED,MAAM,CAAC,OAAO,YAAY,qBAAwC;EAChE,cAAc,OAAO,iBAAiB,cAAc,eAAe,aAAa,EAAE,GAAG;EACrF,UAAU;EACV,OAAO;EACR,CAAC;CAEF,MAAM,WAAW,OAA2E,EAAE,CAAC;CAE/F,MAAM,WAAW,aAAa,KAAa,OAAiC;EAC1E,MAAM,QAAQ;GAAE;GAAK;GAAI,UAAU,CAAC,CAAC,IAAI;GAAU;AACnD,WAAS,UAAU,CAAC,GAAG,SAAS,QAAQ,QAAQ,MAAM,EAAE,QAAQ,IAAI,EAAE,MAAM;AAC5E,eAAa;AACX,YAAS,UAAU,SAAS,QAAQ,QAAQ,MAAM,EAAE,QAAQ,IAAI;;IAEjE,EAAE,CAAC;CAEN,MAAM,gBAAgB,kBAAkB,SAAS,QAAQ,OAAO,EAAE,EAAE,CAAC;CAErE,MAAM,gBAAgB,aACnB,QAAgB;AACf,MAAI,WAAY,QAAO,MAAM,QAAQ,MAAM,IAAI,MAAM,SAAS,IAAI;AAClE,SAAO,UAAU;IAEnB,CAAC,YAAY,MAAM,CACpB;CAED,MAAM,eAAe,aAAa,SAA4B,SAAS,KAAK,EAAE,CAAC,SAAS,CAAC;CAEzF,MAAM,mBAAmB,aACtB,UAAkB;EACjB,MAAM,QAAQ,SAAS;AACvB,MAAI,MAAM,WAAW,EAAG;EACxB,MAAM,OAAO,MAAM,SAAS;AAG5B,EADe,MADC,QAAS,QAAQ,MAAM,SAAU,MAAM,UAAU,MAAM,SAAS,MAAM,OAAO,GAAG,KAAK,GAE7F,IAAI,OAAO;IAErB,CAAC,KAAK,CACP;CAED,MAAM,MAAM,eACH;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACD,GACD;EAAC;EAAkB;EAAe;EAAe;EAAe;EAAM;EAAM;EAAa;EAAU;EAAc;EAAM;EAAM,CAC9H;CAED,MAAM,aAAa;AAEnB,QACE,qBAAC,OAAD;EAAgB;EAAW,iBAAe,gBAAgB,KAAK;EAAW,eAAa;EAAY,oBAAkB;EAAa,aAAW;EAAU,aAAW;EAAU,gBAAc;EAAa,MAAK;EAAQ,GAAI;YAAxN;GACE,oBAAC,aAAa,UAAd;IAAuB,OAAO;cAAM,MAAM;IAAiC;GAE1E,cAAc,SAAS,YAAY,OAAO,UAAU,WAAW,oBAAC,SAAD;IAAO,MAAK;IAAS,MAAM;IAAmB;IAAS,IAAG;GAEzH,cAAc,SAAS,cAAc,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,MAAM,oBAAC,SAAD;IAAe,MAAK;IAAS,MAAM,aAAa;IAAM,OAAO;IAAK,EAAtD,EAAsD,CAAC,GAAG;GAChJ;;;AAYV,MAAa,sBAAsB,SAAS,gBAAgB,EAC1D,KACA,OACA,UACA,WACA,UACA,WACA,SACA,GAAG,QAGF;CACD,MAAM,MAAM,WAAW,aAAa;AACpC,KAAI,CAAC,IAAK,OAAM,IAAI,MAAM,kDAAkD;CAE5E,MAAM,EAAE,MAAM,aAAa,eAAe,UAAU,eAAe,eAAe,aAAa;CAE/F,MAAM,SAAS,OAAiC,KAAK;AACrD,qBAAoB,WAAW;AAC7B,MAAI,CAAC,OAAO,QACV,OAAM,IAAI,MAAM,wCAAwC;AAE1D,SAAO,OAAO;GACd;AAEF,iBAAgB,SAAS,OAAO,OAAO,QAAQ,EAAE,CAAC,UAAU,MAAM,CAAC;CAEnE,MAAM,UAAU,cAAc,MAAM;CAEpC,MAAM,WAAW,kBAAkB;AACjC,MAAI,iBAAiB,SAAU;AAC/B,MAAI,SAAS,SAAU,UAAS,UAAU,KAAK,MAAM;OAChD;GACH,MAAM,UAAU,IAAI;AAEpB,YADa,UAAU,QAAQ,QAAQ,MAAM,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,MAAM,CACjE;;IAEf;EAAC,IAAI;EAAO;EAAU;EAAe;EAAS;EAAU;EAAM;EAAM,CAAC;CAExE,MAAM,gBAAgB,aACnB,MAAwC;AACvC,MAAI,UAAW,WAAU,EAAE;AAC3B,MAAI,EAAE,iBAAkB;AACxB,MAAI,EAAE,QAAQ,OAAO,EAAE,QAAQ,SAAS;AACtC,KAAE,gBAAgB;AAClB,aAAU;AACV;;EAEF,MAAM,QAAQ,eAAe;EAC7B,MAAM,QAAQ,MAAM,WAAW,MAAM,EAAE,QAAQ,MAAM;EACrD,MAAM,UAAU,gBAAgB,eAAe,cAAc;EAC7D,MAAM,UAAU,gBAAgB,eAAe,eAAe;AAC9D,MAAI,EAAE,QAAQ,SAAS;AACrB,KAAE,gBAAgB;AAClB,OAAI,iBAAiB,QAAQ,EAAE;aACtB,EAAE,QAAQ,SAAS;AAC5B,KAAE,gBAAgB;AAClB,OAAI,iBAAiB,QAAQ,EAAE;aACtB,EAAE,QAAQ,QAAQ;AAC3B,KAAE,gBAAgB;AAClB,OAAI,iBAAiB,EAAE;aACd,EAAE,QAAQ,OAAO;AAC1B,KAAE,gBAAgB;AAClB,OAAI,iBAAiB,MAAM,SAAS,EAAE;;IAG1C;EAAC;EAAK;EAAe;EAAW;EAAa;EAAU;EAAM,CAC9D;CAED,MAAM,cAAc,aACjB,MAAqC;AACpC,MAAI,QAAS,SAAQ,EAAE;AACvB,MAAI,EAAE,iBAAkB;AACxB,YAAU;IAEZ,CAAC,SAAS,SAAS,CACpB;AAED,QACE,oBAAC,UAAD;EAAQ,gBAAc;EAAoB;EAAW,iBAAe,iBAAiB,WAAW,KAAK;EAAW,cAAY,UAAU,OAAO;EAAO,UAAU,iBAAiB;EAAU,SAAS;EAAa,WAAW;EAAe,KAAK;EAAQ,MAAK;EAAS,GAAI;EACrQ;EACM"}
|
|
1
|
+
{"version":3,"file":"ToggleGroupBase.js","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { clamp } from '@utils/sharedUtils'\nimport { createContext, useCallback, useContext, useEffect, useImperativeHandle, useMemo, useRef, type ButtonHTMLAttributes, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type ReactNode, type Ref } from 'react'\n\ntype VoidFn = () => void\ntype Orientation = 'horizontal' | 'vertical'\n\nexport interface CommonGroupProps {\n className?: string\n disabled?: boolean\n loop?: boolean\n name?: string\n orientation?: Orientation\n}\n\nexport type SingleProps = CommonGroupProps & {\n defaultValue?: string\n onValueChange?: (v: string) => void\n type?: 'single'\n value?: string\n}\n\nexport type MultipleProps = CommonGroupProps & {\n defaultValue?: string[]\n onValueChange?: (v: string[]) => void\n type: 'multiple'\n value?: string[]\n}\n\nexport type ToggleGroupProps = (SingleProps | MultipleProps) & Omit<HTMLAttributes<HTMLDivElement>, 'onChange'>\n\nexport interface ItemRenderProps {\n children?: ReactNode\n className?: string\n disabled?: boolean\n value: string\n}\n\nconst GroupContext = createContext<{\n focusItemByIndex: (index: number) => void\n groupDisabled: boolean\n loop: boolean\n isItemPressed: (val: string) => boolean\n itemsSnapshot: () => { val: string; el: HTMLButtonElement | null; disabled: boolean }[]\n name?: string\n orientation: Orientation\n register: (val: string, el: HTMLButtonElement | null) => VoidFn\n setValue: (next: string | string[]) => void\n type: 'single' | 'multiple'\n value: string | string[]\n} | null>(null)\n\nexport const ToggleGroupBase = (props: ToggleGroupProps & Record<`data-${string}`, unknown>) => {\n const {\n className,\n defaultValue,\n disabled: groupDisabled = false,\n loop = true,\n name,\n onValueChange,\n orientation = 'horizontal',\n type = 'single',\n value: valueProp,\n 'data-variant': dataVariant,\n 'data-size': dataSize,\n 'data-slot': dataSlot,\n 'data-layout': dataLayout,\n ...rest\n } = props\n\n const isMultiple = type === 'multiple'\n\n const handleValueChange = useCallback(\n (next: string | string[]) => {\n if (!onValueChange) return\n if (isMultiple) {\n const onValueChangeMultiple = onValueChange as (v: string[]) => void\n onValueChangeMultiple(next as string[])\n return\n }\n const onValueChangeSingle = onValueChange as (v: string) => void\n onValueChangeSingle(next as string)\n },\n [isMultiple, onValueChange],\n )\n\n const [value, setValue] = useUncontrolledState<string | string[]>({\n defaultValue: typeof defaultValue !== 'undefined' ? defaultValue : isMultiple ? [] : '',\n onChange: handleValueChange,\n value: valueProp,\n })\n\n const registry = useRef<{ val: string; el: HTMLButtonElement | null; disabled: boolean }[]>([])\n\n const register = useCallback((val: string, el: HTMLButtonElement | null) => {\n const entry = { val, el, disabled: !!el?.disabled }\n registry.current = [...registry.current.filter((i) => i.val !== val), entry]\n return () => {\n registry.current = registry.current.filter((i) => i.val !== val)\n }\n }, [])\n\n const itemsSnapshot = useCallback(() => registry.current.slice(), [])\n\n const isItemPressed = useCallback(\n (val: string) => {\n if (isMultiple) return Array.isArray(value) && value.includes(val)\n return value === val\n },\n [isMultiple, value],\n )\n\n const setValueSafe = useCallback((next: string | string[]) => setValue(next), [setValue])\n\n const focusItemByIndex = useCallback(\n (index: number) => {\n const items = registry.current\n if (items.length === 0) return\n const last = items.length - 1\n const clamped = loop ? ((index % items.length) + items.length) % items.length : clamp(index, 0, last)\n const target = items[clamped]\n target?.el?.focus()\n },\n [loop],\n )\n\n const ctx = useMemo(\n () => ({\n focusItemByIndex,\n groupDisabled,\n isItemPressed,\n itemsSnapshot,\n loop,\n name,\n orientation,\n register,\n setValue: setValueSafe,\n type,\n value,\n }),\n [focusItemByIndex, groupDisabled, isItemPressed, itemsSnapshot, loop, name, orientation, register, setValueSafe, type, value],\n )\n\n const hiddenName = name\n\n return (\n <div\n className={className}\n data-disabled={groupDisabled ? '' : undefined}\n data-layout={dataLayout}\n data-orientation={orientation}\n data-size={dataSize}\n data-slot={dataSlot}\n data-variant={dataVariant}\n role='group'\n {...rest}\n >\n <GroupContext.Provider value={ctx}>{props.children}</GroupContext.Provider>\n\n {hiddenName && type === 'single' && typeof value === 'string' ? (\n <input\n type='hidden'\n name={hiddenName}\n value={value}\n />\n ) : null}\n\n {hiddenName && type === 'multiple' && Array.isArray(value)\n ? value.map((v) => (\n <input\n key={v}\n type='hidden'\n name={hiddenName + '[]'}\n value={v}\n />\n ))\n : null}\n </div>\n )\n}\n\nexport type ToggleGroupItemProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'onPressedChange' | 'pressed' | 'defaultPressed'> &\n ItemRenderProps & {\n /** @deprecated This prop is ignored - pressed state is managed by ToggleGroup */\n pressed?: boolean\n /** @deprecated This prop is ignored - pressed state is managed by ToggleGroup */\n defaultPressed?: boolean\n }\n\nexport const ToggleGroupItemBase = function ToggleGroupItem({\n ref,\n value,\n disabled,\n className,\n children,\n onKeyDown,\n onClick,\n ...rest\n}: ToggleGroupItemProps & {\n ref?: Ref<HTMLButtonElement>\n}) {\n const ctx = useContext(GroupContext)\n if (!ctx) throw new Error('ToggleGroupItem must be used within ToggleGroup')\n\n const { type, orientation, groupDisabled, setValue, isItemPressed, itemsSnapshot, register } = ctx\n\n const btnRef = useRef<HTMLButtonElement | null>(null)\n useImperativeHandle(ref, () => {\n if (!btnRef.current) {\n throw new Error('ToggleGroupItem button ref is not set')\n }\n return btnRef.current\n })\n\n useEffect(() => register(value, btnRef.current), [register, value])\n\n const pressed = isItemPressed(value)\n\n const toggleMe = useCallback(() => {\n if (groupDisabled || disabled) return\n if (type === 'single') setValue(pressed ? '' : value)\n else {\n const current = ctx.value as string[]\n const next = pressed ? current.filter((v) => v !== value) : [...current, value]\n setValue(next)\n }\n }, [ctx.value, disabled, groupDisabled, pressed, setValue, type, value])\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n if (onKeyDown) onKeyDown(e)\n if (e.defaultPrevented) return\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault()\n toggleMe()\n return\n }\n const items = itemsSnapshot()\n const index = items.findIndex((i) => i.val === value)\n const prevKey = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp'\n const nextKey = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown'\n if (e.key === prevKey) {\n e.preventDefault()\n ctx.focusItemByIndex(index - 1)\n } else if (e.key === nextKey) {\n e.preventDefault()\n ctx.focusItemByIndex(index + 1)\n } else if (e.key === 'Home') {\n e.preventDefault()\n ctx.focusItemByIndex(0)\n } else if (e.key === 'End') {\n e.preventDefault()\n ctx.focusItemByIndex(items.length - 1)\n }\n },\n [ctx, itemsSnapshot, onKeyDown, orientation, toggleMe, value],\n )\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n if (onClick) onClick(e)\n if (e.defaultPrevented) return\n toggleMe()\n },\n [onClick, toggleMe],\n )\n\n return (\n <button\n aria-pressed={pressed}\n className={className}\n data-disabled={groupDisabled || disabled ? '' : undefined}\n data-state={pressed ? 'on' : 'off'}\n disabled={groupDisabled || disabled}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n ref={btnRef}\n type='button'\n {...rest}\n >\n {children}\n </button>\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { ActiveColor,
|
|
2
|
+
import { ActiveColor, ActiveTextColor } from "../utils/activeColorStyle.js";
|
|
3
|
+
import { toggleVariants } from "../Toggle.js";
|
|
3
4
|
import { ToggleGroupItemBase } from "./ToggleGroupBase.js";
|
|
4
5
|
import { ComponentProps, Ref } from "react";
|
|
5
6
|
import * as _$react_jsx_runtime0 from "react/jsx-runtime";
|
|
@@ -8,7 +9,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
8
9
|
//#region src/components/ToggleGroup/ToggleGroupItem.d.ts
|
|
9
10
|
type ToggleGroupItemProps = ComponentProps<typeof ToggleGroupItemBase> & VariantProps<typeof toggleVariants> & {
|
|
10
11
|
activeColor?: ActiveColor;
|
|
11
|
-
activeTextColor?:
|
|
12
|
+
activeTextColor?: ActiveTextColor;
|
|
12
13
|
};
|
|
13
14
|
declare function ToggleGroupItem({
|
|
14
15
|
activeColor,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupItem.d.ts","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupItem.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ToggleGroupItem.d.ts","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupItem.tsx"],"mappings":";;;;;;;;;KAQY,oBAAA,GAAuB,cAAA,QAAsB,mBAAA,IACvD,YAAA,QAAoB,cAAA;EAClB,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;AAAA;AAAA;EAIpB,WAAA;EACA,eAAA;EACA,QAAA;EACA,SAAA;EACA,MAAA;EACA,GAAA;EACA,IAAA;EACA,KAAA;EACA,KAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,oBAAA;EACD,GAAA,GAAM,GAAA,CAAI,iBAAA;AAAA,IACX,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { cn } from "../utils/twUtils.js";
|
|
3
|
-
import { getActiveColorStyle
|
|
3
|
+
import { getActiveColorStyle } from "../utils/activeColorStyle.js";
|
|
4
|
+
import { toggleVariants } from "../Toggle.js";
|
|
4
5
|
import { ToggleGroupContext } from "../components/ToggleGroup/ToggleGroup.context.js";
|
|
5
6
|
import { ToggleGroupItemBase } from "./ToggleGroupBase.js";
|
|
6
7
|
import { useContext } from "react";
|
|
@@ -20,7 +21,7 @@ const ToggleGroupItem = ({ activeColor, activeTextColor, children, className, la
|
|
|
20
21
|
variant: resolvedVariant,
|
|
21
22
|
size: resolvedSize,
|
|
22
23
|
layout: resolvedLayout
|
|
23
|
-
}), "group rounded-none shadow-none focus:z-10 focus-visible:z-10 data-[variant=outline]:border-toggle-border data-[variant=outline]:hover:border-toggle-border data-[variant=outline]:data-[state=on]:border-
|
|
24
|
+
}), "group data-[variant=separated]:rounded-md rounded-none shadow-none focus:z-10 focus-visible:z-10 data-[variant=outline]:border-toggle-border data-[variant=outline]:hover:border-toggle-border data-[variant=outline]:data-[state=on]:border-toggle-border--active data-[variant=outline]:data-[state=on]:hover:border-toggle-border--active data-[variant=separated]:border-toggle-border data-[variant=separated]:hover:border-toggle-border--hover data-[variant=separated]:data-[state=on]:border-toggle-border--active data-[variant=separated]:data-[state=on]:bg-toggle-bg--active data-[variant=separated]:data-[state=on]:hover:border-toggle-border--active data-[variant=separated]:data-[state=on]:hover:bg-toggle-bg--active", className),
|
|
24
25
|
"data-layout": resolvedLayout,
|
|
25
26
|
"data-size": resolvedSize,
|
|
26
27
|
"data-slot": "toggle-group-item",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupItem.js","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupItem.tsx"],"sourcesContent":["import { getActiveColorStyle,
|
|
1
|
+
{"version":3,"file":"ToggleGroupItem.js","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupItem.tsx"],"sourcesContent":["import { toggleVariants } from '@components/Toggle/Toggle'\nimport { getActiveColorStyle, type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { type VariantProps } from 'class-variance-authority'\nimport { useContext, type ComponentProps, type Ref } from 'react'\nimport { ToggleGroupContext } from './ToggleGroup.context'\nimport { ToggleGroupItemBase } from './ToggleGroupBase'\n\nexport type ToggleGroupItemProps = ComponentProps<typeof ToggleGroupItemBase> &\n VariantProps<typeof toggleVariants> & {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n }\n\nexport const ToggleGroupItem = ({\n activeColor,\n activeTextColor,\n children,\n className,\n layout,\n ref,\n size,\n style,\n value,\n variant,\n ...props\n}: ToggleGroupItemProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const context = useContext(ToggleGroupContext)\n const resolvedVariant = variant ?? context.variant\n const resolvedSize = size ?? context.size\n const resolvedLayout = layout ?? context.layout\n const resolvedActiveColor = activeColor ?? context.activeColor\n const resolvedActiveTextColor = activeTextColor ?? context.activeTextColor\n\n return (\n <ToggleGroupItemBase\n className={cn(\n toggleVariants({\n variant: resolvedVariant,\n size: resolvedSize,\n layout: resolvedLayout,\n }),\n 'group data-[variant=separated]:rounded-md rounded-none shadow-none focus:z-10 focus-visible:z-10 data-[variant=outline]:border-toggle-border data-[variant=outline]:hover:border-toggle-border data-[variant=outline]:data-[state=on]:border-toggle-border--active data-[variant=outline]:data-[state=on]:hover:border-toggle-border--active data-[variant=separated]:border-toggle-border data-[variant=separated]:hover:border-toggle-border--hover data-[variant=separated]:data-[state=on]:border-toggle-border--active data-[variant=separated]:data-[state=on]:bg-toggle-bg--active data-[variant=separated]:data-[state=on]:hover:border-toggle-border--active data-[variant=separated]:data-[state=on]:hover:bg-toggle-bg--active',\n className,\n )}\n data-layout={resolvedLayout}\n data-size={resolvedSize}\n data-slot='toggle-group-item'\n data-testid='spectral-toggle-group-item'\n data-variant={resolvedVariant}\n ref={ref}\n style={{ ...getActiveColorStyle(resolvedActiveColor, resolvedActiveTextColor), ...style }}\n value={value}\n {...props}\n >\n {children}\n </ToggleGroupItemBase>\n )\n}\n\nToggleGroupItem.displayName = 'ToggleGroupItem'\n"],"mappings":";;;;;;;;;;;AAcA,MAAa,mBAAmB,EAC9B,aACA,iBACA,UACA,WACA,QACA,KACA,MACA,OACA,OACA,SACA,GAAG,YAGC;CACJ,MAAM,UAAU,WAAW,mBAAmB;CAC9C,MAAM,kBAAkB,WAAW,QAAQ;CAC3C,MAAM,eAAe,QAAQ,QAAQ;CACrC,MAAM,iBAAiB,UAAU,QAAQ;CACzC,MAAM,sBAAsB,eAAe,QAAQ;CACnD,MAAM,0BAA0B,mBAAmB,QAAQ;AAE3D,QACE,oBAAC,qBAAD;EACE,WAAW,GACT,eAAe;GACb,SAAS;GACT,MAAM;GACN,QAAQ;GACT,CAAC,EACF,6sBACA,UACD;EACD,eAAa;EACb,aAAW;EACX,aAAU;EACV,eAAY;EACZ,gBAAc;EACT;EACL,OAAO;GAAE,GAAG,oBAAoB,qBAAqB,wBAAwB;GAAE,GAAG;GAAO;EAClF;EACP,GAAI;EAEH;EACmB;;AAI1B,gBAAgB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupSplitMenuItem.d.ts","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupSplitMenuItem.tsx"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"ToggleGroupSplitMenuItem.d.ts","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupSplitMenuItem.tsx"],"mappings":";;;;;;;UASiB,6BAAA,SAAsC,IAAA,CAAK,oBAAA;EAC1D,QAAA,EAAU,SAAA;EACV,aAAA,GAAgB,iBAAA;EAChB,iBAAA;EACA,uBAAA;EACA,wBAAA,GAA2B,iBAAA;EAC3B,mBAAA,GAAsB,aAAA;EACtB,eAAA,EAAiB,kBAAA;EACjB,YAAA,GAAe,iBAAA;EACf,aAAA;EACA,kBAAA;EACA,qBAAA,IAAyB,KAAA;EACzB,WAAA,GAAc,SAAA;AAAA;AAAA;EAId,WAAA;EACA,eAAA;EACA,QAAA;EACA,SAAA;EACA,aAAA;EACA,iBAAA;EACA,uBAAA;EACA,mBAAA;EACA,wBAAA;EACA,eAAA;EACA,YAAA;EACA,aAAA;EACA,kBAAA;EACA,MAAA;EACA,qBAAA;EACA,SAAA;EACA,IAAA;EACA,KAAA;EACA,WAAA;EACA,KAAA;EACA,OAAA;EAAA,GACG;AAAA,GACF,6BAAA,GAA6B,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { ChevronDownIcon } from "../Icons/ChevronDownIcon.js";
|
|
3
3
|
import { cn } from "../utils/twUtils.js";
|
|
4
|
-
import { getActiveColorStyle
|
|
4
|
+
import { getActiveColorStyle } from "../utils/activeColorStyle.js";
|
|
5
|
+
import { toggleVariants } from "../Toggle.js";
|
|
5
6
|
import { ToggleGroupContext } from "../components/ToggleGroup/ToggleGroup.context.js";
|
|
6
7
|
import { ToggleGroupItem } from "./ToggleGroupItem.js";
|
|
7
8
|
import { DropdownMenu } from "../DropdownMenu.js";
|
|
@@ -52,7 +53,7 @@ const ToggleGroupSplitMenuItem = ({ activeColor, activeTextColor, children, clas
|
|
|
52
53
|
};
|
|
53
54
|
const handleDropdownOpenChange = (nextOpen) => {
|
|
54
55
|
if (nextOpen) {
|
|
55
|
-
|
|
56
|
+
openerRef.current ??= "chevron";
|
|
56
57
|
setOpen(true);
|
|
57
58
|
setTimeout(() => {
|
|
58
59
|
focusFirstEnabledDropdownItem("first");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroupSplitMenuItem.js","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupSplitMenuItem.tsx"],"sourcesContent":["import { DropdownMenu, type DropdownMenuOption, type DropdownMenuProps } from '@components/DropdownMenu/DropdownMenu'\nimport { ChevronDownIcon } from '@components/Icons'\nimport { getActiveColorStyle, toggleVariants } from '@components/Toggle/Toggle'\nimport { cn } from '@utils/twUtils'\nimport { useContext, useRef, useState, type CSSProperties, type KeyboardEvent, type ReactNode } from 'react'\nimport { ToggleGroupContext } from './ToggleGroup.context'\nimport { ToggleGroupItem, type ToggleGroupItemProps } from './ToggleGroupItem'\n\nexport interface ToggleGroupSplitMenuItemProps extends Omit<ToggleGroupItemProps, 'children'> {\n children: ReactNode\n dropdownAlign?: DropdownMenuProps['align']\n dropdownAriaLabel: string\n dropdownButtonClassName?: string\n dropdownCollisionPadding?: DropdownMenuProps['collisionPadding']\n dropdownButtonStyle?: CSSProperties\n dropdownOptions: DropdownMenuOption[]\n dropdownSide?: DropdownMenuProps['side']\n dropdownValue?: string | string[]\n dropdownValueLabel?: string\n onDropdownValueChange?: (value: string | string[]) => void\n triggerIcon?: ReactNode\n}\n\nexport const ToggleGroupSplitMenuItem = ({\n activeColor,\n activeTextColor,\n children,\n className,\n dropdownAlign = 'end',\n dropdownAriaLabel,\n dropdownButtonClassName,\n dropdownButtonStyle,\n dropdownCollisionPadding = 12,\n dropdownOptions,\n dropdownSide = 'bottom',\n dropdownValue,\n dropdownValueLabel,\n layout,\n onDropdownValueChange,\n onKeyDown,\n size,\n style,\n triggerIcon = <ChevronDownIcon size={16} />,\n value,\n variant,\n ...props\n}: ToggleGroupSplitMenuItemProps) => {\n const [open, setOpen] = useState(false)\n const dropdownContentRef = useRef<HTMLDivElement | null>(null)\n const primaryButtonRef = useRef<HTMLButtonElement | null>(null)\n const chevronButtonRef = useRef<HTMLButtonElement | null>(null)\n const openerRef = useRef<'primary' | 'chevron' | null>(null)\n const isDisabled = props.disabled ?? false\n const context = useContext(ToggleGroupContext)\n const resolvedVariant = variant ?? context.variant\n const resolvedSize = size ?? context.size\n const resolvedLayout = layout ?? context.layout\n const resolvedOrientation = context.orientation ?? 'horizontal'\n const resolvedActiveColor = activeColor ?? context.activeColor\n const resolvedActiveTextColor = activeTextColor ?? context.activeTextColor\n const sharedActiveStyle = {\n ...getActiveColorStyle(resolvedActiveColor, resolvedActiveTextColor),\n ...style,\n }\n\n const focusFirstEnabledDropdownItem = (focusTarget: 'first' | 'last' = 'first'): void => {\n const content = dropdownContentRef.current\n if (!content) return\n\n const menuItemSelector = '[role=\"menuitem\"]:not([data-disabled]), [role=\"menuitemcheckbox\"]:not([data-disabled]), [role=\"menuitemradio\"]:not([data-disabled])'\n const enabledItems = Array.from(content.querySelectorAll<HTMLElement>(menuItemSelector))\n if (enabledItems.length === 0) return\n\n if (focusTarget === 'last') {\n enabledItems[enabledItems.length - 1]?.focus()\n return\n }\n\n enabledItems[0]?.focus()\n }\n\n const openMenu = (opener: 'primary' | 'chevron'): void => {\n openerRef.current = opener\n setOpen(true)\n setTimeout(() => {\n focusFirstEnabledDropdownItem('first')\n }, 0)\n }\n\n const restoreFocusToOpener = (): void => {\n const opener = openerRef.current\n const focusTarget = opener === 'primary' ? primaryButtonRef.current : chevronButtonRef.current\n openerRef.current = null\n focusTarget?.focus()\n }\n\n const handleDropdownOpenChange = (nextOpen: boolean): void => {\n if (nextOpen) {\n if (!openerRef.current) {\n openerRef.current = 'chevron'\n }\n setOpen(true)\n setTimeout(() => {\n focusFirstEnabledDropdownItem('first')\n }, 0)\n return\n }\n\n setOpen(false)\n restoreFocusToOpener()\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'ArrowDown' && resolvedOrientation !== 'vertical') {\n event.preventDefault()\n openMenu('primary')\n if (onKeyDown) onKeyDown(event)\n return\n }\n\n if (onKeyDown) onKeyDown(event)\n }\n\n const handleDropdownTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (open && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n event.preventDefault()\n focusFirstEnabledDropdownItem(event.key === 'ArrowUp' ? 'last' : 'first')\n if (onKeyDown) onKeyDown(event)\n return\n }\n\n const isOpenMenuKey = event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ' || event.key === 'Space' || event.key === 'Spacebar'\n\n if (isOpenMenuKey) {\n event.preventDefault()\n openMenu('chevron')\n if (onKeyDown) onKeyDown(event)\n return\n }\n\n if (onKeyDown) onKeyDown(event)\n }\n\n const toggleAriaLabel = props['aria-label'] ? `${props['aria-label']}${dropdownValueLabel ? `, ${dropdownValueLabel}` : ''}` : undefined\n\n return (\n <>\n <ToggleGroupItem\n activeColor={resolvedActiveColor}\n activeTextColor={resolvedActiveTextColor}\n aria-label={toggleAriaLabel}\n className={cn('peer/spectral-split-menu rounded-r-none! border-r-0', className)}\n layout={resolvedLayout}\n onKeyDown={handleKeyDown}\n ref={primaryButtonRef}\n size={resolvedSize}\n style={sharedActiveStyle}\n value={value}\n variant={resolvedVariant}\n {...(({ 'aria-label': _, ...rest }) => rest)(props)}\n >\n {children}\n </ToggleGroupItem>\n\n <DropdownMenu\n align={dropdownAlign}\n asChild\n collisionPadding={dropdownCollisionPadding}\n disabled={isDisabled}\n dropdownContentRef={dropdownContentRef}\n onOpenChange={handleDropdownOpenChange}\n onValueChange={onDropdownValueChange}\n open={open}\n options={dropdownOptions}\n side={dropdownSide}\n trigger={\n <button\n aria-expanded={open}\n aria-haspopup='menu'\n aria-label={dropdownAriaLabel}\n className={cn(\n toggleVariants({\n layout: resolvedLayout,\n size: resolvedSize,\n variant: resolvedVariant,\n }),\n 'px-1 min-w-6 data-[size=sm]:min-w-5 data-[size=sm]:px-0.5 relative rounded-none border-l-0 shadow-none',\n 'data-[size=lg]:min-w-7 data-[size=lg]:px-1.5 data-[variant=outline]:border-toggle-border',\n 'hover:opacity-100! data-[variant=outline]:hover:border-toggle-border',\n 'before:inset-y-2 before:left-0 before:pointer-events-none before:absolute before:w-px before:bg-border-secondary/6',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'peer-data-[state=on]/spectral-split-menu:border-toggle-border--active!',\n 'peer-data-[state=on]/spectral-split-menu:bg-toggle-bg--active',\n 'peer-data-[state=on]/spectral-split-menu:hover:border-toggle-border--active!',\n 'peer-data-[state=on]/spectral-split-menu:hover:bg-toggle-bg--active!',\n 'peer-data-[state=on]/spectral-split-menu:text-toggle-text--active',\n 'peer-data-[state=on]/spectral-split-menu:hover:text-toggle-text--active!',\n dropdownButtonClassName,\n )}\n data-layout={resolvedLayout}\n data-size={resolvedSize}\n data-variant={resolvedVariant}\n disabled={isDisabled}\n onKeyDown={handleDropdownTriggerKeyDown}\n onPointerDown={() => {\n openerRef.current = 'chevron'\n }}\n ref={chevronButtonRef}\n style={{ ...sharedActiveStyle, ...dropdownButtonStyle }}\n type='button'\n >\n {triggerIcon}\n </button>\n }\n value={dropdownValue}\n />\n </>\n )\n}\n\nToggleGroupSplitMenuItem.displayName = 'ToggleGroupSplitMenuItem'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ToggleGroupSplitMenuItem.js","names":[],"sources":["../../src/components/ToggleGroup/ToggleGroupSplitMenuItem.tsx"],"sourcesContent":["import { DropdownMenu, type DropdownMenuOption, type DropdownMenuProps } from '@components/DropdownMenu/DropdownMenu'\nimport { ChevronDownIcon } from '@components/Icons'\nimport { toggleVariants } from '@components/Toggle/Toggle'\nimport { getActiveColorStyle } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { useContext, useRef, useState, type CSSProperties, type KeyboardEvent, type ReactNode } from 'react'\nimport { ToggleGroupContext } from './ToggleGroup.context'\nimport { ToggleGroupItem, type ToggleGroupItemProps } from './ToggleGroupItem'\n\nexport interface ToggleGroupSplitMenuItemProps extends Omit<ToggleGroupItemProps, 'children'> {\n children: ReactNode\n dropdownAlign?: DropdownMenuProps['align']\n dropdownAriaLabel: string\n dropdownButtonClassName?: string\n dropdownCollisionPadding?: DropdownMenuProps['collisionPadding']\n dropdownButtonStyle?: CSSProperties\n dropdownOptions: DropdownMenuOption[]\n dropdownSide?: DropdownMenuProps['side']\n dropdownValue?: string | string[]\n dropdownValueLabel?: string\n onDropdownValueChange?: (value: string | string[]) => void\n triggerIcon?: ReactNode\n}\n\nexport const ToggleGroupSplitMenuItem = ({\n activeColor,\n activeTextColor,\n children,\n className,\n dropdownAlign = 'end',\n dropdownAriaLabel,\n dropdownButtonClassName,\n dropdownButtonStyle,\n dropdownCollisionPadding = 12,\n dropdownOptions,\n dropdownSide = 'bottom',\n dropdownValue,\n dropdownValueLabel,\n layout,\n onDropdownValueChange,\n onKeyDown,\n size,\n style,\n triggerIcon = <ChevronDownIcon size={16} />,\n value,\n variant,\n ...props\n}: ToggleGroupSplitMenuItemProps) => {\n const [open, setOpen] = useState(false)\n const dropdownContentRef = useRef<HTMLDivElement | null>(null)\n const primaryButtonRef = useRef<HTMLButtonElement | null>(null)\n const chevronButtonRef = useRef<HTMLButtonElement | null>(null)\n const openerRef = useRef<'primary' | 'chevron' | null>(null)\n const isDisabled = props.disabled ?? false\n const context = useContext(ToggleGroupContext)\n const resolvedVariant = variant ?? context.variant\n const resolvedSize = size ?? context.size\n const resolvedLayout = layout ?? context.layout\n const resolvedOrientation = context.orientation ?? 'horizontal'\n const resolvedActiveColor = activeColor ?? context.activeColor\n const resolvedActiveTextColor = activeTextColor ?? context.activeTextColor\n const sharedActiveStyle = {\n ...getActiveColorStyle(resolvedActiveColor, resolvedActiveTextColor),\n ...style,\n }\n\n const focusFirstEnabledDropdownItem = (focusTarget: 'first' | 'last' = 'first'): void => {\n const content = dropdownContentRef.current\n if (!content) return\n\n const menuItemSelector = '[role=\"menuitem\"]:not([data-disabled]), [role=\"menuitemcheckbox\"]:not([data-disabled]), [role=\"menuitemradio\"]:not([data-disabled])'\n const enabledItems = Array.from(content.querySelectorAll<HTMLElement>(menuItemSelector))\n if (enabledItems.length === 0) return\n\n if (focusTarget === 'last') {\n enabledItems[enabledItems.length - 1]?.focus()\n return\n }\n\n enabledItems[0]?.focus()\n }\n\n const openMenu = (opener: 'primary' | 'chevron'): void => {\n openerRef.current = opener\n setOpen(true)\n setTimeout(() => {\n focusFirstEnabledDropdownItem('first')\n }, 0)\n }\n\n const restoreFocusToOpener = (): void => {\n const opener = openerRef.current\n const focusTarget = opener === 'primary' ? primaryButtonRef.current : chevronButtonRef.current\n openerRef.current = null\n focusTarget?.focus()\n }\n\n const handleDropdownOpenChange = (nextOpen: boolean): void => {\n if (nextOpen) {\n openerRef.current ??= 'chevron'\n setOpen(true)\n setTimeout(() => {\n focusFirstEnabledDropdownItem('first')\n }, 0)\n return\n }\n\n setOpen(false)\n restoreFocusToOpener()\n }\n\n const handleKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (event.key === 'ArrowDown' && resolvedOrientation !== 'vertical') {\n event.preventDefault()\n openMenu('primary')\n if (onKeyDown) onKeyDown(event)\n return\n }\n\n if (onKeyDown) onKeyDown(event)\n }\n\n const handleDropdownTriggerKeyDown = (event: KeyboardEvent<HTMLButtonElement>) => {\n if (open && (event.key === 'ArrowDown' || event.key === 'ArrowUp')) {\n event.preventDefault()\n focusFirstEnabledDropdownItem(event.key === 'ArrowUp' ? 'last' : 'first')\n if (onKeyDown) onKeyDown(event)\n return\n }\n\n const isOpenMenuKey = event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ' || event.key === 'Space' || event.key === 'Spacebar'\n\n if (isOpenMenuKey) {\n event.preventDefault()\n openMenu('chevron')\n if (onKeyDown) onKeyDown(event)\n return\n }\n\n if (onKeyDown) onKeyDown(event)\n }\n\n const toggleAriaLabel = props['aria-label'] ? `${props['aria-label']}${dropdownValueLabel ? `, ${dropdownValueLabel}` : ''}` : undefined\n\n return (\n <>\n <ToggleGroupItem\n activeColor={resolvedActiveColor}\n activeTextColor={resolvedActiveTextColor}\n aria-label={toggleAriaLabel}\n className={cn('peer/spectral-split-menu rounded-r-none! border-r-0', className)}\n layout={resolvedLayout}\n onKeyDown={handleKeyDown}\n ref={primaryButtonRef}\n size={resolvedSize}\n style={sharedActiveStyle}\n value={value}\n variant={resolvedVariant}\n {...(({ 'aria-label': _, ...rest }) => rest)(props)}\n >\n {children}\n </ToggleGroupItem>\n\n <DropdownMenu\n align={dropdownAlign}\n asChild\n collisionPadding={dropdownCollisionPadding}\n disabled={isDisabled}\n dropdownContentRef={dropdownContentRef}\n onOpenChange={handleDropdownOpenChange}\n onValueChange={onDropdownValueChange}\n open={open}\n options={dropdownOptions}\n side={dropdownSide}\n trigger={\n <button\n aria-expanded={open}\n aria-haspopup='menu'\n aria-label={dropdownAriaLabel}\n className={cn(\n toggleVariants({\n layout: resolvedLayout,\n size: resolvedSize,\n variant: resolvedVariant,\n }),\n 'px-1 min-w-6 data-[size=sm]:min-w-5 data-[size=sm]:px-0.5 relative rounded-none border-l-0 shadow-none',\n 'data-[size=lg]:min-w-7 data-[size=lg]:px-1.5 data-[variant=outline]:border-toggle-border',\n 'hover:opacity-100! data-[variant=outline]:hover:border-toggle-border',\n 'before:inset-y-2 before:left-0 before:pointer-events-none before:absolute before:w-px before:bg-border-secondary/6',\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent',\n 'peer-data-[state=on]/spectral-split-menu:border-toggle-border--active!',\n 'peer-data-[state=on]/spectral-split-menu:bg-toggle-bg--active',\n 'peer-data-[state=on]/spectral-split-menu:hover:border-toggle-border--active!',\n 'peer-data-[state=on]/spectral-split-menu:hover:bg-toggle-bg--active!',\n 'peer-data-[state=on]/spectral-split-menu:text-toggle-text--active',\n 'peer-data-[state=on]/spectral-split-menu:hover:text-toggle-text--active!',\n dropdownButtonClassName,\n )}\n data-layout={resolvedLayout}\n data-size={resolvedSize}\n data-variant={resolvedVariant}\n disabled={isDisabled}\n onKeyDown={handleDropdownTriggerKeyDown}\n onPointerDown={() => {\n openerRef.current = 'chevron'\n }}\n ref={chevronButtonRef}\n style={{ ...sharedActiveStyle, ...dropdownButtonStyle }}\n type='button'\n >\n {triggerIcon}\n </button>\n }\n value={dropdownValue}\n />\n </>\n )\n}\n\nToggleGroupSplitMenuItem.displayName = 'ToggleGroupSplitMenuItem'\n"],"mappings":"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"}
|
package/dist/ToggleGroup.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { ActiveColor,
|
|
2
|
+
import { ActiveColor, ActiveTextColor } from "./utils/activeColorStyle.js";
|
|
3
|
+
import { toggleVariants } from "./Toggle.js";
|
|
3
4
|
import { ToggleGroupBase } from "./ToggleGroup/ToggleGroupBase.js";
|
|
4
5
|
import { ToggleGroupItem, ToggleGroupItemProps } from "./ToggleGroup/ToggleGroupItem.js";
|
|
5
6
|
import { ToggleGroupSplitMenuItem, ToggleGroupSplitMenuItemProps } from "./ToggleGroup/ToggleGroupSplitMenuItem.js";
|
|
@@ -10,7 +11,7 @@ import { VariantProps } from "class-variance-authority";
|
|
|
10
11
|
//#region src/components/ToggleGroup/ToggleGroup.d.ts
|
|
11
12
|
type ToggleGroupProps = ComponentProps<typeof ToggleGroupBase> & VariantProps<typeof toggleVariants> & {
|
|
12
13
|
activeColor?: ActiveColor;
|
|
13
|
-
activeTextColor?:
|
|
14
|
+
activeTextColor?: ActiveTextColor;
|
|
14
15
|
};
|
|
15
16
|
declare const ToggleGroup: ({
|
|
16
17
|
className,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroup.d.ts","names":[],"sources":["../src/components/ToggleGroup/ToggleGroup.tsx"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ToggleGroup.d.ts","names":[],"sources":["../src/components/ToggleGroup/ToggleGroup.tsx"],"mappings":";;;;;;;;;;;KAUY,gBAAA,GAAmB,cAAA,QAAsB,eAAA,IACnD,YAAA,QAAoB,cAAA;EAClB,WAAA,GAAc,WAAA;EACd,eAAA,GAAkB,eAAA;AAAA;AAAA,cAGT,WAAA;EAAW,SAAA;EAAA,OAAA;EAAA,IAAA;EAAA,MAAA;EAAA,WAAA;EAAA,eAAA;EAAA,WAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAAyG,gBAAA,KAAgB,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/ToggleGroup.js
CHANGED
|
@@ -11,7 +11,7 @@ import "class-variance-authority";
|
|
|
11
11
|
//#region src/components/ToggleGroup/ToggleGroup.tsx
|
|
12
12
|
const ToggleGroup = ({ className, variant, size, layout, activeColor, activeTextColor, orientation, children, ...props }) => {
|
|
13
13
|
return /* @__PURE__ */ jsx(ToggleGroupBase, {
|
|
14
|
-
className: cn(`group/toggle-group rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md data-[variant='outline']:gap-0 flex h-fit w-fit items-center data-[layout='expanded']:w-full data-[variant='outline']:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant='outline']:[&_button:not(:first-of-type)]:border-l-0 data-[variant='outline']:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)] data-[variant='outline']:[&_button[data-state='on']:not(:last-of-type)]:[border-right-color:var(--color-toggle-border--active)]`, className),
|
|
14
|
+
className: cn(`group/toggle-group rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md data-[variant='outline']:gap-0 data-[variant='separated']:gap-1.5 data-[size='sm']:data-[variant='separated']:gap-1 data-[size='lg']:data-[variant='separated']:gap-2 flex h-fit w-fit items-center data-[layout='expanded']:w-full data-[variant='outline']:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant='outline']:[&_button:not(:first-of-type)]:border-l-0 data-[variant='outline']:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)] data-[variant='outline']:[&_button[data-state='on']:not(:last-of-type)]:[border-right-color:var(--color-toggle-border--active)]`, className),
|
|
15
15
|
"data-layout": layout,
|
|
16
16
|
"data-size": size,
|
|
17
17
|
"data-slot": "toggle-group",
|
package/dist/ToggleGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToggleGroup.js","names":[],"sources":["../src/components/ToggleGroup/ToggleGroup.tsx"],"sourcesContent":["import { type
|
|
1
|
+
{"version":3,"file":"ToggleGroup.js","names":[],"sources":["../src/components/ToggleGroup/ToggleGroup.tsx"],"sourcesContent":["import { type toggleVariants } from '@components/Toggle/Toggle'\nimport { type ActiveColor, type ActiveTextColor } from '@utils/activeColorStyle'\nimport { cn } from '@utils/twUtils'\nimport { type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\nimport { ToggleGroupContext } from './ToggleGroup.context'\nimport { ToggleGroupBase } from './ToggleGroupBase'\nexport { ToggleGroupItem, type ToggleGroupItemProps } from './ToggleGroupItem'\nexport { ToggleGroupSplitMenuItem, type ToggleGroupSplitMenuItemProps } from './ToggleGroupSplitMenuItem'\n\nexport type ToggleGroupProps = ComponentProps<typeof ToggleGroupBase> &\n VariantProps<typeof toggleVariants> & {\n activeColor?: ActiveColor\n activeTextColor?: ActiveTextColor\n }\n\nexport const ToggleGroup = ({ className, variant, size, layout, activeColor, activeTextColor, orientation, children, ...props }: ToggleGroupProps) => {\n return (\n <ToggleGroupBase\n className={cn(\n `group/toggle-group rounded-md [&_button:first-of-type]:rounded-l-md [&_button:last-of-type]:rounded-r-md data-[variant='outline']:gap-0 data-[variant='separated']:gap-1.5 data-[size='sm']:data-[variant='separated']:gap-1 data-[size='lg']:data-[variant='separated']:gap-2 flex h-fit w-fit items-center data-[layout='expanded']:w-full data-[variant='outline']:[--color-toggle-border:var(--color-toggle-outline-border)] data-[variant='outline']:[&_button:not(:first-of-type)]:border-l-0 data-[variant='outline']:[&_button:not(:last-of-type)]:[border-right-color:var(--color-toggle-outline-divider)] data-[variant='outline']:[&_button[data-state='on']:not(:last-of-type)]:[border-right-color:var(--color-toggle-border--active)]`,\n className,\n )}\n data-layout={layout}\n data-size={size}\n data-slot='toggle-group'\n data-testid='spectral-toggle-group'\n data-variant={variant}\n orientation={orientation}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant, size, layout, activeColor, activeTextColor, orientation }}>{children}</ToggleGroupContext.Provider>\n </ToggleGroupBase>\n )\n}\n"],"mappings":";;;;;;;;;;;AAgBA,MAAa,eAAe,EAAE,WAAW,SAAS,MAAM,QAAQ,aAAa,iBAAiB,aAAa,UAAU,GAAG,YAA8B;AACpJ,QACE,oBAAC,iBAAD;EACE,WAAW,GACT,utBACA,UACD;EACD,eAAa;EACb,aAAW;EACX,aAAU;EACV,eAAY;EACZ,gBAAc;EACD;EACb,GAAI;YAEJ,oBAAC,mBAAmB,UAApB;GAA6B,OAAO;IAAE;IAAS;IAAM;IAAQ;IAAa;IAAiB;IAAa;GAAG;GAAuC;EAClI"}
|
package/dist/Tooltip.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.d.ts","names":[],"sources":["../src/components/Tooltip/Tooltip.tsx"],"mappings":";;;;;;;;cAKa,eAAA;EAAe,aAAA;EAAA,GAAA;AAAA,GAAqC,cAAA,QAAsB,gBAAA,CAAiB,QAAA,MAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"Tooltip.d.ts","names":[],"sources":["../src/components/Tooltip/Tooltip.tsx"],"mappings":";;;;;;;;cAKa,eAAA;EAAe,aAAA;EAAA,GAAA;AAAA,GAAqC,cAAA,QAAsB,gBAAA,CAAiB,QAAA,MAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAUpG,OAAA;EAAA,GAAO;AAAA,GAAkB,cAAA,QAAsB,gBAAA,CAAiB,IAAA,MAAK,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAYrE,cAAA;EAAc,OAAA;EAAA,QAAA;EAAA,GAAA;AAAA,GAAqC,cAAA,QAAsB,gBAAA,CAAiB,OAAA,MAAQ,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAczG,eAAA,GAAe,KAAA;;IAapB,iCAAA,CAAA,SAAA;AAAA,cAcY,cAAA;EAAc,QAAA;EAAA,SAAA;EAAA,SAAA;EAAA,IAAA;EAAA,UAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAQxB,cAAA,QAAsB,gBAAA,CAAiB,OAAA,IACxC,YAAA,QAAoB,eAAA;EAClB,SAAA;AAAA,MACD,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/Tooltip.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tooltip.js","names":[],"sources":["../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport const TooltipProvider = ({ delayDuration = 0, ...props }: ComponentProps<typeof TooltipPrimitive.Provider>) => {\n return <TooltipPrimitive.Provider
|
|
1
|
+
{"version":3,"file":"Tooltip.js","names":[],"sources":["../src/components/Tooltip/Tooltip.tsx"],"sourcesContent":["import * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport { cn } from '@utils/twUtils'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { type ComponentProps } from 'react'\n\nexport const TooltipProvider = ({ delayDuration = 0, ...props }: ComponentProps<typeof TooltipPrimitive.Provider>) => {\n return (\n <TooltipPrimitive.Provider\n data-slot='tooltip-provider'\n delayDuration={delayDuration}\n {...props}\n />\n )\n}\n\nexport const Tooltip = ({ ...props }: ComponentProps<typeof TooltipPrimitive.Root>) => {\n return (\n <TooltipProvider>\n <TooltipPrimitive.Root\n data-slot='tooltip'\n data-testid='spectral-tooltip'\n {...props}\n />\n </TooltipProvider>\n )\n}\n\nexport const TooltipTrigger = ({ asChild, children, ...props }: ComponentProps<typeof TooltipPrimitive.Trigger>) => {\n return (\n <TooltipPrimitive.Trigger\n asChild={asChild}\n className='w-fit'\n data-slot='tooltip-trigger'\n data-testid='spectral-tooltip-trigger'\n {...props}\n >\n {children}\n </TooltipPrimitive.Trigger>\n )\n}\n\nconst tooltipVariants = cva(\n `tooltip-effects rounded-md px-3 py-1.5 text-xs pointer-events-auto z-50 w-fit bg-tooltip-bg text-text-primary will-change-transform outline-none select-none motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=left]:slide-in-from-right-2 motion-safe:data-[side=right]:slide-in-from-left-2 motion-safe:data-[side=top]:slide-in-from-bottom-2 motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:animate-in motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=open]:zoom-in-95`,\n {\n variants: {\n variant: {\n default: '',\n outline: 'border-2 border-tooltip-outline-border',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n)\n\nconst tooltipArrowVariants = cva('size-2.5 z-[-1] rotate-45 rounded-[2px] bg-tooltip-arrow fill-tooltip-arrow', {\n variants: {\n variant: {\n default: '-translate-y-[calc(50%+1px)]',\n outline: '-translate-y-[calc(50%-1.5px)] border-2 border-t-0 border-l-0 border-tooltip-outline-arrow',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n})\n\nexport const TooltipContent = ({\n children,\n className,\n showArrow = false,\n side,\n sideOffset = 0,\n variant = 'default',\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content> &\n VariantProps<typeof tooltipVariants> & {\n showArrow?: boolean\n }) => {\n return (\n <TooltipPrimitive.Portal\n data-testid='spectral-tooltip-portal'\n data-slot='tooltip-portal'\n >\n <TooltipPrimitive.Content\n className={cn(tooltipVariants({ variant }), className)}\n data-slot='tooltip-content'\n data-testid='spectral-tooltip-content'\n side={side}\n sideOffset={sideOffset}\n {...props}\n >\n {children}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={cn(tooltipArrowVariants({ variant }))}\n height={8}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n}\n"],"mappings":";;;;;;;;AAKA,MAAa,mBAAmB,EAAE,gBAAgB,GAAG,GAAG,YAA8D;AACpH,QACE,oBAAC,iBAAiB,UAAlB;EACE,aAAU;EACK;EACf,GAAI;EACJ;;AAIN,MAAa,WAAW,EAAE,GAAG,YAA0D;AACrF,QACE,oBAAC,iBAAD,YACE,oBAAC,iBAAiB,MAAlB;EACE,aAAU;EACV,eAAY;EACZ,GAAI;EACJ,GACc;;AAItB,MAAa,kBAAkB,EAAE,SAAS,UAAU,GAAG,YAA6D;AAClH,QACE,oBAAC,iBAAiB,SAAlB;EACW;EACT,WAAU;EACV,aAAU;EACV,eAAY;EACZ,GAAI;EAEH;EACwB;;AAI/B,MAAM,kBAAkB,IACtB,ymBACA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,SAAS;EACV,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CACF;AAED,MAAM,uBAAuB,IAAI,+EAA+E;CAC9G,UAAU,EACR,SAAS;EACP,SAAS;EACT,SAAS;EACV,EACF;CACD,iBAAiB,EACf,SAAS,WACV;CACF,CAAC;AAEF,MAAa,kBAAkB,EAC7B,UACA,WACA,YAAY,OACZ,MACA,aAAa,GACb,UAAU,WACV,GAAG,YAIG;AACN,QACE,oBAAC,iBAAiB,QAAlB;EACE,eAAY;EACZ,aAAU;YAEV,qBAAC,iBAAiB,SAAlB;GACE,WAAW,GAAG,gBAAgB,EAAE,SAAS,CAAC,EAAE,UAAU;GACtD,aAAU;GACV,eAAY;GACN;GACM;GACZ,GAAI;aANN,CAQG,UACA,aACC,oBAAC,iBAAiB,OAAlB;IACE,WAAW,GAAG,qBAAqB,EAAE,SAAS,CAAC,CAAC;IAChD,QAAQ;IACR,EAEqB;;EACH"}
|