beacon-ui 3.1.4 → 3.1.7
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/CHANGELOG.md +34 -0
- package/README.md +407 -16
- package/dist/components/Avatar.d.ts +13 -16
- package/dist/components/Avatar.d.ts.map +1 -1
- package/dist/components/Avatar.js +6 -4
- package/dist/components/Button.d.ts +19 -19
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/Button.js +57 -61
- package/dist/components/Card.d.ts +8 -11
- package/dist/components/Card.d.ts.map +1 -1
- package/dist/components/Card.js +5 -3
- package/dist/components/Checkbox.d.ts +5 -6
- package/dist/components/Checkbox.d.ts.map +1 -1
- package/dist/components/Checkbox.js +191 -38
- package/dist/components/Chip.d.ts +6 -9
- package/dist/components/Chip.d.ts.map +1 -1
- package/dist/components/Chip.js +6 -5
- package/dist/components/Input.d.ts +10 -15
- package/dist/components/Input.d.ts.map +1 -1
- package/dist/components/Input.js +22 -21
- package/dist/components/Menu.d.ts +4 -5
- package/dist/components/Menu.d.ts.map +1 -1
- package/dist/components/Menu.js +13 -10
- package/dist/components/RadioButton.d.ts +6 -8
- package/dist/components/RadioButton.d.ts.map +1 -1
- package/dist/components/RadioButton.js +68 -16
- package/dist/components/Switch.d.ts +5 -6
- package/dist/components/Switch.d.ts.map +1 -1
- package/dist/components/Switch.js +296 -38
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAIvD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAC3C,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAuDD,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,IAAW,EACX,MAAkB,EAClB,SAAgB,EAChB,SAAS,EACT,OAAO,EACP,eAAe,EACf,SAAiB,EACjB,YAA+B,EAC/B,YAAY,EACZ,OAAe,EACf,QAAgB,EAChB,QAAgB,EAChB,SAAS,EACT,KAAK,EACL,KAAK,EACL,WAAW,EACX,GAAG,EACH,GAAG,IAAI,EACR,EAAE,UAAU,2CAuKZ"}
|
package/dist/components/Input.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo } from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { useThemeSafe } from "../providers/ThemeProvider";
|
|
5
|
+
import { AlertTriangleErrorIcon } from "../icons";
|
|
5
6
|
const SIZE_CONFIG = {
|
|
6
7
|
sm: {
|
|
7
8
|
height: "28px",
|
|
@@ -40,9 +41,10 @@ const SIZE_CONFIG = {
|
|
|
40
41
|
gap: "var(--spacing-200)",
|
|
41
42
|
},
|
|
42
43
|
};
|
|
43
|
-
export function Input({ label
|
|
44
|
+
export function Input({ label, size = "md", status = "default", showLabel = true, startIcon, endIcon, placeholderIcon, showError = false, errorMessage = "Error message!", numberPrefix, rounded = false, iconOnly = false, disabled = false, className, style, value, placeholder, ref, ...rest }) {
|
|
45
|
+
useThemeSafe(); // Ensure theme context is available
|
|
44
46
|
const sizeConfig = SIZE_CONFIG[size];
|
|
45
|
-
const hasValue = value.length > 0;
|
|
47
|
+
const hasValue = value != null && String(value).length > 0;
|
|
46
48
|
const borderColor = useMemo(() => {
|
|
47
49
|
if (disabled) {
|
|
48
50
|
return "var(--border-strong-100)";
|
|
@@ -72,22 +74,6 @@ export function Input({ label = "Label", placeholder = "Placeholder", value = ""
|
|
|
72
74
|
};
|
|
73
75
|
return baseStyles;
|
|
74
76
|
}, [sizeConfig, borderColor, rounded, iconOnly, disabled]);
|
|
75
|
-
const textStyles = useMemo(() => {
|
|
76
|
-
return {
|
|
77
|
-
fontSize: sizeConfig.fontSize,
|
|
78
|
-
lineHeight: sizeConfig.lineHeight,
|
|
79
|
-
fontFamily: "var(--font-secondary)",
|
|
80
|
-
color: hasValue
|
|
81
|
-
? "var(--fg-neutral-secondary)"
|
|
82
|
-
: disabled
|
|
83
|
-
? "var(--fg-disabled)"
|
|
84
|
-
: "var(--fg-disabled)",
|
|
85
|
-
fontWeight: hasValue ? 500 : 400,
|
|
86
|
-
flex: iconOnly ? "none" : "1 0 0",
|
|
87
|
-
minWidth: iconOnly ? "auto" : 0,
|
|
88
|
-
minHeight: iconOnly ? "auto" : 0,
|
|
89
|
-
};
|
|
90
|
-
}, [sizeConfig, hasValue, disabled, iconOnly]);
|
|
91
77
|
const labelStyles = useMemo(() => {
|
|
92
78
|
return {
|
|
93
79
|
fontSize: sizeConfig.labelFontSize,
|
|
@@ -131,8 +117,23 @@ export function Input({ label = "Label", placeholder = "Placeholder", value = ""
|
|
|
131
117
|
color: "var(--fg-critical)",
|
|
132
118
|
};
|
|
133
119
|
}, []);
|
|
120
|
+
const inputStyles = {
|
|
121
|
+
fontSize: sizeConfig.fontSize,
|
|
122
|
+
lineHeight: sizeConfig.lineHeight,
|
|
123
|
+
fontFamily: "var(--font-secondary)",
|
|
124
|
+
color: hasValue ? "var(--fg-neutral-secondary)" : disabled ? "var(--fg-disabled)" : "var(--fg-disabled)",
|
|
125
|
+
fontWeight: hasValue ? 500 : 400,
|
|
126
|
+
flex: iconOnly ? "none" : "1 0 0",
|
|
127
|
+
minWidth: iconOnly ? "auto" : 0,
|
|
128
|
+
minHeight: iconOnly ? "auto" : 0,
|
|
129
|
+
border: "none",
|
|
130
|
+
background: "transparent",
|
|
131
|
+
outline: "none",
|
|
132
|
+
padding: 0,
|
|
133
|
+
width: "100%",
|
|
134
|
+
};
|
|
134
135
|
if (iconOnly) {
|
|
135
|
-
return (_jsx("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-100)", width: "100%" }, children: _jsxs("div", { style: inputContainerStyles, children: [
|
|
136
|
+
return (_jsx("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-100)", width: "100%" }, children: _jsxs("div", { style: inputContainerStyles, children: [placeholderIcon && (_jsx("div", { style: { color: "var(--fg-neutral)", display: "flex", alignItems: "center", justifyContent: "center" }, children: placeholderIcon })), startIcon && !placeholderIcon && (_jsx("div", { style: { color: "var(--fg-neutral)", display: "flex", alignItems: "center", justifyContent: "center" }, children: startIcon }))] }) }));
|
|
136
137
|
}
|
|
137
|
-
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-100)", width: "100%" }, children: [showLabel && (_jsx("
|
|
138
|
+
return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-100)", width: "100%" }, children: [showLabel && label && (_jsx("label", { htmlFor: rest.id, style: labelStyles, children: label })), _jsxs("div", { style: inputContainerStyles, children: [startIcon && (_jsx("div", { style: { color: "var(--fg-neutral)", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: startIcon })), placeholderIcon && !hasValue && (_jsx("div", { style: { color: iconOnly ? "var(--fg-neutral)" : "var(--fg-disabled)", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: placeholderIcon })), numberPrefix && (_jsx("div", { style: prefixStyles, children: numberPrefix })), _jsx("input", { ref: ref, type: "text", value: value, placeholder: placeholder, disabled: disabled, className: className, style: { ...inputStyles, ...style }, ...rest }), endIcon && (_jsx("div", { style: { color: "var(--fg-neutral-tertiary)", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: endIcon }))] }), showError && (_jsxs("div", { style: errorContainerStyles, children: [_jsx("div", { style: { ...errorIconStyles, display: "flex", alignItems: "center", justifyContent: "center" }, children: _jsx(AlertTriangleErrorIcon, { size: 16 }) }), _jsx("p", { style: errorMessageStyles, children: errorMessage })] }))] }));
|
|
138
139
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ComponentPropsWithRef } from "react";
|
|
2
2
|
type MenuVariant = "desktop" | "tablet-open" | "tablet-closed" | "mobile-open" | "mobile-closed" | "close-menu";
|
|
3
3
|
interface MenuItem {
|
|
4
4
|
id: string;
|
|
5
5
|
label: string;
|
|
6
6
|
}
|
|
7
|
-
interface MenuProps {
|
|
7
|
+
export interface MenuProps extends ComponentPropsWithRef<"div"> {
|
|
8
8
|
variant?: MenuVariant;
|
|
9
9
|
showMenu?: boolean;
|
|
10
10
|
showButton?: boolean;
|
|
@@ -12,9 +12,8 @@ interface MenuProps {
|
|
|
12
12
|
headerTitle?: string;
|
|
13
13
|
headerSubtitle?: string;
|
|
14
14
|
showChevrons?: boolean;
|
|
15
|
-
|
|
16
|
-
hue?: HueVariant;
|
|
15
|
+
avatarImageUrl?: string;
|
|
17
16
|
}
|
|
18
|
-
export declare function Menu({ variant, showMenu, showButton, menuItems, headerTitle, headerSubtitle, showChevrons,
|
|
17
|
+
export declare function Menu({ variant, showMenu, showButton, menuItems, headerTitle, headerSubtitle, showChevrons, avatarImageUrl, className, style, ref, ...rest }: MenuProps): import("react/jsx-runtime").JSX.Element;
|
|
19
18
|
export {};
|
|
20
19
|
//# sourceMappingURL=Menu.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../src/components/Menu.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Menu.d.ts","sourceRoot":"","sources":["../../src/components/Menu.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAW,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAKvD,KAAK,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,GAAG,YAAY,CAAC;AAEhH,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,SAAU,SAAQ,qBAAqB,CAAC,KAAK,CAAC;IAC7D,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAUD,wBAAgB,IAAI,CAAC,EACnB,OAAmB,EACnB,QAAe,EACf,UAAiB,EACjB,SAA8B,EAC9B,WAAqB,EACrB,cAA2B,EAC3B,YAAmB,EACnB,cAAc,EACd,SAAS,EACT,KAAK,EACL,GAAG,EACH,GAAG,IAAI,EACR,EAAE,SAAS,2CAgZX"}
|
package/dist/components/Menu.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useMemo } from "react";
|
|
4
4
|
import { UserPersonIcon, ChevronRightIcon, CloseIcon, MenuIcon, DownloadIcon } from "../icons";
|
|
5
|
-
import {
|
|
5
|
+
import { Switch } from "./Switch";
|
|
6
|
+
import { useThemeSafe } from "../providers/ThemeProvider";
|
|
6
7
|
const DEFAULT_MENU_ITEMS = [
|
|
7
8
|
{ id: "1", label: "Menu Item #1" },
|
|
8
9
|
{ id: "2", label: "Menu Item #2" },
|
|
@@ -10,7 +11,9 @@ const DEFAULT_MENU_ITEMS = [
|
|
|
10
11
|
{ id: "4", label: "Menu Item #4" },
|
|
11
12
|
{ id: "5", label: "Menu Item #5" },
|
|
12
13
|
];
|
|
13
|
-
export function Menu({ variant = "desktop", showMenu = true, showButton = true, menuItems = DEFAULT_MENU_ITEMS, headerTitle = "Title", headerSubtitle = "Subtitle", showChevrons = true,
|
|
14
|
+
export function Menu({ variant = "desktop", showMenu = true, showButton = true, menuItems = DEFAULT_MENU_ITEMS, headerTitle = "Title", headerSubtitle = "Subtitle", showChevrons = true, avatarImageUrl, className, style, ref, ...rest }) {
|
|
15
|
+
const themeContext = useThemeSafe();
|
|
16
|
+
const theme = themeContext?.theme ?? "dark";
|
|
14
17
|
const containerStyles = useMemo(() => {
|
|
15
18
|
const baseStyles = {
|
|
16
19
|
display: "flex",
|
|
@@ -26,7 +29,7 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
26
29
|
return {
|
|
27
30
|
...baseStyles,
|
|
28
31
|
width: "240px",
|
|
29
|
-
height: "
|
|
32
|
+
height: "100%",
|
|
30
33
|
borderLeft: "none",
|
|
31
34
|
borderTop: "none",
|
|
32
35
|
borderBottom: "none",
|
|
@@ -184,7 +187,7 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
184
187
|
};
|
|
185
188
|
}, []);
|
|
186
189
|
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 }) }) }) }));
|
|
190
|
+
return (_jsx("div", { ref: ref, className: className, style: { ...containerStyles, ...style }, ...rest, 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
191
|
}
|
|
189
192
|
const isDesktop = variant === "desktop";
|
|
190
193
|
const isTabletOpen = variant === "tablet-open";
|
|
@@ -193,12 +196,12 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
193
196
|
const isMobileClosed = variant === "mobile-closed";
|
|
194
197
|
const showMenuItems = (isDesktop || isTabletOpen || isMobileOpen) && showMenu;
|
|
195
198
|
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:
|
|
199
|
+
return (_jsxs("div", { ref: ref, className: className, style: { ...containerStyles, ...style }, ...rest, children: [isDesktop ? (_jsx(_Fragment, { children: _jsxs("div", { style: headerStyles, children: [_jsx("div", { style: avatarStyles, children: avatarImageUrl ? (_jsx("img", { src: avatarImageUrl, alt: "User avatar", style: {
|
|
197
200
|
width: "100%",
|
|
198
201
|
height: "100%",
|
|
199
202
|
objectFit: "cover",
|
|
200
203
|
objectPosition: "center",
|
|
201
|
-
} }) }), showHeaderContent && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-none)", flex: 1 }, children: [_jsx("p", { style: {
|
|
204
|
+
} })) : (_jsx(UserPersonIcon, { size: 24 })) }), showHeaderContent && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-none)", flex: 1 }, children: [_jsx("p", { style: {
|
|
202
205
|
fontFamily: "var(--font-secondary)",
|
|
203
206
|
fontSize: "var(--body-small-text-size)",
|
|
204
207
|
lineHeight: "var(--body-small-line-height)",
|
|
@@ -214,12 +217,12 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
214
217
|
margin: 0,
|
|
215
218
|
}, children: headerSubtitle })] }))] }) })) : (
|
|
216
219
|
/* 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:
|
|
220
|
+
_jsxs("div", { style: mainRowStyles, children: [_jsxs("div", { style: headerStyles, children: [_jsx("div", { style: avatarStyles, children: avatarImageUrl ? (_jsx("img", { src: avatarImageUrl, alt: "User avatar", style: {
|
|
218
221
|
width: "100%",
|
|
219
222
|
height: "100%",
|
|
220
223
|
objectFit: "cover",
|
|
221
224
|
objectPosition: "center",
|
|
222
|
-
} }) }), showHeaderContent && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-none)", flex: 1 }, children: [_jsx("p", { style: {
|
|
225
|
+
} })) : (_jsx(UserPersonIcon, { size: 24 })) }), showHeaderContent && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "var(--spacing-none)", flex: 1 }, children: [_jsx("p", { style: {
|
|
223
226
|
fontFamily: "var(--font-secondary)",
|
|
224
227
|
fontSize: "var(--body-small-text-size)",
|
|
225
228
|
lineHeight: "var(--body-small-line-height)",
|
|
@@ -233,7 +236,7 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
233
236
|
fontWeight: "var(--font-weight-secondary-medium)",
|
|
234
237
|
color: "var(--fg-neutral)",
|
|
235
238
|
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(
|
|
239
|
+
}, 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(Switch, { checked: theme === "dark", showIcons: true }), _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
240
|
display: "flex",
|
|
238
241
|
flexDirection: "column",
|
|
239
242
|
gap: "var(--spacing-200)",
|
|
@@ -248,5 +251,5 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
248
251
|
color: "var(--fg-neutral-secondary)",
|
|
249
252
|
margin: 0,
|
|
250
253
|
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(
|
|
254
|
+
}, 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(Switch, { checked: theme === "dark", showIcons: true }) })] }))] }));
|
|
252
255
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
type RadioButtonStatus = "default" | "hovered" | "focused" | "pressed" | "disabled";
|
|
3
|
-
interface RadioButtonProps {
|
|
1
|
+
import { ComponentPropsWithRef } from "react";
|
|
2
|
+
export type RadioButtonStatus = "default" | "hovered" | "focused" | "pressed" | "disabled";
|
|
3
|
+
export interface RadioButtonProps extends Omit<ComponentPropsWithRef<"input">, "type" | "onChange"> {
|
|
4
4
|
selected?: boolean;
|
|
5
|
-
|
|
5
|
+
onChange?: (selected: boolean) => void;
|
|
6
6
|
label?: string;
|
|
7
7
|
showLabel?: boolean;
|
|
8
|
-
|
|
9
|
-
hue?: HueVariant;
|
|
8
|
+
status?: RadioButtonStatus;
|
|
10
9
|
}
|
|
11
|
-
export declare function RadioButton({ selected,
|
|
12
|
-
export {};
|
|
10
|
+
export declare function RadioButton({ selected, onChange, disabled, id, label, showLabel, status: statusProp, className, style, onClick, onFocus, onBlur, onMouseEnter, onMouseLeave, onMouseDown, onMouseUp, ref, ...rest }: RadioButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
13
11
|
//# sourceMappingURL=RadioButton.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RadioButton.d.ts","sourceRoot":"","sources":["../../src/components/RadioButton.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"RadioButton.d.ts","sourceRoot":"","sources":["../../src/components/RadioButton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAkC,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAG9E,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAE3F,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IACjG,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC5B;AAID,wBAAgB,WAAW,CAAC,EAC1B,QAAgB,EAChB,QAAQ,EACR,QAAgB,EAChB,EAAE,EACF,KAAsB,EACtB,SAAgB,EAChB,MAAM,EAAE,UAAU,EAClB,SAAS,EACT,KAAK,EACL,OAAO,EACP,OAAO,EACP,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,SAAS,EACT,GAAG,EACH,GAAG,IAAI,EACR,EAAE,gBAAgB,2CA4PlB"}
|
|
@@ -1,9 +1,55 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useMemo } from "react";
|
|
3
|
+
import { useMemo, useState, useCallback } from "react";
|
|
4
|
+
import { useThemeSafe } from "../providers/ThemeProvider";
|
|
4
5
|
const RADIO_SIZE = 20;
|
|
5
|
-
export function RadioButton({ selected = false,
|
|
6
|
-
|
|
6
|
+
export function RadioButton({ selected = false, onChange, disabled = false, id, label = "Radio Button", showLabel = true, status: statusProp, className, style, onClick, onFocus, onBlur, onMouseEnter, onMouseLeave, onMouseDown, onMouseUp, ref, ...rest }) {
|
|
7
|
+
useThemeSafe(); // Ensure theme context is available
|
|
8
|
+
const [internalStatus, setInternalStatus] = useState("default");
|
|
9
|
+
const status = statusProp ?? internalStatus;
|
|
10
|
+
const handleClick = useCallback((e) => {
|
|
11
|
+
if (!disabled && onChange) {
|
|
12
|
+
onChange(!selected);
|
|
13
|
+
}
|
|
14
|
+
onClick?.(e);
|
|
15
|
+
}, [selected, disabled, onChange, onClick]);
|
|
16
|
+
const handleFocus = useCallback((e) => {
|
|
17
|
+
if (!disabled && !statusProp) {
|
|
18
|
+
setInternalStatus("focused");
|
|
19
|
+
}
|
|
20
|
+
onFocus?.(e);
|
|
21
|
+
}, [disabled, statusProp, onFocus]);
|
|
22
|
+
const handleBlur = useCallback((e) => {
|
|
23
|
+
if (!disabled && !statusProp) {
|
|
24
|
+
setInternalStatus("default");
|
|
25
|
+
}
|
|
26
|
+
onBlur?.(e);
|
|
27
|
+
}, [disabled, statusProp, onBlur]);
|
|
28
|
+
const handleMouseEnter = useCallback((e) => {
|
|
29
|
+
if (!disabled && !statusProp) {
|
|
30
|
+
setInternalStatus("hovered");
|
|
31
|
+
}
|
|
32
|
+
onMouseEnter?.(e);
|
|
33
|
+
}, [disabled, statusProp, onMouseEnter]);
|
|
34
|
+
const handleMouseLeave = useCallback((e) => {
|
|
35
|
+
if (!disabled && !statusProp) {
|
|
36
|
+
setInternalStatus("default");
|
|
37
|
+
}
|
|
38
|
+
onMouseLeave?.(e);
|
|
39
|
+
}, [disabled, statusProp, onMouseLeave]);
|
|
40
|
+
const handleMouseDown = useCallback((e) => {
|
|
41
|
+
if (!disabled && !statusProp) {
|
|
42
|
+
setInternalStatus("pressed");
|
|
43
|
+
}
|
|
44
|
+
onMouseDown?.(e);
|
|
45
|
+
}, [disabled, statusProp, onMouseDown]);
|
|
46
|
+
const handleMouseUp = useCallback((e) => {
|
|
47
|
+
if (!disabled && !statusProp) {
|
|
48
|
+
setInternalStatus("default");
|
|
49
|
+
}
|
|
50
|
+
onMouseUp?.(e);
|
|
51
|
+
}, [disabled, statusProp, onMouseUp]);
|
|
52
|
+
const currentStatus = disabled ? "disabled" : status;
|
|
7
53
|
const radioStyles = useMemo(() => {
|
|
8
54
|
const baseStyles = {
|
|
9
55
|
width: `${RADIO_SIZE}px`,
|
|
@@ -28,7 +74,7 @@ export function RadioButton({ selected = false, status = "default", label = "Rad
|
|
|
28
74
|
backgroundColor: "transparent",
|
|
29
75
|
};
|
|
30
76
|
}
|
|
31
|
-
if (
|
|
77
|
+
if (currentStatus === "hovered") {
|
|
32
78
|
return {
|
|
33
79
|
...baseStyles,
|
|
34
80
|
borderWidth: "var(--border-width-150)",
|
|
@@ -37,7 +83,7 @@ export function RadioButton({ selected = false, status = "default", label = "Rad
|
|
|
37
83
|
backgroundColor: "transparent",
|
|
38
84
|
};
|
|
39
85
|
}
|
|
40
|
-
if (
|
|
86
|
+
if (currentStatus === "focused" || currentStatus === "pressed") {
|
|
41
87
|
return {
|
|
42
88
|
...baseStyles,
|
|
43
89
|
borderWidth: "var(--border-width-150)",
|
|
@@ -66,7 +112,7 @@ export function RadioButton({ selected = false, status = "default", label = "Rad
|
|
|
66
112
|
backgroundColor: "transparent",
|
|
67
113
|
};
|
|
68
114
|
}
|
|
69
|
-
if (
|
|
115
|
+
if (currentStatus === "hovered" || currentStatus === "focused" || currentStatus === "pressed") {
|
|
70
116
|
return {
|
|
71
117
|
...baseStyles,
|
|
72
118
|
borderWidth: "var(--border-width-25)",
|
|
@@ -84,7 +130,7 @@ export function RadioButton({ selected = false, status = "default", label = "Rad
|
|
|
84
130
|
backgroundColor: "transparent",
|
|
85
131
|
};
|
|
86
132
|
}
|
|
87
|
-
}, [selected,
|
|
133
|
+
}, [selected, currentStatus, disabled]);
|
|
88
134
|
const labelStyles = useMemo(() => {
|
|
89
135
|
const baseStyles = {
|
|
90
136
|
fontFamily: "var(--font-secondary)",
|
|
@@ -105,14 +151,8 @@ export function RadioButton({ selected = false, status = "default", label = "Rad
|
|
|
105
151
|
};
|
|
106
152
|
}, [disabled]);
|
|
107
153
|
const focusRingStyles = useMemo(() => {
|
|
108
|
-
if (
|
|
154
|
+
if (currentStatus !== "focused")
|
|
109
155
|
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
156
|
return {
|
|
117
157
|
position: "absolute",
|
|
118
158
|
top: "50%",
|
|
@@ -130,11 +170,23 @@ export function RadioButton({ selected = false, status = "default", label = "Rad
|
|
|
130
170
|
: "var(--border-neutral-primary)",
|
|
131
171
|
pointerEvents: "none",
|
|
132
172
|
};
|
|
133
|
-
}, [
|
|
173
|
+
}, [currentStatus, selected]);
|
|
134
174
|
return (_jsxs("div", { style: {
|
|
135
175
|
display: "flex",
|
|
136
176
|
alignItems: "center",
|
|
137
177
|
gap: "var(--spacing-200)",
|
|
138
178
|
position: "relative",
|
|
139
|
-
}, children: [_jsx("div", { style: radioStyles, children: focusRingStyles && _jsx("div", { style: focusRingStyles }) }),
|
|
179
|
+
}, className: className, children: [_jsx("div", { style: radioStyles, children: focusRingStyles && _jsx("div", { style: focusRingStyles }) }), _jsx("input", { ref: ref, type: "radio", id: id, checked: selected, disabled: disabled, onChange: () => {
|
|
180
|
+
if (!disabled && onChange) {
|
|
181
|
+
onChange(!selected);
|
|
182
|
+
}
|
|
183
|
+
}, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onMouseDown: handleMouseDown, onMouseUp: handleMouseUp, style: {
|
|
184
|
+
position: "absolute",
|
|
185
|
+
opacity: 0,
|
|
186
|
+
width: `${RADIO_SIZE}px`,
|
|
187
|
+
height: `${RADIO_SIZE}px`,
|
|
188
|
+
margin: 0,
|
|
189
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
190
|
+
...style,
|
|
191
|
+
}, ...rest }), showLabel && label && (_jsx("label", { htmlFor: id, style: labelStyles, children: label }))] }));
|
|
140
192
|
}
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
import { ComponentPropsWithRef } from "react";
|
|
2
|
+
export type SwitchStatus = "default" | "hovered" | "focused" | "pressed" | "disabled";
|
|
3
|
+
export interface SwitchProps extends Omit<ComponentPropsWithRef<"button">, "onChange" | "type"> {
|
|
2
4
|
checked?: boolean;
|
|
3
5
|
onChange?: (checked: boolean) => void;
|
|
4
|
-
disabled?: boolean;
|
|
5
|
-
id?: string;
|
|
6
|
-
ariaLabel?: string;
|
|
7
6
|
showIcons?: boolean;
|
|
7
|
+
status?: SwitchStatus;
|
|
8
8
|
}
|
|
9
|
-
export declare function Switch({ checked, onChange, disabled, id, ariaLabel, showIcons, }: SwitchProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
export {};
|
|
9
|
+
export declare function Switch({ checked, onChange, disabled, id, "aria-label": ariaLabel, showIcons, status: statusProp, className, style, onClick, onKeyDown, onMouseEnter, onMouseLeave, onFocus, onBlur, onMouseDown, onMouseUp, ref, ...rest }: SwitchProps): import("react/jsx-runtime").JSX.Element;
|
|
11
10
|
//# sourceMappingURL=Switch.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/components/Switch.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/components/Switch.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAkC,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAI9E,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;AAEtF,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC7F,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAOD,wBAAgB,MAAM,CAAC,EACrB,OAAe,EACf,QAAQ,EACR,QAAgB,EAChB,EAAE,EACF,YAAY,EAAE,SAAS,EACvB,SAAiB,EACjB,MAAM,EAAE,UAAU,EAClB,SAAS,EACT,KAAK,EACL,OAAO,EACP,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,GAAG,EACH,GAAG,IAAI,EACR,EAAE,WAAW,2CA2Yb"}
|