beacon-ui 3.1.5 → 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 +24 -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 +3 -5
- package/dist/components/Menu.d.ts.map +1 -1
- package/dist/components/Menu.js +5 -6
- 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;
|
|
@@ -13,9 +13,7 @@ interface MenuProps {
|
|
|
13
13
|
headerSubtitle?: string;
|
|
14
14
|
showChevrons?: boolean;
|
|
15
15
|
avatarImageUrl?: string;
|
|
16
|
-
theme?: Theme;
|
|
17
|
-
hue?: HueVariant;
|
|
18
16
|
}
|
|
19
|
-
export declare function Menu({ variant, showMenu, showButton, menuItems, headerTitle, headerSubtitle, showChevrons, avatarImageUrl,
|
|
17
|
+
export declare function Menu({ variant, showMenu, showButton, menuItems, headerTitle, headerSubtitle, showChevrons, avatarImageUrl, className, style, ref, ...rest }: MenuProps): import("react/jsx-runtime").JSX.Element;
|
|
20
18
|
export {};
|
|
21
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
|
@@ -11,10 +11,9 @@ const DEFAULT_MENU_ITEMS = [
|
|
|
11
11
|
{ id: "4", label: "Menu Item #4" },
|
|
12
12
|
{ id: "5", label: "Menu Item #5" },
|
|
13
13
|
];
|
|
14
|
-
export function Menu({ variant = "desktop", showMenu = true, showButton = true, menuItems = DEFAULT_MENU_ITEMS, headerTitle = "Title", headerSubtitle = "Subtitle", showChevrons = true, avatarImageUrl,
|
|
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
15
|
const themeContext = useThemeSafe();
|
|
16
|
-
const theme =
|
|
17
|
-
const hue = hueProp ?? themeContext?.hue ?? "chromatic-prime";
|
|
16
|
+
const theme = themeContext?.theme ?? "dark";
|
|
18
17
|
const containerStyles = useMemo(() => {
|
|
19
18
|
const baseStyles = {
|
|
20
19
|
display: "flex",
|
|
@@ -30,7 +29,7 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
30
29
|
return {
|
|
31
30
|
...baseStyles,
|
|
32
31
|
width: "240px",
|
|
33
|
-
height: "
|
|
32
|
+
height: "100%",
|
|
34
33
|
borderLeft: "none",
|
|
35
34
|
borderTop: "none",
|
|
36
35
|
borderBottom: "none",
|
|
@@ -188,7 +187,7 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
188
187
|
};
|
|
189
188
|
}, []);
|
|
190
189
|
if (variant === "close-menu") {
|
|
191
|
-
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 }) }) }) }));
|
|
192
191
|
}
|
|
193
192
|
const isDesktop = variant === "desktop";
|
|
194
193
|
const isTabletOpen = variant === "tablet-open";
|
|
@@ -197,7 +196,7 @@ export function Menu({ variant = "desktop", showMenu = true, showButton = true,
|
|
|
197
196
|
const isMobileClosed = variant === "mobile-closed";
|
|
198
197
|
const showMenuItems = (isDesktop || isTabletOpen || isMobileOpen) && showMenu;
|
|
199
198
|
const showHeaderContent = isDesktop || isTabletOpen || isTabletClosed;
|
|
200
|
-
return (_jsxs("div", { style: containerStyles, children: [isDesktop ? (_jsx(_Fragment, { children: _jsxs("div", { style: headerStyles, children: [_jsx("div", { style: avatarStyles, children: avatarImageUrl ? (_jsx("img", { src: avatarImageUrl, alt: "User avatar", style: {
|
|
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: {
|
|
201
200
|
width: "100%",
|
|
202
201
|
height: "100%",
|
|
203
202
|
objectFit: "cover",
|
|
@@ -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"}
|