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.
@@ -1 +1 @@
1
- {"version":3,"file":"Input.d.ts","sourceRoot":"","sources":["../../src/components/Input.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGzD,KAAK,SAAS,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACpC,KAAK,WAAW,GAAG,SAAS,GAAG,QAAQ,CAAC;AAExC,UAAU,UAAU;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAuDD,wBAAgB,KAAK,CAAC,EACpB,KAAe,EACf,WAA2B,EAC3B,KAAU,EACV,IAAW,EACX,MAAkB,EAClB,SAAgB,EAChB,aAAqB,EACrB,WAAmB,EACnB,mBAA2B,EAC3B,SAAiB,EACjB,gBAAwB,EACxB,OAAe,EACf,QAAgB,EAChB,QAAgB,EAChB,KAAK,EACL,GAAG,GACJ,EAAE,UAAU,2CAgKZ"}
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"}
@@ -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 { UserPersonIcon, SearchIcon, ChevronDownIcon, AlertTriangleErrorIcon } from "../icons";
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 = "Label", placeholder = "Placeholder", value = "", size = "md", status = "default", showLabel = true, showStartIcon = false, showEndIcon = false, showPlaceholderIcon = false, showError = false, showNumberPrefix = false, rounded = false, iconOnly = false, disabled = false, theme, hue, }) {
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: [showPlaceholderIcon && (_jsx("div", { style: { color: "var(--fg-neutral)", display: "flex", alignItems: "center", justifyContent: "center" }, children: _jsx(SearchIcon, { size: sizeConfig.iconSize }) })), showStartIcon && !showPlaceholderIcon && (_jsx("div", { style: { color: "var(--fg-neutral)", display: "flex", alignItems: "center", justifyContent: "center" }, children: _jsx(UserPersonIcon, { size: sizeConfig.iconSize }) }))] }) }));
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("p", { style: labelStyles, children: label })), _jsxs("div", { style: inputContainerStyles, children: [showStartIcon && (_jsx("div", { style: { color: "var(--fg-neutral)", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: _jsx(UserPersonIcon, { size: sizeConfig.iconSize }) })), showPlaceholderIcon && !hasValue && (_jsx("div", { style: { color: iconOnly ? "var(--fg-neutral)" : "var(--fg-disabled)", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: _jsx(SearchIcon, { size: sizeConfig.iconSize }) })), showNumberPrefix && (_jsx("div", { style: prefixStyles, children: "+33" })), hasValue ? (_jsx("p", { style: textStyles, children: value })) : (_jsx("p", { style: textStyles, children: placeholder })), showEndIcon && (_jsx("div", { style: { color: "var(--fg-neutral-tertiary)", flexShrink: 0, display: "flex", alignItems: "center", justifyContent: "center" }, children: _jsx(ChevronDownIcon, { size: sizeConfig.iconSize }) }))] }), 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: "Error message!" })] }))] }));
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 type { Theme, HueVariant } from "../tokens/types";
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
- theme?: Theme;
16
- hue?: HueVariant;
15
+ avatarImageUrl?: string;
17
16
  }
18
- export declare function Menu({ variant, showMenu, showButton, menuItems, headerTitle, headerSubtitle, showChevrons, theme, hue, }: MenuProps): import("react/jsx-runtime").JSX.Element;
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":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAIzD,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,UAAU,SAAS;IACjB,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,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,GAAG,CAAC,EAAE,UAAU,CAAC;CAClB;AAUD,wBAAgB,IAAI,CAAC,EACnB,OAAmB,EACnB,QAAe,EACf,UAAiB,EACjB,SAA8B,EAC9B,WAAqB,EACrB,cAA2B,EAC3B,YAAmB,EACnB,KAAK,EACL,GAAG,GACJ,EAAE,SAAS,2CA0YX"}
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"}
@@ -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 { SwitchPreview } from "./SwitchPreview";
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, theme, hue, }) {
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: "600px",
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: "/images/avatars/avatar-female.png", 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: {
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: "/images/avatars/avatar-female.png", alt: "User avatar", style: {
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(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: {
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(SwitchPreview, { checked: theme === "dark", showIcons: true, theme: theme, hue: hue }) })] }))] }));
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 type { Theme, HueVariant } from "../tokens/types";
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
- status?: RadioButtonStatus;
5
+ onChange?: (selected: boolean) => void;
6
6
  label?: string;
7
7
  showLabel?: boolean;
8
- theme?: Theme;
9
- hue?: HueVariant;
8
+ status?: RadioButtonStatus;
10
9
  }
11
- export declare function RadioButton({ selected, status, label, showLabel, theme, hue, }: RadioButtonProps): import("react/jsx-runtime").JSX.Element;
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":"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"}
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, status = "default", label = "Radio Button", showLabel = true, theme, hue, }) {
6
- const disabled = status === "disabled";
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 (status === "hovered") {
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 (status === "focused" || status === "pressed") {
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 (status === "hovered" || status === "focused" || status === "pressed") {
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, status, disabled]);
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 (status !== "focused")
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
- }, [status, selected]);
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 }) }), showLabel && label && _jsx("p", { style: labelStyles, children: label })] }));
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
- interface SwitchProps {
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":"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"}
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"}