@spear-ai/spectral 1.15.3 → 1.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Accordion.d.ts.map +1 -1
- package/dist/Accordion.js +1 -1
- package/dist/Accordion.js.map +1 -1
- package/dist/Alert/AlertBase.d.ts.map +1 -1
- package/dist/Alert/AlertBase.js.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.map +1 -1
- package/dist/Button.js +6 -6
- package/dist/Button.js.map +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.d.ts +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.d.ts.map +1 -1
- package/dist/ButtonGroup/ButtonGroupButton.js +2 -1
- package/dist/ButtonGroup/ButtonGroupButton.js.map +1 -1
- package/dist/ButtonGroup.d.ts +2 -2
- package/dist/ButtonGroup.d.ts.map +1 -1
- package/dist/ButtonGroup.js +2 -1
- package/dist/ButtonGroup.js.map +1 -1
- package/dist/ButtonIcon.d.ts.map +1 -1
- package/dist/ButtonIcon.js +6 -5
- package/dist/ButtonIcon.js.map +1 -1
- package/dist/ButtonIconSlideout.d.ts +49 -0
- package/dist/ButtonIconSlideout.d.ts.map +1 -0
- package/dist/ButtonIconSlideout.js +108 -0
- package/dist/ButtonIconSlideout.js.map +1 -0
- package/dist/Checkbox/CheckboxBase.js.map +1 -1
- package/dist/Checkbox.js.map +1 -1
- package/dist/Combobox.js.map +1 -1
- package/dist/ControlGroup/ControlGroupSelect.js.map +1 -1
- package/dist/ControlGroup.d.ts.map +1 -1
- package/dist/ControlGroup.js +1 -1
- package/dist/ControlGroup.js.map +1 -1
- package/dist/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 +2 -2
- package/dist/Dialog.js.map +1 -1
- package/dist/Drawer.js +3 -3
- 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.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/SyncIcon.d.ts.map +1 -1
- package/dist/Icons/SyncIcon.js.map +1 -1
- package/dist/Icons/SyncOffIcon.d.ts.map +1 -1
- package/dist/Icons/SyncOffIcon.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 +1 -1
- package/dist/Input.js.map +1 -1
- package/dist/InputNumeric.d.ts.map +1 -1
- package/dist/InputNumeric.js.map +1 -1
- package/dist/InputOTP.d.ts.map +1 -1
- package/dist/InputOTP.js.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.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.js +4 -1
- package/dist/RadioButton.js.map +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.d.ts +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.d.ts.map +1 -1
- package/dist/RadioButtonGroup/RadioButtonGroupBase.js +7 -2
- package/dist/RadioButtonGroup/RadioButtonGroupBase.js.map +1 -1
- package/dist/RadioButtonGroup.d.ts.map +1 -1
- package/dist/RadioButtonGroup.js.map +1 -1
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +1 -1
- package/dist/RadioGroup.js.map +1 -1
- package/dist/Select.js.map +1 -1
- package/dist/Skeleton.js.map +1 -1
- package/dist/Slider.js.map +1 -1
- package/dist/Switch/SwitchBase.d.ts.map +1 -1
- package/dist/Switch/SwitchBase.js.map +1 -1
- package/dist/Switch.js.map +1 -1
- package/dist/Tabs/TabsBase.d.ts.map +1 -1
- package/dist/Tabs/TabsBase.js.map +1 -1
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/Tabs.js.map +1 -1
- package/dist/Textarea.js.map +1 -1
- package/dist/Toast.d.ts.map +1 -1
- package/dist/Toast.js.map +1 -1
- package/dist/Toggle/ToggleBase.js.map +1 -1
- package/dist/Toggle.d.ts +1 -1
- package/dist/Toggle.d.ts.map +1 -1
- package/dist/Toggle.js +7 -2
- package/dist/Toggle.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupBase.d.ts.map +1 -1
- package/dist/ToggleGroup/ToggleGroupBase.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.js +1 -1
- package/dist/ToggleGroup/ToggleGroupItem.js.map +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js +1 -1
- package/dist/ToggleGroup/ToggleGroupSplitMenuItem.js.map +1 -1
- package/dist/ToggleGroup.js +9 -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 +1 -1
- package/dist/Tray.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/styles/horizon/utilities.css +13 -8
- package/dist/styles/spectral.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { CloseIcon } from "./Icons/CloseIcon.js";
|
|
3
|
+
import { LabelIcon } from "./Icons/LabelIcon.js";
|
|
4
|
+
import { cn } from "./utils/twUtils.js";
|
|
5
|
+
import { ButtonIcon } from "./ButtonIcon.js";
|
|
6
|
+
import { useControllableState } from "./hooks/useControllableState.js";
|
|
7
|
+
import { useId } from "react";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
|
|
10
|
+
//#region src/components/ButtonIconSlideout/ButtonIconSlideout.tsx
|
|
11
|
+
const contentHeightBySize = {
|
|
12
|
+
sm: "h-8",
|
|
13
|
+
md: "h-10",
|
|
14
|
+
lg: "h-12"
|
|
15
|
+
};
|
|
16
|
+
const iconContainerSizeByButtonSize = {
|
|
17
|
+
sm: "size-4",
|
|
18
|
+
md: "size-6",
|
|
19
|
+
lg: "size-8"
|
|
20
|
+
};
|
|
21
|
+
const iconPixelsByButtonSize = {
|
|
22
|
+
sm: 16,
|
|
23
|
+
md: 24,
|
|
24
|
+
lg: 32
|
|
25
|
+
};
|
|
26
|
+
const fontSizeByButtonSize = {
|
|
27
|
+
sm: "text-xs",
|
|
28
|
+
md: "text-sm",
|
|
29
|
+
lg: "text-base"
|
|
30
|
+
};
|
|
31
|
+
const ButtonIconSlideout = ({ buttonClassName, className, closeLabel = "Close panel", content, contentClassName, dataTestId = "spectral-button-icon-slideout", defaultOpen = false, icons = [LabelIcon, CloseIcon], label, shape = "square", size = "md", onClick, onClose, onOpen, onOpenChange, open, ...buttonProps }) => {
|
|
32
|
+
const [isOpen, setIsOpen] = useControllableState({
|
|
33
|
+
value: open,
|
|
34
|
+
defaultValue: defaultOpen,
|
|
35
|
+
onChange: onOpenChange
|
|
36
|
+
});
|
|
37
|
+
const contentId = useId();
|
|
38
|
+
const handleToggle = (event) => {
|
|
39
|
+
onClick?.(event);
|
|
40
|
+
if (event.defaultPrevented) return;
|
|
41
|
+
if (isOpen) onClose?.(event);
|
|
42
|
+
else onOpen?.(event);
|
|
43
|
+
setIsOpen((previous) => !previous);
|
|
44
|
+
};
|
|
45
|
+
const [OpenIcon, CloseIconComponent] = icons;
|
|
46
|
+
const iconSize = iconPixelsByButtonSize[size];
|
|
47
|
+
const contentLeftPosition = shape === "circle" ? {
|
|
48
|
+
sm: "left-[calc(100%-1rem)]",
|
|
49
|
+
md: "left-[calc(100%-1.25rem)]",
|
|
50
|
+
lg: "left-[calc(100%-1.5rem)]"
|
|
51
|
+
}[size] : "left-[calc(100%-0.75rem)]";
|
|
52
|
+
const contentLeftPadding = shape === "circle" ? {
|
|
53
|
+
sm: "pl-5",
|
|
54
|
+
md: "pl-6",
|
|
55
|
+
lg: "pl-7"
|
|
56
|
+
}[size] : "pl-4";
|
|
57
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
58
|
+
className: cn("relative isolate inline-flex w-fit items-center", className),
|
|
59
|
+
"data-testid": dataTestId,
|
|
60
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
61
|
+
"aria-hidden": !isOpen,
|
|
62
|
+
className: cn("pointer-events-none absolute inset-y-0 z-0 w-max max-w-44 rounded-r-xl bg-level-three pr-3 text-text-primary font-medium", contentLeftPosition, contentLeftPadding, contentHeightBySize[size], "flex items-center overflow-hidden transition-[transform,opacity,clip-path] duration-200 ease-in motion-reduce:transition-none", isOpen ? "translate-x-0 opacity-100 [clip-path:inset(0_0_0_0)]" : "-translate-x-2 opacity-0 [clip-path:inset(0_100%_0_0)]"),
|
|
63
|
+
"data-testid": `${dataTestId}-content`,
|
|
64
|
+
id: contentId,
|
|
65
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
66
|
+
className: cn("block max-w-full truncate whitespace-nowrap leading-5", fontSizeByButtonSize[size], contentClassName),
|
|
67
|
+
children: content
|
|
68
|
+
})
|
|
69
|
+
}), /* @__PURE__ */ jsx(ButtonIcon, {
|
|
70
|
+
...buttonProps,
|
|
71
|
+
"aria-controls": contentId,
|
|
72
|
+
"aria-expanded": isOpen,
|
|
73
|
+
className: cn("relative z-10", isOpen && "bg-level-three hover:bg-level-three shadow-[4px_0_10px_rgb(0_0_0_/_0.18)]", buttonClassName),
|
|
74
|
+
"data-testid": `${dataTestId}-button`,
|
|
75
|
+
icon: () => /* @__PURE__ */ jsxs("span", {
|
|
76
|
+
className: cn("relative inline-flex items-center justify-center", iconContainerSizeByButtonSize[size]),
|
|
77
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
78
|
+
"aria-hidden": isOpen,
|
|
79
|
+
className: cn("absolute inset-0 flex items-center justify-center transition-[filter,opacity,transform] duration-200 ease-in motion-reduce:transition-none", isOpen ? "pointer-events-none opacity-0 blur-[2px] scale-95" : "opacity-100 blur-0 scale-100"),
|
|
80
|
+
"data-icon-state": "closed",
|
|
81
|
+
children: /* @__PURE__ */ jsx(OpenIcon, {
|
|
82
|
+
"aria-hidden": "true",
|
|
83
|
+
className: "size-full shrink-0",
|
|
84
|
+
size: iconSize
|
|
85
|
+
})
|
|
86
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
87
|
+
"aria-hidden": !isOpen,
|
|
88
|
+
className: cn("absolute inset-0 flex items-center justify-center transition-[filter,opacity,transform] duration-200 ease-in motion-reduce:transition-none", isOpen ? "opacity-100 blur-0 scale-100" : "pointer-events-none opacity-0 blur-[2px] scale-95"),
|
|
89
|
+
"data-icon-state": "open",
|
|
90
|
+
children: /* @__PURE__ */ jsx(CloseIconComponent, {
|
|
91
|
+
"aria-hidden": "true",
|
|
92
|
+
className: "size-full shrink-0",
|
|
93
|
+
size: iconSize
|
|
94
|
+
})
|
|
95
|
+
})]
|
|
96
|
+
}),
|
|
97
|
+
label: isOpen ? closeLabel : label,
|
|
98
|
+
onClick: handleToggle,
|
|
99
|
+
shape,
|
|
100
|
+
size
|
|
101
|
+
})]
|
|
102
|
+
});
|
|
103
|
+
};
|
|
104
|
+
ButtonIconSlideout.displayName = "ButtonIconSlideout";
|
|
105
|
+
|
|
106
|
+
//#endregion
|
|
107
|
+
export { ButtonIconSlideout };
|
|
108
|
+
//# sourceMappingURL=ButtonIconSlideout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonIconSlideout.js","names":[],"sources":["../src/components/ButtonIconSlideout/ButtonIconSlideout.tsx"],"sourcesContent":["import { ButtonIcon, type ButtonIconProps } from '@components/ButtonIcon/ButtonIcon'\nimport { CloseIcon, LabelIcon } from '@components/Icons'\nimport { type IconProps } from '@components/Icons/iconTypes'\nimport { useControllableState } from '@hooks/useControllableState'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentType, type MouseEvent, useId } from 'react'\n\ntype SlideoutSize = NonNullable<ButtonIconProps['size']>\ntype SlideoutIcons = [openIcon: ComponentType<IconProps>, closeIcon: ComponentType<IconProps>]\n\nconst contentHeightBySize: Record<SlideoutSize, string> = {\n sm: 'h-8',\n md: 'h-10',\n lg: 'h-12',\n}\n\nconst iconContainerSizeByButtonSize: Record<SlideoutSize, string> = {\n sm: 'size-4',\n md: 'size-6',\n lg: 'size-8',\n}\n\nconst iconPixelsByButtonSize: Record<SlideoutSize, number> = {\n sm: 16,\n md: 24,\n lg: 32,\n}\n\nconst fontSizeByButtonSize: Record<SlideoutSize, string> = {\n sm: 'text-xs',\n md: 'text-sm',\n lg: 'text-base',\n}\n\nexport interface ButtonIconSlideoutProps extends Omit<ButtonIconProps, 'className' | 'content' | 'icon' | 'label' | 'onClick'> {\n buttonClassName?: string\n className?: string\n closeLabel?: string\n content: number | string\n contentClassName?: string\n dataTestId?: string\n defaultOpen?: boolean\n icons?: SlideoutIcons\n label: string\n onClick?: (event: MouseEvent<HTMLButtonElement>) => void\n onClose?: (event: MouseEvent<HTMLButtonElement>) => void\n onOpen?: (event: MouseEvent<HTMLButtonElement>) => void\n onOpenChange?: (isOpen: boolean) => void\n open?: boolean\n}\n\nexport const ButtonIconSlideout = ({\n buttonClassName,\n className,\n closeLabel = 'Close panel',\n content,\n contentClassName,\n dataTestId = 'spectral-button-icon-slideout',\n defaultOpen = false,\n icons = [LabelIcon, CloseIcon],\n label,\n shape = 'square',\n size = 'md',\n onClick,\n onClose,\n onOpen,\n onOpenChange,\n open,\n ...buttonProps\n}: ButtonIconSlideoutProps) => {\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n value: open,\n defaultValue: defaultOpen,\n onChange: onOpenChange,\n })\n const contentId = useId()\n\n const handleToggle = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event)\n\n if (event.defaultPrevented) return\n\n if (isOpen) {\n onClose?.(event)\n } else {\n onOpen?.(event)\n }\n\n setIsOpen((previous) => !previous)\n }\n\n const [OpenIcon, CloseIconComponent] = icons\n const iconSize = iconPixelsByButtonSize[size]\n const contentLeftPosition =\n shape === 'circle'\n ? {\n sm: 'left-[calc(100%-1rem)]',\n md: 'left-[calc(100%-1.25rem)]',\n lg: 'left-[calc(100%-1.5rem)]',\n }[size]\n : 'left-[calc(100%-0.75rem)]'\n const contentLeftPadding =\n shape === 'circle'\n ? {\n sm: 'pl-5',\n md: 'pl-6',\n lg: 'pl-7',\n }[size]\n : 'pl-4'\n\n return (\n <div className={cn('relative isolate inline-flex w-fit items-center', className)} data-testid={dataTestId}>\n <div\n aria-hidden={!isOpen}\n className={cn(\n 'pointer-events-none absolute inset-y-0 z-0 w-max max-w-44 rounded-r-xl bg-level-three pr-3 text-text-primary font-medium',\n contentLeftPosition,\n contentLeftPadding,\n contentHeightBySize[size],\n 'flex items-center overflow-hidden transition-[transform,opacity,clip-path] duration-200 ease-in motion-reduce:transition-none',\n isOpen ? 'translate-x-0 opacity-100 [clip-path:inset(0_0_0_0)]' : '-translate-x-2 opacity-0 [clip-path:inset(0_100%_0_0)]',\n )}\n data-testid={`${dataTestId}-content`}\n id={contentId}\n >\n <span className={cn('block max-w-full truncate whitespace-nowrap leading-5', fontSizeByButtonSize[size], contentClassName)}>{content}</span>\n </div>\n\n <ButtonIcon\n {...buttonProps}\n aria-controls={contentId}\n aria-expanded={isOpen}\n className={cn('relative z-10', isOpen && 'bg-level-three hover:bg-level-three shadow-[4px_0_10px_rgb(0_0_0_/_0.18)]', buttonClassName)}\n data-testid={`${dataTestId}-button`}\n icon={() => (\n <span className={cn('relative inline-flex items-center justify-center', iconContainerSizeByButtonSize[size])}>\n <span\n aria-hidden={isOpen}\n className={cn(\n 'absolute inset-0 flex items-center justify-center transition-[filter,opacity,transform] duration-200 ease-in motion-reduce:transition-none',\n isOpen ? 'pointer-events-none opacity-0 blur-[2px] scale-95' : 'opacity-100 blur-0 scale-100',\n )}\n data-icon-state='closed'\n >\n <OpenIcon aria-hidden='true' className='size-full shrink-0' size={iconSize} />\n </span>\n\n <span\n aria-hidden={!isOpen}\n className={cn(\n 'absolute inset-0 flex items-center justify-center transition-[filter,opacity,transform] duration-200 ease-in motion-reduce:transition-none',\n isOpen ? 'opacity-100 blur-0 scale-100' : 'pointer-events-none opacity-0 blur-[2px] scale-95',\n )}\n data-icon-state='open'\n >\n <CloseIconComponent aria-hidden='true' className='size-full shrink-0' size={iconSize} />\n </span>\n </span>\n )}\n label={isOpen ? closeLabel : label}\n onClick={handleToggle}\n shape={shape}\n size={size}\n />\n </div>\n )\n}\n\nButtonIconSlideout.displayName = 'ButtonIconSlideout'\n"],"mappings":";;;;;;;;;;AAUA,MAAM,sBAAoD;CACxD,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,MAAM,gCAA8D;CAClE,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,MAAM,yBAAuD;CAC3D,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAED,MAAM,uBAAqD;CACzD,IAAI;CACJ,IAAI;CACJ,IAAI;CACL;AAmBD,MAAa,sBAAsB,EACjC,iBACA,WACA,aAAa,eACb,SACA,kBACA,aAAa,iCACb,cAAc,OACd,QAAQ,CAAC,WAAW,UAAU,EAC9B,OACA,QAAQ,UACR,OAAO,MACP,SACA,SACA,QACA,cACA,MACA,GAAG,kBAC0B;CAC7B,MAAM,CAAC,QAAQ,aAAa,qBAA8B;EACxD,OAAO;EACP,cAAc;EACd,UAAU;EACX,CAAC;CACF,MAAM,YAAY,OAAO;CAEzB,MAAM,gBAAgB,UAAyC;AAC7D,YAAU,MAAM;AAEhB,MAAI,MAAM,iBAAkB;AAE5B,MAAI,OACF,WAAU,MAAM;MAEhB,UAAS,MAAM;AAGjB,aAAW,aAAa,CAAC,SAAS;;CAGpC,MAAM,CAAC,UAAU,sBAAsB;CACvC,MAAM,WAAW,uBAAuB;CACxC,MAAM,sBACJ,UAAU,WACN;EACE,IAAI;EACJ,IAAI;EACJ,IAAI;EACL,CAAC,QACF;CACN,MAAM,qBACJ,UAAU,WACN;EACE,IAAI;EACJ,IAAI;EACJ,IAAI;EACL,CAAC,QACF;AAEN,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,mDAAmD,UAAU;EAAE,eAAa;YAA/F,CACE,oBAAC,OAAD;GACE,eAAa,CAAC;GACd,WAAW,GACT,4HACA,qBACA,oBACA,oBAAoB,OACpB,iIACA,SAAS,yDAAyD,yDACnE;GACD,eAAa,GAAG,WAAW;GAC3B,IAAI;aAEJ,oBAAC,QAAD;IAAM,WAAW,GAAG,yDAAyD,qBAAqB,OAAO,iBAAiB;cAAG;IAAe;GACxI,GAEN,oBAAC,YAAD;GACE,GAAI;GACJ,iBAAe;GACf,iBAAe;GACf,WAAW,GAAG,iBAAiB,UAAU,6EAA6E,gBAAgB;GACtI,eAAa,GAAG,WAAW;GAC3B,YACE,qBAAC,QAAD;IAAM,WAAW,GAAG,oDAAoD,8BAA8B,MAAM;cAA5G,CACE,oBAAC,QAAD;KACE,eAAa;KACb,WAAW,GACT,8IACA,SAAS,sDAAsD,+BAChE;KACD,mBAAgB;eAEhB,oBAAC,UAAD;MAAU,eAAY;MAAO,WAAU;MAAqB,MAAM;MAAY;KACzE,GAEP,oBAAC,QAAD;KACE,eAAa,CAAC;KACd,WAAW,GACT,8IACA,SAAS,iCAAiC,oDAC3C;KACD,mBAAgB;eAEhB,oBAAC,oBAAD;MAAoB,eAAY;MAAO,WAAU;MAAqB,MAAM;MAAY;KACnF,EACF;;GAET,OAAO,SAAS,aAAa;GAC7B,SAAS;GACF;GACD;GACN,EACE;;;AAIV,mBAAmB,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CheckboxBase.js","names":[],"sources":["../../src/components/Checkbox/CheckboxBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { Slot, type AsChildProp } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useCallback, useContext, useEffect, useId, useRef, type ButtonHTMLAttributes, type ElementType, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type Ref } from 'react'\n\nexport type CheckedState = boolean | 'indeterminate'\n\ntype BaseButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'>\n\nexport type CheckboxBaseProps = BaseButtonProps &\n AsChildProp & {\n checked?: CheckedState\n defaultChecked?: CheckedState\n form?: string\n name?: string\n onCheckedChange?: (checked: CheckedState) => void\n required?: boolean\n value?: string\n }\n\ninterface Ctx {\n disabled: boolean | undefined\n state: CheckedState\n}\n\nconst CheckboxCtx = createContext<Ctx | null>(null)\n\nconst dataState = (checked: CheckedState): 'checked' | 'unchecked' | 'indeterminate' => {\n if (checked === 'indeterminate') return 'indeterminate'\n return checked ? 'checked' : 'unchecked'\n}\n\nconst getNext = (checked: CheckedState): CheckedState => {\n if (checked === 'indeterminate') return true\n return !checked\n}\n\nexport const CheckboxBase = ({\n asChild,\n checked,\n className,\n defaultChecked = false,\n disabled,\n form,\n id,\n name,\n onCheckedChange,\n onClick,\n onKeyDown,\n ref,\n required,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type,\n value = 'on',\n ...rest\n}: CheckboxBaseProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const autoId = useId()\n const resolvedId = id ?? `chk-${autoId}`\n\n const [state, setState] = useUncontrolledState<CheckedState>({\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n value: checked,\n })\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = state === 'indeterminate'\n }, [state])\n\n useEffect(() => {\n const formEl = inputRef.current?.form ?? null\n if (!formEl) return\n const handleReset = () => {\n setState(defaultChecked)\n }\n formEl.addEventListener('reset', handleReset)\n return () => formEl.removeEventListener('reset', handleReset)\n }, [defaultChecked, setState])\n\n const emitFormChange = useCallback(() => {\n const el = inputRef.current\n if (!el) return\n el.checked = state === true\n el.indeterminate = state === 'indeterminate'\n const event = new Event('change', { bubbles: true })\n el.dispatchEvent(event)\n }, [state])\n\n const handleToggle = useCallback(() => {\n if (disabled) return\n const next = getNext(state)\n setState(next)\n queueMicrotask(() => emitFormChange())\n }, [disabled, emitFormChange, setState, state])\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick],\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(e)\n if (e.defaultPrevented) return\n if (e.key === ' ') {\n e.preventDefault()\n handleToggle()\n }\n },\n [handleToggle, onKeyDown],\n )\n\n const Comp: ElementType = asChild ? Slot : 'button'\n\n return (\n <CheckboxCtx.Provider value={{ state, disabled }}>\n <Comp\n aria-checked={state === 'indeterminate' ? 'mixed' : state}\n aria-disabled={disabled ?? undefined}\n className={cn(\n 'h-4 w-4 inline-flex shrink-0 items-center justify-center',\n 'border-input rounded-sm border bg-background',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n className,\n )}\n data-indeterminate={state === 'indeterminate' ? '' : undefined}\n data-state={dataState(state)}\n disabled={disabled}\n id={resolvedId}\n ref={ref}\n role='checkbox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role\n type='button'\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {/* hidden input for forms */}\n <input\n aria-hidden='true'\n checked={state === true}\n disabled={disabled}\n form={form}\n name={name}\n readOnly\n ref={inputRef}\n required={required}\n // visually hidden but in the DOM for form submission\n style={{\n position: 'absolute',\n opacity: 0,\n width: 0,\n height: 0,\n pointerEvents: 'none',\n }}\n tabIndex={-1}\n type='checkbox'\n value={value}\n />\n {rest.children}\n </Comp>\n </CheckboxCtx.Provider>\n )\n}\nCheckboxBase.displayName = 'CheckboxBase'\n\nexport type CheckboxIndicatorProps = HTMLAttributes<HTMLSpanElement> &\n AsChildProp & {\n forceMount?: boolean\n }\n\nexport const CheckboxIndicator = ({\n asChild,\n className,\n forceMount,\n ref,\n ...props\n}: CheckboxIndicatorProps & {\n ref?: Ref<HTMLSpanElement>\n}) => {\n const ctx = useContext(CheckboxCtx)\n if (!ctx) return null\n const visible = ctx.state === true || ctx.state === 'indeterminate'\n if (!visible && !forceMount) return null\n\n const Comp: ElementType = asChild ? Slot : 'span'\n\n return
|
|
1
|
+
{"version":3,"file":"CheckboxBase.js","names":[],"sources":["../../src/components/Checkbox/CheckboxBase.tsx"],"sourcesContent":["import { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { Slot, type AsChildProp } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useCallback, useContext, useEffect, useId, useRef, type ButtonHTMLAttributes, type ElementType, type HTMLAttributes, type KeyboardEvent, type MouseEvent, type Ref } from 'react'\n\nexport type CheckedState = boolean | 'indeterminate'\n\ntype BaseButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onChange' | 'value'>\n\nexport type CheckboxBaseProps = BaseButtonProps &\n AsChildProp & {\n checked?: CheckedState\n defaultChecked?: CheckedState\n form?: string\n name?: string\n onCheckedChange?: (checked: CheckedState) => void\n required?: boolean\n value?: string\n }\n\ninterface Ctx {\n disabled: boolean | undefined\n state: CheckedState\n}\n\nconst CheckboxCtx = createContext<Ctx | null>(null)\n\nconst dataState = (checked: CheckedState): 'checked' | 'unchecked' | 'indeterminate' => {\n if (checked === 'indeterminate') return 'indeterminate'\n return checked ? 'checked' : 'unchecked'\n}\n\nconst getNext = (checked: CheckedState): CheckedState => {\n if (checked === 'indeterminate') return true\n return !checked\n}\n\nexport const CheckboxBase = ({\n asChild,\n checked,\n className,\n defaultChecked = false,\n disabled,\n form,\n id,\n name,\n onCheckedChange,\n onClick,\n onKeyDown,\n ref,\n required,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n type,\n value = 'on',\n ...rest\n}: CheckboxBaseProps & {\n ref?: Ref<HTMLButtonElement>\n}) => {\n const inputRef = useRef<HTMLInputElement | null>(null)\n const autoId = useId()\n const resolvedId = id ?? `chk-${autoId}`\n\n const [state, setState] = useUncontrolledState<CheckedState>({\n defaultValue: defaultChecked,\n onChange: onCheckedChange,\n value: checked,\n })\n\n useEffect(() => {\n if (inputRef.current) inputRef.current.indeterminate = state === 'indeterminate'\n }, [state])\n\n useEffect(() => {\n const formEl = inputRef.current?.form ?? null\n if (!formEl) return\n const handleReset = () => {\n setState(defaultChecked)\n }\n formEl.addEventListener('reset', handleReset)\n return () => formEl.removeEventListener('reset', handleReset)\n }, [defaultChecked, setState])\n\n const emitFormChange = useCallback(() => {\n const el = inputRef.current\n if (!el) return\n el.checked = state === true\n el.indeterminate = state === 'indeterminate'\n const event = new Event('change', { bubbles: true })\n el.dispatchEvent(event)\n }, [state])\n\n const handleToggle = useCallback(() => {\n if (disabled) return\n const next = getNext(state)\n setState(next)\n queueMicrotask(() => emitFormChange())\n }, [disabled, emitFormChange, setState, state])\n\n const handleClick = useCallback(\n (e: MouseEvent<HTMLButtonElement>) => {\n onClick?.(e)\n if (e.defaultPrevented) return\n handleToggle()\n },\n [handleToggle, onClick],\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLButtonElement>) => {\n onKeyDown?.(e)\n if (e.defaultPrevented) return\n if (e.key === ' ') {\n e.preventDefault()\n handleToggle()\n }\n },\n [handleToggle, onKeyDown],\n )\n\n const Comp: ElementType = asChild ? Slot : 'button'\n\n return (\n <CheckboxCtx.Provider value={{ state, disabled }}>\n <Comp\n aria-checked={state === 'indeterminate' ? 'mixed' : state}\n aria-disabled={disabled ?? undefined}\n className={cn(\n 'h-4 w-4 inline-flex shrink-0 items-center justify-center',\n 'border-input rounded-sm border bg-background',\n 'focus-visible:ring-ring focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground',\n className,\n )}\n data-indeterminate={state === 'indeterminate' ? '' : undefined}\n data-state={dataState(state)}\n disabled={disabled}\n id={resolvedId}\n ref={ref}\n role='checkbox' // oxlint-disable-line jsx-a11y/prefer-tag-over-role\n type='button'\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n {...rest}\n >\n {/* hidden input for forms */}\n <input\n aria-hidden='true'\n checked={state === true}\n disabled={disabled}\n form={form}\n name={name}\n readOnly\n ref={inputRef}\n required={required}\n // visually hidden but in the DOM for form submission\n style={{\n position: 'absolute',\n opacity: 0,\n width: 0,\n height: 0,\n pointerEvents: 'none',\n }}\n tabIndex={-1}\n type='checkbox'\n value={value}\n />\n {rest.children}\n </Comp>\n </CheckboxCtx.Provider>\n )\n}\nCheckboxBase.displayName = 'CheckboxBase'\n\nexport type CheckboxIndicatorProps = HTMLAttributes<HTMLSpanElement> &\n AsChildProp & {\n forceMount?: boolean\n }\n\nexport const CheckboxIndicator = ({\n asChild,\n className,\n forceMount,\n ref,\n ...props\n}: CheckboxIndicatorProps & {\n ref?: Ref<HTMLSpanElement>\n}) => {\n const ctx = useContext(CheckboxCtx)\n if (!ctx) return null\n const visible = ctx.state === true || ctx.state === 'indeterminate'\n if (!visible && !forceMount) return null\n\n const Comp: ElementType = asChild ? Slot : 'span'\n\n return <Comp className={cn('flex items-center justify-center text-current', className)} data-indeterminate={ctx.state === 'indeterminate' ? '' : undefined} data-state={dataState(ctx.state)} ref={ref} {...props} />\n}\nCheckboxIndicator.displayName = 'CheckboxIndicator'\n"],"mappings":"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"}
|
package/dist/Checkbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Checkbox.js","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckmarkIcon, MinusIcon } from '@components/Icons'\nimport { ErrorMessage, WarningMessage, useFormFieldId, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\nimport { CheckboxBase, CheckboxIndicator } from './CheckboxBase'\n\nexport interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBase>, 'onCheckedChange'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n checked?: boolean | 'indeterminate'\n disabled?: boolean\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n labelText?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n onCheckedChange: (value: boolean | 'indeterminate') => void\n required?: boolean\n state?: FormFieldState\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Checkbox = ({\n checked,\n className,\n errorMessage,\n id,\n label,\n labelText,\n messageReserveLines = 1,\n messageReserveSpace = false,\n onCheckedChange,\n ref,\n required,\n state = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n ...props\n}: CheckboxProps & {\n ref?: Ref<ComponentRef<typeof CheckboxBase>>\n}) => {\n const inputId = useFormFieldId(id, props.name)\n const resolvedLabelText = labelText ?? label\n const errorMessageId = `${inputId}-error`\n const warningMessageId = `${inputId}-warning`\n const messageId = state === 'error' && errorMessage && errorMessageId ? errorMessageId : state === 'warning' && warningMessage && warningMessageId ? warningMessageId : undefined\n\n return (\n <div>\n <div className='gap-2 flex items-center'>\n <CheckboxBase\n aria-describedby={[messageId, ariaDescribedBy].filter(Boolean).join(' ') || undefined}\n aria-invalid={state === 'error' ? true : undefined}\n aria-label={ariaLabel ?? (!resolvedLabelText ? 'Checkbox' : undefined)}\n aria-required={required ?? undefined}\n checked={checked}\n className={cn(\n 'checkbox peer h-5 w-5 rounded-sm shrink-0 border border-checkbox-border hover:opacity-80 focus:outline-none focus-visible:outline-1 focus-visible:outline-checkbox-border--focus',\n 'focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-checkbox-border--checked',\n className,\n )}\n data-field-state={state}\n data-testid='spectral-checkbox'\n id={inputId}\n onCheckedChange={onCheckedChange}\n ref={ref}\n {...props}\n >\n <CheckboxIndicator
|
|
1
|
+
{"version":3,"file":"Checkbox.js","names":[],"sources":["../src/components/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckmarkIcon, MinusIcon } from '@components/Icons'\nimport { ErrorMessage, WarningMessage, useFormFieldId, type BaseFormFieldProps, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentPropsWithoutRef, type ComponentRef, type Ref } from 'react'\nimport { CheckboxBase, CheckboxIndicator } from './CheckboxBase'\n\nexport interface CheckboxProps extends Omit<ComponentPropsWithoutRef<typeof CheckboxBase>, 'onCheckedChange'> {\n 'aria-describedby'?: string\n 'aria-label'?: string\n checked?: boolean | 'indeterminate'\n disabled?: boolean\n errorMessage?: BaseFormFieldProps['errorMessage']\n id?: string\n label?: string\n labelText?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n onCheckedChange: (value: boolean | 'indeterminate') => void\n required?: boolean\n state?: FormFieldState\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Checkbox = ({\n checked,\n className,\n errorMessage,\n id,\n label,\n labelText,\n messageReserveLines = 1,\n messageReserveSpace = false,\n onCheckedChange,\n ref,\n required,\n state = 'default',\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n ...props\n}: CheckboxProps & {\n ref?: Ref<ComponentRef<typeof CheckboxBase>>\n}) => {\n const inputId = useFormFieldId(id, props.name)\n const resolvedLabelText = labelText ?? label\n const errorMessageId = `${inputId}-error`\n const warningMessageId = `${inputId}-warning`\n const messageId = state === 'error' && errorMessage && errorMessageId ? errorMessageId : state === 'warning' && warningMessage && warningMessageId ? warningMessageId : undefined\n\n return (\n <div>\n <div className='gap-2 flex items-center'>\n <CheckboxBase\n aria-describedby={[messageId, ariaDescribedBy].filter(Boolean).join(' ') || undefined}\n aria-invalid={state === 'error' ? true : undefined}\n aria-label={ariaLabel ?? (!resolvedLabelText ? 'Checkbox' : undefined)}\n aria-required={required ?? undefined}\n checked={checked}\n className={cn(\n 'checkbox peer h-5 w-5 rounded-sm shrink-0 border border-checkbox-border hover:opacity-80 focus:outline-none focus-visible:outline-1 focus-visible:outline-checkbox-border--focus',\n 'focus-visible:outline-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-checkbox-border--checked',\n className,\n )}\n data-field-state={state}\n data-testid='spectral-checkbox'\n id={inputId}\n onCheckedChange={onCheckedChange}\n ref={ref}\n {...props}\n >\n <CheckboxIndicator data-testid='spectral-checkbox-indicator' className={cn('checkbox-indicator flex items-center justify-center text-checkbox-indicator--checked')}>\n {checked === 'indeterminate' ? <MinusIcon className='checkbox-indeterminate' size={16} strokeWidth={4} /> : <CheckmarkIcon className='checkbox-check' size={16} strokeWidth={4} />}\n </CheckboxIndicator>\n </CheckboxBase>\n {resolvedLabelText && (\n <label className='text-md peer-disabled:text-neutral-400 text-text-primary' data-testid='spectral-checkbox-label' htmlFor={inputId}>\n {resolvedLabelText}\n </label>\n )}\n </div>\n <ErrorMessage\n dataTestId='spectral-checkbox-error-message'\n id={errorMessageId}\n message={state === 'error' ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-checkbox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nCheckbox.displayName = 'Checkbox'\n"],"mappings":";;;;;;;;;;;AAyBA,MAAa,YAAY,EACvB,SACA,WACA,cACA,IACA,OACA,WACA,sBAAsB,GACtB,sBAAsB,OACtB,iBACA,KACA,UACA,QAAQ,WACR,gBACA,oBAAoB,iBACpB,cAAc,WACd,GAAG,YAGC;CACJ,MAAM,UAAU,eAAe,IAAI,MAAM,KAAK;CAC9C,MAAM,oBAAoB,aAAa;CACvC,MAAM,iBAAiB,GAAG,QAAQ;CAClC,MAAM,mBAAmB,GAAG,QAAQ;AAGpC,QACE,qBAAC,OAAD;EACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,cAAD;IACE,oBAAkB,CANR,UAAU,WAAW,gBAAgB,iBAAiB,iBAAiB,UAAU,aAAa,kBAAkB,mBAAmB,mBAAmB,QAMlI,gBAAgB,CAAC,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI;IAC5E,gBAAc,UAAU,UAAU,OAAO;IACzC,cAAY,cAAc,CAAC,oBAAoB,aAAa;IAC5D,iBAAe,YAAY;IAClB;IACT,WAAW,GACT,oLACA,uIACA,UACD;IACD,oBAAkB;IAClB,eAAY;IACZ,IAAI;IACa;IACZ;IACL,GAAI;cAEJ,oBAAC,mBAAD;KAAmB,eAAY;KAA8B,WAAW,GAAG,uFAAuF;eAC/J,YAAY,kBAAkB,oBAAC,WAAD;MAAW,WAAU;MAAyB,MAAM;MAAI,aAAa;MAAK,IAAG,oBAAC,eAAD;MAAe,WAAU;MAAiB,MAAM;MAAI,aAAa;MAAK;KAChK;IACP,GACd,qBACC,oBAAC,SAAD;IAAO,WAAU;IAA2D,eAAY;IAA0B,SAAS;cACxH;IACK,EAEN;;EACN,oBAAC,cAAD;GACE,YAAW;GACX,IAAI;GACJ,SAAS,UAAU,UAAU,eAAe;GACvB;GACrB,qBAAqB,uBAAuB,UAAU;GACtD;EACF,oBAAC,gBAAD;GACE,YAAW;GACX,IAAI;GACJ,SAAS,UAAU,YAAY,iBAAiB;GAC3B;GACrB,qBAAqB,uBAAuB,UAAU;GACtD;EACE;;AAGV,SAAS,cAAc"}
|
package/dist/Combobox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.js","names":["ComboboxPrimitive"],"sources":["../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import { Combobox as ComboboxPrimitive } from '@base-ui/react'\nimport { CheckmarkIcon, ChevronDownIcon, LoaderIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { InputGroup, InputGroupAddon } from '@primitives/input-group'\nimport {\n EmptyState,\n ErrorMessage,\n getAriaProps,\n getDropdownWidthStyles,\n getDropdownSurfaceClasses,\n getErrorMessageId,\n getFormFieldCSSProperties,\n getOptionClasses,\n getTriggerClasses,\n LoadingState,\n WarningMessage,\n useFormFieldId,\n type BaseFormFieldProps,\n type BaseOption,\n type DropdownWidth,\n type FormFieldState,\n} from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useMemo, useRef, useState, type CSSProperties, type MouseEvent, type Ref } from 'react'\n\nexport type ComboboxOption = BaseOption\n\nexport interface ComboboxProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'> {\n className?: string\n defaultValue?: string\n dropdownWidth?: DropdownWidth\n emptyMessage?: string\n labelClassName?: string\n loadingMessage?: string\n onChange?: (value: string) => void\n onValueChange?: (value: string) => void\n options: ComboboxOption[]\n placeholder?: string\n state?: Exclude<FormFieldState, 'disabled'>\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Combobox = ({\n className,\n disabled,\n defaultValue = '',\n dropdownWidth = 'trigger',\n emptyMessage = 'No options found.',\n errorMessage,\n id,\n label,\n labelClassName,\n loadingMessage = 'Loading…',\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onChange,\n onValueChange,\n options,\n placeholder = 'Search…',\n ref,\n required,\n state = 'default',\n value: valueProp,\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n}: ComboboxProps & { ref?: Ref<HTMLDivElement> }) => {\n if (process.env.NODE_ENV !== 'production' && !label && !ariaLabel) {\n console.warn('Combobox: provide either `label` or `aria-label` for an accessible name.')\n }\n\n const comboboxId = useFormFieldId(id, name)\n const listboxId = `${comboboxId}-listbox`\n const errorMessageId = getErrorMessageId(comboboxId)\n const warningMessageId = `${comboboxId}-warning`\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const isDisabled = Boolean(disabled)\n const isLoading = state === 'loading'\n const isInvalid = state === 'error'\n const ariaProps = getAriaProps(state, ariaDescribedBy, required, messageId)\n\n const [open, setOpen] = useState(false)\n const [inputValue, setInputValue] = useState('')\n const inputRef = useRef<HTMLInputElement>(null)\n const suppressNextInputFocusOpenRef = useRef(false)\n const clearFocusSuppression = () => {\n suppressNextInputFocusOpenRef.current = false\n }\n const [value, setValue] = useUncontrolledState<string>({\n value: valueProp,\n defaultValue,\n onChange: (nextValue) => {\n if (onChange) {\n onChange(nextValue)\n } else {\n onValueChange?.(nextValue)\n }\n },\n })\n\n const selectedOption = useMemo(() => options.find((o) => o.value === value) ?? null, [options, value])\n const filteredOptions = useMemo(() => {\n const query = inputValue.trim().toLowerCase()\n if (!query) return options\n return options.filter((option) => option.label.toLowerCase().includes(query))\n }, [inputValue, options])\n const showsSelectedValueAsPlaceholder = Boolean(selectedOption && inputValue.length === 0)\n const { dropdownWidthMode, dropdownWidthStyle } = getDropdownWidthStyles({\n dropdownWidth,\n triggerWidth: 'var(--anchor-width)',\n })\n\n const handleValueChange = (nextOption: ComboboxOption | null, eventDetails: { reason?: string }) => {\n const nextValue = nextOption?.value ?? ''\n const shouldClearSelection = eventDetails.reason === 'item-press' && nextValue === value\n setValue(shouldClearSelection ? '' : nextValue)\n setInputValue('')\n setOpen(false)\n }\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (isDisabled || isLoading) {\n setOpen(false)\n return\n }\n\n if (!nextOpen) {\n setInputValue('')\n }\n\n setOpen(nextOpen)\n }\n\n const handleTriggerContainerClick = (event: MouseEvent<HTMLDivElement>) => {\n if (isDisabled || isLoading) return\n\n const target = event.target as HTMLElement\n if (target === inputRef.current) return\n if (target.closest('[data-slot=combobox-trigger-button]')) return\n inputRef.current?.focus()\n setOpen(true)\n }\n\n return (\n <div\n className='w-full'\n ref={ref}\n >\n {label && (\n <Label\n className={cn('mb-2 block text-text-primary', labelClassName, isDisabled && 'text-text-secondary')}\n data-testid='spectral-combobox-label'\n htmlFor={comboboxId}\n >\n {label}\n </Label>\n )}\n\n <ComboboxPrimitive.Root\n autoHighlight\n disabled={isDisabled || isLoading}\n filter={null}\n inputValue={inputValue}\n itemToStringLabel={(option: ComboboxOption) => option.label}\n itemToStringValue={(option: ComboboxOption) => option.value}\n openOnInputClick\n onInputValueChange={(nextInputValue, eventDetails) => {\n if (eventDetails.reason !== 'input-change' && eventDetails.reason !== 'input-clear') return\n setInputValue(nextInputValue)\n }}\n name={name}\n onOpenChange={handleOpenChange}\n onValueChange={handleValueChange}\n open={open}\n required={required}\n value={selectedOption}\n >\n <ComboboxPrimitive.InputGroup\n render={\n <InputGroup\n data-slot='combobox-content'\n data-state={state}\n data-testid='spectral-combobox-trigger'\n className={cn(getTriggerClasses(open, state), 'ring-0! outline-none focus-within:outline-none has-[[data-slot=input-group-control]:focus-visible]:outline-0', isDisabled && 'pointer-events-none cursor-not-allowed', className)}\n onClick={handleTriggerContainerClick}\n style={getFormFieldCSSProperties() as CSSProperties}\n />\n }\n >\n <ComboboxPrimitive.Input\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel ?? label}\n autoComplete='off'\n className={cn(\n 'min-w-0 text-base flex-1 truncate overflow-hidden border-0 bg-transparent whitespace-nowrap text-input-text outline-hidden outline-0 placeholder:opacity-100 focus-visible:ring-0 focus-visible:outline-none',\n showsSelectedValueAsPlaceholder ? 'placeholder:text-input-text!' : 'placeholder:text-input-text-placeholder!',\n )}\n data-slot='input-group-control'\n id={comboboxId}\n onFocus={() => {\n if (suppressNextInputFocusOpenRef.current) {\n suppressNextInputFocusOpenRef.current = false\n return\n }\n\n if (!isDisabled && !isLoading) {\n setOpen(true)\n }\n }}\n ref={inputRef}\n placeholder={selectedOption?.label ?? placeholder}\n {...ariaProps}\n />\n <InputGroupAddon\n align='inline-end'\n className='cursor-pointer'\n >\n <ComboboxPrimitive.Trigger\n aria-label='Toggle options'\n className='cursor-pointer'\n data-slot='combobox-trigger-button'\n onPointerDownCapture={() => {\n const inputElement = inputRef.current\n if (!inputElement) {\n clearFocusSuppression()\n return\n }\n\n const activeElement = inputElement.ownerDocument.activeElement\n suppressNextInputFocusOpenRef.current = activeElement !== inputElement\n }}\n onPointerUpCapture={clearFocusSuppression}\n onPointerCancelCapture={clearFocusSuppression}\n onTouchEndCapture={clearFocusSuppression}\n >\n {isLoading ? <LoaderIcon className='size-5 motion-safe:animate-spin' /> : <ChevronDownIcon className={cn('size-5 shrink-0 transition-transform duration-200', open && 'rotate-180')} />}\n </ComboboxPrimitive.Trigger>\n </InputGroupAddon>\n </ComboboxPrimitive.InputGroup>\n\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Positioner\n align='start'\n className='isolate z-50'\n sideOffset={4}\n >\n <ComboboxPrimitive.Popup\n className={cn(\n 'p-1 z-50 motion-safe:data-closed:animate-out motion-safe:data-open:animate-in',\n getDropdownSurfaceClasses(),\n 'motion-safe:data-closed:fade-out-0 motion-safe:data-closed:zoom-out-95 motion-safe:data-open:fade-in-0 motion-safe:data-open:zoom-in-95',\n 'max-h-[min(var(--available-height),18rem)] motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=top]:slide-in-from-bottom-2',\n // Keep a single scroll container (the list) to avoid dual scrollbar styles.\n 'min-w-32 origin-(--transform-origin) overflow-hidden',\n )}\n data-dropdown-width-mode={dropdownWidthMode}\n data-dropdown-width-value={dropdownWidthMode === 'custom' ? dropdownWidth : undefined}\n data-testid='spectral-combobox-content'\n style={dropdownWidthStyle}\n >\n {isLoading ? (\n <LoadingState message={loadingMessage} />\n ) : filteredOptions.length === 0 ? (\n <EmptyState message={emptyMessage} />\n ) : (\n <ComboboxPrimitive.List\n className='max-h-[min(var(--available-height),18rem)] overflow-y-auto'\n id={listboxId}\n >\n {filteredOptions.map((option) => (\n <ComboboxPrimitive.Item\n className={cn(getOptionClasses(!!option.disabled, false, value === option.value), 'group/command-item relative flex w-full items-center data-highlighted:bg-input-bg--hover')}\n data-testid='spectral-combobox-item'\n disabled={option.disabled}\n key={option.value}\n value={option}\n >\n <span className='min-w-0 flex-1 truncate whitespace-nowrap'>{option.label}</span>\n <ComboboxPrimitive.ItemIndicator\n render={\n <span className='right-2 h-4 w-4 absolute flex items-center justify-center'>\n <CheckmarkIcon size={16} />\n </span>\n }\n />\n </ComboboxPrimitive.Item>\n ))}\n </ComboboxPrimitive.List>\n )}\n </ComboboxPrimitive.Popup>\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n </ComboboxPrimitive.Root>\n\n <ErrorMessage\n dataTestId='spectral-combobox-error-message'\n id={errorMessageId}\n message={isInvalid ? (errorMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-combobox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? (warningMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nCombobox.displayName = 'Combobox'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Combobox.js","names":["ComboboxPrimitive"],"sources":["../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import { Combobox as ComboboxPrimitive } from '@base-ui/react'\nimport { CheckmarkIcon, ChevronDownIcon, LoaderIcon } from '@components/Icons'\nimport { Label } from '@components/Label/Label'\nimport { useUncontrolledState } from '@hooks/useUncontrolledState'\nimport { InputGroup, InputGroupAddon } from '@primitives/input-group'\nimport {\n EmptyState,\n ErrorMessage,\n getAriaProps,\n getDropdownWidthStyles,\n getDropdownSurfaceClasses,\n getErrorMessageId,\n getFormFieldCSSProperties,\n getOptionClasses,\n getTriggerClasses,\n LoadingState,\n WarningMessage,\n useFormFieldId,\n type BaseFormFieldProps,\n type BaseOption,\n type DropdownWidth,\n type FormFieldState,\n} from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useMemo, useRef, useState, type CSSProperties, type MouseEvent, type Ref } from 'react'\n\nexport type ComboboxOption = BaseOption\n\nexport interface ComboboxProps extends Omit<BaseFormFieldProps, 'onChange' | 'state'> {\n className?: string\n defaultValue?: string\n dropdownWidth?: DropdownWidth\n emptyMessage?: string\n labelClassName?: string\n loadingMessage?: string\n onChange?: (value: string) => void\n onValueChange?: (value: string) => void\n options: ComboboxOption[]\n placeholder?: string\n state?: Exclude<FormFieldState, 'disabled'>\n value?: string\n warningMessage?: BaseFormFieldProps['errorMessage']\n}\n\nexport const Combobox = ({\n className,\n disabled,\n defaultValue = '',\n dropdownWidth = 'trigger',\n emptyMessage = 'No options found.',\n errorMessage,\n id,\n label,\n labelClassName,\n loadingMessage = 'Loading…',\n messageReserveLines = 1,\n messageReserveSpace = false,\n name,\n onChange,\n onValueChange,\n options,\n placeholder = 'Search…',\n ref,\n required,\n state = 'default',\n value: valueProp,\n warningMessage,\n 'aria-describedby': ariaDescribedBy,\n 'aria-label': ariaLabel,\n}: ComboboxProps & { ref?: Ref<HTMLDivElement> }) => {\n if (process.env.NODE_ENV !== 'production' && !label && !ariaLabel) {\n console.warn('Combobox: provide either `label` or `aria-label` for an accessible name.')\n }\n\n const comboboxId = useFormFieldId(id, name)\n const listboxId = `${comboboxId}-listbox`\n const errorMessageId = getErrorMessageId(comboboxId)\n const warningMessageId = `${comboboxId}-warning`\n const messageId = state === 'error' ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n const isDisabled = Boolean(disabled)\n const isLoading = state === 'loading'\n const isInvalid = state === 'error'\n const ariaProps = getAriaProps(state, ariaDescribedBy, required, messageId)\n\n const [open, setOpen] = useState(false)\n const [inputValue, setInputValue] = useState('')\n const inputRef = useRef<HTMLInputElement>(null)\n const suppressNextInputFocusOpenRef = useRef(false)\n const clearFocusSuppression = () => {\n suppressNextInputFocusOpenRef.current = false\n }\n const [value, setValue] = useUncontrolledState<string>({\n value: valueProp,\n defaultValue,\n onChange: (nextValue) => {\n if (onChange) {\n onChange(nextValue)\n } else {\n onValueChange?.(nextValue)\n }\n },\n })\n\n const selectedOption = useMemo(() => options.find((o) => o.value === value) ?? null, [options, value])\n const filteredOptions = useMemo(() => {\n const query = inputValue.trim().toLowerCase()\n if (!query) return options\n return options.filter((option) => option.label.toLowerCase().includes(query))\n }, [inputValue, options])\n const showsSelectedValueAsPlaceholder = Boolean(selectedOption && inputValue.length === 0)\n const { dropdownWidthMode, dropdownWidthStyle } = getDropdownWidthStyles({\n dropdownWidth,\n triggerWidth: 'var(--anchor-width)',\n })\n\n const handleValueChange = (nextOption: ComboboxOption | null, eventDetails: { reason?: string }) => {\n const nextValue = nextOption?.value ?? ''\n const shouldClearSelection = eventDetails.reason === 'item-press' && nextValue === value\n setValue(shouldClearSelection ? '' : nextValue)\n setInputValue('')\n setOpen(false)\n }\n\n const handleOpenChange = (nextOpen: boolean) => {\n if (isDisabled || isLoading) {\n setOpen(false)\n return\n }\n\n if (!nextOpen) {\n setInputValue('')\n }\n\n setOpen(nextOpen)\n }\n\n const handleTriggerContainerClick = (event: MouseEvent<HTMLDivElement>) => {\n if (isDisabled || isLoading) return\n\n const target = event.target as HTMLElement\n if (target === inputRef.current) return\n if (target.closest('[data-slot=combobox-trigger-button]')) return\n inputRef.current?.focus()\n setOpen(true)\n }\n\n return (\n <div className='w-full' ref={ref}>\n {label && (\n <Label className={cn('mb-2 block text-text-primary', labelClassName, isDisabled && 'text-text-secondary')} data-testid='spectral-combobox-label' htmlFor={comboboxId}>\n {label}\n </Label>\n )}\n\n <ComboboxPrimitive.Root\n autoHighlight\n disabled={isDisabled || isLoading}\n filter={null}\n inputValue={inputValue}\n itemToStringLabel={(option: ComboboxOption) => option.label}\n itemToStringValue={(option: ComboboxOption) => option.value}\n openOnInputClick\n onInputValueChange={(nextInputValue, eventDetails) => {\n if (eventDetails.reason !== 'input-change' && eventDetails.reason !== 'input-clear') return\n setInputValue(nextInputValue)\n }}\n name={name}\n onOpenChange={handleOpenChange}\n onValueChange={handleValueChange}\n open={open}\n required={required}\n value={selectedOption}\n >\n <ComboboxPrimitive.InputGroup\n render={\n <InputGroup\n data-slot='combobox-content'\n data-state={state}\n data-testid='spectral-combobox-trigger'\n className={cn(getTriggerClasses(open, state), 'ring-0! outline-none focus-within:outline-none has-[[data-slot=input-group-control]:focus-visible]:outline-0', isDisabled && 'pointer-events-none cursor-not-allowed', className)}\n onClick={handleTriggerContainerClick}\n style={getFormFieldCSSProperties() as CSSProperties}\n />\n }\n >\n <ComboboxPrimitive.Input\n aria-controls={listboxId}\n aria-expanded={open}\n aria-label={ariaLabel ?? label}\n autoComplete='off'\n className={cn(\n 'min-w-0 text-base flex-1 truncate overflow-hidden border-0 bg-transparent whitespace-nowrap text-input-text outline-hidden outline-0 placeholder:opacity-100 focus-visible:ring-0 focus-visible:outline-none',\n showsSelectedValueAsPlaceholder ? 'placeholder:text-input-text!' : 'placeholder:text-input-text-placeholder!',\n )}\n data-slot='input-group-control'\n id={comboboxId}\n onFocus={() => {\n if (suppressNextInputFocusOpenRef.current) {\n suppressNextInputFocusOpenRef.current = false\n return\n }\n\n if (!isDisabled && !isLoading) {\n setOpen(true)\n }\n }}\n ref={inputRef}\n placeholder={selectedOption?.label ?? placeholder}\n {...ariaProps}\n />\n <InputGroupAddon align='inline-end' className='cursor-pointer'>\n <ComboboxPrimitive.Trigger\n aria-label='Toggle options'\n className='cursor-pointer'\n data-slot='combobox-trigger-button'\n onPointerDownCapture={() => {\n const inputElement = inputRef.current\n if (!inputElement) {\n clearFocusSuppression()\n return\n }\n\n const activeElement = inputElement.ownerDocument.activeElement\n suppressNextInputFocusOpenRef.current = activeElement !== inputElement\n }}\n onPointerUpCapture={clearFocusSuppression}\n onPointerCancelCapture={clearFocusSuppression}\n onTouchEndCapture={clearFocusSuppression}\n >\n {isLoading ? <LoaderIcon className='size-5 motion-safe:animate-spin' /> : <ChevronDownIcon className={cn('size-5 shrink-0 transition-transform duration-200', open && 'rotate-180')} />}\n </ComboboxPrimitive.Trigger>\n </InputGroupAddon>\n </ComboboxPrimitive.InputGroup>\n\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Positioner align='start' className='isolate z-50' sideOffset={4}>\n <ComboboxPrimitive.Popup\n className={cn(\n 'p-1 z-50 motion-safe:data-closed:animate-out motion-safe:data-open:animate-in',\n getDropdownSurfaceClasses(),\n 'motion-safe:data-closed:fade-out-0 motion-safe:data-closed:zoom-out-95 motion-safe:data-open:fade-in-0 motion-safe:data-open:zoom-in-95',\n 'max-h-[min(var(--available-height),18rem)] motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=top]:slide-in-from-bottom-2',\n // Keep a single scroll container (the list) to avoid dual scrollbar styles.\n 'min-w-32 origin-(--transform-origin) overflow-hidden',\n )}\n data-dropdown-width-mode={dropdownWidthMode}\n data-dropdown-width-value={dropdownWidthMode === 'custom' ? dropdownWidth : undefined}\n data-testid='spectral-combobox-content'\n style={dropdownWidthStyle}\n >\n {isLoading ? (\n <LoadingState message={loadingMessage} />\n ) : filteredOptions.length === 0 ? (\n <EmptyState message={emptyMessage} />\n ) : (\n <ComboboxPrimitive.List className='max-h-[min(var(--available-height),18rem)] overflow-y-auto' id={listboxId}>\n {filteredOptions.map((option) => (\n <ComboboxPrimitive.Item\n className={cn(getOptionClasses(!!option.disabled, false, value === option.value), 'group/command-item relative flex w-full items-center data-highlighted:bg-input-bg--hover')}\n data-testid='spectral-combobox-item'\n disabled={option.disabled}\n key={option.value}\n value={option}\n >\n <span className='min-w-0 flex-1 truncate whitespace-nowrap'>{option.label}</span>\n <ComboboxPrimitive.ItemIndicator\n render={\n <span className='right-2 h-4 w-4 absolute flex items-center justify-center'>\n <CheckmarkIcon size={16} />\n </span>\n }\n />\n </ComboboxPrimitive.Item>\n ))}\n </ComboboxPrimitive.List>\n )}\n </ComboboxPrimitive.Popup>\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n </ComboboxPrimitive.Root>\n\n <ErrorMessage\n dataTestId='spectral-combobox-error-message'\n id={errorMessageId}\n message={isInvalid ? (errorMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-combobox-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? (warningMessage ?? null) : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n )\n}\nCombobox.displayName = 'Combobox'\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroupSelect.js","names":[],"sources":["../../src/components/ControlGroup/ControlGroupSelect.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { Input } from '@primitives/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@primitives/select'\nimport { getStateClasses, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useId, type ComponentProps } from 'react'\nimport { ControlGroup, ControlGroupItem, useControlGroup, type ControlGroupProps } from './ControlGroup'\n\nconst numberInputNoSpinner = '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'\nconst defaultInputLabel = 'Amount'\nconst defaultSelectLabel = 'Select an option'\n\nexport interface SelectOptionType {\n disabled?: boolean\n label: string\n value: string\n}\n\n/** `inline`: `inputPlaceholder` / `selectPlaceholder` show inside the fields. `above`: same strings render as labels above each control (no inner placeholders). */\nexport type ControlGroupSelectCaptionLayout = 'above' | 'inline'\n\ntype ControlGroupSelectInputControlProps =\n | {\n inputValue: ComponentProps<typeof Input>['value']\n onInputChange: ComponentProps<typeof Input>['onChange']\n }\n | {\n inputValue?: undefined\n onInputChange?: undefined\n }\n\ntype ControlGroupSelectBaseProps = ComponentProps<typeof Select> &\n Pick<ControlGroupProps, 'orientation'> & {\n amountStep?: number\n /** Accessible name for the group wrapper (use when there is no visible group heading). */\n ariaLabel?: string\n captionLayout?: ControlGroupSelectCaptionLayout\n className?: string\n dataTestId?: string\n disabled?: boolean\n dropdownWidth?: DropdownWidth\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n /** Class applied to the input `ControlGroupItem` segment for width/split composition. */\n inputItemClassName?: string\n /** When `captionLayout` is `inline`, overrides the input's accessible name (defaults to `inputPlaceholder` when set). */\n inputAriaLabel?: string\n inputPlaceholder?: string\n maxAmount?: number\n /** Number of message lines to reserve (default: 1). */\n messageReserveLines?: number\n /** Whether to keep message space reserved when hidden (default: false). */\n messageReserveSpace?: boolean\n minAmount?: number\n selectPlaceholder?: string\n /** When `captionLayout` is `inline` and `selectPlaceholder` is empty, sets the select trigger's accessible name. */\n selectAriaLabel?: string\n /** Class applied to the select `ControlGroupItem` segment for width/split composition. */\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n state?: Exclude<FormFieldState, 'disabled'>\n type?: 'number' | 'text'\n warningMessage?: string | string[] | Record<string, unknown> | null\n }\n\nexport type ControlGroupSelectProps = ControlGroupSelectBaseProps & ControlGroupSelectInputControlProps\n\nconst fieldStackClass = 'flex w-full min-w-0 flex-col gap-1.5'\nconst groupedFieldBaseClasses =\n 'h-12! min-h-12! border-2! border-input-border bg-input-bg text-base text-input-text transition duration-200 placeholder:text-input-text-placeholder hover:border-input-border--hover focus-visible:border-input-border--focus focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus disabled:pointer-events-none disabled:border-input-border--disabled disabled:bg-input-bg--disabled disabled:text-input-text--disabled'\n\nconst getFieldMinWidth = (caption?: string, extraCharacters: number = 0): string | undefined => {\n const normalizedCaption = caption?.trim()\n if (!normalizedCaption) return undefined\n return `${Math.max(normalizedCaption.length + extraCharacters, 8)}ch`\n}\n\nconst getReadableLabel = (label: string | undefined, fallback: string): string => {\n const normalizedLabel = label?.trim()\n return normalizedLabel && normalizedLabel.length > 0 ? normalizedLabel : fallback\n}\n\nexport const ControlGroupSelect = ({\n amountStep,\n ariaLabel,\n captionLayout = 'inline',\n className,\n dataTestId = 'spectral-control-group-select',\n disabled,\n errorMessage,\n id,\n dropdownWidth = 'trigger',\n inputAriaLabel,\n inputPlaceholder,\n inputItemClassName,\n inputValue,\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxAmount = 1000000,\n minAmount = 0,\n onInputChange,\n orientation = 'horizontal',\n selectAriaLabel,\n selectItemClassName,\n selectOptions,\n selectPlaceholder,\n state = 'default',\n type = 'number',\n warningMessage,\n ...selectProps\n}: ControlGroupSelectProps) => {\n const baseId = useId()\n const idPrefix = id ?? baseId\n const inputId = `${idPrefix}-amount`\n const selectTriggerId = `${idPrefix}-select`\n const inputLabelId = `${inputId}-label`\n const selectLabelId = `${selectTriggerId}-label`\n\n const useAboveLabels = captionLayout === 'above'\n const inputCaption = useAboveLabels ? undefined : inputPlaceholder\n const selectCaption = useAboveLabels ? undefined : selectPlaceholder\n const inputLabelText = getReadableLabel(inputPlaceholder, defaultInputLabel)\n const selectLabelText = getReadableLabel(selectPlaceholder, defaultSelectLabel)\n\n const inputAccessibleName = inputAriaLabel ?? (useAboveLabels ? undefined : inputLabelText)\n const selectTriggerAriaLabel = selectAriaLabel ?? (useAboveLabels ? undefined : selectLabelText)\n const inputMinWidth = getFieldMinWidth(inputPlaceholder, 3)\n const selectTriggerMinWidth = getFieldMinWidth(selectPlaceholder, 5)\n const groupAriaLabel = ariaLabel ?? `${inputLabelText} and ${selectLabelText}`\n\n const isDisabled = !!disabled\n const isInputControlled = inputValue !== undefined && onInputChange !== undefined\n\n return (\n <ControlGroup\n aria-label={groupAriaLabel}\n className={className}\n data-testid={dataTestId}\n disabled={disabled}\n errorMessage={errorMessage}\n id={idPrefix}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n orientation={orientation}\n state={state}\n warningMessage={warningMessage}\n >\n <ControlGroupSelectInner\n amountStep={amountStep}\n dataTestId={dataTestId}\n inputAccessibleName={inputAccessibleName}\n inputCaption={inputCaption}\n inputId={inputId}\n inputLabelId={inputLabelId}\n inputLabelText={inputLabelText}\n inputItemClassName={inputItemClassName}\n inputMinWidth={inputMinWidth}\n inputValue={isInputControlled ? inputValue : undefined}\n isDisabled={isDisabled}\n maxAmount={maxAmount}\n minAmount={minAmount}\n onInputChange={isInputControlled ? onInputChange : undefined}\n dropdownWidth={dropdownWidth}\n selectCaption={selectCaption}\n selectOptions={selectOptions}\n selectLabelId={selectLabelId}\n selectLabelText={selectLabelText}\n selectItemClassName={selectItemClassName}\n selectProps={selectProps}\n selectTriggerAriaLabel={selectTriggerAriaLabel}\n selectTriggerId={selectTriggerId}\n selectTriggerMinWidth={selectTriggerMinWidth}\n type={type}\n useAboveLabels={useAboveLabels}\n />\n </ControlGroup>\n )\n}\n\ninterface ControlGroupSelectInnerProps {\n amountStep?: number\n dataTestId: string\n dropdownWidth: DropdownWidth\n inputAccessibleName?: string\n inputCaption?: string\n inputId: string\n inputLabelId: string\n inputLabelText: string\n inputItemClassName?: string\n inputMinWidth?: string\n inputValue?: ComponentProps<typeof Input>['value']\n isDisabled: boolean\n maxAmount: number\n minAmount: number\n onInputChange?: ComponentProps<typeof Input>['onChange']\n selectCaption?: string\n selectLabelId: string\n selectLabelText: string\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n selectProps: Omit<ComponentProps<typeof Select>, 'children'>\n selectTriggerAriaLabel?: string\n selectTriggerId: string\n selectTriggerMinWidth?: string\n type: 'number' | 'text'\n useAboveLabels: boolean\n}\n\nconst ControlGroupSelectInner = ({\n amountStep,\n dataTestId,\n dropdownWidth,\n inputAccessibleName,\n inputCaption,\n inputId,\n inputLabelId,\n inputLabelText,\n inputItemClassName,\n inputMinWidth,\n inputValue,\n isDisabled,\n maxAmount,\n minAmount,\n onInputChange,\n selectCaption,\n selectLabelId,\n selectLabelText,\n selectItemClassName,\n selectOptions,\n selectProps,\n selectTriggerAriaLabel,\n selectTriggerId,\n selectTriggerMinWidth,\n type,\n useAboveLabels,\n}: ControlGroupSelectInnerProps) => {\n const { messageId, orientation, state } = useControlGroup()\n const isSelectOpenControlled = selectProps.open !== undefined\n const handleSelectOpenChange: NonNullable<ComponentProps<typeof Select>['onOpenChange']> = (nextOpen) => {\n selectProps.onOpenChange?.(nextOpen)\n }\n\n const inputRadiusClasses = orientation === 'horizontal' ? 'rounded-s-md rounded-e-none' : 'rounded-ss-md rounded-se-md rounded-es-none rounded-ee-none'\n const selectRadiusClasses = orientation === 'horizontal' ? 'rounded-s-none rounded-e-md' : 'rounded-ss-none rounded-se-none rounded-es-md rounded-ee-md'\n const firstItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0' : 'mbe-0'\n const secondItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0 [&>*:last-child]:-ms-0.5' : 'mbe-0 [&>*:last-child]:-mt-0.5'\n\n const inputElement = (\n <Input\n aria-describedby={messageId}\n aria-label={inputAccessibleName}\n aria-labelledby={useAboveLabels ? inputLabelId : undefined}\n className={cn(groupedFieldBaseClasses, inputRadiusClasses, getStateClasses(state), type === 'number' && numberInputNoSpinner, type === 'number' && 'tabular-nums')}\n data-testid={`${dataTestId}-input`}\n disabled={isDisabled}\n id={useAboveLabels ? inputId : undefined}\n type={type === 'number' ? 'number' : 'text'}\n placeholder={inputCaption}\n style={inputMinWidth ? { minWidth: inputMinWidth } : undefined}\n min={minAmount ?? 0}\n max={maxAmount ?? 1000000}\n {...(inputValue !== undefined && onInputChange !== undefined ? { value: inputValue, onChange: onInputChange } : {})}\n step={amountStep ?? 1}\n />\n )\n\n const selectTriggerElement = (\n <SelectTrigger\n aria-describedby={messageId}\n aria-label={selectTriggerAriaLabel}\n aria-labelledby={useAboveLabels ? selectLabelId : undefined}\n className={cn(\n 'text-input-text data-placeholder:text-input-text-placeholder!',\n selectRadiusClasses,\n 'px-4 w-full justify-between focus-visible:border-input-border--focus focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus',\n getStateClasses(state),\n )}\n data-testid={`${dataTestId}-select-trigger`}\n disabled={isDisabled}\n id={useAboveLabels ? selectTriggerId : undefined}\n style={selectTriggerMinWidth ? { minWidth: selectTriggerMinWidth } : undefined}\n >\n <SelectValue\n className='min-w-0 block max-w-full truncate text-left whitespace-nowrap text-input-text! data-placeholder:text-input-text-placeholder!'\n placeholder={selectCaption}\n />\n </SelectTrigger>\n )\n\n return (\n <>\n <ControlGroupItem className={cn(useAboveLabels ? firstItemAboveLabelClasses : undefined, inputItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label\n className='text-text-primary'\n htmlFor={inputId}\n id={inputLabelId}\n >\n {inputLabelText}\n </Label>\n {inputElement}\n </div>\n ) : (\n inputElement\n )}\n </ControlGroupItem>\n <Select\n {...selectProps}\n data-testid={`${dataTestId}-select-root`}\n disabled={isDisabled}\n {...(isSelectOpenControlled ? { open: selectProps.open } : {})}\n onOpenChange={handleSelectOpenChange}\n >\n <ControlGroupItem className={cn(useAboveLabels ? secondItemAboveLabelClasses : undefined, selectItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label\n className='text-text-primary'\n htmlFor={selectTriggerId}\n id={selectLabelId}\n >\n {selectLabelText}\n </Label>\n {selectTriggerElement}\n </div>\n ) : (\n selectTriggerElement\n )}\n </ControlGroupItem>\n <SelectContent\n data-testid={`${dataTestId}-select-content`}\n dropdownWidth={dropdownWidth}\n >\n {selectOptions.map((option) => (\n <SelectItem\n disabled={option.disabled}\n key={option.value}\n value={option.value}\n >\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ControlGroupSelect.js","names":[],"sources":["../../src/components/ControlGroup/ControlGroupSelect.tsx"],"sourcesContent":["import { Label } from '@components/Label/Label'\nimport { Input } from '@primitives/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@primitives/select'\nimport { getStateClasses, type DropdownWidth, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { useId, type ComponentProps } from 'react'\nimport { ControlGroup, ControlGroupItem, useControlGroup, type ControlGroupProps } from './ControlGroup'\n\nconst numberInputNoSpinner = '[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none'\nconst defaultInputLabel = 'Amount'\nconst defaultSelectLabel = 'Select an option'\n\nexport interface SelectOptionType {\n disabled?: boolean\n label: string\n value: string\n}\n\n/** `inline`: `inputPlaceholder` / `selectPlaceholder` show inside the fields. `above`: same strings render as labels above each control (no inner placeholders). */\nexport type ControlGroupSelectCaptionLayout = 'above' | 'inline'\n\ntype ControlGroupSelectInputControlProps =\n | {\n inputValue: ComponentProps<typeof Input>['value']\n onInputChange: ComponentProps<typeof Input>['onChange']\n }\n | {\n inputValue?: undefined\n onInputChange?: undefined\n }\n\ntype ControlGroupSelectBaseProps = ComponentProps<typeof Select> &\n Pick<ControlGroupProps, 'orientation'> & {\n amountStep?: number\n /** Accessible name for the group wrapper (use when there is no visible group heading). */\n ariaLabel?: string\n captionLayout?: ControlGroupSelectCaptionLayout\n className?: string\n dataTestId?: string\n disabled?: boolean\n dropdownWidth?: DropdownWidth\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n /** Class applied to the input `ControlGroupItem` segment for width/split composition. */\n inputItemClassName?: string\n /** When `captionLayout` is `inline`, overrides the input's accessible name (defaults to `inputPlaceholder` when set). */\n inputAriaLabel?: string\n inputPlaceholder?: string\n maxAmount?: number\n /** Number of message lines to reserve (default: 1). */\n messageReserveLines?: number\n /** Whether to keep message space reserved when hidden (default: false). */\n messageReserveSpace?: boolean\n minAmount?: number\n selectPlaceholder?: string\n /** When `captionLayout` is `inline` and `selectPlaceholder` is empty, sets the select trigger's accessible name. */\n selectAriaLabel?: string\n /** Class applied to the select `ControlGroupItem` segment for width/split composition. */\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n state?: Exclude<FormFieldState, 'disabled'>\n type?: 'number' | 'text'\n warningMessage?: string | string[] | Record<string, unknown> | null\n }\n\nexport type ControlGroupSelectProps = ControlGroupSelectBaseProps & ControlGroupSelectInputControlProps\n\nconst fieldStackClass = 'flex w-full min-w-0 flex-col gap-1.5'\nconst groupedFieldBaseClasses =\n 'h-12! min-h-12! border-2! border-input-border bg-input-bg text-base text-input-text transition duration-200 placeholder:text-input-text-placeholder hover:border-input-border--hover focus-visible:border-input-border--focus focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus disabled:pointer-events-none disabled:border-input-border--disabled disabled:bg-input-bg--disabled disabled:text-input-text--disabled'\n\nconst getFieldMinWidth = (caption?: string, extraCharacters: number = 0): string | undefined => {\n const normalizedCaption = caption?.trim()\n if (!normalizedCaption) return undefined\n return `${Math.max(normalizedCaption.length + extraCharacters, 8)}ch`\n}\n\nconst getReadableLabel = (label: string | undefined, fallback: string): string => {\n const normalizedLabel = label?.trim()\n return normalizedLabel && normalizedLabel.length > 0 ? normalizedLabel : fallback\n}\n\nexport const ControlGroupSelect = ({\n amountStep,\n ariaLabel,\n captionLayout = 'inline',\n className,\n dataTestId = 'spectral-control-group-select',\n disabled,\n errorMessage,\n id,\n dropdownWidth = 'trigger',\n inputAriaLabel,\n inputPlaceholder,\n inputItemClassName,\n inputValue,\n messageReserveLines = 1,\n messageReserveSpace = false,\n maxAmount = 1000000,\n minAmount = 0,\n onInputChange,\n orientation = 'horizontal',\n selectAriaLabel,\n selectItemClassName,\n selectOptions,\n selectPlaceholder,\n state = 'default',\n type = 'number',\n warningMessage,\n ...selectProps\n}: ControlGroupSelectProps) => {\n const baseId = useId()\n const idPrefix = id ?? baseId\n const inputId = `${idPrefix}-amount`\n const selectTriggerId = `${idPrefix}-select`\n const inputLabelId = `${inputId}-label`\n const selectLabelId = `${selectTriggerId}-label`\n\n const useAboveLabels = captionLayout === 'above'\n const inputCaption = useAboveLabels ? undefined : inputPlaceholder\n const selectCaption = useAboveLabels ? undefined : selectPlaceholder\n const inputLabelText = getReadableLabel(inputPlaceholder, defaultInputLabel)\n const selectLabelText = getReadableLabel(selectPlaceholder, defaultSelectLabel)\n\n const inputAccessibleName = inputAriaLabel ?? (useAboveLabels ? undefined : inputLabelText)\n const selectTriggerAriaLabel = selectAriaLabel ?? (useAboveLabels ? undefined : selectLabelText)\n const inputMinWidth = getFieldMinWidth(inputPlaceholder, 3)\n const selectTriggerMinWidth = getFieldMinWidth(selectPlaceholder, 5)\n const groupAriaLabel = ariaLabel ?? `${inputLabelText} and ${selectLabelText}`\n\n const isDisabled = !!disabled\n const isInputControlled = inputValue !== undefined && onInputChange !== undefined\n\n return (\n <ControlGroup\n aria-label={groupAriaLabel}\n className={className}\n data-testid={dataTestId}\n disabled={disabled}\n errorMessage={errorMessage}\n id={idPrefix}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace}\n orientation={orientation}\n state={state}\n warningMessage={warningMessage}\n >\n <ControlGroupSelectInner\n amountStep={amountStep}\n dataTestId={dataTestId}\n inputAccessibleName={inputAccessibleName}\n inputCaption={inputCaption}\n inputId={inputId}\n inputLabelId={inputLabelId}\n inputLabelText={inputLabelText}\n inputItemClassName={inputItemClassName}\n inputMinWidth={inputMinWidth}\n inputValue={isInputControlled ? inputValue : undefined}\n isDisabled={isDisabled}\n maxAmount={maxAmount}\n minAmount={minAmount}\n onInputChange={isInputControlled ? onInputChange : undefined}\n dropdownWidth={dropdownWidth}\n selectCaption={selectCaption}\n selectOptions={selectOptions}\n selectLabelId={selectLabelId}\n selectLabelText={selectLabelText}\n selectItemClassName={selectItemClassName}\n selectProps={selectProps}\n selectTriggerAriaLabel={selectTriggerAriaLabel}\n selectTriggerId={selectTriggerId}\n selectTriggerMinWidth={selectTriggerMinWidth}\n type={type}\n useAboveLabels={useAboveLabels}\n />\n </ControlGroup>\n )\n}\n\ninterface ControlGroupSelectInnerProps {\n amountStep?: number\n dataTestId: string\n dropdownWidth: DropdownWidth\n inputAccessibleName?: string\n inputCaption?: string\n inputId: string\n inputLabelId: string\n inputLabelText: string\n inputItemClassName?: string\n inputMinWidth?: string\n inputValue?: ComponentProps<typeof Input>['value']\n isDisabled: boolean\n maxAmount: number\n minAmount: number\n onInputChange?: ComponentProps<typeof Input>['onChange']\n selectCaption?: string\n selectLabelId: string\n selectLabelText: string\n selectItemClassName?: string\n selectOptions: SelectOptionType[]\n selectProps: Omit<ComponentProps<typeof Select>, 'children'>\n selectTriggerAriaLabel?: string\n selectTriggerId: string\n selectTriggerMinWidth?: string\n type: 'number' | 'text'\n useAboveLabels: boolean\n}\n\nconst ControlGroupSelectInner = ({\n amountStep,\n dataTestId,\n dropdownWidth,\n inputAccessibleName,\n inputCaption,\n inputId,\n inputLabelId,\n inputLabelText,\n inputItemClassName,\n inputMinWidth,\n inputValue,\n isDisabled,\n maxAmount,\n minAmount,\n onInputChange,\n selectCaption,\n selectLabelId,\n selectLabelText,\n selectItemClassName,\n selectOptions,\n selectProps,\n selectTriggerAriaLabel,\n selectTriggerId,\n selectTriggerMinWidth,\n type,\n useAboveLabels,\n}: ControlGroupSelectInnerProps) => {\n const { messageId, orientation, state } = useControlGroup()\n const isSelectOpenControlled = selectProps.open !== undefined\n const handleSelectOpenChange: NonNullable<ComponentProps<typeof Select>['onOpenChange']> = (nextOpen) => {\n selectProps.onOpenChange?.(nextOpen)\n }\n\n const inputRadiusClasses = orientation === 'horizontal' ? 'rounded-s-md rounded-e-none' : 'rounded-ss-md rounded-se-md rounded-es-none rounded-ee-none'\n const selectRadiusClasses = orientation === 'horizontal' ? 'rounded-s-none rounded-e-md' : 'rounded-ss-none rounded-se-none rounded-es-md rounded-ee-md'\n const firstItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0' : 'mbe-0'\n const secondItemAboveLabelClasses = orientation === 'horizontal' ? 'me-0 [&>*:last-child]:-ms-0.5' : 'mbe-0 [&>*:last-child]:-mt-0.5'\n\n const inputElement = (\n <Input\n aria-describedby={messageId}\n aria-label={inputAccessibleName}\n aria-labelledby={useAboveLabels ? inputLabelId : undefined}\n className={cn(groupedFieldBaseClasses, inputRadiusClasses, getStateClasses(state), type === 'number' && numberInputNoSpinner, type === 'number' && 'tabular-nums')}\n data-testid={`${dataTestId}-input`}\n disabled={isDisabled}\n id={useAboveLabels ? inputId : undefined}\n type={type === 'number' ? 'number' : 'text'}\n placeholder={inputCaption}\n style={inputMinWidth ? { minWidth: inputMinWidth } : undefined}\n min={minAmount ?? 0}\n max={maxAmount ?? 1000000}\n {...(inputValue !== undefined && onInputChange !== undefined ? { value: inputValue, onChange: onInputChange } : {})}\n step={amountStep ?? 1}\n />\n )\n\n const selectTriggerElement = (\n <SelectTrigger\n aria-describedby={messageId}\n aria-label={selectTriggerAriaLabel}\n aria-labelledby={useAboveLabels ? selectLabelId : undefined}\n className={cn(\n 'text-input-text data-placeholder:text-input-text-placeholder!',\n selectRadiusClasses,\n 'px-4 w-full justify-between focus-visible:border-input-border--focus focus-visible:ring-0 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-input-border--focus',\n getStateClasses(state),\n )}\n data-testid={`${dataTestId}-select-trigger`}\n disabled={isDisabled}\n id={useAboveLabels ? selectTriggerId : undefined}\n style={selectTriggerMinWidth ? { minWidth: selectTriggerMinWidth } : undefined}\n >\n <SelectValue className='min-w-0 block max-w-full truncate text-left whitespace-nowrap text-input-text! data-placeholder:text-input-text-placeholder!' placeholder={selectCaption} />\n </SelectTrigger>\n )\n\n return (\n <>\n <ControlGroupItem className={cn(useAboveLabels ? firstItemAboveLabelClasses : undefined, inputItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={inputId} id={inputLabelId}>\n {inputLabelText}\n </Label>\n {inputElement}\n </div>\n ) : (\n inputElement\n )}\n </ControlGroupItem>\n <Select {...selectProps} data-testid={`${dataTestId}-select-root`} disabled={isDisabled} {...(isSelectOpenControlled ? { open: selectProps.open } : {})} onOpenChange={handleSelectOpenChange}>\n <ControlGroupItem className={cn(useAboveLabels ? secondItemAboveLabelClasses : undefined, selectItemClassName)}>\n {useAboveLabels ? (\n <div className={fieldStackClass}>\n <Label className='text-text-primary' htmlFor={selectTriggerId} id={selectLabelId}>\n {selectLabelText}\n </Label>\n {selectTriggerElement}\n </div>\n ) : (\n selectTriggerElement\n )}\n </ControlGroupItem>\n <SelectContent data-testid={`${dataTestId}-select-content`} dropdownWidth={dropdownWidth}>\n {selectOptions.map((option) => (\n <SelectItem disabled={option.disabled} key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </>\n )\n}\n"],"mappings":";;;;;;;;;;;AAQA,MAAM,uBAAuB;AAC7B,MAAM,oBAAoB;AAC1B,MAAM,qBAAqB;AAyD3B,MAAM,kBAAkB;AACxB,MAAM,0BACJ;AAEF,MAAM,oBAAoB,SAAkB,kBAA0B,MAA0B;CAC9F,MAAM,oBAAoB,SAAS,MAAM;AACzC,KAAI,CAAC,kBAAmB,QAAO;AAC/B,QAAO,GAAG,KAAK,IAAI,kBAAkB,SAAS,iBAAiB,EAAE,CAAC;;AAGpE,MAAM,oBAAoB,OAA2B,aAA6B;CAChF,MAAM,kBAAkB,OAAO,MAAM;AACrC,QAAO,mBAAmB,gBAAgB,SAAS,IAAI,kBAAkB;;AAG3E,MAAa,sBAAsB,EACjC,YACA,WACA,gBAAgB,UAChB,WACA,aAAa,iCACb,UACA,cACA,IACA,gBAAgB,WAChB,gBACA,kBACA,oBACA,YACA,sBAAsB,GACtB,sBAAsB,OACtB,YAAY,KACZ,YAAY,GACZ,eACA,cAAc,cACd,iBACA,qBACA,eACA,mBACA,QAAQ,WACR,OAAO,UACP,gBACA,GAAG,kBAC0B;CAC7B,MAAM,SAAS,OAAO;CACtB,MAAM,WAAW,MAAM;CACvB,MAAM,UAAU,GAAG,SAAS;CAC5B,MAAM,kBAAkB,GAAG,SAAS;CACpC,MAAM,eAAe,GAAG,QAAQ;CAChC,MAAM,gBAAgB,GAAG,gBAAgB;CAEzC,MAAM,iBAAiB,kBAAkB;CACzC,MAAM,eAAe,iBAAiB,SAAY;CAClD,MAAM,gBAAgB,iBAAiB,SAAY;CACnD,MAAM,iBAAiB,iBAAiB,kBAAkB,kBAAkB;CAC5E,MAAM,kBAAkB,iBAAiB,mBAAmB,mBAAmB;CAE/E,MAAM,sBAAsB,mBAAmB,iBAAiB,SAAY;CAC5E,MAAM,yBAAyB,oBAAoB,iBAAiB,SAAY;CAChF,MAAM,gBAAgB,iBAAiB,kBAAkB,EAAE;CAC3D,MAAM,wBAAwB,iBAAiB,mBAAmB,EAAE;CACpE,MAAM,iBAAiB,aAAa,GAAG,eAAe,OAAO;CAE7D,MAAM,aAAa,CAAC,CAAC;CACrB,MAAM,oBAAoB,eAAe,UAAa,kBAAkB;AAExE,QACE,oBAAC,cAAD;EACE,cAAY;EACD;EACX,eAAa;EACH;EACI;EACd,IAAI;EACiB;EACA;EACR;EACN;EACS;YAEhB,oBAAC,yBAAD;GACc;GACA;GACS;GACP;GACL;GACK;GACE;GACI;GACL;GACf,YAAY,oBAAoB,aAAa;GACjC;GACD;GACA;GACX,eAAe,oBAAoB,gBAAgB;GACpC;GACA;GACA;GACA;GACE;GACI;GACR;GACW;GACP;GACM;GACjB;GACU;GAChB;EACW;;AAiCnB,MAAM,2BAA2B,EAC/B,YACA,YACA,eACA,qBACA,cACA,SACA,cACA,gBACA,oBACA,eACA,YACA,YACA,WACA,WACA,eACA,eACA,eACA,iBACA,qBACA,eACA,aACA,wBACA,iBACA,uBACA,MACA,qBACkC;CAClC,MAAM,EAAE,WAAW,aAAa,UAAU,iBAAiB;CAC3D,MAAM,yBAAyB,YAAY,SAAS;CACpD,MAAM,0BAAsF,aAAa;AACvG,cAAY,eAAe,SAAS;;CAGtC,MAAM,qBAAqB,gBAAgB,eAAe,gCAAgC;CAC1F,MAAM,sBAAsB,gBAAgB,eAAe,gCAAgC;CAC3F,MAAM,6BAA6B,gBAAgB,eAAe,SAAS;CAC3E,MAAM,8BAA8B,gBAAgB,eAAe,kCAAkC;CAErG,MAAM,eACJ,oBAAC,OAAD;EACE,oBAAkB;EAClB,cAAY;EACZ,mBAAiB,iBAAiB,eAAe;EACjD,WAAW,GAAG,yBAAyB,oBAAoB,gBAAgB,MAAM,EAAE,SAAS,YAAY,sBAAsB,SAAS,YAAY,eAAe;EAClK,eAAa,GAAG,WAAW;EAC3B,UAAU;EACV,IAAI,iBAAiB,UAAU;EAC/B,MAAM,SAAS,WAAW,WAAW;EACrC,aAAa;EACb,OAAO,gBAAgB,EAAE,UAAU,eAAe,GAAG;EACrD,KAAK,aAAa;EAClB,KAAK,aAAa;EAClB,GAAK,eAAe,UAAa,kBAAkB,SAAY;GAAE,OAAO;GAAY,UAAU;GAAe,GAAG,EAAE;EAClH,MAAM,cAAc;EACpB;CAGJ,MAAM,uBACJ,oBAAC,eAAD;EACE,oBAAkB;EAClB,cAAY;EACZ,mBAAiB,iBAAiB,gBAAgB;EAClD,WAAW,GACT,iEACA,qBACA,8LACA,gBAAgB,MAAM,CACvB;EACD,eAAa,GAAG,WAAW;EAC3B,UAAU;EACV,IAAI,iBAAiB,kBAAkB;EACvC,OAAO,wBAAwB,EAAE,UAAU,uBAAuB,GAAG;YAErE,oBAAC,aAAD;GAAa,WAAU;GAA+H,aAAa;GAAiB;EACtK;AAGlB,QACE,4CACE,oBAAC,kBAAD;EAAkB,WAAW,GAAG,iBAAiB,6BAA6B,QAAW,mBAAmB;YACzG,iBACC,qBAAC,OAAD;GAAK,WAAW;aAAhB,CACE,oBAAC,OAAD;IAAO,WAAU;IAAoB,SAAS;IAAS,IAAI;cACxD;IACK,GACP,aACG;OAEN;EAEe,GACnB,qBAAC,QAAD;EAAQ,GAAI;EAAa,eAAa,GAAG,WAAW;EAAe,UAAU;EAAY,GAAK,yBAAyB,EAAE,MAAM,YAAY,MAAM,GAAG,EAAE;EAAG,cAAc;YAAvK,CACE,oBAAC,kBAAD;GAAkB,WAAW,GAAG,iBAAiB,8BAA8B,QAAW,oBAAoB;aAC3G,iBACC,qBAAC,OAAD;IAAK,WAAW;cAAhB,CACE,oBAAC,OAAD;KAAO,WAAU;KAAoB,SAAS;KAAiB,IAAI;eAChE;KACK,GACP,qBACG;QAEN;GAEe,GACnB,oBAAC,eAAD;GAAe,eAAa,GAAG,WAAW;GAAiC;aACxE,cAAc,KAAK,WAClB,oBAAC,YAAD;IAAY,UAAU,OAAO;IAA6B,OAAO,OAAO;cACrE,OAAO;IACG,EAF+B,OAAO,MAEtC,CACb;GACY,EACT;IACR"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroup.d.ts","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"mappings":";;;;;;;UAKU,wBAAA;EACR,SAAA;EACA,UAAA;EACA,SAAA;EACA,SAAA;EACA,WAAA;EACA,KAAA,EAAO,cAAA;AAAA;AAAA,cAKI,eAAA,QAAe,wBAAA;AAAA,UAQX,iBAAA,SAA0B,cAAA;EACzC,QAAA;EACA,YAAA,uBAAmC,MAAA;EACnC,EAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,WAAA;EACA,KAAA,GAAQ,cAAA;EACR,cAAA,uBAAqC,MAAA;AAAA;AAAA,cAG1B,YAAA;EAAY,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,EAAA;EAAA,mBAAA;EAAA,mBAAA;EAAA,IAAA;EAAA,WAAA;EAAA,KAAA;EAAA,cAAA;EAAA,GAAA;AAAA,GAAoL,iBAAA,KAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"ControlGroup.d.ts","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"mappings":";;;;;;;UAKU,wBAAA;EACR,SAAA;EACA,UAAA;EACA,SAAA;EACA,SAAA;EACA,WAAA;EACA,KAAA,EAAO,cAAA;AAAA;AAAA,cAKI,eAAA,QAAe,wBAAA;AAAA,UAQX,iBAAA,SAA0B,cAAA;EACzC,QAAA;EACA,YAAA,uBAAmC,MAAA;EACnC,EAAA;EACA,mBAAA;EACA,mBAAA;EACA,IAAA;EACA,WAAA;EACA,KAAA,GAAQ,cAAA;EACR,cAAA,uBAAqC,MAAA;AAAA;AAAA,cAG1B,YAAA;EAAY,SAAA;EAAA,QAAA;EAAA,YAAA;EAAA,EAAA;EAAA,mBAAA;EAAA,mBAAA;EAAA,IAAA;EAAA,WAAA;EAAA,KAAA;EAAA,cAAA;EAAA,GAAA;AAAA,GAAoL,iBAAA,KAAiB,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAuCjN,gBAAA;EAAgB,SAAA;EAAA,GAAA;AAAA,GAA6B,cAAA,QAAsB,IAAA,MAAK,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
package/dist/ControlGroup.js
CHANGED
|
@@ -30,7 +30,7 @@ const ControlGroup = ({ className, disabled, errorMessage, id, messageReserveLin
|
|
|
30
30
|
},
|
|
31
31
|
children: /* @__PURE__ */ jsxs("div", {
|
|
32
32
|
"data-slot": "control-group-field",
|
|
33
|
-
className: "
|
|
33
|
+
className: "flex w-full flex-col gap-1.5",
|
|
34
34
|
children: [
|
|
35
35
|
/* @__PURE__ */ jsx("div", {
|
|
36
36
|
"data-slot": "control-group",
|
package/dist/ControlGroup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ControlGroup.js","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId, useFormFieldState, WarningMessage, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useContext, type ComponentProps } from 'react'\n\ninterface ControlGroupContextValue {\n messageId?: string\n isDisabled: boolean\n isInvalid: boolean\n isLoading: boolean\n orientation: 'horizontal' | 'vertical'\n state: FormFieldState\n}\n\nconst ControlGroupContext = createContext<ControlGroupContextValue | null>(null)\n\nexport const useControlGroup = () => {\n const context = useContext(ControlGroupContext)\n if (context === null) {\n throw new Error('useControlGroup must be used within a ControlGroup')\n }\n return context\n}\n\nexport interface ControlGroupProps extends ComponentProps<'div'> {\n disabled?: boolean\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n orientation?: 'horizontal' | 'vertical'\n state?: FormFieldState\n warningMessage?: string | string[] | Record<string, unknown> | null\n}\n\nexport const ControlGroup = ({ className, disabled, errorMessage, id, messageReserveLines = 1, messageReserveSpace = false, name, orientation = 'horizontal', state = 'default', warningMessage, ...props }: ControlGroupProps) => {\n const groupId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(groupId)\n const warningMessageId = `${groupId}-warning`\n const { isDisabled, isLoading, isInvalid } = useFormFieldState(disabled, state)\n const messageId = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n\n return (\n <ControlGroupContext.Provider value={{ messageId, isDisabled, isInvalid, isLoading, orientation, state }}>\n <div
|
|
1
|
+
{"version":3,"file":"ControlGroup.js","names":[],"sources":["../src/components/ControlGroup/ControlGroup.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { ErrorMessage, getErrorMessageId, useFormFieldId, useFormFieldState, WarningMessage, type FormFieldState } from '@utils/formFieldUtils'\nimport { cn } from '@utils/twUtils'\nimport { createContext, useContext, type ComponentProps } from 'react'\n\ninterface ControlGroupContextValue {\n messageId?: string\n isDisabled: boolean\n isInvalid: boolean\n isLoading: boolean\n orientation: 'horizontal' | 'vertical'\n state: FormFieldState\n}\n\nconst ControlGroupContext = createContext<ControlGroupContextValue | null>(null)\n\nexport const useControlGroup = () => {\n const context = useContext(ControlGroupContext)\n if (context === null) {\n throw new Error('useControlGroup must be used within a ControlGroup')\n }\n return context\n}\n\nexport interface ControlGroupProps extends ComponentProps<'div'> {\n disabled?: boolean\n errorMessage?: string | string[] | Record<string, unknown> | null\n id?: string\n messageReserveLines?: number\n messageReserveSpace?: boolean\n name?: string\n orientation?: 'horizontal' | 'vertical'\n state?: FormFieldState\n warningMessage?: string | string[] | Record<string, unknown> | null\n}\n\nexport const ControlGroup = ({ className, disabled, errorMessage, id, messageReserveLines = 1, messageReserveSpace = false, name, orientation = 'horizontal', state = 'default', warningMessage, ...props }: ControlGroupProps) => {\n const groupId = useFormFieldId(id, name)\n const errorMessageId = getErrorMessageId(groupId)\n const warningMessageId = `${groupId}-warning`\n const { isDisabled, isLoading, isInvalid } = useFormFieldState(disabled, state)\n const messageId = state === 'error' && errorMessage ? errorMessageId : state === 'warning' && warningMessage ? warningMessageId : undefined\n\n return (\n <ControlGroupContext.Provider value={{ messageId, isDisabled, isInvalid, isLoading, orientation, state }}>\n <div data-slot='control-group-field' className='flex w-full flex-col gap-1.5'>\n <div\n data-slot='control-group'\n data-orientation={orientation}\n data-state={state}\n id={groupId}\n role='group'\n aria-describedby={messageId}\n className={cn('group flex w-full', orientation === 'vertical' && 'flex-col', isDisabled && 'pointer-events-none opacity-50', className)}\n {...props}\n />\n <ErrorMessage\n dataTestId='spectral-control-group-error-message'\n id={errorMessageId}\n message={isInvalid ? errorMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'error'}\n />\n <WarningMessage\n dataTestId='spectral-control-group-warning-message'\n id={warningMessageId}\n message={state === 'warning' ? warningMessage : null}\n messageReserveLines={messageReserveLines}\n messageReserveSpace={messageReserveSpace && state === 'warning'}\n />\n </div>\n </ControlGroupContext.Provider>\n )\n}\n\nexport const ControlGroupItem = ({ className, ...props }: ComponentProps<typeof Slot>) => {\n const { orientation } = useControlGroup()\n\n return (\n <Slot\n data-slot='control-group-item'\n className={cn(\n 'rounded-none focus-within:z-10 hover:z-10',\n orientation === 'horizontal' && 'first:rounded-s-md last:me-0 last:rounded-e-md -me-0.5 h-auto',\n orientation === 'vertical' && 'first:rounded-ss-md first:rounded-se-md last:rounded-ee-md last:rounded-es-md last:mbe-0 -mbe-0.5 w-auto',\n className,\n )}\n {...props}\n />\n )\n}\n"],"mappings":";;;;;;;;;AAcA,MAAM,sBAAsB,cAA+C,KAAK;AAEhF,MAAa,wBAAwB;CACnC,MAAM,UAAU,WAAW,oBAAoB;AAC/C,KAAI,YAAY,KACd,OAAM,IAAI,MAAM,qDAAqD;AAEvE,QAAO;;AAeT,MAAa,gBAAgB,EAAE,WAAW,UAAU,cAAc,IAAI,sBAAsB,GAAG,sBAAsB,OAAO,MAAM,cAAc,cAAc,QAAQ,WAAW,gBAAgB,GAAG,YAA+B;CACjO,MAAM,UAAU,eAAe,IAAI,KAAK;CACxC,MAAM,iBAAiB,kBAAkB,QAAQ;CACjD,MAAM,mBAAmB,GAAG,QAAQ;CACpC,MAAM,EAAE,YAAY,WAAW,cAAc,kBAAkB,UAAU,MAAM;CAC/E,MAAM,YAAY,UAAU,WAAW,eAAe,iBAAiB,UAAU,aAAa,iBAAiB,mBAAmB;AAElI,QACE,oBAAC,oBAAoB,UAArB;EAA8B,OAAO;GAAE;GAAW;GAAY;GAAW;GAAW;GAAa;GAAO;YACtG,qBAAC,OAAD;GAAK,aAAU;GAAsB,WAAU;aAA/C;IACE,oBAAC,OAAD;KACE,aAAU;KACV,oBAAkB;KAClB,cAAY;KACZ,IAAI;KACJ,MAAK;KACL,oBAAkB;KAClB,WAAW,GAAG,qBAAqB,gBAAgB,cAAc,YAAY,cAAc,kCAAkC,UAAU;KACvI,GAAI;KACJ;IACF,oBAAC,cAAD;KACE,YAAW;KACX,IAAI;KACJ,SAAS,YAAY,eAAe;KACf;KACrB,qBAAqB,uBAAuB,UAAU;KACtD;IACF,oBAAC,gBAAD;KACE,YAAW;KACX,IAAI;KACJ,SAAS,UAAU,YAAY,iBAAiB;KAC3B;KACrB,qBAAqB,uBAAuB,UAAU;KACtD;IACE;;EACuB;;AAInC,MAAa,oBAAoB,EAAE,WAAW,GAAG,YAAyC;CACxF,MAAM,EAAE,gBAAgB,iBAAiB;AAEzC,QACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,6CACA,gBAAgB,gBAAgB,iEAChC,gBAAgB,cAAc,4GAC9B,UACD;EACD,GAAI;EACJ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.d.ts","names":[],"sources":["../../src/components/DataCard/Card.tsx"],"mappings":";;;;;KAIY,SAAA,GAAY,cAAA;EAA0B,OAAA;AAAA;AAAA,cAIrC,QAAA;EAAA,GAAQ;AAAA,GAAkB,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"Card.d.ts","names":[],"sources":["../../src/components/DataCard/Card.tsx"],"mappings":";;;;;KAIY,SAAA,GAAY,cAAA;EAA0B,OAAA;AAAA;AAAA,cAIrC,QAAA;EAAA,GAAQ;AAAA,GAAkB,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAInC,UAAA;EAAU,SAAA;EAAA,GAAA;AAAA,GAA6B,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIhD,SAAA;EAAS,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAA8C,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAMhE,iBAAA;EAAiB,SAAA;EAAA,OAAA;EAAA,GAAA;AAAA,GAA8C,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAMxE,WAAA;EAAW,SAAA;EAAA,GAAA;AAAA,GAA6B,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,cAIjD,IAAA;EAAI,OAAA;EAAA,QAAA;EAAA,SAAA;EAAA,GAAA;AAAA,GAAwD,SAAA,KAAS,oBAAA,CAAA,GAAA,CAAA,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Card.js","names":[],"sources":["../../src/components/DataCard/Card.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\n\nexport type CardProps = ComponentProps<'div'> & { asChild?: boolean }\n\nconst cardClasses = 'text-text-primary flex flex-col w-full card-effects p-3 gap-6 rounded-xl'\n\nexport const CardBase = ({ ...props }: CardProps) => {\n return
|
|
1
|
+
{"version":3,"file":"Card.js","names":[],"sources":["../../src/components/DataCard/Card.tsx"],"sourcesContent":["import { Slot } from '@primitives/slot'\nimport { cn } from '@utils/twUtils'\nimport { type ComponentProps } from 'react'\n\nexport type CardProps = ComponentProps<'div'> & { asChild?: boolean }\n\nconst cardClasses = 'text-text-primary flex flex-col w-full card-effects p-3 gap-6 rounded-xl'\n\nexport const CardBase = ({ ...props }: CardProps) => {\n return <div data-slot='card' data-testid='spectral-card' {...props} />\n}\n\nexport const CardHeader = ({ className, ...props }: CardProps) => {\n return <div className={cn('pb-4 @container/card-header flex items-center justify-between', className)} data-slot='card-header' data-testid='spectral-card-header' {...props} />\n}\n\nexport const CardTitle = ({ className, asChild = false, ...props }: CardProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return <Comp className={cn('font-semibold text-xl', className)} data-slot='card-title' data-testid='spectral-card-title' {...props} />\n}\n\nexport const CardHeaderEndSlot = ({ className, asChild = false, ...props }: CardProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return <Comp className={cn('justify-self-end', className)} data-slot='card-action' data-testid='spectral-card-action' {...props} />\n}\n\nexport const CardContent = ({ className, ...props }: CardProps) => {\n return <div className={className} data-slot='card-content' data-testid='spectral-card-content' {...props} />\n}\n\nexport const Card = ({ asChild = false, children, className, ...props }: CardProps) => {\n const Comp = asChild ? Slot : 'div'\n\n return (\n <Comp className={cn(cardClasses, className)} data-slot='card' data-testid='spectral-card' {...props}>\n {children}\n </Comp>\n )\n}\n"],"mappings":";;;;;;;AAMA,MAAM,cAAc;AAEpB,MAAa,YAAY,EAAE,GAAG,YAAuB;AACnD,QAAO,oBAAC,OAAD;EAAK,aAAU;EAAO,eAAY;EAAgB,GAAI;EAAS;;AAGxE,MAAa,cAAc,EAAE,WAAW,GAAG,YAAuB;AAChE,QAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,iEAAiE,UAAU;EAAE,aAAU;EAAc,eAAY;EAAuB,GAAI;EAAS;;AAGjL,MAAa,aAAa,EAAE,WAAW,UAAU,OAAO,GAAG,YAAuB;AAGhF,QAAO,oBAFM,UAAU,OAAO,OAEvB;EAAM,WAAW,GAAG,yBAAyB,UAAU;EAAE,aAAU;EAAa,eAAY;EAAsB,GAAI;EAAS;;AAGxI,MAAa,qBAAqB,EAAE,WAAW,UAAU,OAAO,GAAG,YAAuB;AAGxF,QAAO,oBAFM,UAAU,OAAO,OAEvB;EAAM,WAAW,GAAG,oBAAoB,UAAU;EAAE,aAAU;EAAc,eAAY;EAAuB,GAAI;EAAS;;AAGrI,MAAa,eAAe,EAAE,WAAW,GAAG,YAAuB;AACjE,QAAO,oBAAC,OAAD;EAAgB;EAAW,aAAU;EAAe,eAAY;EAAwB,GAAI;EAAS;;AAG9G,MAAa,QAAQ,EAAE,UAAU,OAAO,UAAU,WAAW,GAAG,YAAuB;AAGrF,QACE,oBAHW,UAAU,OAAO,OAG5B;EAAM,WAAW,GAAG,aAAa,UAAU;EAAE,aAAU;EAAO,eAAY;EAAgB,GAAI;EAC3F;EACI"}
|
package/dist/DataCard.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataCard.js","names":[],"sources":["../src/components/DataCard/DataCard.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ReactNode } from 'react'\nimport { Card, CardContent, CardHeader, CardTitle, type CardProps } from './Card'\n\nexport type DataCardProps = CardProps & {\n accentColor: string\n cardHeaderEndSlot: ReactNode\n dataDescription: string\n dataValue: string | number\n title: string\n}\n\nexport const DataCard = ({ accentColor, cardHeaderEndSlot, className, dataDescription, dataValue, title, ...props }: DataCardProps) => {\n return (\n <Card
|
|
1
|
+
{"version":3,"file":"DataCard.js","names":[],"sources":["../src/components/DataCard/DataCard.tsx"],"sourcesContent":["import { cn } from '@utils/twUtils'\nimport { type ReactNode } from 'react'\nimport { Card, CardContent, CardHeader, CardTitle, type CardProps } from './Card'\n\nexport type DataCardProps = CardProps & {\n accentColor: string\n cardHeaderEndSlot: ReactNode\n dataDescription: string\n dataValue: string | number\n title: string\n}\n\nexport const DataCard = ({ accentColor, cardHeaderEndSlot, className, dataDescription, dataValue, title, ...props }: DataCardProps) => {\n return (\n <Card className={cn('gap-4 card-effects', className)} {...props} data-testid='spectral-datacard'>\n <CardHeader className='pb-0' data-testid='spectral-datacard-header'>\n <CardTitle className='text-sm font-bold uppercase' data-testid='spectral-datacard-title'>\n {title}\n </CardTitle>\n <div style={{ color: accentColor }} data-testid='spectral-datacard-end-slot'>\n {cardHeaderEndSlot}\n </div>\n </CardHeader>\n <CardContent>\n <div className='gap-4 flex flex-col'>\n <div className='text-4xl font-bold tabular-nums' data-testid='spectral-datacard-data-value' style={{ color: accentColor }}>\n {dataValue}\n </div>\n <div className='text-xs text-data-card-description' data-testid='spectral-datacard-data-description'>\n {dataDescription}\n </div>\n </div>\n </CardContent>\n </Card>\n )\n}\n"],"mappings":";;;;;;;AAYA,MAAa,YAAY,EAAE,aAAa,mBAAmB,WAAW,iBAAiB,WAAW,OAAO,GAAG,YAA2B;AACrI,QACE,qBAAC,MAAD;EAAM,WAAW,GAAG,sBAAsB,UAAU;EAAE,GAAI;EAAO,eAAY;YAA7E,CACE,qBAAC,YAAD;GAAY,WAAU;GAAO,eAAY;aAAzC,CACE,oBAAC,WAAD;IAAW,WAAU;IAA8B,eAAY;cAC5D;IACS,GACZ,oBAAC,OAAD;IAAK,OAAO,EAAE,OAAO,aAAa;IAAE,eAAY;cAC7C;IACG,EACK;MACb,oBAAC,aAAD,YACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,OAAD;IAAK,WAAU;IAAkC,eAAY;IAA+B,OAAO,EAAE,OAAO,aAAa;cACtH;IACG,GACN,oBAAC,OAAD;IAAK,WAAU;IAAqC,eAAY;cAC7D;IACG,EACF;MACM,EACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Calendar.js","names":[],"sources":["../../src/components/DateTimePicker/Calendar.tsx"],"sourcesContent":["import { ChevronDownIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { useMemo } from 'react'\nimport { DayPicker, type DayPickerProps, type Matcher, type Locale } from 'react-day-picker'\n\nexport type CalendarProps = DayPickerProps & {\n disabled?: Matcher | Matcher[]\n disablePastDates?: boolean\n fixedWeeks?: boolean\n /** The locale object used to localize dates. Import from 'react-day-picker/locale'. */\n locale?: Partial<Locale>\n}\n\nexport const Calendar = ({ classNames, disabled, disablePastDates = true, fixedWeeks, locale, showOutsideDays = true, ...props }: CalendarProps) => {\n // Memoize today's date to avoid creating new Date objects on every render\n const today = useMemo(() => new Date(), [])\n\n // Combine user-provided disabled dates with past dates if enabled\n const combinedDisabled: Matcher[] = [...(disablePastDates ? [{ before: today }] : []), ...(Array.isArray(disabled) ? disabled : disabled ? [disabled] : [])]\n\n return (\n <DayPicker\n {...props}\n classNames={{\n months: cn('months relative flex'),\n month: cn('month'),\n caption: cn('calendar-header'),\n caption_label: cn('month-title'),\n nav: cn('rdp-nav flex w-full items-center'),\n nav_button: cn('nav-button h-7 w-7 p-0 bg-transparent opacity-50 hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent'),\n button_previous: cn('nav-prev left-1 top-0 absolute'),\n button_next: cn('nav-next right-1 top-0 absolute'),\n table: cn('table w-full border-collapse'),\n head_row: cn('day-head-row flex'),\n head_cell: cn('days-of-week'),\n row: cn('day-row mt-2 flex w-full'),\n cell: cn('day-cell'),\n day: cn('day'),\n day_range_start: cn('day-range-start'),\n day_range_middle: cn('day-range-middle'),\n day_range_end: cn('day-range-end'),\n day_selected: cn('day-selected'),\n day_outside: cn('day-outside'),\n day_disabled: cn('day-disabled'),\n hidden: cn('hidden'),\n ...classNames,\n }}\n components={{\n Chevron: ({ orientation }) =>
|
|
1
|
+
{"version":3,"file":"Calendar.js","names":[],"sources":["../../src/components/DateTimePicker/Calendar.tsx"],"sourcesContent":["import { ChevronDownIcon } from '@components/Icons'\nimport { cn } from '@utils/twUtils'\nimport { useMemo } from 'react'\nimport { DayPicker, type DayPickerProps, type Matcher, type Locale } from 'react-day-picker'\n\nexport type CalendarProps = DayPickerProps & {\n disabled?: Matcher | Matcher[]\n disablePastDates?: boolean\n fixedWeeks?: boolean\n /** The locale object used to localize dates. Import from 'react-day-picker/locale'. */\n locale?: Partial<Locale>\n}\n\nexport const Calendar = ({ classNames, disabled, disablePastDates = true, fixedWeeks, locale, showOutsideDays = true, ...props }: CalendarProps) => {\n // Memoize today's date to avoid creating new Date objects on every render\n const today = useMemo(() => new Date(), [])\n\n // Combine user-provided disabled dates with past dates if enabled\n const combinedDisabled: Matcher[] = [...(disablePastDates ? [{ before: today }] : []), ...(Array.isArray(disabled) ? disabled : disabled ? [disabled] : [])]\n\n return (\n <DayPicker\n {...props}\n classNames={{\n months: cn('months relative flex'),\n month: cn('month'),\n caption: cn('calendar-header'),\n caption_label: cn('month-title'),\n nav: cn('rdp-nav flex w-full items-center'),\n nav_button: cn('nav-button h-7 w-7 p-0 bg-transparent opacity-50 hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent'),\n button_previous: cn('nav-prev left-1 top-0 absolute'),\n button_next: cn('nav-next right-1 top-0 absolute'),\n table: cn('table w-full border-collapse'),\n head_row: cn('day-head-row flex'),\n head_cell: cn('days-of-week'),\n row: cn('day-row mt-2 flex w-full'),\n cell: cn('day-cell'),\n day: cn('day'),\n day_range_start: cn('day-range-start'),\n day_range_middle: cn('day-range-middle'),\n day_range_end: cn('day-range-end'),\n day_selected: cn('day-selected'),\n day_outside: cn('day-outside'),\n day_disabled: cn('day-disabled'),\n hidden: cn('hidden'),\n ...classNames,\n }}\n components={{\n Chevron: ({ orientation }) => <ChevronDownIcon aria-hidden='true' className={cn('size-4', orientation === 'left' && 'rotate-90', orientation === 'right' && '-rotate-90')} />,\n }}\n data-slot='calendar'\n data-testid='spectral-calendar'\n disabled={combinedDisabled.length > 0 ? combinedDisabled : undefined}\n fixedWeeks={fixedWeeks}\n locale={locale}\n showOutsideDays={showOutsideDays}\n />\n )\n}\n\nCalendar.displayName = 'Calendar'\n"],"mappings":";;;;;;;;AAaA,MAAa,YAAY,EAAE,YAAY,UAAU,mBAAmB,MAAM,YAAY,QAAQ,kBAAkB,MAAM,GAAG,YAA2B;CAElJ,MAAM,QAAQ,8BAAc,IAAI,MAAM,EAAE,EAAE,CAAC;CAG3C,MAAM,mBAA8B,CAAC,GAAI,mBAAmB,CAAC,EAAE,QAAQ,OAAO,CAAC,GAAG,EAAE,EAAG,GAAI,MAAM,QAAQ,SAAS,GAAG,WAAW,WAAW,CAAC,SAAS,GAAG,EAAE,CAAE;AAE5J,QACE,oBAAC,WAAD;EACE,GAAI;EACJ,YAAY;GACV,QAAQ,GAAG,uBAAuB;GAClC,OAAO,GAAG,QAAQ;GAClB,SAAS,GAAG,kBAAkB;GAC9B,eAAe,GAAG,cAAc;GAChC,KAAK,GAAG,mCAAmC;GAC3C,YAAY,GAAG,mLAAmL;GAClM,iBAAiB,GAAG,iCAAiC;GACrD,aAAa,GAAG,kCAAkC;GAClD,OAAO,GAAG,+BAA+B;GACzC,UAAU,GAAG,oBAAoB;GACjC,WAAW,GAAG,eAAe;GAC7B,KAAK,GAAG,2BAA2B;GACnC,MAAM,GAAG,WAAW;GACpB,KAAK,GAAG,MAAM;GACd,iBAAiB,GAAG,kBAAkB;GACtC,kBAAkB,GAAG,mBAAmB;GACxC,eAAe,GAAG,gBAAgB;GAClC,cAAc,GAAG,eAAe;GAChC,aAAa,GAAG,cAAc;GAC9B,cAAc,GAAG,eAAe;GAChC,QAAQ,GAAG,SAAS;GACpB,GAAG;GACJ;EACD,YAAY,EACV,UAAU,EAAE,kBAAkB,oBAAC,iBAAD;GAAiB,eAAY;GAAO,WAAW,GAAG,UAAU,gBAAgB,UAAU,aAAa,gBAAgB,WAAW,aAAa;GAAI,GAC9K;EACD,aAAU;EACV,eAAY;EACZ,UAAU,iBAAiB,SAAS,IAAI,mBAAmB;EAC/C;EACJ;EACS;EACjB;;AAIN,SAAS,cAAc"}
|