beacon-ui 3.1.4

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +175 -0
  3. package/dist/components/Avatar.d.ts +20 -0
  4. package/dist/components/Avatar.d.ts.map +1 -0
  5. package/dist/components/Avatar.js +174 -0
  6. package/dist/components/Button.d.ts +21 -0
  7. package/dist/components/Button.d.ts.map +1 -0
  8. package/dist/components/Button.js +227 -0
  9. package/dist/components/Card.d.ts +40 -0
  10. package/dist/components/Card.d.ts.map +1 -0
  11. package/dist/components/Card.js +517 -0
  12. package/dist/components/Checkbox.d.ts +12 -0
  13. package/dist/components/Checkbox.d.ts.map +1 -0
  14. package/dist/components/Checkbox.js +64 -0
  15. package/dist/components/CheckboxPreview.d.ts +13 -0
  16. package/dist/components/CheckboxPreview.d.ts.map +1 -0
  17. package/dist/components/CheckboxPreview.js +155 -0
  18. package/dist/components/Chip.d.ts +15 -0
  19. package/dist/components/Chip.d.ts.map +1 -0
  20. package/dist/components/Chip.js +99 -0
  21. package/dist/components/Input.d.ts +24 -0
  22. package/dist/components/Input.d.ts.map +1 -0
  23. package/dist/components/Input.js +138 -0
  24. package/dist/components/Menu.d.ts +20 -0
  25. package/dist/components/Menu.d.ts.map +1 -0
  26. package/dist/components/Menu.js +252 -0
  27. package/dist/components/RadioButton.d.ts +13 -0
  28. package/dist/components/RadioButton.d.ts.map +1 -0
  29. package/dist/components/RadioButton.js +140 -0
  30. package/dist/components/Switch.d.ts +11 -0
  31. package/dist/components/Switch.d.ts.map +1 -0
  32. package/dist/components/Switch.js +64 -0
  33. package/dist/components/SwitchPreview.d.ts +14 -0
  34. package/dist/components/SwitchPreview.d.ts.map +1 -0
  35. package/dist/components/SwitchPreview.js +281 -0
  36. package/dist/icons/index.d.ts +97 -0
  37. package/dist/icons/index.d.ts.map +1 -0
  38. package/dist/icons/index.js +383 -0
  39. package/dist/index.d.ts +13 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +12 -0
  42. package/dist/providers/ThemeProvider.d.ts +23 -0
  43. package/dist/providers/ThemeProvider.d.ts.map +1 -0
  44. package/dist/providers/ThemeProvider.js +79 -0
  45. package/dist/tokens/types.d.ts +14 -0
  46. package/dist/tokens/types.d.ts.map +1 -0
  47. package/dist/tokens/types.js +5 -0
  48. package/dist/utils/patternPaths.d.ts +28 -0
  49. package/dist/utils/patternPaths.d.ts.map +1 -0
  50. package/dist/utils/patternPaths.js +92 -0
  51. package/package.json +51 -0
  52. package/tokens/generated/brand-dark.css +86 -0
  53. package/tokens/generated/brand-light.css +86 -0
  54. package/tokens/generated/effects.css +10 -0
  55. package/tokens/generated/index.css +804 -0
  56. package/tokens/generated/primitives.css +116 -0
  57. package/tokens/generated/responsive.css +235 -0
  58. package/tokens/generated/semantic.css +138 -0
  59. package/tokens/generated/typography.css +124 -0
@@ -0,0 +1,252 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ import { UserPersonIcon, ChevronRightIcon, CloseIcon, MenuIcon, DownloadIcon } from "../icons";
5
+ import { SwitchPreview } from "./SwitchPreview";
6
+ const DEFAULT_MENU_ITEMS = [
7
+ { id: "1", label: "Menu Item #1" },
8
+ { id: "2", label: "Menu Item #2" },
9
+ { id: "3", label: "Menu Item #3" },
10
+ { id: "4", label: "Menu Item #4" },
11
+ { id: "5", label: "Menu Item #5" },
12
+ ];
13
+ export function Menu({ variant = "desktop", showMenu = true, showButton = true, menuItems = DEFAULT_MENU_ITEMS, headerTitle = "Title", headerSubtitle = "Subtitle", showChevrons = true, theme, hue, }) {
14
+ const containerStyles = useMemo(() => {
15
+ const baseStyles = {
16
+ display: "flex",
17
+ flexDirection: "column",
18
+ backgroundColor: "var(--bg-page-primary)",
19
+ borderTop: "var(--border-width-25) solid var(--border-neutral-primary)",
20
+ borderRight: "var(--border-width-25) solid var(--border-neutral-primary)",
21
+ borderBottom: "var(--border-width-25) solid var(--border-neutral-primary)",
22
+ borderLeft: "var(--border-width-25) solid var(--border-neutral-primary)",
23
+ position: "relative",
24
+ };
25
+ if (variant === "desktop") {
26
+ return {
27
+ ...baseStyles,
28
+ width: "240px",
29
+ height: "600px",
30
+ borderLeft: "none",
31
+ borderTop: "none",
32
+ borderBottom: "none",
33
+ borderRight: "var(--border-width-25) solid var(--border-neutral-primary)",
34
+ padding: "var(--spacing-500) var(--spacing-400)",
35
+ gap: "var(--spacing-none)",
36
+ };
37
+ }
38
+ if (variant === "tablet-open" || variant === "tablet-closed") {
39
+ return {
40
+ ...baseStyles,
41
+ width: "430px",
42
+ borderTop: "none",
43
+ borderRight: "none",
44
+ borderBottom: "var(--border-width-25) solid var(--border-neutral-primary)",
45
+ borderLeft: "none",
46
+ padding: variant === "tablet-open" ? "var(--spacing-200) var(--spacing-400)" : "8px 0",
47
+ gap: "var(--spacing-none)",
48
+ };
49
+ }
50
+ if (variant === "mobile-open" || variant === "mobile-closed") {
51
+ return {
52
+ ...baseStyles,
53
+ width: "400px",
54
+ borderTop: "none",
55
+ borderRight: "none",
56
+ borderBottom: "var(--border-width-25) solid var(--border-neutral-primary)",
57
+ borderLeft: "none",
58
+ padding: variant === "mobile-open" ? "var(--spacing-200) var(--spacing-400)" : "var(--spacing-200) var(--spacing-none)",
59
+ gap: "var(--spacing-none)",
60
+ };
61
+ }
62
+ if (variant === "close-menu") {
63
+ return {
64
+ ...baseStyles,
65
+ width: "100%",
66
+ borderTop: "none",
67
+ borderRight: "none",
68
+ borderBottom: "var(--border-width-25) solid var(--border-neutral-primary)",
69
+ borderLeft: "none",
70
+ padding: "var(--spacing-200) var(--spacing-400)",
71
+ alignItems: "flex-end",
72
+ justifyContent: "center",
73
+ };
74
+ }
75
+ return baseStyles;
76
+ }, [variant]);
77
+ const headerStyles = useMemo(() => {
78
+ if (variant === "desktop") {
79
+ return {
80
+ display: "flex",
81
+ gap: "var(--spacing-200)",
82
+ alignItems: "center",
83
+ padding: "var(--spacing-200)",
84
+ borderRadius: "var(--corner-radius-100)",
85
+ width: "100%",
86
+ };
87
+ }
88
+ // For tablet/mobile, header is part of the main row
89
+ return {
90
+ display: "flex",
91
+ gap: "var(--spacing-200)",
92
+ alignItems: "center",
93
+ padding: "var(--spacing-200)",
94
+ borderRadius: "var(--corner-radius-100)",
95
+ flex: 1,
96
+ };
97
+ }, [variant]);
98
+ const avatarStyles = useMemo(() => {
99
+ return {
100
+ width: "48px",
101
+ height: "48px",
102
+ borderRadius: "var(--corner-radius-200)",
103
+ backgroundColor: "var(--bg-primary)",
104
+ display: "flex",
105
+ alignItems: "center",
106
+ justifyContent: "center",
107
+ flexShrink: 0,
108
+ overflow: "hidden",
109
+ };
110
+ }, []);
111
+ const menuItemStyles = useMemo(() => {
112
+ return {
113
+ display: "flex",
114
+ gap: "var(--spacing-200)",
115
+ alignItems: "center",
116
+ padding: "var(--spacing-200) var(--spacing-200)",
117
+ borderRadius: "var(--corner-radius-200)",
118
+ backgroundColor: "var(--bg-page-primary)",
119
+ width: "100%",
120
+ };
121
+ }, []);
122
+ const buttonStyles = useMemo(() => {
123
+ return {
124
+ display: "flex",
125
+ gap: "var(--spacing-200)",
126
+ alignItems: "center",
127
+ padding: "var(--spacing-200) var(--spacing-300)",
128
+ borderRadius: "var(--corner-radius-200)",
129
+ backgroundColor: "var(--bg-primary-tonal)",
130
+ color: "var(--fg-primary-on-tonal)",
131
+ fontFamily: "var(--font-secondary)",
132
+ fontSize: "var(--body-small-text-size)",
133
+ lineHeight: "var(--body-small-line-height)",
134
+ fontWeight: "var(--font-weight-secondary-medium)",
135
+ cursor: "pointer",
136
+ width: variant === "desktop" ? "100%" : "92px",
137
+ };
138
+ }, [variant]);
139
+ const footerStyles = useMemo(() => {
140
+ if (variant === "desktop") {
141
+ return {
142
+ display: "flex",
143
+ flexDirection: "column",
144
+ gap: "var(--spacing-400)",
145
+ alignItems: "flex-start",
146
+ justifyContent: "center",
147
+ padding: "var(--spacing-400) var(--spacing-400) var(--spacing-200)",
148
+ width: "100%",
149
+ };
150
+ }
151
+ // For tablet/mobile, footer is part of the main row
152
+ return {
153
+ display: "flex",
154
+ gap: "var(--spacing-300)",
155
+ alignItems: "center",
156
+ justifyContent: "flex-end",
157
+ };
158
+ }, [variant]);
159
+ const mainRowStyles = useMemo(() => {
160
+ if (variant === "desktop") {
161
+ return {};
162
+ }
163
+ // For tablet/mobile, combine header and footer in one row
164
+ return {
165
+ display: "flex",
166
+ alignItems: "center",
167
+ width: "100%",
168
+ gap: "var(--spacing-200)",
169
+ };
170
+ }, [variant]);
171
+ const iconButtonStyles = useMemo(() => {
172
+ return {
173
+ display: "flex",
174
+ alignItems: "center",
175
+ justifyContent: "center",
176
+ padding: 0,
177
+ borderRadius: "var(--corner-radius-full)",
178
+ width: "40px",
179
+ height: "40px",
180
+ cursor: "pointer",
181
+ backgroundColor: "transparent",
182
+ border: "none",
183
+ color: "var(--fg-neutral)",
184
+ };
185
+ }, []);
186
+ if (variant === "close-menu") {
187
+ return (_jsx("div", { style: containerStyles, children: _jsx("button", { style: iconButtonStyles, children: _jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "32px", height: "32px" }, children: _jsx(CloseIcon, { size: 32 }) }) }) }));
188
+ }
189
+ const isDesktop = variant === "desktop";
190
+ const isTabletOpen = variant === "tablet-open";
191
+ const isMobileOpen = variant === "mobile-open";
192
+ const isTabletClosed = variant === "tablet-closed";
193
+ const isMobileClosed = variant === "mobile-closed";
194
+ const showMenuItems = (isDesktop || isTabletOpen || isMobileOpen) && showMenu;
195
+ const showHeaderContent = isDesktop || isTabletOpen || isTabletClosed;
196
+ return (_jsxs("div", { style: containerStyles, children: [isDesktop ? (_jsx(_Fragment, { children: _jsxs("div", { style: headerStyles, children: [_jsx("div", { style: avatarStyles, children: _jsx("img", { src: "/images/avatars/avatar-female.png", alt: "User avatar", style: {
197
+ width: "100%",
198
+ height: "100%",
199
+ objectFit: "cover",
200
+ objectPosition: "center",
201
+ } }) }), showHeaderContent && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-none)", flex: 1 }, children: [_jsx("p", { style: {
202
+ fontFamily: "var(--font-secondary)",
203
+ fontSize: "var(--body-small-text-size)",
204
+ lineHeight: "var(--body-small-line-height)",
205
+ fontWeight: "var(--font-weight-secondary-regular)",
206
+ color: "var(--fg-neutral)",
207
+ margin: 0,
208
+ }, children: headerTitle }), _jsx("p", { style: {
209
+ fontFamily: "var(--font-secondary)",
210
+ fontSize: "var(--body-regular-text-size)",
211
+ lineHeight: "var(--body-regular-line-height)",
212
+ fontWeight: "var(--font-weight-secondary-medium)",
213
+ color: "var(--fg-neutral)",
214
+ margin: 0,
215
+ }, children: headerSubtitle })] }))] }) })) : (
216
+ /* Tablet/Mobile: Header and Footer in single row */
217
+ _jsxs("div", { style: mainRowStyles, children: [_jsxs("div", { style: headerStyles, children: [_jsx("div", { style: avatarStyles, children: _jsx("img", { src: "/images/avatars/avatar-female.png", alt: "User avatar", style: {
218
+ width: "100%",
219
+ height: "100%",
220
+ objectFit: "cover",
221
+ objectPosition: "center",
222
+ } }) }), showHeaderContent && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-none)", flex: 1 }, children: [_jsx("p", { style: {
223
+ fontFamily: "var(--font-secondary)",
224
+ fontSize: "var(--body-small-text-size)",
225
+ lineHeight: "var(--body-small-line-height)",
226
+ fontWeight: "var(--font-weight-secondary-regular)",
227
+ color: "var(--fg-neutral)",
228
+ margin: 0,
229
+ }, children: headerTitle }), _jsx("p", { style: {
230
+ fontFamily: "var(--font-secondary)",
231
+ fontSize: "var(--body-regular-text-size)",
232
+ lineHeight: "var(--body-regular-line-height)",
233
+ fontWeight: "var(--font-weight-secondary-medium)",
234
+ color: "var(--fg-neutral)",
235
+ margin: 0,
236
+ }, children: headerSubtitle })] }))] }), _jsxs("div", { style: footerStyles, children: [showButton && (_jsxs("div", { style: buttonStyles, children: [_jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "16px", height: "16px" }, children: _jsx(DownloadIcon, { size: 16 }) }), _jsx("span", { children: "Button" })] })), _jsx(SwitchPreview, { checked: theme === "dark", showIcons: true, theme: theme, hue: hue }), _jsx("button", { style: iconButtonStyles, children: _jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "32px", height: "32px" }, children: [(isTabletOpen || isMobileOpen) && _jsx(CloseIcon, { size: 32 }), (isTabletClosed || isMobileClosed) && _jsx(MenuIcon, { size: 32 })] }) })] })] })), showMenuItems && (_jsx("div", { style: {
237
+ display: "flex",
238
+ flexDirection: "column",
239
+ gap: "var(--spacing-200)",
240
+ padding: isDesktop ? "var(--spacing-600) 0" : "var(--spacing-400) var(--spacing-200)",
241
+ width: "100%",
242
+ flex: isDesktop ? 1 : undefined,
243
+ }, children: menuItems.map((item) => (_jsxs("div", { style: menuItemStyles, children: [_jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "20px", height: "20px", flexShrink: 0, color: "var(--fg-neutral)" }, children: _jsx(UserPersonIcon, { size: 20 }) }), _jsx("p", { style: {
244
+ fontFamily: "var(--font-secondary)",
245
+ fontSize: "var(--body-small-text-size)",
246
+ lineHeight: "var(--body-small-line-height)",
247
+ fontWeight: "var(--font-weight-secondary-medium)",
248
+ color: "var(--fg-neutral-secondary)",
249
+ margin: 0,
250
+ flex: 1,
251
+ }, children: item.label }), showChevrons && (_jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "16px", height: "16px", flexShrink: 0, color: "var(--fg-neutral)" }, children: _jsx(ChevronRightIcon, { size: 16 }) }))] }, item.id))) })), isDesktop && (_jsxs(_Fragment, { children: [showButton && (_jsx("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-400)", padding: "var(--spacing-400)", width: "100%" }, children: _jsxs("div", { style: buttonStyles, children: [_jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: "16px", height: "16px" }, children: _jsx(DownloadIcon, { size: 16 }) }), _jsx("span", { children: "Button" })] }) })), _jsx("div", { style: footerStyles, children: _jsx(SwitchPreview, { checked: theme === "dark", showIcons: true, theme: theme, hue: hue }) })] }))] }));
252
+ }
@@ -0,0 +1,13 @@
1
+ import type { Theme, HueVariant } from "../tokens/types";
2
+ type RadioButtonStatus = "default" | "hovered" | "focused" | "pressed" | "disabled";
3
+ interface RadioButtonProps {
4
+ selected?: boolean;
5
+ status?: RadioButtonStatus;
6
+ label?: string;
7
+ showLabel?: boolean;
8
+ theme?: Theme;
9
+ hue?: HueVariant;
10
+ }
11
+ export declare function RadioButton({ selected, status, label, showLabel, theme, hue, }: RadioButtonProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
13
+ //# sourceMappingURL=RadioButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RadioButton.d.ts","sourceRoot":"","sources":["../../src/components/RadioButton.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEzD,KAAK,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAEpF,UAAU,gBAAgB;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,iBAAiB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAID,wBAAgB,WAAW,CAAC,EAC1B,QAAgB,EAChB,MAAkB,EAClB,KAAsB,EACtB,SAAgB,EAChB,KAAK,EACL,GAAG,GACJ,EAAE,gBAAgB,2CAuJlB"}
@@ -0,0 +1,140 @@
1
+ "use client";
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useMemo } from "react";
4
+ const RADIO_SIZE = 20;
5
+ export function RadioButton({ selected = false, status = "default", label = "Radio Button", showLabel = true, theme, hue, }) {
6
+ const disabled = status === "disabled";
7
+ const radioStyles = useMemo(() => {
8
+ const baseStyles = {
9
+ width: `${RADIO_SIZE}px`,
10
+ height: `${RADIO_SIZE}px`,
11
+ borderRadius: "var(--corner-radius-full)",
12
+ display: "flex",
13
+ alignItems: "center",
14
+ justifyContent: "center",
15
+ flexShrink: 0,
16
+ boxSizing: "border-box",
17
+ position: "relative",
18
+ transition: "border-color 0.15s ease, background-color 0.15s ease",
19
+ };
20
+ if (selected) {
21
+ // Selected state
22
+ if (disabled) {
23
+ return {
24
+ ...baseStyles,
25
+ borderWidth: "var(--border-width-150)",
26
+ borderStyle: "solid",
27
+ borderColor: "var(--border-primary-disabled)",
28
+ backgroundColor: "transparent",
29
+ };
30
+ }
31
+ if (status === "hovered") {
32
+ return {
33
+ ...baseStyles,
34
+ borderWidth: "var(--border-width-150)",
35
+ borderStyle: "solid",
36
+ borderColor: "var(--border-primary-on-hover)",
37
+ backgroundColor: "transparent",
38
+ };
39
+ }
40
+ if (status === "focused" || status === "pressed") {
41
+ return {
42
+ ...baseStyles,
43
+ borderWidth: "var(--border-width-150)",
44
+ borderStyle: "solid",
45
+ borderColor: "var(--border-primary-pressed)",
46
+ backgroundColor: "transparent",
47
+ };
48
+ }
49
+ // Default selected
50
+ return {
51
+ ...baseStyles,
52
+ borderWidth: "var(--border-width-150)",
53
+ borderStyle: "solid",
54
+ borderColor: "var(--border-primary)",
55
+ backgroundColor: "transparent",
56
+ };
57
+ }
58
+ else {
59
+ // Unselected state
60
+ if (disabled) {
61
+ return {
62
+ ...baseStyles,
63
+ borderWidth: "var(--border-width-25)",
64
+ borderStyle: "solid",
65
+ borderColor: "var(--border-disabled)",
66
+ backgroundColor: "transparent",
67
+ };
68
+ }
69
+ if (status === "hovered" || status === "focused" || status === "pressed") {
70
+ return {
71
+ ...baseStyles,
72
+ borderWidth: "var(--border-width-25)",
73
+ borderStyle: "solid",
74
+ borderColor: "var(--border-neutral-primary)",
75
+ backgroundColor: "transparent",
76
+ };
77
+ }
78
+ // Default unselected
79
+ return {
80
+ ...baseStyles,
81
+ borderWidth: "var(--border-width-25)",
82
+ borderStyle: "solid",
83
+ borderColor: "var(--border-neutral-primary)",
84
+ backgroundColor: "transparent",
85
+ };
86
+ }
87
+ }, [selected, status, disabled]);
88
+ const labelStyles = useMemo(() => {
89
+ const baseStyles = {
90
+ fontFamily: "var(--font-secondary)",
91
+ fontSize: "var(--body-small-text-size)",
92
+ lineHeight: "var(--body-small-line-height)",
93
+ fontWeight: "var(--font-weight-secondary-medium)",
94
+ margin: 0,
95
+ };
96
+ if (disabled) {
97
+ return {
98
+ ...baseStyles,
99
+ color: "var(--fg-disabled)",
100
+ };
101
+ }
102
+ return {
103
+ ...baseStyles,
104
+ color: "var(--fg-neutral-secondary)",
105
+ };
106
+ }, [disabled]);
107
+ const focusRingStyles = useMemo(() => {
108
+ if (status !== "focused")
109
+ return null;
110
+ // Focus ring should be positioned outside the radio button
111
+ // The container is always 20px with box-sizing: border-box
112
+ // When selected: border is 6px (border-width-150), so the visual outer edge is at 20px
113
+ // When unselected: border is 1px (border-width-25), so the visual outer edge is at 20px
114
+ // The focus ring should be 4px outside the container edge, centered on the container
115
+ // Using explicit width/height and centering to ensure consistent alignment: 20px + 8px (4px on each side) = 28px
116
+ return {
117
+ position: "absolute",
118
+ top: "50%",
119
+ left: "50%",
120
+ transform: "translate(-50%, -50%)",
121
+ width: "28px",
122
+ height: "28px",
123
+ marginTop: "0",
124
+ marginLeft: "0",
125
+ borderRadius: "var(--corner-radius-full)",
126
+ borderWidth: "var(--border-width-25)",
127
+ borderStyle: "solid",
128
+ borderColor: selected
129
+ ? "var(--border-primary)"
130
+ : "var(--border-neutral-primary)",
131
+ pointerEvents: "none",
132
+ };
133
+ }, [status, selected]);
134
+ return (_jsxs("div", { style: {
135
+ display: "flex",
136
+ alignItems: "center",
137
+ gap: "var(--spacing-200)",
138
+ position: "relative",
139
+ }, children: [_jsx("div", { style: radioStyles, children: focusRingStyles && _jsx("div", { style: focusRingStyles }) }), showLabel && label && _jsx("p", { style: labelStyles, children: label })] }));
140
+ }
@@ -0,0 +1,11 @@
1
+ interface SwitchProps {
2
+ checked?: boolean;
3
+ onChange?: (checked: boolean) => void;
4
+ disabled?: boolean;
5
+ id?: string;
6
+ ariaLabel?: string;
7
+ showIcons?: boolean;
8
+ }
9
+ export declare function Switch({ checked, onChange, disabled, id, ariaLabel, showIcons, }: SwitchProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=Switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/components/Switch.tsx"],"names":[],"mappings":"AAQA,UAAU,WAAW;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,MAAM,CAAC,EACrB,OAAe,EACf,QAAQ,EACR,QAAgB,EAChB,EAAE,EACF,SAAS,EACT,SAAiB,GAClB,EAAE,WAAW,2CAkGb"}
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useState, useCallback } from "react";
4
+ import { SwitchPreview } from "./SwitchPreview";
5
+ import { useThemeSafe } from "../providers/ThemeProvider";
6
+ export function Switch({ checked = false, onChange, disabled = false, id, ariaLabel, showIcons = false, }) {
7
+ const themeContext = useThemeSafe();
8
+ const theme = themeContext?.theme;
9
+ const hue = themeContext?.hue;
10
+ const [status, setStatus] = useState("default");
11
+ const handleClick = useCallback(() => {
12
+ if (!disabled && onChange) {
13
+ onChange(!checked);
14
+ }
15
+ }, [checked, disabled, onChange]);
16
+ const handleKeyDown = useCallback((e) => {
17
+ if (disabled)
18
+ return;
19
+ if (e.key === " " || e.key === "Enter") {
20
+ e.preventDefault();
21
+ if (onChange) {
22
+ onChange(!checked);
23
+ }
24
+ }
25
+ }, [checked, disabled, onChange]);
26
+ const handleMouseEnter = useCallback(() => {
27
+ if (!disabled) {
28
+ setStatus("hovered");
29
+ }
30
+ }, [disabled]);
31
+ const handleMouseLeave = useCallback(() => {
32
+ if (!disabled) {
33
+ setStatus("default");
34
+ }
35
+ }, [disabled]);
36
+ const handleFocus = useCallback(() => {
37
+ if (!disabled) {
38
+ setStatus("focused");
39
+ }
40
+ }, [disabled]);
41
+ const handleBlur = useCallback(() => {
42
+ if (!disabled) {
43
+ setStatus("default");
44
+ }
45
+ }, [disabled]);
46
+ const handleMouseDown = useCallback(() => {
47
+ if (!disabled) {
48
+ setStatus("pressed");
49
+ }
50
+ }, [disabled]);
51
+ const handleMouseUp = useCallback(() => {
52
+ if (!disabled) {
53
+ setStatus("hovered");
54
+ }
55
+ }, [disabled]);
56
+ const currentStatus = disabled ? "disabled" : status;
57
+ return (_jsx("button", { type: "button", id: id, role: "switch", "aria-checked": checked, "aria-label": ariaLabel, "aria-disabled": disabled, disabled: disabled, onClick: handleClick, onKeyDown: handleKeyDown, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, style: {
58
+ border: "none",
59
+ background: "none",
60
+ padding: 0,
61
+ cursor: disabled ? "not-allowed" : "pointer",
62
+ outline: "none",
63
+ }, children: _jsx(SwitchPreview, { checked: checked, status: currentStatus, showIcons: showIcons, theme: theme, hue: hue }) }));
64
+ }
@@ -0,0 +1,14 @@
1
+ import type { Theme, HueVariant } from "../tokens/types";
2
+ type SwitchStatus = "default" | "hovered" | "focused" | "pressed" | "disabled";
3
+ interface SwitchPreviewProps {
4
+ checked?: boolean;
5
+ status?: SwitchStatus;
6
+ showIcons?: boolean;
7
+ label?: string;
8
+ showLabel?: boolean;
9
+ theme?: Theme;
10
+ hue?: HueVariant;
11
+ }
12
+ export declare function SwitchPreview({ checked, status, showIcons, label, showLabel, theme, hue, }: SwitchPreviewProps): import("react/jsx-runtime").JSX.Element;
13
+ export {};
14
+ //# sourceMappingURL=SwitchPreview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwitchPreview.d.ts","sourceRoot":"","sources":["../../src/components/SwitchPreview.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGzD,KAAK,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAOD,wBAAgB,aAAa,CAAC,EAC5B,OAAe,EACf,MAAkB,EAClB,SAAiB,EACjB,KAAgB,EAChB,SAAiB,EACjB,KAAK,EACL,GAAG,GACJ,EAAE,kBAAkB,2CAqTpB"}