@karakuri-ui/react 0.3.3 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -4
- package/dist/components/ui/accordion.js +27 -24
- package/dist/components/ui/accordion.js.map +1 -1
- package/dist/components/ui/accordion.mjs +28 -25
- package/dist/components/ui/accordion.mjs.map +1 -1
- package/dist/components/ui/alert.js +45 -27
- package/dist/components/ui/alert.js.map +1 -1
- package/dist/components/ui/alert.mjs +46 -28
- package/dist/components/ui/alert.mjs.map +1 -1
- package/dist/components/ui/avatar.js +41 -32
- package/dist/components/ui/avatar.js.map +1 -1
- package/dist/components/ui/avatar.mjs +42 -33
- package/dist/components/ui/avatar.mjs.map +1 -1
- package/dist/components/ui/badge.js +46 -43
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/badge.mjs +47 -44
- package/dist/components/ui/badge.mjs.map +1 -1
- package/dist/components/ui/breadcrumb.js +30 -25
- package/dist/components/ui/breadcrumb.js.map +1 -1
- package/dist/components/ui/breadcrumb.mjs +31 -26
- package/dist/components/ui/breadcrumb.mjs.map +1 -1
- package/dist/components/ui/button-group.js +6 -5
- package/dist/components/ui/button-group.js.map +1 -1
- package/dist/components/ui/button-group.mjs +7 -6
- package/dist/components/ui/button-group.mjs.map +1 -1
- package/dist/components/ui/button.js +24 -14
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/button.mjs +26 -16
- package/dist/components/ui/button.mjs.map +1 -1
- package/dist/components/ui/card.js +53 -39
- package/dist/components/ui/card.js.map +1 -1
- package/dist/components/ui/card.mjs +54 -40
- package/dist/components/ui/card.mjs.map +1 -1
- package/dist/components/ui/chart.d.mts +1 -1
- package/dist/components/ui/chart.d.ts +1 -1
- package/dist/components/ui/chart.js +154 -130
- package/dist/components/ui/chart.js.map +1 -1
- package/dist/components/ui/chart.mjs +155 -131
- package/dist/components/ui/chart.mjs.map +1 -1
- package/dist/components/ui/checkbox.js +47 -40
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/checkbox.mjs +49 -42
- package/dist/components/ui/checkbox.mjs.map +1 -1
- package/dist/components/ui/divider.js +16 -13
- package/dist/components/ui/divider.js.map +1 -1
- package/dist/components/ui/divider.mjs +17 -14
- package/dist/components/ui/divider.mjs.map +1 -1
- package/dist/components/ui/drawer.js +44 -35
- package/dist/components/ui/drawer.js.map +1 -1
- package/dist/components/ui/drawer.mjs +45 -36
- package/dist/components/ui/drawer.mjs.map +1 -1
- package/dist/components/ui/dropdown.js +31 -24
- package/dist/components/ui/dropdown.js.map +1 -1
- package/dist/components/ui/dropdown.mjs +32 -25
- package/dist/components/ui/dropdown.mjs.map +1 -1
- package/dist/components/ui/field.js +18 -15
- package/dist/components/ui/field.js.map +1 -1
- package/dist/components/ui/field.mjs +19 -16
- package/dist/components/ui/field.mjs.map +1 -1
- package/dist/components/ui/icon-button.js +17 -14
- package/dist/components/ui/icon-button.js.map +1 -1
- package/dist/components/ui/icon-button.mjs +19 -16
- package/dist/components/ui/icon-button.mjs.map +1 -1
- package/dist/components/ui/index.mjs +35 -35
- package/dist/components/ui/input.js +34 -29
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/input.mjs +36 -31
- package/dist/components/ui/input.mjs.map +1 -1
- package/dist/components/ui/metric-card.js +24 -21
- package/dist/components/ui/metric-card.js.map +1 -1
- package/dist/components/ui/metric-card.mjs +25 -22
- package/dist/components/ui/metric-card.mjs.map +1 -1
- package/dist/components/ui/modal.js +91 -74
- package/dist/components/ui/modal.js.map +1 -1
- package/dist/components/ui/modal.mjs +92 -75
- package/dist/components/ui/modal.mjs.map +1 -1
- package/dist/components/ui/navigation-menu.js +114 -93
- package/dist/components/ui/navigation-menu.js.map +1 -1
- package/dist/components/ui/navigation-menu.mjs +115 -94
- package/dist/components/ui/navigation-menu.mjs.map +1 -1
- package/dist/components/ui/pagination.js +66 -55
- package/dist/components/ui/pagination.js.map +1 -1
- package/dist/components/ui/pagination.mjs +67 -56
- package/dist/components/ui/pagination.mjs.map +1 -1
- package/dist/components/ui/popover.js +39 -36
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/popover.mjs +40 -37
- package/dist/components/ui/popover.mjs.map +1 -1
- package/dist/components/ui/progress.js +73 -64
- package/dist/components/ui/progress.js.map +1 -1
- package/dist/components/ui/progress.mjs +74 -65
- package/dist/components/ui/progress.mjs.map +1 -1
- package/dist/components/ui/radio-group.js +23 -19
- package/dist/components/ui/radio-group.js.map +1 -1
- package/dist/components/ui/radio-group.mjs +25 -21
- package/dist/components/ui/radio-group.mjs.map +1 -1
- package/dist/components/ui/segmented.js +7 -6
- package/dist/components/ui/segmented.js.map +1 -1
- package/dist/components/ui/segmented.mjs +8 -7
- package/dist/components/ui/segmented.mjs.map +1 -1
- package/dist/components/ui/select.js +55 -48
- package/dist/components/ui/select.js.map +1 -1
- package/dist/components/ui/select.mjs +56 -49
- package/dist/components/ui/select.mjs.map +1 -1
- package/dist/components/ui/skeleton.js +20 -19
- package/dist/components/ui/skeleton.js.map +1 -1
- package/dist/components/ui/skeleton.mjs +21 -20
- package/dist/components/ui/skeleton.mjs.map +1 -1
- package/dist/components/ui/slider.js +68 -58
- package/dist/components/ui/slider.js.map +1 -1
- package/dist/components/ui/slider.mjs +69 -59
- package/dist/components/ui/slider.mjs.map +1 -1
- package/dist/components/ui/spinner.js +185 -176
- package/dist/components/ui/spinner.js.map +1 -1
- package/dist/components/ui/spinner.mjs +186 -177
- package/dist/components/ui/spinner.mjs.map +1 -1
- package/dist/components/ui/switch.js +39 -28
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/switch.mjs +41 -30
- package/dist/components/ui/switch.mjs.map +1 -1
- package/dist/components/ui/table.js +26 -23
- package/dist/components/ui/table.js.map +1 -1
- package/dist/components/ui/table.mjs +27 -24
- package/dist/components/ui/table.mjs.map +1 -1
- package/dist/components/ui/tabs.js +25 -9
- package/dist/components/ui/tabs.js.map +1 -1
- package/dist/components/ui/tabs.mjs +26 -10
- package/dist/components/ui/tabs.mjs.map +1 -1
- package/dist/components/ui/textarea.js +2 -1
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/components/ui/textarea.mjs +4 -3
- package/dist/components/ui/textarea.mjs.map +1 -1
- package/dist/components/ui/toast.js +104 -80
- package/dist/components/ui/toast.js.map +1 -1
- package/dist/components/ui/toast.mjs +105 -81
- package/dist/components/ui/toast.mjs.map +1 -1
- package/dist/components/ui/toggle-group.js +9 -8
- package/dist/components/ui/toggle-group.js.map +1 -1
- package/dist/components/ui/toggle-group.mjs +10 -9
- package/dist/components/ui/toggle-group.mjs.map +1 -1
- package/dist/components/ui/toggle.js +3 -2
- package/dist/components/ui/toggle.js.map +1 -1
- package/dist/components/ui/toggle.mjs +4 -3
- package/dist/components/ui/toggle.mjs.map +1 -1
- package/dist/components/ui/tooltip.js +18 -15
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/components/ui/tooltip.mjs +19 -16
- package/dist/components/ui/tooltip.mjs.map +1 -1
- package/package.json +27 -19
|
@@ -35,6 +35,7 @@ __export(radio_group_exports, {
|
|
|
35
35
|
radioItemVariants: () => radioItemVariants
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(radio_group_exports);
|
|
38
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
38
39
|
var React = __toESM(require("react"));
|
|
39
40
|
var RadioGroupPrimitive = __toESM(require("@radix-ui/react-radio-group"));
|
|
40
41
|
var import_class_variance_authority = require("class-variance-authority");
|
|
@@ -65,7 +66,7 @@ const radioGroupVariants = (0, import_class_variance_authority.cva)("grid gap-3"
|
|
|
65
66
|
const RadioGroup = React.forwardRef(({ className, orientation, size = "default", weight = "bold", color = "default", disabled, ...props }, ref) => {
|
|
66
67
|
const fieldContext = (0, import_field.useFieldContext)();
|
|
67
68
|
const resolvedDisabled = disabled ?? fieldContext?.disabled;
|
|
68
|
-
return /* @__PURE__ */
|
|
69
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupContext.Provider, { value: { size, weight, color, disabled: resolvedDisabled }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
69
70
|
RadioGroupPrimitive.Root,
|
|
70
71
|
{
|
|
71
72
|
ref,
|
|
@@ -74,7 +75,7 @@ const RadioGroup = React.forwardRef(({ className, orientation, size = "default",
|
|
|
74
75
|
disabled: resolvedDisabled,
|
|
75
76
|
...props
|
|
76
77
|
}
|
|
77
|
-
));
|
|
78
|
+
) });
|
|
78
79
|
});
|
|
79
80
|
RadioGroup.displayName = "RadioGroup";
|
|
80
81
|
const radioItemVariants = (0, import_class_variance_authority.cva)(
|
|
@@ -133,7 +134,7 @@ const RadioGroupItem = React.forwardRef(({ className, label, disabled, ...props
|
|
|
133
134
|
const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext);
|
|
134
135
|
const resolvedDisabled = disabled ?? groupDisabled;
|
|
135
136
|
const itemId = React.useId();
|
|
136
|
-
const radio = /* @__PURE__ */
|
|
137
|
+
const radio = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
137
138
|
RadioGroupPrimitive.Item,
|
|
138
139
|
{
|
|
139
140
|
ref,
|
|
@@ -144,24 +145,27 @@ const RadioGroupItem = React.forwardRef(({ className, label, disabled, ...props
|
|
|
144
145
|
radioColorMap[color].border,
|
|
145
146
|
className
|
|
146
147
|
),
|
|
147
|
-
...props
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
...props,
|
|
149
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center animate-radio-enter", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_utils.cn)("rounded-full", radioColorMap[color].dot, dotSizes[size]) }) })
|
|
150
|
+
}
|
|
150
151
|
);
|
|
151
152
|
if (!label) return radio;
|
|
152
|
-
return /* @__PURE__ */
|
|
153
|
-
"
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: (0, import_utils.cn)("group flex items-center", gapSizes[size]), children: [
|
|
154
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "flex items-center", children: radio }),
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
156
|
+
"label",
|
|
157
|
+
{
|
|
158
|
+
htmlFor: itemId,
|
|
159
|
+
className: (0, import_utils.cn)(
|
|
160
|
+
labelSizes[size],
|
|
161
|
+
"text-text-muted cursor-pointer select-none transition-colors duration-micro",
|
|
162
|
+
"group-hover:text-foreground",
|
|
163
|
+
resolvedDisabled && "opacity-50 cursor-not-allowed"
|
|
164
|
+
),
|
|
165
|
+
children: label
|
|
166
|
+
}
|
|
167
|
+
)
|
|
168
|
+
] });
|
|
165
169
|
});
|
|
166
170
|
RadioGroupItem.displayName = "RadioGroupItem";
|
|
167
171
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6DM;AA3DN,YAAuB;AACvB,0BAAqC;AACrC,sCAAoB;AACpB,mBAAmB;AACnB,mBAAgC;AAGhC,MAAM,gBAAgB;AAAA,EACpB,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AAAA,EACA,SAAS;AAAA,IACP,QAAQ;AAAA,IACR,KAAK;AAAA,EACP;AACF;AAWA,MAAM,oBAAoB,MAAM,cAAsC,EAAE,MAAM,WAAW,QAAQ,QAAQ,OAAO,UAAU,CAAC;AAG3H,MAAM,yBAAqB,qCAAI,cAAc;AAAA,EAC3C,UAAU;AAAA,IACR,aAAa;AAAA,MACX,UAAU;AAAA,MACV,YAAY;AAAA,IACd;AAAA,EACF;AAAA,EACA,iBAAiB;AAAA,IACf,aAAa;AAAA,EACf;AACF,CAAC;AAUD,MAAM,aAAa,MAAM,WAGvB,CAAC,EAAE,WAAW,aAAa,OAAO,WAAW,SAAS,QAAQ,QAAQ,WAAW,UAAU,GAAG,MAAM,GAAG,QAAQ;AAC/G,QAAM,mBAAe,8BAAgB;AACrC,QAAM,mBAAmB,YAAY,cAAc;AAEnD,SACE,4CAAC,kBAAkB,UAAlB,EAA2B,OAAO,EAAE,MAAM,QAAQ,OAAO,UAAU,iBAAiB,GACnF;AAAA,IAAC,oBAAoB;AAAA,IAApB;AAAA,MACC;AAAA,MACA,eAAW,iBAAG,mBAAmB,EAAE,YAAY,CAAC,GAAG,SAAS;AAAA,MAC5D,aAAa,eAAe;AAAA,MAC5B,UAAU;AAAA,MACT,GAAG;AAAA;AAAA,EACN,GACF;AAEJ,CAAC;AACD,WAAW,cAAc;AAGzB,MAAM,wBAAoB;AAAA,EACxB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA;AAAA,IAEA;AAAA,EACF,EAAE,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,MAAM;AAAA,QACJ,IAAI;AAAA;AAAA,QACJ,SAAS;AAAA;AAAA,QACT,IAAI;AAAA;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,QACN,MAAM;AAAA;AAAA,QACN,MAAM;AAAA;AAAA,MACR;AAAA,IACF;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,MACN,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAGA,MAAM,WAAW;AAAA,EACf,IAAI;AAAA;AAAA,EACJ,SAAS;AAAA;AAAA,EACT,IAAI;AAAA;AACN;AAGA,MAAM,aAAa;AAAA,EACjB,IAAI;AAAA;AAAA,EACJ,SAAS;AAAA;AAAA,EACT,IAAI;AAAA;AACN;AAGA,MAAM,WAAW;AAAA,EACf,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,IAAI;AACN;AAOA,MAAM,iBAAiB,MAAM,WAG3B,CAAC,EAAE,WAAW,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ;AACnD,QAAM,EAAE,MAAM,QAAQ,OAAO,UAAU,cAAc,IAAI,MAAM,WAAW,iBAAiB;AAC3F,QAAM,mBAAmB,YAAY;AACrC,QAAM,SAAS,MAAM,MAAM;AAE3B,QAAM,QACJ;AAAA,IAAC,oBAAoB;AAAA,IAApB;AAAA,MACC;AAAA,MACA,IAAI,QAAQ,SAAS;AAAA,MACrB,UAAU;AAAA,MACV,eAAW;AAAA,QACT,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAAA,QAClC,cAAc,KAAK,EAAE;AAAA,QACrB;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,sDAAC,oBAAoB,WAApB,EAA8B,WAAU,wDACvC,sDAAC,SAAI,eAAW,iBAAG,gBAAgB,cAAc,KAAK,EAAE,KAAK,SAAS,IAAI,CAAC,GAAG,GAChF;AAAA;AAAA,EACF;AAGF,MAAI,CAAC,MAAO,QAAO;AAEnB,SACE,6CAAC,SAAI,eAAW,iBAAG,2BAA2B,SAAS,IAAI,CAAC,GAC1D;AAAA,gDAAC,SAAI,WAAU,qBACZ,iBACH;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,eAAW;AAAA,UACT,WAAW,IAAI;AAAA,UACf;AAAA,UACA;AAAA,UACA,oBAAoB;AAAA,QACtB;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,KACF;AAEJ,CAAC;AACD,eAAe,cAAc;","names":[]}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
4
5
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import { cn } from "../../lib/utils";
|
|
6
|
-
import { useFieldContext } from "./field";
|
|
6
|
+
import { cn } from "../../lib/utils.mjs";
|
|
7
|
+
import { useFieldContext } from "./field.mjs";
|
|
7
8
|
const radioColorMap = {
|
|
8
9
|
default: {
|
|
9
10
|
border: "data-[state=checked]:border-foreground",
|
|
@@ -29,7 +30,7 @@ const radioGroupVariants = cva("grid gap-3", {
|
|
|
29
30
|
const RadioGroup = React.forwardRef(({ className, orientation, size = "default", weight = "bold", color = "default", disabled, ...props }, ref) => {
|
|
30
31
|
const fieldContext = useFieldContext();
|
|
31
32
|
const resolvedDisabled = disabled ?? fieldContext?.disabled;
|
|
32
|
-
return /* @__PURE__ */
|
|
33
|
+
return /* @__PURE__ */ jsx(RadioGroupContext.Provider, { value: { size, weight, color, disabled: resolvedDisabled }, children: /* @__PURE__ */ jsx(
|
|
33
34
|
RadioGroupPrimitive.Root,
|
|
34
35
|
{
|
|
35
36
|
ref,
|
|
@@ -38,7 +39,7 @@ const RadioGroup = React.forwardRef(({ className, orientation, size = "default",
|
|
|
38
39
|
disabled: resolvedDisabled,
|
|
39
40
|
...props
|
|
40
41
|
}
|
|
41
|
-
));
|
|
42
|
+
) });
|
|
42
43
|
});
|
|
43
44
|
RadioGroup.displayName = "RadioGroup";
|
|
44
45
|
const radioItemVariants = cva(
|
|
@@ -97,7 +98,7 @@ const RadioGroupItem = React.forwardRef(({ className, label, disabled, ...props
|
|
|
97
98
|
const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext);
|
|
98
99
|
const resolvedDisabled = disabled ?? groupDisabled;
|
|
99
100
|
const itemId = React.useId();
|
|
100
|
-
const radio = /* @__PURE__ */
|
|
101
|
+
const radio = /* @__PURE__ */ jsx(
|
|
101
102
|
RadioGroupPrimitive.Item,
|
|
102
103
|
{
|
|
103
104
|
ref,
|
|
@@ -108,24 +109,27 @@ const RadioGroupItem = React.forwardRef(({ className, label, disabled, ...props
|
|
|
108
109
|
radioColorMap[color].border,
|
|
109
110
|
className
|
|
110
111
|
),
|
|
111
|
-
...props
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
...props,
|
|
113
|
+
children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center animate-radio-enter", children: /* @__PURE__ */ jsx("div", { className: cn("rounded-full", radioColorMap[color].dot, dotSizes[size]) }) })
|
|
114
|
+
}
|
|
114
115
|
);
|
|
115
116
|
if (!label) return radio;
|
|
116
|
-
return /* @__PURE__ */
|
|
117
|
-
"
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
117
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("group flex items-center", gapSizes[size]), children: [
|
|
118
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center", children: radio }),
|
|
119
|
+
/* @__PURE__ */ jsx(
|
|
120
|
+
"label",
|
|
121
|
+
{
|
|
122
|
+
htmlFor: itemId,
|
|
123
|
+
className: cn(
|
|
124
|
+
labelSizes[size],
|
|
125
|
+
"text-text-muted cursor-pointer select-none transition-colors duration-micro",
|
|
126
|
+
"group-hover:text-foreground",
|
|
127
|
+
resolvedDisabled && "opacity-50 cursor-not-allowed"
|
|
128
|
+
),
|
|
129
|
+
children: label
|
|
130
|
+
}
|
|
131
|
+
)
|
|
132
|
+
] });
|
|
129
133
|
});
|
|
130
134
|
RadioGroupItem.displayName = "RadioGroupItem";
|
|
131
135
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/radio-group.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\nimport { useFieldContext } from './field'\n\n// Color maps for checked state\nconst radioColorMap = {\n default: {\n border: 'data-[state=checked]:border-foreground',\n dot: 'bg-foreground',\n },\n primary: {\n border: 'data-[state=checked]:border-primary',\n dot: 'bg-primary',\n },\n} as const\n\nexport type RadioColor = keyof typeof radioColorMap\n\n// Context to pass size, weight, color from RadioGroup to RadioGroupItem\ntype RadioGroupContextValue = {\n size: 'sm' | 'default' | 'lg'\n weight: 'thin' | 'bold'\n color: RadioColor\n disabled?: boolean\n}\nconst RadioGroupContext = React.createContext<RadioGroupContextValue>({ size: 'default', weight: 'bold', color: 'default' })\n\n// RadioGroup container\nconst radioGroupVariants = cva('grid gap-3', {\n variants: {\n orientation: {\n vertical: 'grid-cols-1',\n horizontal: 'grid-flow-col auto-cols-max gap-4',\n },\n },\n defaultVariants: {\n orientation: 'vertical',\n },\n})\n\nexport interface RadioGroupProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root> {\n size?: 'sm' | 'default' | 'lg'\n weight?: 'thin' | 'bold'\n /** Checked state color */\n color?: RadioColor\n}\n\nconst RadioGroup = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n RadioGroupProps\n>(({ className, orientation, size = 'default', weight = 'bold', color = 'default', disabled, ...props }, ref) => {\n const fieldContext = useFieldContext()\n const resolvedDisabled = disabled ?? fieldContext?.disabled\n\n return (\n <RadioGroupContext.Provider value={{ size, weight, color, disabled: resolvedDisabled }}>\n <RadioGroupPrimitive.Root\n ref={ref}\n className={cn(radioGroupVariants({ orientation }), className)}\n orientation={orientation || undefined}\n disabled={resolvedDisabled}\n {...props}\n />\n </RadioGroupContext.Provider>\n )\n})\nRadioGroup.displayName = 'RadioGroup'\n\n// RadioGroupItem circle variants\nconst radioItemVariants = cva(\n [\n 'relative shrink-0 rounded-full border-border-form hover:border-border-form-strong transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n // Transparent hit area expansion via ::after\n \"after:absolute after:content-['']\",\n ].join(' '),\n {\n variants: {\n size: {\n sm: 'w-3.5 h-3.5 after:-inset-[5px]', // 14px circle → 24px click\n default: 'w-4 h-4 after:-inset-2', // 16px circle → 32px click\n lg: 'w-5 h-5 after:-inset-2', // 20px circle → 36px click\n },\n weight: {\n thin: 'border', // 1px\n bold: 'border-2', // 2px\n },\n },\n defaultVariants: {\n size: 'default',\n weight: 'bold',\n },\n }\n)\n\n// Dot sizes per radio size\nconst dotSizes = {\n sm: 'w-1.5 h-1.5', // 6px\n default: 'w-2 h-2', // 8px\n lg: 'w-2.5 h-2.5', // 10px\n}\n\n// Label font sizes\nconst labelSizes = {\n sm: 'text-xs', // 12px\n default: 'text-md', // 14px\n lg: 'text-base', // 16px\n}\n\n// Gap between radio and label\nconst gapSizes = {\n sm: 'gap-1.5',\n default: 'gap-2',\n lg: 'gap-2.5',\n}\n\nexport interface RadioGroupItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item> {\n label?: string\n}\n\nconst RadioGroupItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n RadioGroupItemProps\n>(({ className, label, disabled, ...props }, ref) => {\n const { size, weight, color, disabled: groupDisabled } = React.useContext(RadioGroupContext)\n const resolvedDisabled = disabled ?? groupDisabled\n const itemId = React.useId()\n\n const radio = (\n <RadioGroupPrimitive.Item\n ref={ref}\n id={label ? itemId : undefined}\n disabled={resolvedDisabled}\n className={cn(\n radioItemVariants({ size, weight }),\n radioColorMap[color].border,\n className\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator className=\"flex items-center justify-center animate-radio-enter\">\n <div className={cn('rounded-full', radioColorMap[color].dot, dotSizes[size])} />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n )\n\n if (!label) return radio\n\n return (\n <div className={cn('group flex items-center', gapSizes[size])}>\n <div className=\"flex items-center\">\n {radio}\n </div>\n <label\n htmlFor={itemId}\n className={cn(\n labelSizes[size],\n 'text-text-muted cursor-pointer select-none transition-colors duration-micro',\n 'group-hover:text-foreground',\n resolvedDisabled && 'opacity-50 cursor-not-allowed'\n )}\n >\n {label}\n </label>\n </div>\n )\n})\nRadioGroupItem.displayName = 'RadioGroupItem'\n\nexport { RadioGroup, RadioGroupItem, radioGroupVariants, radioItemVariants }\n"],"mappings":"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","names":[]}
|
|
@@ -35,6 +35,7 @@ __export(segmented_exports, {
|
|
|
35
35
|
segmentedVariants: () => segmentedVariants
|
|
36
36
|
});
|
|
37
37
|
module.exports = __toCommonJS(segmented_exports);
|
|
38
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
38
39
|
var React = __toESM(require("react"));
|
|
39
40
|
var RadioGroupPrimitive = __toESM(require("@radix-ui/react-radio-group"));
|
|
40
41
|
var import_class_variance_authority = require("class-variance-authority");
|
|
@@ -189,14 +190,14 @@ const segmentedItemVariants = (0, import_class_variance_authority.cva)(
|
|
|
189
190
|
);
|
|
190
191
|
const Segmented = React.forwardRef(({ className, variant, size, radius, fontWeight, ...props }, ref) => {
|
|
191
192
|
const resolvedFontWeight = fontWeight ?? "normal";
|
|
192
|
-
return /* @__PURE__ */
|
|
193
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(SegmentedContext.Provider, { value: { variant: variant || "default", size: size || "default", radius: radius || "default" }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
193
194
|
RadioGroupPrimitive.Root,
|
|
194
195
|
{
|
|
195
196
|
className: (0, import_utils.cn)(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className),
|
|
196
197
|
...props,
|
|
197
198
|
ref
|
|
198
199
|
}
|
|
199
|
-
));
|
|
200
|
+
) });
|
|
200
201
|
});
|
|
201
202
|
Segmented.displayName = "Segmented";
|
|
202
203
|
const iconSizeClasses = {
|
|
@@ -213,7 +214,7 @@ const SegmentedItem = React.forwardRef(({ className, children, size, radius, con
|
|
|
213
214
|
const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext();
|
|
214
215
|
const resolvedSize = size || contextSize || "default";
|
|
215
216
|
const resolvedRadius = radius || contextRadius || "default";
|
|
216
|
-
return /* @__PURE__ */
|
|
217
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
217
218
|
RadioGroupPrimitive.Item,
|
|
218
219
|
{
|
|
219
220
|
ref,
|
|
@@ -222,9 +223,9 @@ const SegmentedItem = React.forwardRef(({ className, children, size, radius, con
|
|
|
222
223
|
iconSizeClasses[resolvedSize],
|
|
223
224
|
className
|
|
224
225
|
),
|
|
225
|
-
...props
|
|
226
|
-
|
|
227
|
-
|
|
226
|
+
...props,
|
|
227
|
+
children
|
|
228
|
+
}
|
|
228
229
|
);
|
|
229
230
|
});
|
|
230
231
|
SegmentedItem.displayName = "SegmentedItem";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/segmented.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass variant and size from Segmented to SegmentedItem\ntype SegmentedContextValue = {\n variant?: 'default' | 'outline' | 'underline' | 'ghost'\n size?: 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst SegmentedContext = React.createContext<SegmentedContextValue>({})\nconst useSegmentedContext = () => React.useContext(SegmentedContext)\n\nconst segmentedVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n default: 'bg-background-muted gap-1',\n outline: 'bg-background border border-border-form gap-1',\n underline: 'bg-transparent border-b border-border-form gap-0',\n ghost: 'bg-transparent gap-1',\n },\n size: {\n sm: 'h-8', // 32px height\n md: 'h-9', // 36px height\n default: 'h-10', // 40px height\n lg: 'h-12', // 48px height\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n fontWeight: {\n normal: '[&>*]:font-normal',\n semibold: '[&>*]:font-semibold',\n },\n },\n compoundVariants: [\n // Padding for default/outline/ghost variants\n { variant: 'default', className: 'p-1' },\n { variant: 'outline', className: 'p-1' },\n { variant: 'ghost', className: 'p-1' },\n // Underline has no padding\n { variant: 'underline', className: 'p-0' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n },\n }\n)\n\nconst segmentedItemVariants = cva(\n [\n 'inline-flex items-center justify-center whitespace-nowrap h-full',\n 'transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n // Default: light background when selected, text emphasis on hover\n default: [\n 'hover:text-foreground',\n 'data-[state=checked]:bg-background data-[state=checked]:text-foreground',\n 'data-[state=checked]:shadow-sm',\n ].join(' '),\n // Outline: gray background when selected\n outline: [\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n 'hover:text-foreground hover:bg-background-muted',\n ].join(' '),\n // Underline: bottom border indicator (Stripe/GitHub style)\n underline: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border-form',\n 'data-[state=checked]:text-foreground data-[state=checked]:border-foreground',\n ].join(' '),\n // Ghost: pill background only on selected (Notion/Figma style)\n ghost: [\n 'hover:text-foreground hover:bg-background-muted',\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n ].join(' '),\n },\n size: {\n sm: 'text-xs', // 12px\n md: 'text-sm', // 13px\n default: 'text-sm', // 13px\n lg: 'text-md', // 14px\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n },\n // Content type determines padding and aspect ratio\n contentType: {\n // Icon only: square aspect ratio like IconButton\n icon: 'aspect-square',\n // Icon + text: rectangular (gap is set via compoundVariants)\n 'icon-text': '',\n // Text only: standard button padding\n text: '',\n },\n },\n compoundVariants: [\n // Icon + text - same padding rules as Button/Toggle\n { contentType: 'icon-text', size: 'sm', className: 'px-3 gap-2' }, // 12px padding, 8px gap\n { contentType: 'icon-text', size: 'md', className: 'px-3.5 gap-2' }, // 14px padding, 8px gap\n { contentType: 'icon-text', size: 'default', className: 'px-4 gap-2' }, // 16px padding, 8px gap\n { contentType: 'icon-text', size: 'lg', className: 'px-6 gap-2' }, // 24px padding, 8px gap\n // Text only - same padding rules as Button/Toggle\n { contentType: 'text', size: 'sm', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'md', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'default', className: 'px-4' }, // 16px\n { contentType: 'text', size: 'lg', className: 'px-6' }, // 24px\n // Underline variant has no rounded corners\n { variant: 'underline', className: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n contentType: 'text',\n },\n }\n)\n\nexport interface SegmentedProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n VariantProps<typeof segmentedVariants> {}\n\nconst Segmented = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n SegmentedProps\n>(({ className, variant, size, radius, fontWeight, ...props }, ref) => {\n // All variants default to normal font weight\n const resolvedFontWeight = fontWeight ?? 'normal'\n\n return (\n <SegmentedContext.Provider value={{ variant: variant || 'default', size: size || 'default', radius: radius || 'default' }}>\n <RadioGroupPrimitive.Root\n className={cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className)}\n {...props}\n ref={ref}\n />\n </SegmentedContext.Provider>\n )\n})\nSegmented.displayName = 'Segmented'\n\n// Icon size for segmented control (4-step scale, Icon+Text mode)\n// sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nexport interface SegmentedItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n Omit<VariantProps<typeof segmentedItemVariants>, 'variant'> {}\n\nconst SegmentedItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n SegmentedItemProps\n>(({ className, children, size, radius, contentType, ...props }, ref) => {\n const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext()\n const resolvedSize = size || contextSize || 'default'\n const resolvedRadius = radius || contextRadius || 'default'\n\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n segmentedItemVariants({ variant, size: resolvedSize, radius: resolvedRadius, contentType }),\n iconSizeClasses[resolvedSize],\n className\n )}\n {...props}\n >\n {children}\n </RadioGroupPrimitive.Item>\n )\n})\nSegmentedItem.displayName = 'SegmentedItem'\n\nexport { Segmented, SegmentedItem, segmentedVariants, segmentedItemVariants }\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/segmented.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass variant and size from Segmented to SegmentedItem\ntype SegmentedContextValue = {\n variant?: 'default' | 'outline' | 'underline' | 'ghost'\n size?: 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst SegmentedContext = React.createContext<SegmentedContextValue>({})\nconst useSegmentedContext = () => React.useContext(SegmentedContext)\n\nconst segmentedVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n default: 'bg-background-muted gap-1',\n outline: 'bg-background border border-border-form gap-1',\n underline: 'bg-transparent border-b border-border-form gap-0',\n ghost: 'bg-transparent gap-1',\n },\n size: {\n sm: 'h-8', // 32px height\n md: 'h-9', // 36px height\n default: 'h-10', // 40px height\n lg: 'h-12', // 48px height\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n fontWeight: {\n normal: '[&>*]:font-normal',\n semibold: '[&>*]:font-semibold',\n },\n },\n compoundVariants: [\n // Padding for default/outline/ghost variants\n { variant: 'default', className: 'p-1' },\n { variant: 'outline', className: 'p-1' },\n { variant: 'ghost', className: 'p-1' },\n // Underline has no padding\n { variant: 'underline', className: 'p-0' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n },\n }\n)\n\nconst segmentedItemVariants = cva(\n [\n 'inline-flex items-center justify-center whitespace-nowrap h-full',\n 'transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n // Default: light background when selected, text emphasis on hover\n default: [\n 'hover:text-foreground',\n 'data-[state=checked]:bg-background data-[state=checked]:text-foreground',\n 'data-[state=checked]:shadow-sm',\n ].join(' '),\n // Outline: gray background when selected\n outline: [\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n 'hover:text-foreground hover:bg-background-muted',\n ].join(' '),\n // Underline: bottom border indicator (Stripe/GitHub style)\n underline: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border-form',\n 'data-[state=checked]:text-foreground data-[state=checked]:border-foreground',\n ].join(' '),\n // Ghost: pill background only on selected (Notion/Figma style)\n ghost: [\n 'hover:text-foreground hover:bg-background-muted',\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n ].join(' '),\n },\n size: {\n sm: 'text-xs', // 12px\n md: 'text-sm', // 13px\n default: 'text-sm', // 13px\n lg: 'text-md', // 14px\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n },\n // Content type determines padding and aspect ratio\n contentType: {\n // Icon only: square aspect ratio like IconButton\n icon: 'aspect-square',\n // Icon + text: rectangular (gap is set via compoundVariants)\n 'icon-text': '',\n // Text only: standard button padding\n text: '',\n },\n },\n compoundVariants: [\n // Icon + text - same padding rules as Button/Toggle\n { contentType: 'icon-text', size: 'sm', className: 'px-3 gap-2' }, // 12px padding, 8px gap\n { contentType: 'icon-text', size: 'md', className: 'px-3.5 gap-2' }, // 14px padding, 8px gap\n { contentType: 'icon-text', size: 'default', className: 'px-4 gap-2' }, // 16px padding, 8px gap\n { contentType: 'icon-text', size: 'lg', className: 'px-6 gap-2' }, // 24px padding, 8px gap\n // Text only - same padding rules as Button/Toggle\n { contentType: 'text', size: 'sm', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'md', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'default', className: 'px-4' }, // 16px\n { contentType: 'text', size: 'lg', className: 'px-6' }, // 24px\n // Underline variant has no rounded corners\n { variant: 'underline', className: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n contentType: 'text',\n },\n }\n)\n\nexport interface SegmentedProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n VariantProps<typeof segmentedVariants> {}\n\nconst Segmented = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n SegmentedProps\n>(({ className, variant, size, radius, fontWeight, ...props }, ref) => {\n // All variants default to normal font weight\n const resolvedFontWeight = fontWeight ?? 'normal'\n\n return (\n <SegmentedContext.Provider value={{ variant: variant || 'default', size: size || 'default', radius: radius || 'default' }}>\n <RadioGroupPrimitive.Root\n className={cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className)}\n {...props}\n ref={ref}\n />\n </SegmentedContext.Provider>\n )\n})\nSegmented.displayName = 'Segmented'\n\n// Icon size for segmented control (4-step scale, Icon+Text mode)\n// sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nexport interface SegmentedItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n Omit<VariantProps<typeof segmentedItemVariants>, 'variant'> {}\n\nconst SegmentedItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n SegmentedItemProps\n>(({ className, children, size, radius, contentType, ...props }, ref) => {\n const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext()\n const resolvedSize = size || contextSize || 'default'\n const resolvedRadius = radius || contextRadius || 'default'\n\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n segmentedItemVariants({ variant, size: resolvedSize, radius: resolvedRadius, contentType }),\n iconSizeClasses[resolvedSize],\n className\n )}\n {...props}\n >\n {children}\n </RadioGroupPrimitive.Item>\n )\n})\nSegmentedItem.displayName = 'SegmentedItem'\n\nexport { Segmented, SegmentedItem, segmentedVariants, segmentedItemVariants }\n"],"mappings":"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","names":[]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
3
|
import * as React from "react";
|
|
3
4
|
import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
|
|
4
5
|
import { cva } from "class-variance-authority";
|
|
5
|
-
import { cn } from "../../lib/utils";
|
|
6
|
+
import { cn } from "../../lib/utils.mjs";
|
|
6
7
|
const SegmentedContext = React.createContext({});
|
|
7
8
|
const useSegmentedContext = () => React.useContext(SegmentedContext);
|
|
8
9
|
const segmentedVariants = cva(
|
|
@@ -153,14 +154,14 @@ const segmentedItemVariants = cva(
|
|
|
153
154
|
);
|
|
154
155
|
const Segmented = React.forwardRef(({ className, variant, size, radius, fontWeight, ...props }, ref) => {
|
|
155
156
|
const resolvedFontWeight = fontWeight ?? "normal";
|
|
156
|
-
return /* @__PURE__ */
|
|
157
|
+
return /* @__PURE__ */ jsx(SegmentedContext.Provider, { value: { variant: variant || "default", size: size || "default", radius: radius || "default" }, children: /* @__PURE__ */ jsx(
|
|
157
158
|
RadioGroupPrimitive.Root,
|
|
158
159
|
{
|
|
159
160
|
className: cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className),
|
|
160
161
|
...props,
|
|
161
162
|
ref
|
|
162
163
|
}
|
|
163
|
-
));
|
|
164
|
+
) });
|
|
164
165
|
});
|
|
165
166
|
Segmented.displayName = "Segmented";
|
|
166
167
|
const iconSizeClasses = {
|
|
@@ -177,7 +178,7 @@ const SegmentedItem = React.forwardRef(({ className, children, size, radius, con
|
|
|
177
178
|
const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext();
|
|
178
179
|
const resolvedSize = size || contextSize || "default";
|
|
179
180
|
const resolvedRadius = radius || contextRadius || "default";
|
|
180
|
-
return /* @__PURE__ */
|
|
181
|
+
return /* @__PURE__ */ jsx(
|
|
181
182
|
RadioGroupPrimitive.Item,
|
|
182
183
|
{
|
|
183
184
|
ref,
|
|
@@ -186,9 +187,9 @@ const SegmentedItem = React.forwardRef(({ className, children, size, radius, con
|
|
|
186
187
|
iconSizeClasses[resolvedSize],
|
|
187
188
|
className
|
|
188
189
|
),
|
|
189
|
-
...props
|
|
190
|
-
|
|
191
|
-
|
|
190
|
+
...props,
|
|
191
|
+
children
|
|
192
|
+
}
|
|
192
193
|
);
|
|
193
194
|
});
|
|
194
195
|
SegmentedItem.displayName = "SegmentedItem";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/ui/segmented.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass variant and size from Segmented to SegmentedItem\ntype SegmentedContextValue = {\n variant?: 'default' | 'outline' | 'underline' | 'ghost'\n size?: 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst SegmentedContext = React.createContext<SegmentedContextValue>({})\nconst useSegmentedContext = () => React.useContext(SegmentedContext)\n\nconst segmentedVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n default: 'bg-background-muted gap-1',\n outline: 'bg-background border border-border-form gap-1',\n underline: 'bg-transparent border-b border-border-form gap-0',\n ghost: 'bg-transparent gap-1',\n },\n size: {\n sm: 'h-8', // 32px height\n md: 'h-9', // 36px height\n default: 'h-10', // 40px height\n lg: 'h-12', // 48px height\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n fontWeight: {\n normal: '[&>*]:font-normal',\n semibold: '[&>*]:font-semibold',\n },\n },\n compoundVariants: [\n // Padding for default/outline/ghost variants\n { variant: 'default', className: 'p-1' },\n { variant: 'outline', className: 'p-1' },\n { variant: 'ghost', className: 'p-1' },\n // Underline has no padding\n { variant: 'underline', className: 'p-0' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n },\n }\n)\n\nconst segmentedItemVariants = cva(\n [\n 'inline-flex items-center justify-center whitespace-nowrap h-full',\n 'transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n // Default: light background when selected, text emphasis on hover\n default: [\n 'hover:text-foreground',\n 'data-[state=checked]:bg-background data-[state=checked]:text-foreground',\n 'data-[state=checked]:shadow-sm',\n ].join(' '),\n // Outline: gray background when selected\n outline: [\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n 'hover:text-foreground hover:bg-background-muted',\n ].join(' '),\n // Underline: bottom border indicator (Stripe/GitHub style)\n underline: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border-form',\n 'data-[state=checked]:text-foreground data-[state=checked]:border-foreground',\n ].join(' '),\n // Ghost: pill background only on selected (Notion/Figma style)\n ghost: [\n 'hover:text-foreground hover:bg-background-muted',\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n ].join(' '),\n },\n size: {\n sm: 'text-xs', // 12px\n md: 'text-sm', // 13px\n default: 'text-sm', // 13px\n lg: 'text-md', // 14px\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n },\n // Content type determines padding and aspect ratio\n contentType: {\n // Icon only: square aspect ratio like IconButton\n icon: 'aspect-square',\n // Icon + text: rectangular (gap is set via compoundVariants)\n 'icon-text': '',\n // Text only: standard button padding\n text: '',\n },\n },\n compoundVariants: [\n // Icon + text - same padding rules as Button/Toggle\n { contentType: 'icon-text', size: 'sm', className: 'px-3 gap-2' }, // 12px padding, 8px gap\n { contentType: 'icon-text', size: 'md', className: 'px-3.5 gap-2' }, // 14px padding, 8px gap\n { contentType: 'icon-text', size: 'default', className: 'px-4 gap-2' }, // 16px padding, 8px gap\n { contentType: 'icon-text', size: 'lg', className: 'px-6 gap-2' }, // 24px padding, 8px gap\n // Text only - same padding rules as Button/Toggle\n { contentType: 'text', size: 'sm', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'md', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'default', className: 'px-4' }, // 16px\n { contentType: 'text', size: 'lg', className: 'px-6' }, // 24px\n // Underline variant has no rounded corners\n { variant: 'underline', className: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n contentType: 'text',\n },\n }\n)\n\nexport interface SegmentedProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n VariantProps<typeof segmentedVariants> {}\n\nconst Segmented = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n SegmentedProps\n>(({ className, variant, size, radius, fontWeight, ...props }, ref) => {\n // All variants default to normal font weight\n const resolvedFontWeight = fontWeight ?? 'normal'\n\n return (\n <SegmentedContext.Provider value={{ variant: variant || 'default', size: size || 'default', radius: radius || 'default' }}>\n <RadioGroupPrimitive.Root\n className={cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className)}\n {...props}\n ref={ref}\n />\n </SegmentedContext.Provider>\n )\n})\nSegmented.displayName = 'Segmented'\n\n// Icon size for segmented control (4-step scale, Icon+Text mode)\n// sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nexport interface SegmentedItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n Omit<VariantProps<typeof segmentedItemVariants>, 'variant'> {}\n\nconst SegmentedItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n SegmentedItemProps\n>(({ className, children, size, radius, contentType, ...props }, ref) => {\n const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext()\n const resolvedSize = size || contextSize || 'default'\n const resolvedRadius = radius || contextRadius || 'default'\n\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n segmentedItemVariants({ variant, size: resolvedSize, radius: resolvedRadius, contentType }),\n iconSizeClasses[resolvedSize],\n className\n )}\n {...props}\n >\n {children}\n </RadioGroupPrimitive.Item>\n )\n})\nSegmentedItem.displayName = 'SegmentedItem'\n\nexport { Segmented, SegmentedItem, segmentedVariants, segmentedItemVariants }\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/components/ui/segmented.tsx"],"sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as RadioGroupPrimitive from '@radix-ui/react-radio-group'\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport { cn } from '../../lib/utils'\n\n// Context to pass variant and size from Segmented to SegmentedItem\ntype SegmentedContextValue = {\n variant?: 'default' | 'outline' | 'underline' | 'ghost'\n size?: 'sm' | 'md' | 'default' | 'lg'\n radius?: 'none' | 'sm' | 'base' | 'default' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'\n}\nconst SegmentedContext = React.createContext<SegmentedContextValue>({})\nconst useSegmentedContext = () => React.useContext(SegmentedContext)\n\nconst segmentedVariants = cva(\n 'inline-flex items-center text-text-subtle',\n {\n variants: {\n variant: {\n default: 'bg-background-muted gap-1',\n outline: 'bg-background border border-border-form gap-1',\n underline: 'bg-transparent border-b border-border-form gap-0',\n ghost: 'bg-transparent gap-1',\n },\n size: {\n sm: 'h-8', // 32px height\n md: 'h-9', // 36px height\n default: 'h-10', // 40px height\n lg: 'h-12', // 48px height\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-lg',\n xl: 'rounded-xl',\n '2xl': 'rounded-2xl',\n '3xl': 'rounded-3xl',\n full: 'rounded-full',\n },\n fontWeight: {\n normal: '[&>*]:font-normal',\n semibold: '[&>*]:font-semibold',\n },\n },\n compoundVariants: [\n // Padding for default/outline/ghost variants\n { variant: 'default', className: 'p-1' },\n { variant: 'outline', className: 'p-1' },\n { variant: 'ghost', className: 'p-1' },\n // Underline has no padding\n { variant: 'underline', className: 'p-0' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n fontWeight: 'normal',\n },\n }\n)\n\nconst segmentedItemVariants = cva(\n [\n 'inline-flex items-center justify-center whitespace-nowrap h-full',\n 'transition-all duration-micro ease-out',\n 'focus-visible:focus-ring',\n 'disabled:pointer-events-none disabled:opacity-50',\n ].join(' '),\n {\n variants: {\n variant: {\n // Default: light background when selected, text emphasis on hover\n default: [\n 'hover:text-foreground',\n 'data-[state=checked]:bg-background data-[state=checked]:text-foreground',\n 'data-[state=checked]:shadow-sm',\n ].join(' '),\n // Outline: gray background when selected\n outline: [\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n 'hover:text-foreground hover:bg-background-muted',\n ].join(' '),\n // Underline: bottom border indicator (Stripe/GitHub style)\n underline: [\n 'border-b-2 border-transparent -mb-px',\n 'hover:text-foreground hover:border-border-form',\n 'data-[state=checked]:text-foreground data-[state=checked]:border-foreground',\n ].join(' '),\n // Ghost: pill background only on selected (Notion/Figma style)\n ghost: [\n 'hover:text-foreground hover:bg-background-muted',\n 'data-[state=checked]:bg-background-muted data-[state=checked]:text-foreground',\n ].join(' '),\n },\n size: {\n sm: 'text-xs', // 12px\n md: 'text-sm', // 13px\n default: 'text-sm', // 13px\n lg: 'text-md', // 14px\n },\n radius: {\n none: 'rounded-none',\n sm: 'rounded-sm',\n base: 'rounded',\n default: 'rounded-md',\n lg: 'rounded-md',\n xl: 'rounded-lg',\n '2xl': 'rounded-xl',\n '3xl': 'rounded-2xl',\n full: 'rounded-full',\n },\n // Content type determines padding and aspect ratio\n contentType: {\n // Icon only: square aspect ratio like IconButton\n icon: 'aspect-square',\n // Icon + text: rectangular (gap is set via compoundVariants)\n 'icon-text': '',\n // Text only: standard button padding\n text: '',\n },\n },\n compoundVariants: [\n // Icon + text - same padding rules as Button/Toggle\n { contentType: 'icon-text', size: 'sm', className: 'px-3 gap-2' }, // 12px padding, 8px gap\n { contentType: 'icon-text', size: 'md', className: 'px-3.5 gap-2' }, // 14px padding, 8px gap\n { contentType: 'icon-text', size: 'default', className: 'px-4 gap-2' }, // 16px padding, 8px gap\n { contentType: 'icon-text', size: 'lg', className: 'px-6 gap-2' }, // 24px padding, 8px gap\n // Text only - same padding rules as Button/Toggle\n { contentType: 'text', size: 'sm', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'md', className: 'px-3.5' }, // 14px\n { contentType: 'text', size: 'default', className: 'px-4' }, // 16px\n { contentType: 'text', size: 'lg', className: 'px-6' }, // 24px\n // Underline variant has no rounded corners\n { variant: 'underline', className: 'rounded-none' },\n ],\n defaultVariants: {\n variant: 'default',\n size: 'default',\n radius: 'default',\n contentType: 'text',\n },\n }\n)\n\nexport interface SegmentedProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Root>,\n VariantProps<typeof segmentedVariants> {}\n\nconst Segmented = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Root>,\n SegmentedProps\n>(({ className, variant, size, radius, fontWeight, ...props }, ref) => {\n // All variants default to normal font weight\n const resolvedFontWeight = fontWeight ?? 'normal'\n\n return (\n <SegmentedContext.Provider value={{ variant: variant || 'default', size: size || 'default', radius: radius || 'default' }}>\n <RadioGroupPrimitive.Root\n className={cn(segmentedVariants({ variant, size, radius, fontWeight: resolvedFontWeight }), className)}\n {...props}\n ref={ref}\n />\n </SegmentedContext.Provider>\n )\n})\nSegmented.displayName = 'Segmented'\n\n// Icon size for segmented control (4-step scale, Icon+Text mode)\n// sm: 14px, md~default~lg: 16px\nconst iconSizeClasses = {\n sm: '[&>svg]:icon-xs', // 14px\n md: '[&>svg]:icon-sm', // 16px\n default: '[&>svg]:icon-sm', // 16px\n lg: '[&>svg]:icon-sm', // 16px\n}\n\nexport interface SegmentedItemProps\n extends React.ComponentPropsWithoutRef<typeof RadioGroupPrimitive.Item>,\n Omit<VariantProps<typeof segmentedItemVariants>, 'variant'> {}\n\nconst SegmentedItem = React.forwardRef<\n React.ElementRef<typeof RadioGroupPrimitive.Item>,\n SegmentedItemProps\n>(({ className, children, size, radius, contentType, ...props }, ref) => {\n const { variant, size: contextSize, radius: contextRadius } = useSegmentedContext()\n const resolvedSize = size || contextSize || 'default'\n const resolvedRadius = radius || contextRadius || 'default'\n\n return (\n <RadioGroupPrimitive.Item\n ref={ref}\n className={cn(\n segmentedItemVariants({ variant, size: resolvedSize, radius: resolvedRadius, contentType }),\n iconSizeClasses[resolvedSize],\n className\n )}\n {...props}\n >\n {children}\n </RadioGroupPrimitive.Item>\n )\n})\nSegmentedItem.displayName = 'SegmentedItem'\n\nexport { Segmented, SegmentedItem, segmentedVariants, segmentedItemVariants }\n"],"mappings":"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","names":[]}
|