@fanvue/ui 1.21.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/charts.d.ts +1 -1
- package/dist/cjs/components/Accordion/AccordionContent.cjs +1 -1
- package/dist/cjs/components/Accordion/AccordionContent.cjs.map +1 -1
- package/dist/cjs/components/Accordion/AccordionItem.cjs +1 -1
- package/dist/cjs/components/Accordion/AccordionItem.cjs.map +1 -1
- package/dist/cjs/components/Accordion/AccordionTrigger.cjs +5 -5
- package/dist/cjs/components/Accordion/AccordionTrigger.cjs.map +1 -1
- package/dist/cjs/components/Alert/Alert.cjs +11 -11
- package/dist/cjs/components/Alert/Alert.cjs.map +1 -1
- package/dist/cjs/components/AudioUpload/AudioUpload.cjs +12 -12
- package/dist/cjs/components/AudioUpload/AudioUpload.cjs.map +1 -1
- package/dist/cjs/components/AudioUpload/AudioWaveform.cjs +1 -1
- package/dist/cjs/components/AudioUpload/AudioWaveform.cjs.map +1 -1
- package/dist/cjs/components/Autocomplete/Autocomplete.cjs +12 -12
- package/dist/cjs/components/Autocomplete/Autocomplete.cjs.map +1 -1
- package/dist/cjs/components/Autocomplete/AutocompleteDropdownContent.cjs +3 -3
- package/dist/cjs/components/Autocomplete/AutocompleteDropdownContent.cjs.map +1 -1
- package/dist/cjs/components/Autocomplete/AutocompleteOptionItem.cjs +3 -3
- package/dist/cjs/components/Autocomplete/AutocompleteOptionItem.cjs.map +1 -1
- package/dist/cjs/components/Autocomplete/AutocompleteTag.cjs +2 -2
- package/dist/cjs/components/Autocomplete/AutocompleteTag.cjs.map +1 -1
- package/dist/cjs/components/Avatar/Avatar.cjs +3 -3
- package/dist/cjs/components/Avatar/Avatar.cjs.map +1 -1
- package/dist/cjs/components/Badge/Badge.cjs +23 -23
- package/dist/cjs/components/Badge/Badge.cjs.map +1 -1
- package/dist/cjs/components/Banner/Banner.cjs +4 -4
- package/dist/cjs/components/Banner/Banner.cjs.map +1 -1
- package/dist/cjs/components/BottomNavigation/BottomNavigation.cjs +1 -1
- package/dist/cjs/components/BottomNavigation/BottomNavigation.cjs.map +1 -1
- package/dist/cjs/components/BottomNavigation/BottomNavigationAction.cjs +2 -2
- package/dist/cjs/components/BottomNavigation/BottomNavigationAction.cjs.map +1 -1
- package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs +3 -3
- package/dist/cjs/components/Breadcrumb/Breadcrumb.cjs.map +1 -1
- package/dist/cjs/components/Button/Button.cjs +10 -10
- package/dist/cjs/components/Button/Button.cjs.map +1 -1
- package/dist/cjs/components/Card/Card.cjs +6 -6
- package/dist/cjs/components/Card/Card.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartCard.cjs +6 -6
- package/dist/cjs/components/Chart/ChartCard.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartCenterLabel.cjs +2 -2
- package/dist/cjs/components/Chart/ChartCenterLabel.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartContainer.cjs +7 -7
- package/dist/cjs/components/Chart/ChartContainer.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartLegend.cjs +1 -1
- package/dist/cjs/components/Chart/ChartLegend.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartLoadingOverlay.cjs +1 -1
- package/dist/cjs/components/Chart/ChartLoadingOverlay.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartPieLegend.cjs +2 -2
- package/dist/cjs/components/Chart/ChartPieLegend.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartSeriesToggle.cjs +2 -2
- package/dist/cjs/components/Chart/ChartSeriesToggle.cjs.map +1 -1
- package/dist/cjs/components/Chart/ChartTooltip.cjs +4 -4
- package/dist/cjs/components/Chart/ChartTooltip.cjs.map +1 -1
- package/dist/cjs/components/Checkbox/Checkbox.cjs +13 -13
- package/dist/cjs/components/Checkbox/Checkbox.cjs.map +1 -1
- package/dist/cjs/components/Chip/Chip.cjs +7 -7
- package/dist/cjs/components/Chip/Chip.cjs.map +1 -1
- package/dist/cjs/components/Count/Count.cjs +7 -7
- package/dist/cjs/components/Count/Count.cjs.map +1 -1
- package/dist/cjs/components/DatePicker/DatePicker.cjs +14 -14
- package/dist/cjs/components/DatePicker/DatePicker.cjs.map +1 -1
- package/dist/cjs/components/Dialog/Dialog.cjs +6 -6
- package/dist/cjs/components/Dialog/Dialog.cjs.map +1 -1
- package/dist/cjs/components/Divider/Divider.cjs +4 -4
- package/dist/cjs/components/Divider/Divider.cjs.map +1 -1
- package/dist/cjs/components/Drawer/Drawer.cjs +5 -5
- package/dist/cjs/components/Drawer/Drawer.cjs.map +1 -1
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs +6 -6
- package/dist/cjs/components/DropdownMenu/DropdownMenu.cjs.map +1 -1
- package/dist/cjs/components/IconButton/IconButton.cjs +10 -10
- package/dist/cjs/components/IconButton/IconButton.cjs.map +1 -1
- package/dist/cjs/components/Icons/LockerOffIcon.cjs +1 -1
- package/dist/cjs/components/Icons/LockerOffIcon.cjs.map +1 -1
- package/dist/cjs/components/Icons/LockerOnIcon.cjs +1 -1
- package/dist/cjs/components/Icons/LockerOnIcon.cjs.map +1 -1
- package/dist/cjs/components/InfoBox/InfoBox.cjs +6 -6
- package/dist/cjs/components/InfoBox/InfoBox.cjs.map +1 -1
- package/dist/cjs/components/Loader/Loader.cjs +1 -1
- package/dist/cjs/components/Loader/Loader.cjs.map +1 -1
- package/dist/cjs/components/Logo/Logo.cjs +13 -13
- package/dist/cjs/components/Logo/Logo.cjs.map +1 -1
- package/dist/cjs/components/MobileStepper/MobileStepper.cjs +2 -2
- package/dist/cjs/components/MobileStepper/MobileStepper.cjs.map +1 -1
- package/dist/cjs/components/OnlineBlinkingIcon/OnlineBlinkingIcon.cjs +2 -2
- package/dist/cjs/components/OnlineBlinkingIcon/OnlineBlinkingIcon.cjs.map +1 -1
- package/dist/cjs/components/Pagination/Pagination.cjs +3 -3
- package/dist/cjs/components/Pagination/Pagination.cjs.map +1 -1
- package/dist/cjs/components/PasswordField/PasswordField.cjs +1 -1
- package/dist/cjs/components/PasswordField/PasswordField.cjs.map +1 -1
- package/dist/cjs/components/Pill/Pill.cjs +10 -10
- package/dist/cjs/components/Pill/Pill.cjs.map +1 -1
- package/dist/cjs/components/ProgressBar/ProgressBar.cjs +13 -13
- package/dist/cjs/components/ProgressBar/ProgressBar.cjs.map +1 -1
- package/dist/cjs/components/Radio/Radio.cjs +4 -4
- package/dist/cjs/components/Radio/Radio.cjs.map +1 -1
- package/dist/cjs/components/Select/Select.cjs +13 -13
- package/dist/cjs/components/Select/Select.cjs.map +1 -1
- package/dist/cjs/components/Skeleton/Skeleton.cjs +2 -2
- package/dist/cjs/components/Skeleton/Skeleton.cjs.map +1 -1
- package/dist/cjs/components/Slider/Slider.cjs +1 -1
- package/dist/cjs/components/Slider/Slider.cjs.map +1 -1
- package/dist/cjs/components/Slider/SliderLayout.cjs +5 -12
- package/dist/cjs/components/Slider/SliderLayout.cjs.map +1 -1
- package/dist/cjs/components/Slider/SliderThumb.cjs +6 -6
- package/dist/cjs/components/Slider/SliderThumb.cjs.map +1 -1
- package/dist/cjs/components/Snackbar/Snackbar.cjs +9 -9
- package/dist/cjs/components/Snackbar/Snackbar.cjs.map +1 -1
- package/dist/cjs/components/Switch/Switch.cjs +3 -3
- package/dist/cjs/components/Switch/Switch.cjs.map +1 -1
- package/dist/cjs/components/SwitchField/SwitchField.cjs +5 -5
- package/dist/cjs/components/SwitchField/SwitchField.cjs.map +1 -1
- package/dist/cjs/components/SwitchToggle/SwitchToggle.cjs +4 -4
- package/dist/cjs/components/SwitchToggle/SwitchToggle.cjs.map +1 -1
- package/dist/cjs/components/Tabs/TabsList.cjs +3 -3
- package/dist/cjs/components/Tabs/TabsList.cjs.map +1 -1
- package/dist/cjs/components/Tabs/TabsTrigger.cjs +8 -8
- package/dist/cjs/components/Tabs/TabsTrigger.cjs.map +1 -1
- package/dist/cjs/components/TextArea/TextArea.cjs +7 -7
- package/dist/cjs/components/TextArea/TextArea.cjs.map +1 -1
- package/dist/cjs/components/TextField/TextField.cjs +11 -11
- package/dist/cjs/components/TextField/TextField.cjs.map +1 -1
- package/dist/cjs/components/Toast/Toast.cjs +7 -7
- package/dist/cjs/components/Toast/Toast.cjs.map +1 -1
- package/dist/cjs/components/Tooltip/Tooltip.cjs +1 -1
- package/dist/cjs/components/Tooltip/Tooltip.cjs.map +1 -1
- package/dist/components/Accordion/AccordionContent.mjs +1 -1
- package/dist/components/Accordion/AccordionContent.mjs.map +1 -1
- package/dist/components/Accordion/AccordionItem.mjs +1 -1
- package/dist/components/Accordion/AccordionItem.mjs.map +1 -1
- package/dist/components/Accordion/AccordionTrigger.mjs +5 -5
- package/dist/components/Accordion/AccordionTrigger.mjs.map +1 -1
- package/dist/components/Alert/Alert.mjs +11 -11
- package/dist/components/Alert/Alert.mjs.map +1 -1
- package/dist/components/AudioUpload/AudioUpload.mjs +12 -12
- package/dist/components/AudioUpload/AudioUpload.mjs.map +1 -1
- package/dist/components/AudioUpload/AudioWaveform.mjs +1 -1
- package/dist/components/AudioUpload/AudioWaveform.mjs.map +1 -1
- package/dist/components/Autocomplete/Autocomplete.mjs +12 -12
- package/dist/components/Autocomplete/Autocomplete.mjs.map +1 -1
- package/dist/components/Autocomplete/AutocompleteDropdownContent.mjs +3 -3
- package/dist/components/Autocomplete/AutocompleteDropdownContent.mjs.map +1 -1
- package/dist/components/Autocomplete/AutocompleteOptionItem.mjs +3 -3
- package/dist/components/Autocomplete/AutocompleteOptionItem.mjs.map +1 -1
- package/dist/components/Autocomplete/AutocompleteTag.mjs +2 -2
- package/dist/components/Autocomplete/AutocompleteTag.mjs.map +1 -1
- package/dist/components/Avatar/Avatar.mjs +3 -3
- package/dist/components/Avatar/Avatar.mjs.map +1 -1
- package/dist/components/Badge/Badge.mjs +23 -23
- package/dist/components/Badge/Badge.mjs.map +1 -1
- package/dist/components/Banner/Banner.mjs +4 -4
- package/dist/components/Banner/Banner.mjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.mjs +1 -1
- package/dist/components/BottomNavigation/BottomNavigation.mjs.map +1 -1
- package/dist/components/BottomNavigation/BottomNavigationAction.mjs +2 -2
- package/dist/components/BottomNavigation/BottomNavigationAction.mjs.map +1 -1
- package/dist/components/Breadcrumb/Breadcrumb.mjs +3 -3
- package/dist/components/Breadcrumb/Breadcrumb.mjs.map +1 -1
- package/dist/components/Button/Button.mjs +10 -10
- package/dist/components/Button/Button.mjs.map +1 -1
- package/dist/components/Card/Card.mjs +6 -6
- package/dist/components/Card/Card.mjs.map +1 -1
- package/dist/components/Chart/ChartCard.mjs +6 -6
- package/dist/components/Chart/ChartCard.mjs.map +1 -1
- package/dist/components/Chart/ChartCenterLabel.mjs +2 -2
- package/dist/components/Chart/ChartCenterLabel.mjs.map +1 -1
- package/dist/components/Chart/ChartContainer.mjs +7 -7
- package/dist/components/Chart/ChartContainer.mjs.map +1 -1
- package/dist/components/Chart/ChartLegend.mjs +1 -1
- package/dist/components/Chart/ChartLegend.mjs.map +1 -1
- package/dist/components/Chart/ChartLoadingOverlay.mjs +1 -1
- package/dist/components/Chart/ChartLoadingOverlay.mjs.map +1 -1
- package/dist/components/Chart/ChartPieLegend.mjs +2 -2
- package/dist/components/Chart/ChartPieLegend.mjs.map +1 -1
- package/dist/components/Chart/ChartSeriesToggle.mjs +2 -2
- package/dist/components/Chart/ChartSeriesToggle.mjs.map +1 -1
- package/dist/components/Chart/ChartTooltip.mjs +4 -4
- package/dist/components/Chart/ChartTooltip.mjs.map +1 -1
- package/dist/components/Checkbox/Checkbox.mjs +13 -13
- package/dist/components/Checkbox/Checkbox.mjs.map +1 -1
- package/dist/components/Chip/Chip.mjs +7 -7
- package/dist/components/Chip/Chip.mjs.map +1 -1
- package/dist/components/Count/Count.mjs +7 -7
- package/dist/components/Count/Count.mjs.map +1 -1
- package/dist/components/DatePicker/DatePicker.mjs +14 -14
- package/dist/components/DatePicker/DatePicker.mjs.map +1 -1
- package/dist/components/Dialog/Dialog.mjs +6 -6
- package/dist/components/Dialog/Dialog.mjs.map +1 -1
- package/dist/components/Divider/Divider.mjs +4 -4
- package/dist/components/Divider/Divider.mjs.map +1 -1
- package/dist/components/Drawer/Drawer.mjs +5 -5
- package/dist/components/Drawer/Drawer.mjs.map +1 -1
- package/dist/components/DropdownMenu/DropdownMenu.mjs +6 -6
- package/dist/components/DropdownMenu/DropdownMenu.mjs.map +1 -1
- package/dist/components/IconButton/IconButton.mjs +10 -10
- package/dist/components/IconButton/IconButton.mjs.map +1 -1
- package/dist/components/Icons/LockerOffIcon.mjs +1 -1
- package/dist/components/Icons/LockerOffIcon.mjs.map +1 -1
- package/dist/components/Icons/LockerOnIcon.mjs +1 -1
- package/dist/components/Icons/LockerOnIcon.mjs.map +1 -1
- package/dist/components/InfoBox/InfoBox.mjs +6 -6
- package/dist/components/InfoBox/InfoBox.mjs.map +1 -1
- package/dist/components/Loader/Loader.mjs +1 -1
- package/dist/components/Loader/Loader.mjs.map +1 -1
- package/dist/components/Logo/Logo.mjs +13 -13
- package/dist/components/Logo/Logo.mjs.map +1 -1
- package/dist/components/MobileStepper/MobileStepper.mjs +2 -2
- package/dist/components/MobileStepper/MobileStepper.mjs.map +1 -1
- package/dist/components/OnlineBlinkingIcon/OnlineBlinkingIcon.mjs +2 -2
- package/dist/components/OnlineBlinkingIcon/OnlineBlinkingIcon.mjs.map +1 -1
- package/dist/components/Pagination/Pagination.mjs +3 -3
- package/dist/components/Pagination/Pagination.mjs.map +1 -1
- package/dist/components/PasswordField/PasswordField.mjs +1 -1
- package/dist/components/PasswordField/PasswordField.mjs.map +1 -1
- package/dist/components/Pill/Pill.mjs +10 -10
- package/dist/components/Pill/Pill.mjs.map +1 -1
- package/dist/components/ProgressBar/ProgressBar.mjs +13 -13
- package/dist/components/ProgressBar/ProgressBar.mjs.map +1 -1
- package/dist/components/Radio/Radio.mjs +4 -4
- package/dist/components/Radio/Radio.mjs.map +1 -1
- package/dist/components/Select/Select.mjs +13 -13
- package/dist/components/Select/Select.mjs.map +1 -1
- package/dist/components/Skeleton/Skeleton.mjs +2 -2
- package/dist/components/Skeleton/Skeleton.mjs.map +1 -1
- package/dist/components/Slider/Slider.mjs +1 -1
- package/dist/components/Slider/Slider.mjs.map +1 -1
- package/dist/components/Slider/SliderLayout.mjs +5 -12
- package/dist/components/Slider/SliderLayout.mjs.map +1 -1
- package/dist/components/Slider/SliderThumb.mjs +6 -6
- package/dist/components/Slider/SliderThumb.mjs.map +1 -1
- package/dist/components/Snackbar/Snackbar.mjs +9 -9
- package/dist/components/Snackbar/Snackbar.mjs.map +1 -1
- package/dist/components/Switch/Switch.mjs +3 -3
- package/dist/components/Switch/Switch.mjs.map +1 -1
- package/dist/components/SwitchField/SwitchField.mjs +5 -5
- package/dist/components/SwitchField/SwitchField.mjs.map +1 -1
- package/dist/components/SwitchToggle/SwitchToggle.mjs +4 -4
- package/dist/components/SwitchToggle/SwitchToggle.mjs.map +1 -1
- package/dist/components/Tabs/TabsList.mjs +3 -3
- package/dist/components/Tabs/TabsList.mjs.map +1 -1
- package/dist/components/Tabs/TabsTrigger.mjs +8 -8
- package/dist/components/Tabs/TabsTrigger.mjs.map +1 -1
- package/dist/components/TextArea/TextArea.mjs +7 -7
- package/dist/components/TextArea/TextArea.mjs.map +1 -1
- package/dist/components/TextField/TextField.mjs +11 -11
- package/dist/components/TextField/TextField.mjs.map +1 -1
- package/dist/components/Toast/Toast.mjs +7 -7
- package/dist/components/Toast/Toast.mjs.map +1 -1
- package/dist/components/Tooltip/Tooltip.mjs +1 -1
- package/dist/components/Tooltip/Tooltip.mjs.map +1 -1
- package/dist/styles/theme.css +378 -253
- package/package.json +1 -1
|
@@ -62,7 +62,7 @@ const Select = React.forwardRef(
|
|
|
62
62
|
"label",
|
|
63
63
|
{
|
|
64
64
|
htmlFor: triggerId,
|
|
65
|
-
className: "typography-semibold-body-sm px-1 pt-1 pb-2 text-
|
|
65
|
+
className: "typography-semibold-body-sm px-1 pt-1 pb-2 text-content-primary",
|
|
66
66
|
children: label
|
|
67
67
|
}
|
|
68
68
|
),
|
|
@@ -77,13 +77,13 @@ const Select = React.forwardRef(
|
|
|
77
77
|
"aria-describedby": bottomText ? helperTextId : void 0,
|
|
78
78
|
"aria-invalid": error || void 0,
|
|
79
79
|
className: cn(
|
|
80
|
-
"flex w-full cursor-pointer items-center justify-between rounded-
|
|
80
|
+
"flex w-full cursor-pointer items-center justify-between rounded-sm border bg-neutral-alphas-50 outline-none motion-safe:transition-colors",
|
|
81
81
|
TRIGGER_HEIGHT[size],
|
|
82
82
|
TRIGGER_PADDING_X[size],
|
|
83
83
|
TRIGGER_GAP[size],
|
|
84
84
|
TRIGGER_TYPOGRAPHY[size],
|
|
85
|
-
error ? "border-error-
|
|
86
|
-
!disabled && !error && "hover:border-neutral-400 data-[state=open]:border-neutral-400",
|
|
85
|
+
error ? "border-error-content" : "border-transparent",
|
|
86
|
+
!disabled && !error && "hover:border-neutral-alphas-400 data-[state=open]:border-neutral-alphas-400",
|
|
87
87
|
disabled && "cursor-not-allowed opacity-50"
|
|
88
88
|
),
|
|
89
89
|
children: [
|
|
@@ -91,12 +91,12 @@ const Select = React.forwardRef(
|
|
|
91
91
|
leftIcon && /* @__PURE__ */ jsx(
|
|
92
92
|
"span",
|
|
93
93
|
{
|
|
94
|
-
className: "flex size-5 shrink-0 items-center justify-center text-
|
|
94
|
+
className: "flex size-5 shrink-0 items-center justify-center text-content-secondary",
|
|
95
95
|
"data-testid": "left-icon",
|
|
96
96
|
children: leftIcon
|
|
97
97
|
}
|
|
98
98
|
),
|
|
99
|
-
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left text-
|
|
99
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left text-content-primary [&>[data-placeholder]]:text-content-secondary [&>[data-placeholder]]:opacity-40", children: /* @__PURE__ */ jsx(SelectPrimitive.Value, { placeholder }) })
|
|
100
100
|
] }),
|
|
101
101
|
/* @__PURE__ */ jsx(SelectPrimitive.Icon, { asChild: true, children: /* @__PURE__ */ jsx(ChevronDownIcon, {}) })
|
|
102
102
|
]
|
|
@@ -110,7 +110,7 @@ const Select = React.forwardRef(
|
|
|
110
110
|
id: helperTextId,
|
|
111
111
|
className: cn(
|
|
112
112
|
"typography-regular-body-sm px-2 pt-1 pb-0.5",
|
|
113
|
-
error ? "text-error-
|
|
113
|
+
error ? "text-error-content" : "text-content-secondary"
|
|
114
114
|
),
|
|
115
115
|
children: bottomText
|
|
116
116
|
}
|
|
@@ -130,7 +130,7 @@ const SelectContent = React.forwardRef(({ className, children, position = "poppe
|
|
|
130
130
|
collisionPadding: 8,
|
|
131
131
|
style: { zIndex: "var(--fanvue-ui-portal-z-index, 50)", ...style },
|
|
132
132
|
className: cn(
|
|
133
|
-
"relative min-w-(--radix-select-trigger-width) overflow-hidden rounded-
|
|
133
|
+
"relative min-w-(--radix-select-trigger-width) overflow-hidden rounded-sm border border-neutral-alphas-200 bg-bg-primary text-content-primary shadow-[0_4px_16px_rgba(0,0,0,0.10)]",
|
|
134
134
|
"data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
135
135
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
136
136
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
|
|
@@ -147,14 +147,14 @@ const SelectItem = React.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
147
147
|
{
|
|
148
148
|
ref,
|
|
149
149
|
className: cn(
|
|
150
|
-
"typography-regular-body-lg relative flex w-full cursor-pointer select-none items-center gap-2 rounded-
|
|
151
|
-
"focus:bg-neutral-100 data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
150
|
+
"typography-regular-body-lg relative flex w-full cursor-pointer select-none items-center gap-2 rounded-xs py-2 pr-2 pl-3 text-content-primary outline-none",
|
|
151
|
+
"focus:bg-neutral-alphas-100 data-disabled:pointer-events-none data-disabled:opacity-50",
|
|
152
152
|
className
|
|
153
153
|
),
|
|
154
154
|
...props,
|
|
155
155
|
children: [
|
|
156
156
|
/* @__PURE__ */ jsx(SelectPrimitive.ItemText, { children }),
|
|
157
|
-
/* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { className: "ml-auto flex size-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4 text-
|
|
157
|
+
/* @__PURE__ */ jsx(SelectPrimitive.ItemIndicator, { className: "ml-auto flex size-4 shrink-0 items-center justify-center", children: /* @__PURE__ */ jsx(CheckIcon, { className: "size-4 text-content-primary" }) })
|
|
158
158
|
]
|
|
159
159
|
}
|
|
160
160
|
));
|
|
@@ -165,7 +165,7 @@ const SelectLabel = React.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
165
165
|
SelectPrimitive.Label,
|
|
166
166
|
{
|
|
167
167
|
ref,
|
|
168
|
-
className: cn("typography-semibold-body-sm px-3 py-1.5 text-
|
|
168
|
+
className: cn("typography-semibold-body-sm px-3 py-1.5 text-content-secondary", className),
|
|
169
169
|
...props
|
|
170
170
|
}
|
|
171
171
|
));
|
|
@@ -174,7 +174,7 @@ const SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
174
174
|
SelectPrimitive.Separator,
|
|
175
175
|
{
|
|
176
176
|
ref,
|
|
177
|
-
className: cn("-mx-1 my-1 h-px bg-neutral-200", className),
|
|
177
|
+
className: cn("-mx-1 my-1 h-px bg-neutral-alphas-200", className),
|
|
178
178
|
...props
|
|
179
179
|
}
|
|
180
180
|
));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.mjs","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["import * as SelectPrimitive from \"@radix-ui/react-select\";\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { CheckIcon } from \"../Icons/CheckIcon\";\nimport { ChevronDownIcon } from \"../Icons/ChevronDownIcon\";\n\n/** Select field height in pixels. */\nexport type SelectSize = \"48\" | \"40\" | \"32\";\n\ntype SelectContextValue = {\n size: SelectSize;\n error: boolean;\n disabled?: boolean;\n};\n\nconst SelectContext = React.createContext<SelectContextValue>({\n size: \"48\",\n error: false,\n});\n\nconst TRIGGER_HEIGHT: Record<SelectSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst TRIGGER_PADDING_X: Record<SelectSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nconst TRIGGER_GAP: Record<SelectSize, string> = {\n \"48\": \"gap-3\",\n \"40\": \"gap-3\",\n \"32\": \"gap-2\",\n};\n\nconst TRIGGER_TYPOGRAPHY: Record<SelectSize, string> = {\n \"48\": \"typography-regular-body-lg\",\n \"40\": \"typography-regular-body-lg\",\n \"32\": \"typography-regular-body-md\",\n};\n\nexport interface SelectProps extends Omit<SelectPrimitive.SelectProps, \"dir\"> {\n /** Label text displayed above the trigger. Also used as the accessible name. */\n label?: string;\n /** Accessible name applied directly to the trigger button when no visible `label` is provided. */\n \"aria-label\"?: string;\n /** ID of an external element that labels the trigger button. */\n \"aria-labelledby\"?: string;\n /** Helper text displayed below the trigger. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the select field in pixels. @default \"48\" */\n size?: SelectSize;\n /** Whether the field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the trigger. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Placeholder shown when no value is selected. */\n placeholder?: string;\n /** Icon element displayed at the left side of the trigger. */\n leftIcon?: React.ReactNode;\n /** Whether the field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n /** Wraps the `className` of the outermost container div. */\n className?: string;\n /** HTML `id` applied to the trigger button. Auto-generated if omitted. */\n id?: string;\n}\n\n/**\n * A select field with optional label, helper/error text, and an icon slot,\n * built on Radix UI Select for full accessibility and keyboard navigation.\n *\n * Pair with {@link SelectContent} and {@link SelectItem} to provide options.\n *\n * @example\n * ```tsx\n * <Select label=\"Country\" placeholder=\"Select a country\">\n * <SelectContent>\n * <SelectItem value=\"us\">United States</SelectItem>\n * <SelectItem value=\"uk\">United Kingdom</SelectItem>\n * </SelectContent>\n * </Select>\n * ```\n */\nexport const Select = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n SelectProps\n>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n placeholder,\n leftIcon,\n fullWidth = false,\n className,\n id,\n disabled,\n children,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const triggerId = id ?? generatedId;\n const helperTextId = `${triggerId}-helper`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n return (\n <SelectContext.Provider value={{ size, error, disabled }}>\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={triggerId}\n className=\"typography-semibold-body-sm px-1 pt-1 pb-2 text-foreground-default\"\n >\n {label}\n </label>\n )}\n\n <SelectPrimitive.Root disabled={disabled} {...props}>\n <SelectPrimitive.Trigger\n ref={ref}\n id={triggerId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-describedby={bottomText ? helperTextId : undefined}\n aria-invalid={error || undefined}\n className={cn(\n \"flex w-full cursor-pointer items-center justify-between rounded-xl border bg-neutral-100 outline-none motion-safe:transition-colors\",\n TRIGGER_HEIGHT[size],\n TRIGGER_PADDING_X[size],\n TRIGGER_GAP[size],\n TRIGGER_TYPOGRAPHY[size],\n error ? \"border-error-default\" : \"border-transparent\",\n !disabled &&\n !error &&\n \"hover:border-neutral-400 data-[state=open]:border-neutral-400\",\n disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n {leftIcon && (\n <span\n className=\"flex size-5 shrink-0 items-center justify-center text-foreground-secondary\"\n data-testid=\"left-icon\"\n >\n {leftIcon}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-left text-foreground-default [&>[data-placeholder]]:text-foreground-secondary [&>[data-placeholder]]:opacity-40\">\n <SelectPrimitive.Value placeholder={placeholder} />\n </span>\n </div>\n\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n\n {children}\n </SelectPrimitive.Root>\n\n {bottomText && (\n <p\n id={helperTextId}\n className={cn(\n \"typography-regular-body-sm px-2 pt-1 pb-0.5\",\n error ? \"text-error-default\" : \"text-foreground-secondary\",\n )}\n >\n {bottomText}\n </p>\n )}\n </div>\n </SelectContext.Provider>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n\nexport interface SelectContentProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> {}\n\n/**\n * The dropdown panel rendered inside a portal. Place {@link SelectItem} elements\n * (and optionally {@link SelectGroup} / {@link SelectLabel}) as children.\n */\nexport const SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n SelectContentProps\n>(({ className, children, position = \"popper\", sideOffset = 4, style, ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n position={position}\n sideOffset={sideOffset}\n collisionPadding={8}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...style }}\n className={cn(\n \"relative min-w-(--radix-select-trigger-width) overflow-hidden rounded-xl border border-neutral-200 bg-surface-page text-foreground-default shadow-[0_4px_16px_rgba(0,0,0,0.10)]\",\n \"data-[state=closed]:animate-out data-[state=open]:animate-in\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n >\n <SelectPrimitive.Viewport className=\"max-h-[var(--radix-select-content-available-height)] overflow-y-auto p-1\">\n {children}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\n\nSelectContent.displayName = \"SelectContent\";\n\nexport interface SelectItemProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> {}\n\n/**\n * An individual option inside {@link SelectContent}.\n */\nexport const SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n SelectItemProps\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"typography-regular-body-lg relative flex w-full cursor-pointer select-none items-center gap-2 rounded-lg py-2 pr-2 pl-3 text-foreground-default outline-none\",\n \"focus:bg-neutral-100 data-disabled:pointer-events-none data-disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n <SelectPrimitive.ItemIndicator className=\"ml-auto flex size-4 shrink-0 items-center justify-center\">\n <CheckIcon className=\"size-4 text-foreground-default\" />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n));\n\nSelectItem.displayName = \"SelectItem\";\n\n/** Props for {@link SelectGroup}. */\nexport type SelectGroupProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Group>;\n\n/**\n * Groups related {@link SelectItem} elements under a {@link SelectLabel}.\n */\nexport const SelectGroup = SelectPrimitive.Group;\nSelectGroup.displayName = \"SelectGroup\";\n\nexport interface SelectLabelProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label> {}\n\n/**\n * A non-interactive label shown above a {@link SelectGroup}.\n */\nexport const SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n SelectLabelProps\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"typography-semibold-body-sm px-3 py-1.5 text-foreground-secondary\", className)}\n {...props}\n />\n));\n\nSelectLabel.displayName = \"SelectLabel\";\n\nexport interface SelectSeparatorProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator> {}\n\n/** A horizontal rule that visually separates groups in {@link SelectContent}. */\nexport const SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n SelectSeparatorProps\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-neutral-200\", className)}\n {...props}\n />\n));\n\nSelectSeparator.displayName = \"SelectSeparator\";\n"],"names":[],"mappings":";;;;;;;AAeA,MAAM,gBAAgB,MAAM,cAAkC;AAAA,EAC5D,MAAM;AAAA,EACN,OAAO;AACT,CAAC;AAED,MAAM,iBAA6C;AAAA,EACjD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAEA,MAAM,oBAAgD;AAAA,EACpD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAEA,MAAM,cAA0C;AAAA,EAC9C,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AAEA,MAAM,qBAAiD;AAAA,EACrD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AACR;AA6CO,MAAM,SAAS,MAAM;AAAA,EAI1B,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,cAAc,MAAM,MAAA;AAC1B,UAAM,YAAY,MAAM;AACxB,UAAM,eAAe,GAAG,SAAS;AACjC,UAAM,aAAa,SAAS,eAAe,eAAe;AAE1D,WACE,oBAAC,cAAc,UAAd,EAAuB,OAAO,EAAE,MAAM,OAAO,YAC5C,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW,GAAG,iBAAiB,aAAa,UAAU,SAAS;AAAA,QAC/D,iBAAe,WAAW,KAAK;AAAA,QAC/B,cAAY,QAAQ,KAAK;AAAA,QAExB,UAAA;AAAA,UAAA,SACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,SAAS;AAAA,cACT,WAAU;AAAA,cAET,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,+BAIJ,gBAAgB,MAAhB,EAAqB,UAAqB,GAAG,OAC5C,UAAA;AAAA,YAAA;AAAA,cAAC,gBAAgB;AAAA,cAAhB;AAAA,gBACC;AAAA,gBACA,IAAI;AAAA,gBACJ,cAAY;AAAA,gBACZ,mBAAiB;AAAA,gBACjB,oBAAkB,aAAa,eAAe;AAAA,gBAC9C,gBAAc,SAAS;AAAA,gBACvB,WAAW;AAAA,kBACT;AAAA,kBACA,eAAe,IAAI;AAAA,kBACnB,kBAAkB,IAAI;AAAA,kBACtB,YAAY,IAAI;AAAA,kBAChB,mBAAmB,IAAI;AAAA,kBACvB,QAAQ,yBAAyB;AAAA,kBACjC,CAAC,YACC,CAAC,SACD;AAAA,kBACF,YAAY;AAAA,gBAAA;AAAA,gBAGd,UAAA;AAAA,kBAAA,qBAAC,OAAA,EAAI,WAAU,mCACZ,UAAA;AAAA,oBAAA,YACC;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,WAAU;AAAA,wBACV,eAAY;AAAA,wBAEX,UAAA;AAAA,sBAAA;AAAA,oBAAA;AAAA,oBAGL,oBAAC,UAAK,WAAU,gJACd,8BAAC,gBAAgB,OAAhB,EAAsB,YAAA,CAA0B,EAAA,CACnD;AAAA,kBAAA,GACF;AAAA,kBAEA,oBAAC,gBAAgB,MAAhB,EAAqB,SAAO,MAC3B,UAAA,oBAAC,mBAAgB,EAAA,CACnB;AAAA,gBAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAGD;AAAA,UAAA,GACH;AAAA,UAEC,cACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,WAAW;AAAA,gBACT;AAAA,gBACA,QAAQ,uBAAuB;AAAA,cAAA;AAAA,cAGhC,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA,GAGN;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;AASd,MAAM,gBAAgB,MAAM,WAGjC,CAAC,EAAE,WAAW,UAAU,WAAW,UAAU,aAAa,GAAG,OAAO,GAAG,MAAA,GAAS,QAChF,oBAAC,gBAAgB,QAAhB,EACC,UAAA;AAAA,EAAC,gBAAgB;AAAA,EAAhB;AAAA,IACC;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,OAAO,EAAE,QAAQ,uCAAuC,GAAG,MAAA;AAAA,IAC3D,WAAW;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,IAEJ,8BAAC,gBAAgB,UAAhB,EAAyB,WAAU,4EACjC,SAAA,CACH;AAAA,EAAA;AACF,GACF,CACD;AAED,cAAc,cAAc;AAQrB,MAAM,aAAa,MAAM,WAG9B,CAAC,EAAE,WAAW,UAAU,GAAG,SAAS,QACpC;AAAA,EAAC,gBAAgB;AAAA,EAAhB;AAAA,IACC;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,IAED,GAAG;AAAA,IAEJ,UAAA;AAAA,MAAA,oBAAC,gBAAgB,UAAhB,EAA0B,SAAA,CAAS;AAAA,MACpC,oBAAC,gBAAgB,eAAhB,EAA8B,WAAU,4DACvC,UAAA,oBAAC,WAAA,EAAU,WAAU,iCAAA,CAAiC,EAAA,CACxD;AAAA,IAAA;AAAA,EAAA;AACF,CACD;AAED,WAAW,cAAc;AAQlB,MAAM,cAAc,gBAAgB;AAC3C,YAAY,cAAc;AAQnB,MAAM,cAAc,MAAM,WAG/B,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAC1B;AAAA,EAAC,gBAAgB;AAAA,EAAhB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,qEAAqE,SAAS;AAAA,IAC3F,GAAG;AAAA,EAAA;AACN,CACD;AAED,YAAY,cAAc;AAMnB,MAAM,kBAAkB,MAAM,WAGnC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QAC1B;AAAA,EAAC,gBAAgB;AAAA,EAAhB;AAAA,IACC;AAAA,IACA,WAAW,GAAG,kCAAkC,SAAS;AAAA,IACxD,GAAG;AAAA,EAAA;AACN,CACD;AAED,gBAAgB,cAAc;"}
|
|
1
|
+
{"version":3,"file":"Select.mjs","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":["import * as SelectPrimitive from \"@radix-ui/react-select\";\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { CheckIcon } from \"../Icons/CheckIcon\";\nimport { ChevronDownIcon } from \"../Icons/ChevronDownIcon\";\n\n/** Select field height in pixels. */\nexport type SelectSize = \"48\" | \"40\" | \"32\";\n\ntype SelectContextValue = {\n size: SelectSize;\n error: boolean;\n disabled?: boolean;\n};\n\nconst SelectContext = React.createContext<SelectContextValue>({\n size: \"48\",\n error: false,\n});\n\nconst TRIGGER_HEIGHT: Record<SelectSize, string> = {\n \"48\": \"h-12\",\n \"40\": \"h-10\",\n \"32\": \"h-8\",\n};\n\nconst TRIGGER_PADDING_X: Record<SelectSize, string> = {\n \"48\": \"px-4\",\n \"40\": \"px-4\",\n \"32\": \"px-3\",\n};\n\nconst TRIGGER_GAP: Record<SelectSize, string> = {\n \"48\": \"gap-3\",\n \"40\": \"gap-3\",\n \"32\": \"gap-2\",\n};\n\nconst TRIGGER_TYPOGRAPHY: Record<SelectSize, string> = {\n \"48\": \"typography-regular-body-lg\",\n \"40\": \"typography-regular-body-lg\",\n \"32\": \"typography-regular-body-md\",\n};\n\nexport interface SelectProps extends Omit<SelectPrimitive.SelectProps, \"dir\"> {\n /** Label text displayed above the trigger. Also used as the accessible name. */\n label?: string;\n /** Accessible name applied directly to the trigger button when no visible `label` is provided. */\n \"aria-label\"?: string;\n /** ID of an external element that labels the trigger button. */\n \"aria-labelledby\"?: string;\n /** Helper text displayed below the trigger. Replaced by `errorMessage` when `error` is `true`. */\n helperText?: string;\n /** Height of the select field in pixels. @default \"48\" */\n size?: SelectSize;\n /** Whether the field is in an error state. @default false */\n error?: boolean;\n /** Error message displayed below the trigger. Shown instead of `helperText` when `error` is `true`. */\n errorMessage?: string;\n /** Placeholder shown when no value is selected. */\n placeholder?: string;\n /** Icon element displayed at the left side of the trigger. */\n leftIcon?: React.ReactNode;\n /** Whether the field stretches to fill its container width. @default false */\n fullWidth?: boolean;\n /** Wraps the `className` of the outermost container div. */\n className?: string;\n /** HTML `id` applied to the trigger button. Auto-generated if omitted. */\n id?: string;\n}\n\n/**\n * A select field with optional label, helper/error text, and an icon slot,\n * built on Radix UI Select for full accessibility and keyboard navigation.\n *\n * Pair with {@link SelectContent} and {@link SelectItem} to provide options.\n *\n * @example\n * ```tsx\n * <Select label=\"Country\" placeholder=\"Select a country\">\n * <SelectContent>\n * <SelectItem value=\"us\">United States</SelectItem>\n * <SelectItem value=\"uk\">United Kingdom</SelectItem>\n * </SelectContent>\n * </Select>\n * ```\n */\nexport const Select = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Trigger>,\n SelectProps\n>(\n (\n {\n label,\n helperText,\n size = \"48\",\n error = false,\n errorMessage,\n placeholder,\n leftIcon,\n fullWidth = false,\n className,\n id,\n disabled,\n children,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledby,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const triggerId = id ?? generatedId;\n const helperTextId = `${triggerId}-helper`;\n const bottomText = error && errorMessage ? errorMessage : helperText;\n\n return (\n <SelectContext.Provider value={{ size, error, disabled }}>\n <div\n className={cn(\"flex flex-col\", fullWidth && \"w-full\", className)}\n data-disabled={disabled ? \"\" : undefined}\n data-error={error ? \"\" : undefined}\n >\n {label && (\n <label\n htmlFor={triggerId}\n className=\"typography-semibold-body-sm px-1 pt-1 pb-2 text-content-primary\"\n >\n {label}\n </label>\n )}\n\n <SelectPrimitive.Root disabled={disabled} {...props}>\n <SelectPrimitive.Trigger\n ref={ref}\n id={triggerId}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledby}\n aria-describedby={bottomText ? helperTextId : undefined}\n aria-invalid={error || undefined}\n className={cn(\n \"flex w-full cursor-pointer items-center justify-between rounded-sm border bg-neutral-alphas-50 outline-none motion-safe:transition-colors\",\n TRIGGER_HEIGHT[size],\n TRIGGER_PADDING_X[size],\n TRIGGER_GAP[size],\n TRIGGER_TYPOGRAPHY[size],\n error ? \"border-error-content\" : \"border-transparent\",\n !disabled &&\n !error &&\n \"hover:border-neutral-alphas-400 data-[state=open]:border-neutral-alphas-400\",\n disabled && \"cursor-not-allowed opacity-50\",\n )}\n >\n <div className=\"flex min-w-0 items-center gap-2\">\n {leftIcon && (\n <span\n className=\"flex size-5 shrink-0 items-center justify-center text-content-secondary\"\n data-testid=\"left-icon\"\n >\n {leftIcon}\n </span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-left text-content-primary [&>[data-placeholder]]:text-content-secondary [&>[data-placeholder]]:opacity-40\">\n <SelectPrimitive.Value placeholder={placeholder} />\n </span>\n </div>\n\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n\n {children}\n </SelectPrimitive.Root>\n\n {bottomText && (\n <p\n id={helperTextId}\n className={cn(\n \"typography-regular-body-sm px-2 pt-1 pb-0.5\",\n error ? \"text-error-content\" : \"text-content-secondary\",\n )}\n >\n {bottomText}\n </p>\n )}\n </div>\n </SelectContext.Provider>\n );\n },\n);\n\nSelect.displayName = \"Select\";\n\nexport interface SelectContentProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> {}\n\n/**\n * The dropdown panel rendered inside a portal. Place {@link SelectItem} elements\n * (and optionally {@link SelectGroup} / {@link SelectLabel}) as children.\n */\nexport const SelectContent = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Content>,\n SelectContentProps\n>(({ className, children, position = \"popper\", sideOffset = 4, style, ...props }, ref) => (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Content\n ref={ref}\n position={position}\n sideOffset={sideOffset}\n collisionPadding={8}\n style={{ zIndex: \"var(--fanvue-ui-portal-z-index, 50)\", ...style }}\n className={cn(\n \"relative min-w-(--radix-select-trigger-width) overflow-hidden rounded-sm border border-neutral-alphas-200 bg-bg-primary text-content-primary shadow-[0_4px_16px_rgba(0,0,0,0.10)]\",\n \"data-[state=closed]:animate-out data-[state=open]:animate-in\",\n \"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\",\n \"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n \"data-[side=bottom]:slide-in-from-top-2 data-[side=top]:slide-in-from-bottom-2\",\n className,\n )}\n {...props}\n >\n <SelectPrimitive.Viewport className=\"max-h-[var(--radix-select-content-available-height)] overflow-y-auto p-1\">\n {children}\n </SelectPrimitive.Viewport>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n));\n\nSelectContent.displayName = \"SelectContent\";\n\nexport interface SelectItemProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> {}\n\n/**\n * An individual option inside {@link SelectContent}.\n */\nexport const SelectItem = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Item>,\n SelectItemProps\n>(({ className, children, ...props }, ref) => (\n <SelectPrimitive.Item\n ref={ref}\n className={cn(\n \"typography-regular-body-lg relative flex w-full cursor-pointer select-none items-center gap-2 rounded-xs py-2 pr-2 pl-3 text-content-primary outline-none\",\n \"focus:bg-neutral-alphas-100 data-disabled:pointer-events-none data-disabled:opacity-50\",\n className,\n )}\n {...props}\n >\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n <SelectPrimitive.ItemIndicator className=\"ml-auto flex size-4 shrink-0 items-center justify-center\">\n <CheckIcon className=\"size-4 text-content-primary\" />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n));\n\nSelectItem.displayName = \"SelectItem\";\n\n/** Props for {@link SelectGroup}. */\nexport type SelectGroupProps = React.ComponentPropsWithoutRef<typeof SelectPrimitive.Group>;\n\n/**\n * Groups related {@link SelectItem} elements under a {@link SelectLabel}.\n */\nexport const SelectGroup = SelectPrimitive.Group;\nSelectGroup.displayName = \"SelectGroup\";\n\nexport interface SelectLabelProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label> {}\n\n/**\n * A non-interactive label shown above a {@link SelectGroup}.\n */\nexport const SelectLabel = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Label>,\n SelectLabelProps\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Label\n ref={ref}\n className={cn(\"typography-semibold-body-sm px-3 py-1.5 text-content-secondary\", className)}\n {...props}\n />\n));\n\nSelectLabel.displayName = \"SelectLabel\";\n\nexport interface SelectSeparatorProps\n extends React.ComponentPropsWithoutRef<typeof SelectPrimitive.Separator> {}\n\n/** A horizontal rule that visually separates groups in {@link SelectContent}. */\nexport const SelectSeparator = React.forwardRef<\n React.ComponentRef<typeof SelectPrimitive.Separator>,\n SelectSeparatorProps\n>(({ className, ...props }, ref) => (\n <SelectPrimitive.Separator\n ref={ref}\n className={cn(\"-mx-1 my-1 h-px bg-neutral-alphas-200\", className)}\n {...props}\n />\n));\n\nSelectSeparator.displayName = \"SelectSeparator\";\n"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@ const VARIANT_CLASSES = {
|
|
|
6
6
|
text: "rounded my-0.5",
|
|
7
7
|
circular: "rounded-full",
|
|
8
8
|
rectangular: "",
|
|
9
|
-
rounded: "rounded-
|
|
9
|
+
rounded: "rounded-xs"
|
|
10
10
|
};
|
|
11
11
|
const Skeleton = React.forwardRef(
|
|
12
12
|
({ className, variant = "text", animation = "pulse", width, height, style, children, ...props }, ref) => {
|
|
@@ -26,7 +26,7 @@ const Skeleton = React.forwardRef(
|
|
|
26
26
|
ref,
|
|
27
27
|
"aria-hidden": "true",
|
|
28
28
|
className: cn(
|
|
29
|
-
"block bg-[color-mix(in_srgb,var(--color-
|
|
29
|
+
"block bg-[color-mix(in_srgb,var(--color-content-primary)_11%,var(--color-bg-primary))]",
|
|
30
30
|
VARIANT_CLASSES[variant],
|
|
31
31
|
variant === "text" && !height && !hasChildren && "h-[1em]",
|
|
32
32
|
animation === "pulse" && "animate-pulse",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Skeleton.mjs","sources":["../../../src/components/Skeleton/Skeleton.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Shape variant of the skeleton placeholder. */\nexport type SkeletonVariant = \"text\" | \"circular\" | \"rectangular\" | \"rounded\";\n\n/** Animation style of the skeleton. `false` disables animation. */\nexport type SkeletonAnimation = \"pulse\" | \"wave\" | false;\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Shape variant of the skeleton.\n *\n * - `text` – a single line of text with slight vertical margin and rounded ends\n * - `circular` – a circle (width and height should match)\n * - `rectangular` – a sharp-cornered rectangle\n * - `rounded` – a rectangle with rounded corners\n *\n * @default \"text\"\n */\n variant?: SkeletonVariant;\n /** Animation style. Set to `false` to disable animation. @default \"pulse\" */\n animation?: SkeletonAnimation;\n /** Width of the skeleton. Accepts a CSS value (number is treated as `px`). */\n width?: number | string;\n /** Height of the skeleton. Accepts a CSS value (number is treated as `px`). */\n height?: number | string;\n}\n\nconst VARIANT_CLASSES: Record<SkeletonVariant, string> = {\n text: \"rounded my-0.5\",\n circular: \"rounded-full\",\n rectangular: \"\",\n rounded: \"rounded-
|
|
1
|
+
{"version":3,"file":"Skeleton.mjs","sources":["../../../src/components/Skeleton/Skeleton.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Shape variant of the skeleton placeholder. */\nexport type SkeletonVariant = \"text\" | \"circular\" | \"rectangular\" | \"rounded\";\n\n/** Animation style of the skeleton. `false` disables animation. */\nexport type SkeletonAnimation = \"pulse\" | \"wave\" | false;\n\nexport interface SkeletonProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Shape variant of the skeleton.\n *\n * - `text` – a single line of text with slight vertical margin and rounded ends\n * - `circular` – a circle (width and height should match)\n * - `rectangular` – a sharp-cornered rectangle\n * - `rounded` – a rectangle with rounded corners\n *\n * @default \"text\"\n */\n variant?: SkeletonVariant;\n /** Animation style. Set to `false` to disable animation. @default \"pulse\" */\n animation?: SkeletonAnimation;\n /** Width of the skeleton. Accepts a CSS value (number is treated as `px`). */\n width?: number | string;\n /** Height of the skeleton. Accepts a CSS value (number is treated as `px`). */\n height?: number | string;\n}\n\nconst VARIANT_CLASSES: Record<SkeletonVariant, string> = {\n text: \"rounded my-0.5\",\n circular: \"rounded-full\",\n rectangular: \"\",\n rounded: \"rounded-xs\",\n};\n\n/**\n * A placeholder preview of content before data is loaded, reducing perceived\n * load time. Mirrors common MUI Skeleton props for easy migration.\n *\n * When used as a loading state, wrap the skeleton region with `aria-busy=\"true\"`\n * and provide an accessible label so screen readers can convey the loading state.\n *\n * @example\n * ```tsx\n * <Skeleton variant=\"text\" width={200} />\n * <Skeleton variant=\"circular\" width={40} height={40} />\n * <Skeleton variant=\"rectangular\" width=\"100%\" height={120} />\n * ```\n */\nexport const Skeleton = React.forwardRef<HTMLSpanElement, SkeletonProps>(\n (\n { className, variant = \"text\", animation = \"pulse\", width, height, style, children, ...props },\n ref,\n ) => {\n const hasChildren = React.Children.count(children) > 0;\n const sizeStyle: React.CSSProperties = {\n ...style,\n ...(width !== undefined && {\n width: typeof width === \"number\" ? `${width}px` : width,\n }),\n ...(height !== undefined && {\n height: typeof height === \"number\" ? `${height}px` : height,\n }),\n };\n\n return (\n <span\n ref={ref}\n aria-hidden=\"true\"\n className={cn(\n \"block bg-[color-mix(in_srgb,var(--color-content-primary)_11%,var(--color-bg-primary))]\",\n VARIANT_CLASSES[variant],\n variant === \"text\" && !height && !hasChildren && \"h-[1em]\",\n animation === \"pulse\" && \"animate-pulse\",\n animation === \"wave\" && \"fv-skeleton-wave\",\n hasChildren && \"relative overflow-hidden [&>*]:invisible\",\n className,\n )}\n style={sizeStyle}\n {...props}\n >\n {children}\n </span>\n );\n },\n);\n\nSkeleton.displayName = \"Skeleton\";\n"],"names":[],"mappings":";;;;AA4BA,MAAM,kBAAmD;AAAA,EACvD,MAAM;AAAA,EACN,UAAU;AAAA,EACV,aAAa;AAAA,EACb,SAAS;AACX;AAgBO,MAAM,WAAW,MAAM;AAAA,EAC5B,CACE,EAAE,WAAW,UAAU,QAAQ,YAAY,SAAS,OAAO,QAAQ,OAAO,UAAU,GAAG,MAAA,GACvF,QACG;AACH,UAAM,cAAc,MAAM,SAAS,MAAM,QAAQ,IAAI;AACrD,UAAM,YAAiC;AAAA,MACrC,GAAG;AAAA,MACH,GAAI,UAAU,UAAa;AAAA,QACzB,OAAO,OAAO,UAAU,WAAW,GAAG,KAAK,OAAO;AAAA,MAAA;AAAA,MAEpD,GAAI,WAAW,UAAa;AAAA,QAC1B,QAAQ,OAAO,WAAW,WAAW,GAAG,MAAM,OAAO;AAAA,MAAA;AAAA,IACvD;AAGF,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA,eAAY;AAAA,QACZ,WAAW;AAAA,UACT;AAAA,UACA,gBAAgB,OAAO;AAAA,UACvB,YAAY,UAAU,CAAC,UAAU,CAAC,eAAe;AAAA,UACjD,cAAc,WAAW;AAAA,UACzB,cAAc,UAAU;AAAA,UACxB,eAAe;AAAA,UACf;AAAA,QAAA;AAAA,QAEF,OAAO;AAAA,QACN,GAAG;AAAA,QAEH;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,SAAS,cAAc;"}
|
|
@@ -41,7 +41,7 @@ const Slider = React.forwardRef(
|
|
|
41
41
|
),
|
|
42
42
|
...props,
|
|
43
43
|
children: [
|
|
44
|
-
/* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-3 w-full overflow-hidden rounded-full border border-
|
|
44
|
+
/* @__PURE__ */ jsx(SliderPrimitive.Track, { className: "relative h-3 w-full overflow-hidden rounded-full border border-border-primary bg-surface-secondary", children: /* @__PURE__ */ jsx(SliderPrimitive.Range, { className: "absolute h-full rounded-full bg-brand-primary-default" }) }),
|
|
45
45
|
Array.from({ length: thumbCount }, (_, i) => /* @__PURE__ */ jsx(
|
|
46
46
|
SliderThumb,
|
|
47
47
|
{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slider.mjs","sources":["../../../src/components/Slider/Slider.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { SliderLayout } from \"./SliderLayout\";\nimport { SliderThumb } from \"./SliderThumb\";\n\n/** Position of the slider label relative to the track. */\nexport type SliderLabelPosition = \"top\" | \"left\";\n\nexport interface SliderProps\n extends Omit<\n React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>,\n \"asChild\" | \"children\"\n > {\n /** Label text displayed alongside the slider. */\n label?: string;\n /** Position of the label relative to the slider track. @default \"top\" */\n labelPosition?: SliderLabelPosition;\n /** Text shown at the minimum end of the track. */\n minLabel?: string;\n /** Text shown at the maximum end of the track. */\n maxLabel?: string;\n /** Whether to show a tooltip with the current value above the thumb. @default false */\n showTooltip?: boolean;\n /** Custom formatter for the tooltip value (e.g. to add units or format numbers). */\n formatTooltip?: (value: number) => string;\n}\n\n/**\n * A range input for selecting one or more numeric values along a track.\n * Supports single and multi-thumb modes, optional labels, and a value tooltip.\n *\n * Built on Radix UI `Slider`.\n *\n * @example\n * ```tsx\n * <Slider\n * label=\"Volume\"\n * min={0}\n * max={100}\n * defaultValue={[50]}\n * showTooltip\n * />\n * ```\n */\nexport const Slider = React.forwardRef<\n React.ComponentRef<typeof SliderPrimitive.Root>,\n SliderProps\n>(\n (\n {\n className,\n label,\n labelPosition = \"top\",\n minLabel,\n maxLabel,\n showTooltip = false,\n formatTooltip,\n disabled,\n value,\n defaultValue,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...props\n },\n ref,\n ) => {\n const labelId = React.useId();\n const thumbCount = value?.length ?? defaultValue?.length ?? 1;\n const resolvedLabelledBy = ariaLabelledBy ?? (label ? labelId : undefined);\n const resolvedAriaLabel = !resolvedLabelledBy ? ariaLabel : undefined;\n\n const sliderTrack = (\n <SliderPrimitive.Root\n ref={ref}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n aria-label={resolvedAriaLabel}\n aria-labelledby={resolvedLabelledBy}\n className={cn(\n \"group/slider relative flex w-full touch-none select-none items-center\",\n disabled && \"pointer-events-none opacity-50\",\n className,\n )}\n {...props}\n >\n <SliderPrimitive.Track className=\"relative h-3 w-full overflow-hidden rounded-full border border-
|
|
1
|
+
{"version":3,"file":"Slider.mjs","sources":["../../../src/components/Slider/Slider.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { SliderLayout } from \"./SliderLayout\";\nimport { SliderThumb } from \"./SliderThumb\";\n\n/** Position of the slider label relative to the track. */\nexport type SliderLabelPosition = \"top\" | \"left\";\n\nexport interface SliderProps\n extends Omit<\n React.ComponentPropsWithoutRef<typeof SliderPrimitive.Root>,\n \"asChild\" | \"children\"\n > {\n /** Label text displayed alongside the slider. */\n label?: string;\n /** Position of the label relative to the slider track. @default \"top\" */\n labelPosition?: SliderLabelPosition;\n /** Text shown at the minimum end of the track. */\n minLabel?: string;\n /** Text shown at the maximum end of the track. */\n maxLabel?: string;\n /** Whether to show a tooltip with the current value above the thumb. @default false */\n showTooltip?: boolean;\n /** Custom formatter for the tooltip value (e.g. to add units or format numbers). */\n formatTooltip?: (value: number) => string;\n}\n\n/**\n * A range input for selecting one or more numeric values along a track.\n * Supports single and multi-thumb modes, optional labels, and a value tooltip.\n *\n * Built on Radix UI `Slider`.\n *\n * @example\n * ```tsx\n * <Slider\n * label=\"Volume\"\n * min={0}\n * max={100}\n * defaultValue={[50]}\n * showTooltip\n * />\n * ```\n */\nexport const Slider = React.forwardRef<\n React.ComponentRef<typeof SliderPrimitive.Root>,\n SliderProps\n>(\n (\n {\n className,\n label,\n labelPosition = \"top\",\n minLabel,\n maxLabel,\n showTooltip = false,\n formatTooltip,\n disabled,\n value,\n defaultValue,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n ...props\n },\n ref,\n ) => {\n const labelId = React.useId();\n const thumbCount = value?.length ?? defaultValue?.length ?? 1;\n const resolvedLabelledBy = ariaLabelledBy ?? (label ? labelId : undefined);\n const resolvedAriaLabel = !resolvedLabelledBy ? ariaLabel : undefined;\n\n const sliderTrack = (\n <SliderPrimitive.Root\n ref={ref}\n disabled={disabled}\n value={value}\n defaultValue={defaultValue}\n aria-label={resolvedAriaLabel}\n aria-labelledby={resolvedLabelledBy}\n className={cn(\n \"group/slider relative flex w-full touch-none select-none items-center\",\n disabled && \"pointer-events-none opacity-50\",\n className,\n )}\n {...props}\n >\n <SliderPrimitive.Track className=\"relative h-3 w-full overflow-hidden rounded-full border border-border-primary bg-surface-secondary\">\n <SliderPrimitive.Range className=\"absolute h-full rounded-full bg-brand-primary-default\" />\n </SliderPrimitive.Track>\n\n {Array.from({ length: thumbCount }, (_, i) => (\n <SliderThumb\n // biome-ignore lint/suspicious/noArrayIndexKey: thumbs are fixed-count and never reorder\n key={i}\n showTooltip={showTooltip}\n formatTooltip={formatTooltip}\n index={i}\n aria-label={resolvedAriaLabel}\n aria-labelledby={resolvedLabelledBy}\n />\n ))}\n </SliderPrimitive.Root>\n );\n\n const hasLayout = Boolean(label || minLabel || maxLabel);\n\n if (!hasLayout) return sliderTrack;\n\n return (\n <SliderLayout\n label={label}\n labelId={labelId}\n labelPosition={labelPosition}\n minLabel={minLabel}\n maxLabel={maxLabel}\n >\n {sliderTrack}\n </SliderLayout>\n );\n },\n);\n\nSlider.displayName = \"Slider\";\n"],"names":[],"mappings":";;;;;;;AA6CO,MAAM,SAAS,MAAM;AAAA,EAI1B,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,UAAU,MAAM,MAAA;AACtB,UAAM,aAAa,OAAO,UAAU,cAAc,UAAU;AAC5D,UAAM,qBAAqB,mBAAmB,QAAQ,UAAU;AAChE,UAAM,oBAAoB,CAAC,qBAAqB,YAAY;AAE5D,UAAM,cACJ;AAAA,MAAC,gBAAgB;AAAA,MAAhB;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,cAAY;AAAA,QACZ,mBAAiB;AAAA,QACjB,WAAW;AAAA,UACT;AAAA,UACA,YAAY;AAAA,UACZ;AAAA,QAAA;AAAA,QAED,GAAG;AAAA,QAEJ,UAAA;AAAA,UAAA,oBAAC,gBAAgB,OAAhB,EAAsB,WAAU,sGAC/B,UAAA,oBAAC,gBAAgB,OAAhB,EAAsB,WAAU,wDAAA,CAAwD,EAAA,CAC3F;AAAA,UAEC,MAAM,KAAK,EAAE,QAAQ,cAAc,CAAC,GAAG,MACtC;AAAA,YAAC;AAAA,YAAA;AAAA,cAGC;AAAA,cACA;AAAA,cACA,OAAO;AAAA,cACP,cAAY;AAAA,cACZ,mBAAiB;AAAA,YAAA;AAAA,YALZ;AAAA,UAAA,CAOR;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAIL,UAAM,YAAY,QAAQ,SAAS,YAAY,QAAQ;AAEvD,QAAI,CAAC,UAAW,QAAO;AAEvB,WACE;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QAEC,UAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AACF;AAEA,OAAO,cAAc;"}
|
|
@@ -10,22 +10,15 @@ function SliderLayout({
|
|
|
10
10
|
}) {
|
|
11
11
|
if (labelPosition === "left") {
|
|
12
12
|
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
13
|
-
label && /* @__PURE__ */ jsx(
|
|
14
|
-
|
|
15
|
-
{
|
|
16
|
-
id: labelId,
|
|
17
|
-
className: "typography-semibold-body-lg shrink-0 text-foreground-default",
|
|
18
|
-
children: label
|
|
19
|
-
}
|
|
20
|
-
),
|
|
21
|
-
minLabel && /* @__PURE__ */ jsx("span", { className: "typography-regular-body-md shrink-0 text-foreground-secondary", children: minLabel }),
|
|
13
|
+
label && /* @__PURE__ */ jsx("span", { id: labelId, className: "typography-semibold-body-lg shrink-0 text-content-primary", children: label }),
|
|
14
|
+
minLabel && /* @__PURE__ */ jsx("span", { className: "typography-regular-body-md shrink-0 text-content-secondary", children: minLabel }),
|
|
22
15
|
children,
|
|
23
|
-
maxLabel && /* @__PURE__ */ jsx("span", { className: "typography-regular-body-md shrink-0 text-
|
|
16
|
+
maxLabel && /* @__PURE__ */ jsx("span", { className: "typography-regular-body-md shrink-0 text-content-secondary", children: maxLabel })
|
|
24
17
|
] });
|
|
25
18
|
}
|
|
26
19
|
return /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-3", children: [
|
|
27
|
-
label && /* @__PURE__ */ jsx("span", { id: labelId, className: "typography-semibold-body-lg text-
|
|
28
|
-
(minLabel || maxLabel) && /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start justify-between
|
|
20
|
+
label && /* @__PURE__ */ jsx("span", { id: labelId, className: "typography-semibold-body-lg text-content-primary", children: label }),
|
|
21
|
+
(minLabel || maxLabel) && /* @__PURE__ */ jsxs("div", { className: "flex w-full items-start justify-between typography-regular-body-md text-content-secondary", children: [
|
|
29
22
|
minLabel && /* @__PURE__ */ jsx("span", { children: minLabel }),
|
|
30
23
|
maxLabel && /* @__PURE__ */ jsx("span", { className: "ml-auto", children: maxLabel })
|
|
31
24
|
] }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SliderLayout.mjs","sources":["../../../src/components/Slider/SliderLayout.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport type { SliderLabelPosition } from \"./Slider\";\n\ninterface SliderLayoutProps {\n label?: string;\n labelId: string;\n labelPosition: SliderLabelPosition;\n minLabel?: string;\n maxLabel?: string;\n children: React.ReactNode;\n}\n\nexport function SliderLayout({\n label,\n labelId,\n labelPosition,\n minLabel,\n maxLabel,\n children,\n}: SliderLayoutProps) {\n if (labelPosition === \"left\") {\n return (\n <div className=\"flex items-center gap-3\">\n {label && (\n <span
|
|
1
|
+
{"version":3,"file":"SliderLayout.mjs","sources":["../../../src/components/Slider/SliderLayout.tsx"],"sourcesContent":["import type * as React from \"react\";\nimport type { SliderLabelPosition } from \"./Slider\";\n\ninterface SliderLayoutProps {\n label?: string;\n labelId: string;\n labelPosition: SliderLabelPosition;\n minLabel?: string;\n maxLabel?: string;\n children: React.ReactNode;\n}\n\nexport function SliderLayout({\n label,\n labelId,\n labelPosition,\n minLabel,\n maxLabel,\n children,\n}: SliderLayoutProps) {\n if (labelPosition === \"left\") {\n return (\n <div className=\"flex items-center gap-3\">\n {label && (\n <span id={labelId} className=\"typography-semibold-body-lg shrink-0 text-content-primary\">\n {label}\n </span>\n )}\n {minLabel && (\n <span className=\"typography-regular-body-md shrink-0 text-content-secondary\">\n {minLabel}\n </span>\n )}\n {children}\n {maxLabel && (\n <span className=\"typography-regular-body-md shrink-0 text-content-secondary\">\n {maxLabel}\n </span>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"flex w-full flex-col gap-3\">\n {label && (\n <span id={labelId} className=\"typography-semibold-body-lg text-content-primary\">\n {label}\n </span>\n )}\n {(minLabel || maxLabel) && (\n <div className=\"flex w-full items-start justify-between typography-regular-body-md text-content-secondary\">\n {minLabel && <span>{minLabel}</span>}\n {maxLabel && <span className=\"ml-auto\">{maxLabel}</span>}\n </div>\n )}\n {children}\n </div>\n );\n}\n"],"names":[],"mappings":";;AAYO,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,MAAI,kBAAkB,QAAQ;AAC5B,WACE,qBAAC,OAAA,EAAI,WAAU,2BACZ,UAAA;AAAA,MAAA,6BACE,QAAA,EAAK,IAAI,SAAS,WAAU,6DAC1B,UAAA,OACH;AAAA,MAED,YACC,oBAAC,QAAA,EAAK,WAAU,8DACb,UAAA,UACH;AAAA,MAED;AAAA,MACA,YACC,oBAAC,QAAA,EAAK,WAAU,8DACb,UAAA,SAAA,CACH;AAAA,IAAA,GAEJ;AAAA,EAEJ;AAEA,SACE,qBAAC,OAAA,EAAI,WAAU,8BACZ,UAAA;AAAA,IAAA,6BACE,QAAA,EAAK,IAAI,SAAS,WAAU,oDAC1B,UAAA,OACH;AAAA,KAEA,YAAY,aACZ,qBAAC,OAAA,EAAI,WAAU,6FACZ,UAAA;AAAA,MAAA,YAAY,oBAAC,UAAM,UAAA,SAAA,CAAS;AAAA,MAC5B,YAAY,oBAAC,QAAA,EAAK,WAAU,WAAW,UAAA,SAAA,CAAS;AAAA,IAAA,GACnD;AAAA,IAED;AAAA,EAAA,GACH;AAEJ;"}
|
|
@@ -36,21 +36,21 @@ function SliderThumb({
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
className: cn(
|
|
39
|
-
"flex size-6 items-center justify-center rounded-full border border-
|
|
39
|
+
"flex size-6 items-center justify-center rounded-full border border-border-primary bg-bg-primary shadow-sm",
|
|
40
40
|
"transition-shadow duration-150",
|
|
41
|
-
"hover:ring-2 hover:ring-brand-
|
|
42
|
-
"not-data-disabled:active:ring-2 not-data-disabled:active:ring-brand-
|
|
43
|
-
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
41
|
+
"hover:ring-2 hover:ring-brand-primary-default",
|
|
42
|
+
"not-data-disabled:active:ring-2 not-data-disabled:active:ring-brand-primary-default",
|
|
43
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-interaction-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary",
|
|
44
44
|
"data-disabled:cursor-not-allowed"
|
|
45
45
|
),
|
|
46
46
|
children: [
|
|
47
|
-
/* @__PURE__ */ jsx("span", { className: "block size-3 rounded-full bg-brand-
|
|
47
|
+
/* @__PURE__ */ jsx("span", { className: "block size-3 rounded-full bg-brand-primary-default shadow-[inset_0px_1px_2px_0px_rgba(0,0,0,0.1)]" }),
|
|
48
48
|
showTooltip && /* @__PURE__ */ jsx(
|
|
49
49
|
"span",
|
|
50
50
|
{
|
|
51
51
|
role: "tooltip",
|
|
52
52
|
"data-slider-tooltip": true,
|
|
53
|
-
className: "typography-semibold-body-sm pointer-events-none absolute bottom-full mb-2 rounded-
|
|
53
|
+
className: "typography-semibold-body-sm pointer-events-none absolute bottom-full mb-2 rounded-lg bg-surface-primary-inverted px-2 py-1 text-content-primary-inverted shadow-sm"
|
|
54
54
|
}
|
|
55
55
|
)
|
|
56
56
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SliderThumb.mjs","sources":["../../../src/components/Slider/SliderThumb.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\ninterface SliderThumbProps {\n showTooltip: boolean;\n formatTooltip?: (value: number) => string;\n index: number;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n}\n\nexport function SliderThumb({\n showTooltip,\n formatTooltip,\n index,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n}: SliderThumbProps) {\n const thumbRef = React.useCallback(\n (el: HTMLSpanElement | null) => {\n if (!el || !showTooltip) return;\n syncTooltipText(el, formatTooltip);\n },\n [showTooltip, formatTooltip],\n );\n\n return (\n <SliderPrimitive.Thumb\n ref={thumbRef}\n data-index={index}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onPointerDown={(e) => {\n if (showTooltip) syncTooltipText(e.currentTarget, formatTooltip);\n }}\n onPointerMove={(e) => {\n if (showTooltip) syncTooltipText(e.currentTarget, formatTooltip);\n }}\n onKeyDown={(e) => {\n if (showTooltip) {\n requestAnimationFrame(() => syncTooltipText(e.currentTarget, formatTooltip));\n }\n }}\n className={cn(\n \"flex size-6 items-center justify-center rounded-full border border-
|
|
1
|
+
{"version":3,"file":"SliderThumb.mjs","sources":["../../../src/components/Slider/SliderThumb.tsx"],"sourcesContent":["import * as SliderPrimitive from \"@radix-ui/react-slider\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\ninterface SliderThumbProps {\n showTooltip: boolean;\n formatTooltip?: (value: number) => string;\n index: number;\n \"aria-label\"?: string;\n \"aria-labelledby\"?: string;\n}\n\nexport function SliderThumb({\n showTooltip,\n formatTooltip,\n index,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": ariaLabelledBy,\n}: SliderThumbProps) {\n const thumbRef = React.useCallback(\n (el: HTMLSpanElement | null) => {\n if (!el || !showTooltip) return;\n syncTooltipText(el, formatTooltip);\n },\n [showTooltip, formatTooltip],\n );\n\n return (\n <SliderPrimitive.Thumb\n ref={thumbRef}\n data-index={index}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n onPointerDown={(e) => {\n if (showTooltip) syncTooltipText(e.currentTarget, formatTooltip);\n }}\n onPointerMove={(e) => {\n if (showTooltip) syncTooltipText(e.currentTarget, formatTooltip);\n }}\n onKeyDown={(e) => {\n if (showTooltip) {\n requestAnimationFrame(() => syncTooltipText(e.currentTarget, formatTooltip));\n }\n }}\n className={cn(\n \"flex size-6 items-center justify-center rounded-full border border-border-primary bg-bg-primary shadow-sm\",\n \"transition-shadow duration-150\",\n \"hover:ring-2 hover:ring-brand-primary-default\",\n \"not-data-disabled:active:ring-2 not-data-disabled:active:ring-brand-primary-default\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-interaction-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-primary\",\n \"data-disabled:cursor-not-allowed\",\n )}\n >\n <span className=\"block size-3 rounded-full bg-brand-primary-default shadow-[inset_0px_1px_2px_0px_rgba(0,0,0,0.1)]\" />\n\n {showTooltip && (\n <span\n role=\"tooltip\"\n data-slider-tooltip\n className=\"typography-semibold-body-sm pointer-events-none absolute bottom-full mb-2 rounded-lg bg-surface-primary-inverted px-2 py-1 text-content-primary-inverted shadow-sm\"\n />\n )}\n </SliderPrimitive.Thumb>\n );\n}\n\nfunction syncTooltipText(thumb: HTMLElement, formatTooltip?: (value: number) => string) {\n const raw = thumb.getAttribute(\"aria-valuenow\");\n const tooltip = thumb.querySelector<HTMLSpanElement>(\"[data-slider-tooltip]\");\n if (raw == null || !tooltip) return;\n const num = Number(raw);\n tooltip.textContent = formatTooltip ? formatTooltip(num) : String(num);\n}\n"],"names":[],"mappings":";;;;;AAYO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,mBAAmB;AACrB,GAAqB;AACnB,QAAM,WAAW,MAAM;AAAA,IACrB,CAAC,OAA+B;AAC9B,UAAI,CAAC,MAAM,CAAC,YAAa;AACzB,sBAAgB,IAAI,aAAa;AAAA,IACnC;AAAA,IACA,CAAC,aAAa,aAAa;AAAA,EAAA;AAG7B,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC,KAAK;AAAA,MACL,cAAY;AAAA,MACZ,cAAY;AAAA,MACZ,mBAAiB;AAAA,MACjB,eAAe,CAAC,MAAM;AACpB,YAAI,YAAa,iBAAgB,EAAE,eAAe,aAAa;AAAA,MACjE;AAAA,MACA,eAAe,CAAC,MAAM;AACpB,YAAI,YAAa,iBAAgB,EAAE,eAAe,aAAa;AAAA,MACjE;AAAA,MACA,WAAW,CAAC,MAAM;AAChB,YAAI,aAAa;AACf,gCAAsB,MAAM,gBAAgB,EAAE,eAAe,aAAa,CAAC;AAAA,QAC7E;AAAA,MACF;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,MAGF,UAAA;AAAA,QAAA,oBAAC,QAAA,EAAK,WAAU,oGAAA,CAAoG;AAAA,QAEnH,eACC;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,MAAK;AAAA,YACL,uBAAmB;AAAA,YACnB,WAAU;AAAA,UAAA;AAAA,QAAA;AAAA,MACZ;AAAA,IAAA;AAAA,EAAA;AAIR;AAEA,SAAS,gBAAgB,OAAoB,eAA2C;AACtF,QAAM,MAAM,MAAM,aAAa,eAAe;AAC9C,QAAM,UAAU,MAAM,cAA+B,uBAAuB;AAC5E,MAAI,OAAO,QAAQ,CAAC,QAAS;AAC7B,QAAM,MAAM,OAAO,GAAG;AACtB,UAAQ,cAAc,gBAAgB,cAAc,GAAG,IAAI,OAAO,GAAG;AACvE;"}
|
|
@@ -46,8 +46,8 @@ function VipEarnContent({
|
|
|
46
46
|
icon && /* @__PURE__ */ jsx("span", { className: "flex shrink-0", "aria-hidden": "true", children: icon }),
|
|
47
47
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-4", children: [
|
|
48
48
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
49
|
-
title && /* @__PURE__ */ jsx("p", { className: "typography-semibold-body-lg text-
|
|
50
|
-
description && /* @__PURE__ */ jsx("p", { className: "typography-regular-body-md text-
|
|
49
|
+
title && /* @__PURE__ */ jsx("p", { className: "typography-semibold-body-lg text-content-primary leading-6", children: title }),
|
|
50
|
+
description && /* @__PURE__ */ jsx("p", { className: "typography-regular-body-md text-content-secondary", children: description })
|
|
51
51
|
] }),
|
|
52
52
|
showActions && primary && /* @__PURE__ */ jsx("div", { className: "self-start", children: primary })
|
|
53
53
|
] })
|
|
@@ -71,9 +71,9 @@ function WelcomeContent({
|
|
|
71
71
|
variant: "secondary"
|
|
72
72
|
});
|
|
73
73
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
74
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 px-8 text-center text-
|
|
75
|
-
title && /* @__PURE__ */ jsx("p", { className: "typography-bold-heading-xs text-
|
|
76
|
-
description && /* @__PURE__ */ jsx("p", { className: "typography-regular-body-md text-
|
|
74
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 px-8 text-center text-content-primary", children: [
|
|
75
|
+
title && /* @__PURE__ */ jsx("p", { className: "typography-bold-heading-xs text-content-primary", children: title }),
|
|
76
|
+
description && /* @__PURE__ */ jsx("p", { className: "typography-regular-body-md text-content-secondary", children: description })
|
|
77
77
|
] }),
|
|
78
78
|
showActions && (primary || secondary) && /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-col gap-4 px-8 sm:flex-row sm:*:flex-1", children: [
|
|
79
79
|
secondary,
|
|
@@ -100,7 +100,7 @@ function DefaultContent({
|
|
|
100
100
|
size: "40"
|
|
101
101
|
});
|
|
102
102
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
103
|
-
/* @__PURE__ */ jsx("div", { className: "typography-regular-body-lg flex min-w-0 flex-1 items-center self-stretch text-
|
|
103
|
+
/* @__PURE__ */ jsx("div", { className: "typography-regular-body-lg flex min-w-0 flex-1 items-center self-stretch text-content-primary", children }),
|
|
104
104
|
showActions && (primary || secondary) && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-start gap-2", children: [
|
|
105
105
|
primary,
|
|
106
106
|
secondary
|
|
@@ -136,11 +136,11 @@ const Snackbar = React.forwardRef(
|
|
|
136
136
|
role: "status",
|
|
137
137
|
"data-testid": "snackbar",
|
|
138
138
|
className: cn(
|
|
139
|
-
"flex gap-4 rounded-
|
|
140
|
-
(variant === "default" || variant === "vipEarn") && "border border-neutral-50 bg-surface-
|
|
139
|
+
"flex gap-4 rounded-md",
|
|
140
|
+
(variant === "default" || variant === "vipEarn") && "border border-neutral-alphas-50 bg-surface-primary p-4 backdrop-blur-md",
|
|
141
141
|
variant === "default" && "flex-wrap items-start",
|
|
142
142
|
variant === "vipEarn" && "items-start",
|
|
143
|
-
variant === "welcome" && "relative flex-col items-center bg-
|
|
143
|
+
variant === "welcome" && "relative flex-col items-center bg-bg-primary py-6",
|
|
144
144
|
className
|
|
145
145
|
),
|
|
146
146
|
...props,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Snackbar.mjs","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { CrossIcon } from \"../Icons/CrossIcon\";\n\n/** Layout variant of the snackbar. */\nexport type SnackbarVariant = \"default\" | \"vipEarn\" | \"welcome\";\n\nexport interface SnackbarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Layout variant of the snackbar. @default \"default\" */\n variant?: SnackbarVariant;\n /** Icon element displayed at the leading edge (used by the `vipEarn` variant). */\n icon?: React.ReactNode;\n /** Title content. */\n title?: React.ReactNode;\n /** Descriptive body text. */\n description?: React.ReactNode;\n /** Whether to show primary/secondary action buttons. @default true */\n showActions?: boolean;\n /** Primary CTA label — renders a default {@link Button}. */\n primaryLabel?: string;\n /** Click handler for the primary CTA (used together with `primaryLabel`). */\n primaryOnClick?: () => void;\n /** Custom element rendered as the primary CTA. Overrides `primaryLabel` / `primaryOnClick`. */\n primarySlot?: React.ReactNode;\n /** Secondary CTA label — renders a default {@link Button}. */\n secondaryLabel?: string;\n /** Click handler for the secondary CTA (used together with `secondaryLabel`). */\n secondaryOnClick?: () => void;\n /** Custom element rendered as the secondary CTA. Overrides `secondaryLabel` / `secondaryOnClick`. */\n secondarySlot?: React.ReactNode;\n /** Whether to show the close button. @default false */\n closable?: boolean;\n /** Callback fired when the close button is clicked. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close snackbar\" */\n closeLabel?: string;\n}\n\nfunction CloseButton({\n onClose,\n className,\n closeLabel = \"Close snackbar\",\n}: {\n onClose?: () => void;\n className?: string;\n closeLabel?: string;\n}) {\n return (\n <IconButton\n variant=\"tertiary\"\n size=\"24\"\n onClick={onClose}\n icon={<CrossIcon />}\n className={cn(\"shrink-0\", className)}\n aria-label={closeLabel}\n />\n );\n}\n\n/**\n * Resolves a CTA slot. If a custom slot is provided it takes precedence,\n * otherwise a default Button is rendered from label + onClick.\n */\nfunction resolveCtaSlot(\n slot: React.ReactNode | undefined,\n label: string | undefined,\n onClick: (() => void) | undefined,\n buttonProps: React.ComponentProps<typeof Button>,\n): React.ReactNode | null {\n if (slot) return slot;\n if (label) {\n return (\n <Button onClick={onClick} {...buttonProps}>\n {label}\n </Button>\n );\n }\n return null;\n}\n\nfunction VipEarnContent({\n icon,\n title,\n description,\n showActions,\n primarySlot,\n primaryLabel,\n primaryOnClick,\n}: Pick<\n SnackbarProps,\n | \"icon\"\n | \"title\"\n | \"description\"\n | \"showActions\"\n | \"primarySlot\"\n | \"primaryLabel\"\n | \"primaryOnClick\"\n>) {\n const primary = resolveCtaSlot(primarySlot, primaryLabel, primaryOnClick, {\n variant: \"text\",\n size: \"24\",\n });\n\n return (\n <>\n {icon && (\n <span className=\"flex shrink-0\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col gap-4\">\n <div className=\"flex flex-col\">\n {title && (\n <p className=\"typography-semibold-body-lg text-foreground-default leading-6\">{title}</p>\n )}\n {description && (\n <p className=\"typography-regular-body-md text-foreground-secondary\">{description}</p>\n )}\n </div>\n {showActions && primary && <div className=\"self-start\">{primary}</div>}\n </div>\n </>\n );\n}\n\nfunction WelcomeContent({\n title,\n description,\n showActions,\n primarySlot,\n primaryLabel,\n primaryOnClick,\n secondarySlot,\n secondaryLabel,\n secondaryOnClick,\n}: Pick<\n SnackbarProps,\n | \"title\"\n | \"description\"\n | \"showActions\"\n | \"primarySlot\"\n | \"primaryLabel\"\n | \"primaryOnClick\"\n | \"secondarySlot\"\n | \"secondaryLabel\"\n | \"secondaryOnClick\"\n>) {\n const primary = resolveCtaSlot(primarySlot, primaryLabel, primaryOnClick, {\n variant: \"primary\",\n });\n const secondary = resolveCtaSlot(secondarySlot, secondaryLabel, secondaryOnClick, {\n variant: \"secondary\",\n });\n\n return (\n <>\n <div className=\"flex flex-col items-center gap-2 px-8 text-center text-foreground-default\">\n {title && <p className=\"typography-bold-heading-xs text-foreground-default\">{title}</p>}\n {description && (\n <p className=\"typography-regular-body-md text-foreground-secondary\">{description}</p>\n )}\n </div>\n {showActions && (primary || secondary) && (\n <div className=\"flex w-full flex-col gap-4 px-8 sm:flex-row sm:*:flex-1\">\n {secondary}\n {primary}\n </div>\n )}\n </>\n );\n}\n\nfunction DefaultContent({\n children,\n showActions,\n primarySlot,\n primaryLabel,\n primaryOnClick,\n secondarySlot,\n secondaryLabel,\n secondaryOnClick,\n}: Pick<\n SnackbarProps,\n | \"children\"\n | \"showActions\"\n | \"primarySlot\"\n | \"primaryLabel\"\n | \"primaryOnClick\"\n | \"secondarySlot\"\n | \"secondaryLabel\"\n | \"secondaryOnClick\"\n>) {\n const primary = resolveCtaSlot(primarySlot, primaryLabel, primaryOnClick, {\n variant: \"primary\",\n size: \"40\",\n });\n const secondary = resolveCtaSlot(secondarySlot, secondaryLabel, secondaryOnClick, {\n variant: \"tertiary\",\n size: \"40\",\n });\n\n return (\n <>\n <div className=\"typography-regular-body-lg flex min-w-0 flex-1 items-center self-stretch text-foreground-default\">\n {children}\n </div>\n {showActions && (primary || secondary) && (\n <div className=\"flex shrink-0 items-start gap-2\">\n {primary}\n {secondary}\n </div>\n )}\n </>\n );\n}\n\n/**\n * A prominent inline message with optional title, description, action buttons,\n * and close control. Supports three layout variants: `default`, `vipEarn`, and\n * `welcome`.\n *\n * @example\n * ```tsx\n * <Snackbar\n * variant=\"default\"\n * primaryLabel=\"Undo\"\n * primaryOnClick={undo}\n * closable\n * onClose={dismiss}\n * >\n * Item deleted\n * </Snackbar>\n * ```\n */\nexport const Snackbar = React.forwardRef<HTMLDivElement, SnackbarProps>(\n (\n {\n className,\n variant = \"default\",\n icon,\n title,\n description,\n showActions = true,\n primaryLabel,\n primaryOnClick,\n primarySlot,\n secondaryLabel,\n secondaryOnClick,\n secondarySlot,\n closable = false,\n onClose,\n closeLabel,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n /* biome-ignore lint/a11y/useSemanticElements: output cannot contain div children; browsers would break the wrapper. */\n <div\n ref={ref}\n role=\"status\"\n data-testid=\"snackbar\"\n className={cn(\n \"flex gap-4 rounded-2xl\",\n (variant === \"default\" || variant === \"vipEarn\") &&\n \"border border-neutral-50 bg-surface-container p-4 backdrop-blur-md\",\n variant === \"default\" && \"flex-wrap items-start\",\n variant === \"vipEarn\" && \"items-start\",\n variant === \"welcome\" && \"relative flex-col items-center bg-surface-page py-6\",\n className,\n )}\n {...props}\n >\n {variant === \"vipEarn\" && (\n <VipEarnContent\n icon={icon}\n title={title}\n description={description}\n showActions={showActions}\n primarySlot={primarySlot}\n primaryLabel={primaryLabel}\n primaryOnClick={primaryOnClick}\n />\n )}\n {variant === \"welcome\" && (\n <WelcomeContent\n title={title}\n description={description}\n showActions={showActions}\n primarySlot={primarySlot}\n primaryLabel={primaryLabel}\n primaryOnClick={primaryOnClick}\n secondarySlot={secondarySlot}\n secondaryLabel={secondaryLabel}\n secondaryOnClick={secondaryOnClick}\n />\n )}\n {variant === \"default\" && (\n <DefaultContent\n showActions={showActions}\n primarySlot={primarySlot}\n primaryLabel={primaryLabel}\n primaryOnClick={primaryOnClick}\n secondarySlot={secondarySlot}\n secondaryLabel={secondaryLabel}\n secondaryOnClick={secondaryOnClick}\n >\n {children}\n </DefaultContent>\n )}\n {closable && (\n <CloseButton\n onClose={onClose}\n closeLabel={closeLabel}\n className={variant === \"welcome\" ? \"absolute top-2 right-2\" : undefined}\n />\n )}\n </div>\n );\n },\n);\n\nSnackbar.displayName = \"Snackbar\";\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Snackbar.mjs","sources":["../../../src/components/Snackbar/Snackbar.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../Button/Button\";\nimport { IconButton } from \"../IconButton/IconButton\";\nimport { CrossIcon } from \"../Icons/CrossIcon\";\n\n/** Layout variant of the snackbar. */\nexport type SnackbarVariant = \"default\" | \"vipEarn\" | \"welcome\";\n\nexport interface SnackbarProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"title\"> {\n /** Layout variant of the snackbar. @default \"default\" */\n variant?: SnackbarVariant;\n /** Icon element displayed at the leading edge (used by the `vipEarn` variant). */\n icon?: React.ReactNode;\n /** Title content. */\n title?: React.ReactNode;\n /** Descriptive body text. */\n description?: React.ReactNode;\n /** Whether to show primary/secondary action buttons. @default true */\n showActions?: boolean;\n /** Primary CTA label — renders a default {@link Button}. */\n primaryLabel?: string;\n /** Click handler for the primary CTA (used together with `primaryLabel`). */\n primaryOnClick?: () => void;\n /** Custom element rendered as the primary CTA. Overrides `primaryLabel` / `primaryOnClick`. */\n primarySlot?: React.ReactNode;\n /** Secondary CTA label — renders a default {@link Button}. */\n secondaryLabel?: string;\n /** Click handler for the secondary CTA (used together with `secondaryLabel`). */\n secondaryOnClick?: () => void;\n /** Custom element rendered as the secondary CTA. Overrides `secondaryLabel` / `secondaryOnClick`. */\n secondarySlot?: React.ReactNode;\n /** Whether to show the close button. @default false */\n closable?: boolean;\n /** Callback fired when the close button is clicked. */\n onClose?: () => void;\n /** Accessible label for the close button. @default \"Close snackbar\" */\n closeLabel?: string;\n}\n\nfunction CloseButton({\n onClose,\n className,\n closeLabel = \"Close snackbar\",\n}: {\n onClose?: () => void;\n className?: string;\n closeLabel?: string;\n}) {\n return (\n <IconButton\n variant=\"tertiary\"\n size=\"24\"\n onClick={onClose}\n icon={<CrossIcon />}\n className={cn(\"shrink-0\", className)}\n aria-label={closeLabel}\n />\n );\n}\n\n/**\n * Resolves a CTA slot. If a custom slot is provided it takes precedence,\n * otherwise a default Button is rendered from label + onClick.\n */\nfunction resolveCtaSlot(\n slot: React.ReactNode | undefined,\n label: string | undefined,\n onClick: (() => void) | undefined,\n buttonProps: React.ComponentProps<typeof Button>,\n): React.ReactNode | null {\n if (slot) return slot;\n if (label) {\n return (\n <Button onClick={onClick} {...buttonProps}>\n {label}\n </Button>\n );\n }\n return null;\n}\n\nfunction VipEarnContent({\n icon,\n title,\n description,\n showActions,\n primarySlot,\n primaryLabel,\n primaryOnClick,\n}: Pick<\n SnackbarProps,\n | \"icon\"\n | \"title\"\n | \"description\"\n | \"showActions\"\n | \"primarySlot\"\n | \"primaryLabel\"\n | \"primaryOnClick\"\n>) {\n const primary = resolveCtaSlot(primarySlot, primaryLabel, primaryOnClick, {\n variant: \"text\",\n size: \"24\",\n });\n\n return (\n <>\n {icon && (\n <span className=\"flex shrink-0\" aria-hidden=\"true\">\n {icon}\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col gap-4\">\n <div className=\"flex flex-col\">\n {title && (\n <p className=\"typography-semibold-body-lg text-content-primary leading-6\">{title}</p>\n )}\n {description && (\n <p className=\"typography-regular-body-md text-content-secondary\">{description}</p>\n )}\n </div>\n {showActions && primary && <div className=\"self-start\">{primary}</div>}\n </div>\n </>\n );\n}\n\nfunction WelcomeContent({\n title,\n description,\n showActions,\n primarySlot,\n primaryLabel,\n primaryOnClick,\n secondarySlot,\n secondaryLabel,\n secondaryOnClick,\n}: Pick<\n SnackbarProps,\n | \"title\"\n | \"description\"\n | \"showActions\"\n | \"primarySlot\"\n | \"primaryLabel\"\n | \"primaryOnClick\"\n | \"secondarySlot\"\n | \"secondaryLabel\"\n | \"secondaryOnClick\"\n>) {\n const primary = resolveCtaSlot(primarySlot, primaryLabel, primaryOnClick, {\n variant: \"primary\",\n });\n const secondary = resolveCtaSlot(secondarySlot, secondaryLabel, secondaryOnClick, {\n variant: \"secondary\",\n });\n\n return (\n <>\n <div className=\"flex flex-col items-center gap-2 px-8 text-center text-content-primary\">\n {title && <p className=\"typography-bold-heading-xs text-content-primary\">{title}</p>}\n {description && (\n <p className=\"typography-regular-body-md text-content-secondary\">{description}</p>\n )}\n </div>\n {showActions && (primary || secondary) && (\n <div className=\"flex w-full flex-col gap-4 px-8 sm:flex-row sm:*:flex-1\">\n {secondary}\n {primary}\n </div>\n )}\n </>\n );\n}\n\nfunction DefaultContent({\n children,\n showActions,\n primarySlot,\n primaryLabel,\n primaryOnClick,\n secondarySlot,\n secondaryLabel,\n secondaryOnClick,\n}: Pick<\n SnackbarProps,\n | \"children\"\n | \"showActions\"\n | \"primarySlot\"\n | \"primaryLabel\"\n | \"primaryOnClick\"\n | \"secondarySlot\"\n | \"secondaryLabel\"\n | \"secondaryOnClick\"\n>) {\n const primary = resolveCtaSlot(primarySlot, primaryLabel, primaryOnClick, {\n variant: \"primary\",\n size: \"40\",\n });\n const secondary = resolveCtaSlot(secondarySlot, secondaryLabel, secondaryOnClick, {\n variant: \"tertiary\",\n size: \"40\",\n });\n\n return (\n <>\n <div className=\"typography-regular-body-lg flex min-w-0 flex-1 items-center self-stretch text-content-primary\">\n {children}\n </div>\n {showActions && (primary || secondary) && (\n <div className=\"flex shrink-0 items-start gap-2\">\n {primary}\n {secondary}\n </div>\n )}\n </>\n );\n}\n\n/**\n * A prominent inline message with optional title, description, action buttons,\n * and close control. Supports three layout variants: `default`, `vipEarn`, and\n * `welcome`.\n *\n * @example\n * ```tsx\n * <Snackbar\n * variant=\"default\"\n * primaryLabel=\"Undo\"\n * primaryOnClick={undo}\n * closable\n * onClose={dismiss}\n * >\n * Item deleted\n * </Snackbar>\n * ```\n */\nexport const Snackbar = React.forwardRef<HTMLDivElement, SnackbarProps>(\n (\n {\n className,\n variant = \"default\",\n icon,\n title,\n description,\n showActions = true,\n primaryLabel,\n primaryOnClick,\n primarySlot,\n secondaryLabel,\n secondaryOnClick,\n secondarySlot,\n closable = false,\n onClose,\n closeLabel,\n children,\n ...props\n },\n ref,\n ) => {\n return (\n /* biome-ignore lint/a11y/useSemanticElements: output cannot contain div children; browsers would break the wrapper. */\n <div\n ref={ref}\n role=\"status\"\n data-testid=\"snackbar\"\n className={cn(\n \"flex gap-4 rounded-md\",\n (variant === \"default\" || variant === \"vipEarn\") &&\n \"border border-neutral-alphas-50 bg-surface-primary p-4 backdrop-blur-md\",\n variant === \"default\" && \"flex-wrap items-start\",\n variant === \"vipEarn\" && \"items-start\",\n variant === \"welcome\" && \"relative flex-col items-center bg-bg-primary py-6\",\n className,\n )}\n {...props}\n >\n {variant === \"vipEarn\" && (\n <VipEarnContent\n icon={icon}\n title={title}\n description={description}\n showActions={showActions}\n primarySlot={primarySlot}\n primaryLabel={primaryLabel}\n primaryOnClick={primaryOnClick}\n />\n )}\n {variant === \"welcome\" && (\n <WelcomeContent\n title={title}\n description={description}\n showActions={showActions}\n primarySlot={primarySlot}\n primaryLabel={primaryLabel}\n primaryOnClick={primaryOnClick}\n secondarySlot={secondarySlot}\n secondaryLabel={secondaryLabel}\n secondaryOnClick={secondaryOnClick}\n />\n )}\n {variant === \"default\" && (\n <DefaultContent\n showActions={showActions}\n primarySlot={primarySlot}\n primaryLabel={primaryLabel}\n primaryOnClick={primaryOnClick}\n secondarySlot={secondarySlot}\n secondaryLabel={secondaryLabel}\n secondaryOnClick={secondaryOnClick}\n >\n {children}\n </DefaultContent>\n )}\n {closable && (\n <CloseButton\n onClose={onClose}\n closeLabel={closeLabel}\n className={variant === \"welcome\" ? \"absolute top-2 right-2\" : undefined}\n />\n )}\n </div>\n );\n },\n);\n\nSnackbar.displayName = \"Snackbar\";\n"],"names":[],"mappings":"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"}
|
|
@@ -12,8 +12,8 @@ const Switch = React.forwardRef(({ className, size = "default", ...props }, ref)
|
|
|
12
12
|
className: cn(
|
|
13
13
|
"inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent transition-colors duration-150",
|
|
14
14
|
"focus-visible:shadow-focus-ring focus-visible:outline-none",
|
|
15
|
-
"data-[state=checked]:border-neutral-200 data-[state=checked]:bg-brand-
|
|
16
|
-
"data-[state=unchecked]:bg-neutral-400",
|
|
15
|
+
"data-[state=checked]:border-neutral-alphas-200 data-[state=checked]:bg-brand-primary-default",
|
|
16
|
+
"data-[state=unchecked]:bg-neutral-alphas-400",
|
|
17
17
|
"not-disabled:active:opacity-80",
|
|
18
18
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
19
19
|
size === "default" && "h-6 w-10.5",
|
|
@@ -25,7 +25,7 @@ const Switch = React.forwardRef(({ className, size = "default", ...props }, ref)
|
|
|
25
25
|
SwitchPrimitive.Thumb,
|
|
26
26
|
{
|
|
27
27
|
className: cn(
|
|
28
|
-
"pointer-events-none rounded-full bg-
|
|
28
|
+
"pointer-events-none rounded-full bg-bg-primary shadow-sm transition-transform duration-150",
|
|
29
29
|
thumbSizeClass
|
|
30
30
|
)
|
|
31
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.mjs","sources":["../../../src/components/Switch/Switch.tsx"],"sourcesContent":["import * as SwitchPrimitive from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Size variant of the switch toggle. */\nexport type SwitchSize = \"default\" | \"small\";\n\nexport interface SwitchProps\n extends Omit<React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>, \"asChild\"> {\n /** Size variant of the switch. @default \"default\" */\n size?: SwitchSize;\n}\n\n/**\n * A toggle switch for boolean on/off states. Built on Radix UI `Switch`.\n *\n * For a labelled switch with helper text, see {@link SwitchField}.\n *\n * @example\n * ```tsx\n * <Switch checked={on} onCheckedChange={setOn} />\n * ```\n */\nexport const Switch = React.forwardRef<\n React.ComponentRef<typeof SwitchPrimitive.Root>,\n SwitchProps\n>(({ className, size = \"default\", ...props }, ref) => {\n const thumbSizeClass =\n size === \"default\"\n ? \"size-4.5 translate-x-0.75 data-[state=checked]:translate-x-4.75\"\n : \"size-4 translate-x-0.5 data-[state=checked]:translate-x-4.25\";\n\n return (\n <SwitchPrimitive.Root\n ref={ref}\n className={cn(\n \"inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent transition-colors duration-150\",\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n \"data-[state=checked]:border-neutral-200 data-[state=checked]:bg-brand-
|
|
1
|
+
{"version":3,"file":"Switch.mjs","sources":["../../../src/components/Switch/Switch.tsx"],"sourcesContent":["import * as SwitchPrimitive from \"@radix-ui/react-switch\";\nimport * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\n\n/** Size variant of the switch toggle. */\nexport type SwitchSize = \"default\" | \"small\";\n\nexport interface SwitchProps\n extends Omit<React.ComponentPropsWithoutRef<typeof SwitchPrimitive.Root>, \"asChild\"> {\n /** Size variant of the switch. @default \"default\" */\n size?: SwitchSize;\n}\n\n/**\n * A toggle switch for boolean on/off states. Built on Radix UI `Switch`.\n *\n * For a labelled switch with helper text, see {@link SwitchField}.\n *\n * @example\n * ```tsx\n * <Switch checked={on} onCheckedChange={setOn} />\n * ```\n */\nexport const Switch = React.forwardRef<\n React.ComponentRef<typeof SwitchPrimitive.Root>,\n SwitchProps\n>(({ className, size = \"default\", ...props }, ref) => {\n const thumbSizeClass =\n size === \"default\"\n ? \"size-4.5 translate-x-0.75 data-[state=checked]:translate-x-4.75\"\n : \"size-4 translate-x-0.5 data-[state=checked]:translate-x-4.25\";\n\n return (\n <SwitchPrimitive.Root\n ref={ref}\n className={cn(\n \"inline-flex shrink-0 cursor-pointer items-center rounded-full border border-transparent transition-colors duration-150\",\n \"focus-visible:shadow-focus-ring focus-visible:outline-none\",\n \"data-[state=checked]:border-neutral-alphas-200 data-[state=checked]:bg-brand-primary-default\",\n \"data-[state=unchecked]:bg-neutral-alphas-400\",\n \"not-disabled:active:opacity-80\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n size === \"default\" && \"h-6 w-10.5\",\n size === \"small\" && \"h-5 w-9\",\n className,\n )}\n {...props}\n >\n <SwitchPrimitive.Thumb\n className={cn(\n \"pointer-events-none rounded-full bg-bg-primary shadow-sm transition-transform duration-150\",\n thumbSizeClass,\n )}\n />\n </SwitchPrimitive.Root>\n );\n});\n\nSwitch.displayName = \"Switch\";\n"],"names":[],"mappings":";;;;;AAuBO,MAAM,SAAS,MAAM,WAG1B,CAAC,EAAE,WAAW,OAAO,WAAW,GAAG,MAAA,GAAS,QAAQ;AACpD,QAAM,iBACJ,SAAS,YACL,oEACA;AAEN,SACE;AAAA,IAAC,gBAAgB;AAAA,IAAhB;AAAA,MACC;AAAA,MACA,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,aAAa;AAAA,QACtB,SAAS,WAAW;AAAA,QACpB;AAAA,MAAA;AAAA,MAED,GAAG;AAAA,MAEJ,UAAA;AAAA,QAAC,gBAAgB;AAAA,QAAhB;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,IACF;AAAA,EAAA;AAGN,CAAC;AAED,OAAO,cAAc;"}
|
|
@@ -46,8 +46,8 @@ const SwitchField = React.forwardRef(
|
|
|
46
46
|
{
|
|
47
47
|
htmlFor: id,
|
|
48
48
|
className: cn(
|
|
49
|
-
"cursor-pointer select-none text-
|
|
50
|
-
disabled && "cursor-not-allowed text-
|
|
49
|
+
"cursor-pointer select-none text-content-primary",
|
|
50
|
+
disabled && "cursor-not-allowed text-content-tertiary",
|
|
51
51
|
size === "default" ? "typography-semibold-body-lg" : "typography-semibold-body-md"
|
|
52
52
|
),
|
|
53
53
|
children: label
|
|
@@ -58,7 +58,7 @@ const SwitchField = React.forwardRef(
|
|
|
58
58
|
InfoCircleIcon,
|
|
59
59
|
{
|
|
60
60
|
"aria-hidden": "true",
|
|
61
|
-
className: "size-5 text-
|
|
61
|
+
className: "size-5 text-content-secondary"
|
|
62
62
|
}
|
|
63
63
|
) }) }),
|
|
64
64
|
/* @__PURE__ */ jsx(TooltipContent, { side: "bottom", children: infoText })
|
|
@@ -69,8 +69,8 @@ const SwitchField = React.forwardRef(
|
|
|
69
69
|
{
|
|
70
70
|
id: helperTextId,
|
|
71
71
|
className: cn(
|
|
72
|
-
"text-
|
|
73
|
-
disabled && "text-
|
|
72
|
+
"text-content-secondary",
|
|
73
|
+
disabled && "text-content-tertiary",
|
|
74
74
|
size === "default" ? "typography-regular-body-md" : "typography-regular-body-sm"
|
|
75
75
|
),
|
|
76
76
|
children: helperText
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SwitchField.mjs","sources":["../../../src/components/SwitchField/SwitchField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { Switch, type SwitchSize } from \"../Switch/Switch\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Side on which the switch toggle is positioned relative to the label. */\nexport type SwitchFieldOrientation = \"right\" | \"left\";\n\nexport interface SwitchFieldProps\n extends Omit<React.ComponentPropsWithoutRef<typeof Switch>, \"size\" | \"className\"> {\n /** Side on which the switch is placed relative to the label. @default \"right\" */\n orientation?: SwitchFieldOrientation;\n /** Size variant of the switch and accompanying text. @default \"default\" */\n size?: SwitchSize;\n /** Label text displayed next to the switch. */\n label?: string;\n /** Descriptive text displayed below the label. */\n helperText?: string;\n /** Tooltip text shown when hovering the info icon next to the label. */\n infoText?: string;\n /** Accessible label for the info tooltip trigger button. Override for i18n.\n * @default \"More information\"\n */\n infoLabel?: string;\n /** Additional CSS class name for the outer wrapper. */\n className?: string;\n}\n\n/**\n * A labelled switch field with optional helper text and info tooltip. Composes\n * the {@link Switch} component with a `<label>` and description.\n *\n * @example\n * ```tsx\n * <SwitchField\n * label=\"Notifications\"\n * helperText=\"Receive push notifications\"\n * checked={enabled}\n * onCheckedChange={setEnabled}\n * />\n * ```\n */\nexport const SwitchField = React.forwardRef<React.ComponentRef<typeof Switch>, SwitchFieldProps>(\n (\n {\n className,\n orientation = \"right\",\n size = \"default\",\n label,\n helperText,\n infoText,\n infoLabel = \"More information\",\n disabled,\n id: propId,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const id = propId ?? generatedId;\n const helperTextId = helperText ? `${id}-helper` : undefined;\n\n const switchElement = (\n <Switch\n ref={ref}\n id={id}\n size={size}\n disabled={disabled}\n aria-describedby={helperTextId}\n {...props}\n />\n );\n\n const labelContent = (label || helperText) && (\n <div\n className={cn(\n \"flex min-w-0 flex-1 flex-col items-start\",\n size === \"default\" ? \"gap-1\" : \"gap-0.5\",\n )}\n >\n {label && (\n <div className=\"flex items-center gap-1\">\n <label\n htmlFor={id}\n className={cn(\n \"cursor-pointer select-none text-
|
|
1
|
+
{"version":3,"file":"SwitchField.mjs","sources":["../../../src/components/SwitchField/SwitchField.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"../../utils/cn\";\nimport { InfoCircleIcon } from \"../Icons/InfoCircleIcon\";\nimport { Switch, type SwitchSize } from \"../Switch/Switch\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"../Tooltip/Tooltip\";\n\n/** Side on which the switch toggle is positioned relative to the label. */\nexport type SwitchFieldOrientation = \"right\" | \"left\";\n\nexport interface SwitchFieldProps\n extends Omit<React.ComponentPropsWithoutRef<typeof Switch>, \"size\" | \"className\"> {\n /** Side on which the switch is placed relative to the label. @default \"right\" */\n orientation?: SwitchFieldOrientation;\n /** Size variant of the switch and accompanying text. @default \"default\" */\n size?: SwitchSize;\n /** Label text displayed next to the switch. */\n label?: string;\n /** Descriptive text displayed below the label. */\n helperText?: string;\n /** Tooltip text shown when hovering the info icon next to the label. */\n infoText?: string;\n /** Accessible label for the info tooltip trigger button. Override for i18n.\n * @default \"More information\"\n */\n infoLabel?: string;\n /** Additional CSS class name for the outer wrapper. */\n className?: string;\n}\n\n/**\n * A labelled switch field with optional helper text and info tooltip. Composes\n * the {@link Switch} component with a `<label>` and description.\n *\n * @example\n * ```tsx\n * <SwitchField\n * label=\"Notifications\"\n * helperText=\"Receive push notifications\"\n * checked={enabled}\n * onCheckedChange={setEnabled}\n * />\n * ```\n */\nexport const SwitchField = React.forwardRef<React.ComponentRef<typeof Switch>, SwitchFieldProps>(\n (\n {\n className,\n orientation = \"right\",\n size = \"default\",\n label,\n helperText,\n infoText,\n infoLabel = \"More information\",\n disabled,\n id: propId,\n ...props\n },\n ref,\n ) => {\n const generatedId = React.useId();\n const id = propId ?? generatedId;\n const helperTextId = helperText ? `${id}-helper` : undefined;\n\n const switchElement = (\n <Switch\n ref={ref}\n id={id}\n size={size}\n disabled={disabled}\n aria-describedby={helperTextId}\n {...props}\n />\n );\n\n const labelContent = (label || helperText) && (\n <div\n className={cn(\n \"flex min-w-0 flex-1 flex-col items-start\",\n size === \"default\" ? \"gap-1\" : \"gap-0.5\",\n )}\n >\n {label && (\n <div className=\"flex items-center gap-1\">\n <label\n htmlFor={id}\n className={cn(\n \"cursor-pointer select-none text-content-primary\",\n disabled && \"cursor-not-allowed text-content-tertiary\",\n size === \"default\" ? \"typography-semibold-body-lg\" : \"typography-semibold-body-md\",\n )}\n >\n {label}\n </label>\n {infoText && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <button type=\"button\" aria-label={infoLabel} className=\"flex shrink-0 pt-0.5\">\n <InfoCircleIcon\n aria-hidden=\"true\"\n className=\"size-5 text-content-secondary\"\n />\n </button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">{infoText}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )}\n {helperText && (\n <span\n id={helperTextId}\n className={cn(\n \"text-content-secondary\",\n disabled && \"text-content-tertiary\",\n size === \"default\" ? \"typography-regular-body-md\" : \"typography-regular-body-sm\",\n )}\n >\n {helperText}\n </span>\n )}\n </div>\n );\n\n return (\n <div className={cn(\"flex items-start gap-2\", disabled && \"cursor-not-allowed\", className)}>\n {orientation === \"left\" && switchElement}\n {labelContent}\n {orientation === \"right\" && switchElement}\n </div>\n );\n },\n);\n\nSwitchField.displayName = \"SwitchField\";\n"],"names":[],"mappings":";;;;;;;AA2CO,MAAM,cAAc,MAAM;AAAA,EAC/B,CACE;AAAA,IACE;AAAA,IACA,cAAc;AAAA,IACd,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ;AAAA,IACA,IAAI;AAAA,IACJ,GAAG;AAAA,EAAA,GAEL,QACG;AACH,UAAM,cAAc,MAAM,MAAA;AAC1B,UAAM,KAAK,UAAU;AACrB,UAAM,eAAe,aAAa,GAAG,EAAE,YAAY;AAEnD,UAAM,gBACJ;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,oBAAkB;AAAA,QACjB,GAAG;AAAA,MAAA;AAAA,IAAA;AAIR,UAAM,gBAAgB,SAAS,eAC7B;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,SAAS,YAAY,UAAU;AAAA,QAAA;AAAA,QAGhC,UAAA;AAAA,UAAA,SACC,qBAAC,OAAA,EAAI,WAAU,2BACb,UAAA;AAAA,YAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,SAAS;AAAA,gBACT,WAAW;AAAA,kBACT;AAAA,kBACA,YAAY;AAAA,kBACZ,SAAS,YAAY,gCAAgC;AAAA,gBAAA;AAAA,gBAGtD,UAAA;AAAA,cAAA;AAAA,YAAA;AAAA,YAEF,YACC,oBAAC,iBAAA,EACC,UAAA,qBAAC,SAAA,EACC,UAAA;AAAA,cAAA,oBAAC,gBAAA,EAAe,SAAO,MACrB,UAAA,oBAAC,UAAA,EAAO,MAAK,UAAS,cAAY,WAAW,WAAU,wBACrD,UAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,eAAY;AAAA,kBACZ,WAAU;AAAA,gBAAA;AAAA,cAAA,GAEd,EAAA,CACF;AAAA,cACA,oBAAC,gBAAA,EAAe,MAAK,UAAU,UAAA,SAAA,CAAS;AAAA,YAAA,EAAA,CAC1C,EAAA,CACF;AAAA,UAAA,GAEJ;AAAA,UAED,cACC;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAI;AAAA,cACJ,WAAW;AAAA,gBACT;AAAA,gBACA,YAAY;AAAA,gBACZ,SAAS,YAAY,+BAA+B;AAAA,cAAA;AAAA,cAGrD,UAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QACH;AAAA,MAAA;AAAA,IAAA;AAKN,WACE,qBAAC,SAAI,WAAW,GAAG,0BAA0B,YAAY,sBAAsB,SAAS,GACrF,UAAA;AAAA,MAAA,gBAAgB,UAAU;AAAA,MAC1B;AAAA,MACA,gBAAgB,WAAW;AAAA,IAAA,GAC9B;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;"}
|