aural-ui 2.1.4 → 2.1.6
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.
|
@@ -30,6 +30,24 @@ const meta: Meta<typeof Switch> = {
|
|
|
30
30
|
control: { type: "boolean" },
|
|
31
31
|
description: "Whether the switch is disabled or not",
|
|
32
32
|
},
|
|
33
|
+
size: {
|
|
34
|
+
control: { type: "select" },
|
|
35
|
+
options: ["sm", "md", "lg"],
|
|
36
|
+
description: "Size variant of the switch",
|
|
37
|
+
defaultValue: "md",
|
|
38
|
+
},
|
|
39
|
+
onIcon: {
|
|
40
|
+
control: { type: "text" },
|
|
41
|
+
description: "Custom icon to display when switch is ON",
|
|
42
|
+
},
|
|
43
|
+
offIcon: {
|
|
44
|
+
control: { type: "text" },
|
|
45
|
+
description: "Custom icon to display when switch is OFF",
|
|
46
|
+
},
|
|
47
|
+
classNames: {
|
|
48
|
+
control: { type: "object" },
|
|
49
|
+
description: "Custom classNames for different parts of the switch",
|
|
50
|
+
},
|
|
33
51
|
},
|
|
34
52
|
}
|
|
35
53
|
|
|
@@ -61,6 +79,37 @@ export const DisabledAndChecked: Story = {
|
|
|
61
79
|
},
|
|
62
80
|
}
|
|
63
81
|
|
|
82
|
+
export const SizeVariants: Story = {
|
|
83
|
+
render: () => (
|
|
84
|
+
<div className="flex flex-col items-center space-y-4">
|
|
85
|
+
<div className="flex items-center space-x-4">
|
|
86
|
+
<Switch size="sm" checked={true} />
|
|
87
|
+
<span className="text-sm text-gray-400">Small (sm)</span>
|
|
88
|
+
</div>
|
|
89
|
+
<div className="flex items-center space-x-4">
|
|
90
|
+
<Switch size="md" checked={true} />
|
|
91
|
+
<span className="text-sm text-gray-400">Medium (md)</span>
|
|
92
|
+
</div>
|
|
93
|
+
<div className="flex items-center space-x-4">
|
|
94
|
+
<Switch size="lg" checked={true} />
|
|
95
|
+
<span className="text-sm text-gray-400">Large (lg)</span>
|
|
96
|
+
</div>
|
|
97
|
+
</div>
|
|
98
|
+
),
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const WithCustomClassNames: Story = {
|
|
102
|
+
args: {
|
|
103
|
+
checked: true,
|
|
104
|
+
classNames: {
|
|
105
|
+
root: "border-2 border-blue-500",
|
|
106
|
+
onIcon: "text-green-600 font-bold",
|
|
107
|
+
offIcon: "text-gray-400",
|
|
108
|
+
thumb: "bg-blue-500 shadow-xl",
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
|
|
64
113
|
export const WithLabel: Story = {
|
|
65
114
|
render: () => (
|
|
66
115
|
<div className="flex items-center space-x-2">
|
|
@@ -108,3 +157,57 @@ export const CheckedWithIcons: Story = {
|
|
|
108
157
|
offIcon: <CrossIcon />,
|
|
109
158
|
},
|
|
110
159
|
}
|
|
160
|
+
|
|
161
|
+
export const AllVariants: Story = {
|
|
162
|
+
render: () => (
|
|
163
|
+
<div className="grid grid-cols-2 gap-6">
|
|
164
|
+
<div className="space-y-4">
|
|
165
|
+
<h3 className="text-lg font-semibold">Size Variants</h3>
|
|
166
|
+
<div className="space-y-3">
|
|
167
|
+
<div className="flex items-center justify-between">
|
|
168
|
+
<span>Small</span>
|
|
169
|
+
<Switch size="sm" checked={true} />
|
|
170
|
+
</div>
|
|
171
|
+
<div className="flex items-center justify-between">
|
|
172
|
+
<span>Medium</span>
|
|
173
|
+
<Switch size="md" checked={true} />
|
|
174
|
+
</div>
|
|
175
|
+
<div className="flex items-center justify-between">
|
|
176
|
+
<span>Large</span>
|
|
177
|
+
<Switch size="lg" checked={true} />
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
</div>
|
|
181
|
+
|
|
182
|
+
<div className="space-y-4">
|
|
183
|
+
<h3 className="text-lg font-semibold">With Custom Styling</h3>
|
|
184
|
+
<div className="space-y-3">
|
|
185
|
+
<div className="flex items-center justify-between">
|
|
186
|
+
<span>Custom Colors</span>
|
|
187
|
+
<Switch
|
|
188
|
+
size="md"
|
|
189
|
+
checked={true}
|
|
190
|
+
classNames={{
|
|
191
|
+
root: "border-2 border-purple-500",
|
|
192
|
+
thumb: "bg-purple-500",
|
|
193
|
+
}}
|
|
194
|
+
/>
|
|
195
|
+
</div>
|
|
196
|
+
<div className="flex items-center justify-between">
|
|
197
|
+
<span>With Icons</span>
|
|
198
|
+
<Switch
|
|
199
|
+
size="md"
|
|
200
|
+
checked={true}
|
|
201
|
+
onIcon={<TickIcon />}
|
|
202
|
+
offIcon={<CrossIcon />}
|
|
203
|
+
/>
|
|
204
|
+
</div>
|
|
205
|
+
<div className="flex items-center justify-between">
|
|
206
|
+
<span>Disabled</span>
|
|
207
|
+
<Switch size="md" checked={true} disabled />
|
|
208
|
+
</div>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
),
|
|
213
|
+
}
|
|
@@ -1,57 +1,129 @@
|
|
|
1
1
|
import * as React from "react"
|
|
2
2
|
import { cn } from "@lib/utils"
|
|
3
3
|
import * as SwitchPrimitives from "@radix-ui/react-switch"
|
|
4
|
+
import clsx from "clsx"
|
|
5
|
+
|
|
6
|
+
type SwitchSize = "sm" | "md" | "lg"
|
|
7
|
+
|
|
8
|
+
type SwitchClassNames = {
|
|
9
|
+
root?: string
|
|
10
|
+
onIcon?: string
|
|
11
|
+
offIcon?: string
|
|
12
|
+
thumb?: string
|
|
13
|
+
}
|
|
4
14
|
|
|
5
15
|
type SwitchWithIconsProps = React.ComponentPropsWithoutRef<
|
|
6
16
|
typeof SwitchPrimitives.Root
|
|
7
17
|
> & {
|
|
8
18
|
offIcon?: React.ReactNode
|
|
9
19
|
onIcon?: React.ReactNode
|
|
20
|
+
size?: SwitchSize
|
|
21
|
+
classNames?: SwitchClassNames
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const switchVariants = {
|
|
25
|
+
size: {
|
|
26
|
+
sm: {
|
|
27
|
+
root: "h-6 w-12",
|
|
28
|
+
thumb:
|
|
29
|
+
"size-4 data-[state=checked]:translate-x-6.5 data-[state=unchecked]:translate-x-1",
|
|
30
|
+
onIcon: "left-1 text-fm-xs",
|
|
31
|
+
offIcon: "right-[5px] text-fm-xs",
|
|
32
|
+
},
|
|
33
|
+
md: {
|
|
34
|
+
root: "h-8 w-14",
|
|
35
|
+
thumb:
|
|
36
|
+
"size-6 data-[state=checked]:translate-x-7 data-[state=unchecked]:translate-x-1",
|
|
37
|
+
onIcon: "left-2 text-fm-sm",
|
|
38
|
+
offIcon: "right-1.5 text-fm-sm",
|
|
39
|
+
},
|
|
40
|
+
lg: {
|
|
41
|
+
root: "h-10 w-18",
|
|
42
|
+
thumb:
|
|
43
|
+
"size-8 data-[state=checked]:translate-x-9 data-[state=unchecked]:translate-x-1",
|
|
44
|
+
onIcon: "left-2.5 text-fm-base",
|
|
45
|
+
offIcon: "right-2 text-fm-base",
|
|
46
|
+
},
|
|
47
|
+
},
|
|
10
48
|
}
|
|
11
49
|
|
|
12
50
|
const Switch = React.forwardRef<
|
|
13
51
|
React.ElementRef<typeof SwitchPrimitives.Root>,
|
|
14
52
|
SwitchWithIconsProps
|
|
15
|
-
>(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
>(
|
|
54
|
+
(
|
|
55
|
+
{
|
|
56
|
+
className,
|
|
57
|
+
onIcon,
|
|
58
|
+
offIcon,
|
|
59
|
+
checked,
|
|
60
|
+
disabled,
|
|
61
|
+
size = "md",
|
|
62
|
+
classNames,
|
|
63
|
+
...props
|
|
64
|
+
},
|
|
65
|
+
ref
|
|
66
|
+
) => {
|
|
67
|
+
const sizeConfig = switchVariants.size[size]
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<SwitchPrimitives.Root
|
|
71
|
+
ref={ref}
|
|
72
|
+
checked={checked}
|
|
73
|
+
disabled={disabled}
|
|
74
|
+
className={cn(
|
|
75
|
+
"data-[state=checked]:not-[:disabled]:border-fm-divider-positive data-[state=checked]:not-[:disabled]:bg-fm-green-50",
|
|
76
|
+
"data-[state=unchecked]:not-[:disabled]:border-fm-divider-primary data-[state=unchecked]:not-[:disabled]:bg-fm-surface-primary",
|
|
77
|
+
"data-[state=unchecked]:disabled:border-fm-divider-tertiary data-[state=unchecked]:disabled:bg-fm-surface-secondary",
|
|
78
|
+
"data-[state=checked]:disabled:border-fm-green-100 data-[state=checked]:disabled:bg-fm-green-50",
|
|
79
|
+
"focus-visible:ring-fm-primary focus-visible:ring-offset-fm-green-50",
|
|
80
|
+
"hover:bg-fm-surface-secondary data-[state=unchecked]:not-[:disabled]:hover:bg-fm-surface-secondary",
|
|
81
|
+
"data-[state=unchecked]:not-[:disabled]:hover:border-fm-divider-primary",
|
|
82
|
+
"relative rounded-full border border-solid transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed",
|
|
83
|
+
sizeConfig.root,
|
|
84
|
+
classNames?.root,
|
|
85
|
+
className
|
|
86
|
+
)}
|
|
87
|
+
{...props}
|
|
88
|
+
>
|
|
89
|
+
<span
|
|
90
|
+
className={clsx(
|
|
91
|
+
"font-fm-brand text-fm-positive absolute top-1/2 -translate-y-1/2",
|
|
92
|
+
{
|
|
93
|
+
"text-fm-positive-tert": disabled,
|
|
94
|
+
},
|
|
95
|
+
sizeConfig.onIcon,
|
|
96
|
+
classNames?.onIcon
|
|
97
|
+
)}
|
|
98
|
+
data-state={checked ? "checked" : "unchecked"}
|
|
99
|
+
data-disabled={disabled || undefined}
|
|
100
|
+
>
|
|
101
|
+
{onIcon ?? "ON"}
|
|
102
|
+
</span>
|
|
103
|
+
|
|
104
|
+
<span
|
|
105
|
+
className={clsx(
|
|
106
|
+
"font-fm-brand text-fm-tertiary absolute top-1/2 -translate-y-1/2",
|
|
107
|
+
sizeConfig.offIcon,
|
|
108
|
+
classNames?.offIcon
|
|
109
|
+
)}
|
|
110
|
+
data-state={checked ? "checked" : "unchecked"}
|
|
111
|
+
data-disabled={disabled || undefined}
|
|
112
|
+
>
|
|
113
|
+
{offIcon ?? "OFF"}
|
|
114
|
+
</span>
|
|
115
|
+
|
|
116
|
+
<SwitchPrimitives.Thumb
|
|
117
|
+
className={cn(
|
|
118
|
+
"bg-fm-icon-active data-[disabled]:bg-fm-icon-inactive pointer-events-none z-10 block rounded-full shadow-lg ring-0 transition-transform",
|
|
119
|
+
sizeConfig.thumb,
|
|
120
|
+
classNames?.thumb
|
|
121
|
+
)}
|
|
122
|
+
/>
|
|
123
|
+
</SwitchPrimitives.Root>
|
|
124
|
+
)
|
|
125
|
+
}
|
|
126
|
+
)
|
|
55
127
|
Switch.displayName = SwitchPrimitives.Root.displayName
|
|
56
128
|
|
|
57
|
-
export { Switch }
|
|
129
|
+
export { Switch, type SwitchSize, type SwitchClassNames }
|