@luxfi/ui 7.4.10 → 7.4.11

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 (78) hide show
  1. package/dist/accordion.cjs +107 -166
  2. package/dist/accordion.d.cts +18 -51
  3. package/dist/accordion.d.ts +18 -51
  4. package/dist/accordion.js +109 -166
  5. package/dist/chrome.cjs +193 -379
  6. package/dist/chrome.js +195 -379
  7. package/dist/collapsible.cjs +35 -26
  8. package/dist/collapsible.d.cts +2 -1
  9. package/dist/collapsible.d.ts +2 -1
  10. package/dist/collapsible.js +34 -24
  11. package/dist/dialog.d.cts +1 -1
  12. package/dist/dialog.d.ts +1 -1
  13. package/dist/drawer.cjs +92 -115
  14. package/dist/drawer.d.cts +43 -10
  15. package/dist/drawer.d.ts +43 -10
  16. package/dist/drawer.js +94 -115
  17. package/dist/field.cjs +60 -109
  18. package/dist/field.d.cts +0 -1
  19. package/dist/field.d.ts +0 -1
  20. package/dist/field.js +61 -109
  21. package/dist/heading.cjs +10 -17
  22. package/dist/heading.d.cts +0 -2
  23. package/dist/heading.d.ts +0 -2
  24. package/dist/heading.js +10 -17
  25. package/dist/icon-button.cjs +82 -82
  26. package/dist/icon-button.d.cts +16 -12
  27. package/dist/icon-button.d.ts +16 -12
  28. package/dist/icon-button.js +82 -82
  29. package/dist/index.cjs +1073 -1419
  30. package/dist/index.d.cts +1 -5
  31. package/dist/index.d.ts +1 -5
  32. package/dist/index.js +1075 -1414
  33. package/dist/input-group.cjs +11 -12
  34. package/dist/input-group.js +11 -12
  35. package/dist/input.cjs +27 -27
  36. package/dist/input.d.cts +21 -1
  37. package/dist/input.d.ts +21 -1
  38. package/dist/input.js +25 -28
  39. package/dist/menu.cjs +160 -271
  40. package/dist/menu.d.cts +41 -57
  41. package/dist/menu.d.ts +41 -57
  42. package/dist/menu.js +161 -251
  43. package/dist/popover.cjs +1 -1
  44. package/dist/popover.js +1 -1
  45. package/dist/select.cjs +40 -39
  46. package/dist/select.d.cts +35 -4
  47. package/dist/select.d.ts +35 -4
  48. package/dist/select.js +40 -38
  49. package/dist/separator.cjs +8 -33
  50. package/dist/separator.js +8 -33
  51. package/dist/tabs.cjs +108 -197
  52. package/dist/tabs.d.cts +16 -60
  53. package/dist/tabs.d.ts +16 -60
  54. package/dist/tabs.js +109 -196
  55. package/dist/textarea.cjs +56 -27
  56. package/dist/textarea.js +57 -28
  57. package/dist/toaster.cjs +97 -79
  58. package/dist/toaster.d.cts +7 -8
  59. package/dist/toaster.d.ts +7 -8
  60. package/dist/toaster.js +78 -80
  61. package/package.json +2 -16
  62. package/src/accordion.tsx +173 -227
  63. package/src/collapsible.tsx +55 -52
  64. package/src/drawer.tsx +123 -115
  65. package/src/field.tsx +68 -124
  66. package/src/heading.tsx +22 -26
  67. package/src/icon-button.tsx +134 -141
  68. package/src/ink.tsx +37 -0
  69. package/src/input-group.tsx +21 -12
  70. package/src/input.tsx +41 -32
  71. package/src/menu.tsx +224 -397
  72. package/src/popover.tsx +1 -1
  73. package/src/select.tsx +80 -59
  74. package/src/separator.tsx +13 -34
  75. package/src/tabs.tsx +166 -296
  76. package/src/textarea.tsx +19 -29
  77. package/src/toaster.tsx +118 -86
  78. package/tokens.css +61 -0
package/dist/field.js CHANGED
@@ -1,20 +1,26 @@
1
1
  "use client";
2
- import * as LabelPrimitive from '@radix-ui/react-label';
2
+ import { YStack, Label, Text } from '@hanzo/gui';
3
3
  import * as React from 'react';
4
- import { clsx } from 'clsx';
5
- import { twMerge } from 'tailwind-merge';
6
- import { jsxs, jsx } from 'react/jsx-runtime';
4
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
5
 
8
6
  // src/field.tsx
9
- function cn(...inputs) {
10
- return twMerge(clsx(inputs));
11
- }
12
7
  var space = String.fromCharCode(32);
13
8
  function getComponentDisplayName(type) {
14
9
  if (typeof type === "string") return void 0;
15
10
  if ("displayName" in type) return type.displayName;
16
11
  return void 0;
17
12
  }
13
+ var ERROR = "var(--color-text-error)";
14
+ var MUTED = "var(--color-text-secondary)";
15
+ var Marks = ({ required, optionalText, errorText }) => /* @__PURE__ */ jsxs(Fragment, { children: [
16
+ required && /* @__PURE__ */ jsx(Text, { color: ERROR, "aria-hidden": true, children: "*" }),
17
+ !required && optionalText && /* @__PURE__ */ jsx(Text, { fontSize: 14, color: MUTED, children: optionalText }),
18
+ errorText && /* @__PURE__ */ jsxs(Text, { fontSize: 14, color: ERROR, children: [
19
+ "-",
20
+ space,
21
+ errorText
22
+ ] })
23
+ ] });
18
24
  var Field = React.forwardRef(
19
25
  function Field2(props, ref) {
20
26
  const {
@@ -33,127 +39,73 @@ var Field = React.forwardRef(
33
39
  className,
34
40
  style
35
41
  } = props;
42
+ const flags = {
43
+ "data-disabled": disabled || void 0,
44
+ "data-readonly": readOnly || void 0,
45
+ "data-invalid": invalid || void 0
46
+ };
36
47
  if (floating && label) {
37
- const injectedProps2 = {
38
- className: "peer",
39
- placeholder: " ",
40
- size,
41
- floating,
42
- disabled,
43
- readOnly
44
- };
48
+ const injectedProps = { className: "lux-field-control", placeholder: " ", size, floating, disabled, readOnly };
45
49
  const labelElement = /* @__PURE__ */ jsxs(
46
- LabelPrimitive.Root,
50
+ Label,
47
51
  {
48
- className: cn(
49
- "absolute left-3 top-1/2 -translate-y-1/2",
50
- "text-[var(--color-input-placeholder,theme(colors.gray.400))]",
51
- "pointer-events-none select-none",
52
- "origin-top-left transition-all duration-150",
53
- "peer-focus:top-1 peer-focus:translate-y-0 peer-focus:scale-75",
54
- "peer-[:not(:placeholder-shown)]:top-1 peer-[:not(:placeholder-shown)]:translate-y-0 peer-[:not(:placeholder-shown)]:scale-75"
55
- ),
56
52
  htmlFor: id,
53
+ position: "absolute",
54
+ left: 12,
55
+ top: "50%",
56
+ pointerEvents: "none",
57
+ userSelect: "none",
58
+ flexDirection: "row",
59
+ gap: 4,
60
+ color: "var(--color-input-placeholder)",
61
+ className: "lux-field-float",
57
62
  children: [
58
63
  label,
59
- required && /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-[var(--color-fg-error,theme(colors.red.500))]", "aria-hidden": "true", children: "*" }),
60
- !required && optionalText && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[var(--color-text-secondary,theme(colors.gray.400))] text-sm", children: optionalText }),
61
- errorText && /* @__PURE__ */ jsxs("span", { className: "ml-0.5 text-[var(--color-fg-error,theme(colors.red.500))] text-sm", children: [
62
- "-",
63
- space,
64
- errorText
65
- ] })
64
+ /* @__PURE__ */ jsx(Marks, { required, optionalText, errorText })
66
65
  ]
67
66
  }
68
67
  );
69
- const helperTextElement = helperText ? /* @__PURE__ */ jsx("p", { className: "mt-1.5 text-xs text-[var(--color-text-secondary,theme(colors.gray.400))]", children: helperText }) : null;
68
+ const helperTextElement = helperText ? /* @__PURE__ */ jsx(Text, { marginTop: 6, fontSize: 12, color: MUTED, children: helperText }) : null;
70
69
  const child2 = React.Children.only(children);
71
70
  const isInputGroup = getComponentDisplayName(child2.type) === "InputGroup";
72
71
  if (isInputGroup) {
73
- const inputElement2 = React.cloneElement(
72
+ const inputElement = React.cloneElement(
74
73
  React.Children.only(child2.props.children),
75
- injectedProps2
76
- );
77
- const groupInputElement = React.cloneElement(
78
- child2,
79
- {},
80
- inputElement2,
81
- labelElement
82
- );
83
- return /* @__PURE__ */ jsxs(
84
- "div",
85
- {
86
- ref,
87
- id,
88
- className: cn("relative w-full", className),
89
- style,
90
- "data-disabled": disabled || void 0,
91
- "data-readonly": readOnly || void 0,
92
- "data-invalid": invalid || void 0,
93
- children: [
94
- groupInputElement,
95
- helperTextElement
96
- ]
97
- }
74
+ injectedProps
98
75
  );
76
+ return /* @__PURE__ */ jsxs(YStack, { ref, id, position: "relative", width: "100%", className, style, ...flags, children: [
77
+ React.cloneElement(child2, {}, inputElement, labelElement),
78
+ helperTextElement
79
+ ] });
99
80
  }
100
- const inputElement = React.cloneElement(child2, injectedProps2);
101
- return /* @__PURE__ */ jsxs(
102
- "div",
81
+ return /* @__PURE__ */ jsxs(YStack, { ref, id, position: "relative", width: "100%", className, style, ...flags, children: [
82
+ React.cloneElement(child2, injectedProps),
83
+ labelElement,
84
+ helperTextElement
85
+ ] });
86
+ }
87
+ const child = React.Children.only(children);
88
+ return /* @__PURE__ */ jsxs(YStack, { ref, id, gap: 4, className, style, ...flags, children: [
89
+ label && /* @__PURE__ */ jsxs(
90
+ Label,
103
91
  {
104
- ref,
105
- id,
106
- className: cn("relative w-full", className),
107
- style,
108
- "data-disabled": disabled || void 0,
109
- "data-readonly": readOnly || void 0,
110
- "data-invalid": invalid || void 0,
92
+ htmlFor: id,
93
+ flexDirection: "row",
94
+ gap: 4,
95
+ fontSize: 14,
96
+ fontWeight: "500",
97
+ color: "var(--color-text-primary)",
98
+ opacity: disabled ? 0.4 : 1,
111
99
  children: [
112
- inputElement,
113
- labelElement,
114
- helperTextElement
100
+ label,
101
+ /* @__PURE__ */ jsx(Marks, { required, optionalText })
115
102
  ]
116
103
  }
117
- );
118
- }
119
- const injectedProps = {
120
- size
121
- };
122
- const child = React.Children.only(children);
123
- const clonedChild = React.cloneElement(child, injectedProps);
124
- return /* @__PURE__ */ jsxs(
125
- "div",
126
- {
127
- ref,
128
- id,
129
- className: cn("flex flex-col gap-1", className),
130
- style,
131
- "data-disabled": disabled || void 0,
132
- "data-readonly": readOnly || void 0,
133
- "data-invalid": invalid || void 0,
134
- children: [
135
- label && /* @__PURE__ */ jsxs(
136
- LabelPrimitive.Root,
137
- {
138
- className: cn(
139
- "text-sm font-medium text-[var(--color-field-label,theme(colors.gray.700))]",
140
- "dark:text-[var(--color-field-label,theme(colors.gray.300))]",
141
- disabled && "opacity-40"
142
- ),
143
- htmlFor: id,
144
- children: [
145
- label,
146
- required && /* @__PURE__ */ jsx("span", { className: "ml-0.5 text-[var(--color-fg-error,theme(colors.red.500))]", "aria-hidden": "true", children: "*" }),
147
- !required && optionalText && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[var(--color-text-secondary,theme(colors.gray.400))] text-sm font-normal", children: optionalText })
148
- ]
149
- }
150
- ),
151
- clonedChild,
152
- helperText && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-text-secondary,theme(colors.gray.400))]", children: helperText }),
153
- errorText && /* @__PURE__ */ jsx("p", { className: "text-xs text-[var(--color-fg-error,theme(colors.red.500))]", children: errorText })
154
- ]
155
- }
156
- );
104
+ ),
105
+ React.cloneElement(child, { size }),
106
+ helperText && /* @__PURE__ */ jsx(Text, { fontSize: 12, color: MUTED, children: helperText }),
107
+ errorText && /* @__PURE__ */ jsx(Text, { fontSize: 12, color: ERROR, children: errorText })
108
+ ] });
157
109
  }
158
110
  );
159
111
 
package/dist/heading.cjs CHANGED
@@ -3,8 +3,6 @@
3
3
 
4
4
  var gui = require('@hanzo/gui');
5
5
  var React = require('react');
6
- var clsx = require('clsx');
7
- var tailwindMerge = require('tailwind-merge');
8
6
  var jsxRuntime = require('react/jsx-runtime');
9
7
 
10
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -12,28 +10,23 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
10
  var React__default = /*#__PURE__*/_interopDefault(React);
13
11
 
14
12
  // src/heading.tsx
15
- function cn(...inputs) {
16
- return tailwindMerge.twMerge(clsx.clsx(inputs));
17
- }
18
- var LEVEL_TAG = { "1": gui.H1, "2": gui.H2, "3": gui.H3 };
19
- var LEVEL_CLASSES = {
20
- "1": "text-[18px] leading-[24px] font-medium lg:text-[32px] lg:leading-[40px] lg:tracking-[-0.5px]",
21
- "2": "text-[16px] leading-[24px] font-medium lg:text-[24px] lg:leading-[32px]",
22
- "3": "text-[14px] leading-[20px] font-semibold lg:text-[18px] lg:leading-[24px] lg:font-medium"
13
+ var TAG = { "1": gui.H1, "2": gui.H2, "3": gui.H3 };
14
+ var RAMP = {
15
+ "1": { fontSize: 18, lineHeight: 24, fontWeight: "500", $lg: { fontSize: 32, lineHeight: 40, letterSpacing: -0.5 } },
16
+ "2": { fontSize: 16, lineHeight: 24, fontWeight: "500", $lg: { fontSize: 24, lineHeight: 32 } },
17
+ "3": { fontSize: 14, lineHeight: 20, fontWeight: "600", $lg: { fontSize: 18, lineHeight: 24, fontWeight: "500" } }
23
18
  };
24
- var BASE_CLASSES = "font-heading text-heading";
25
19
  var Heading = React__default.default.forwardRef(
26
- function Heading2({ level, className, mb, size: _size, style: styleProp, ...rest }, ref) {
27
- const Tag = level ? LEVEL_TAG[level] : gui.H2;
28
- const levelClasses = level ? LEVEL_CLASSES[level] : void 0;
29
- const mergedStyle = mb !== void 0 ? { ...styleProp, marginBottom: typeof mb === "number" ? `${mb * 4}px` : mb } : styleProp;
20
+ function Heading2({ level, ...rest }, ref) {
21
+ const Tag = level ? TAG[level] : gui.H2;
30
22
  return /* @__PURE__ */ jsxRuntime.jsx(
31
23
  Tag,
32
24
  {
33
25
  ref,
34
26
  unstyled: true,
35
- className: cn(BASE_CLASSES, levelClasses, className),
36
- style: mergedStyle,
27
+ fontFamily: "$heading",
28
+ color: "var(--color-heading)",
29
+ ...level ? RAMP[level] : null,
37
30
  ...rest
38
31
  }
39
32
  );
@@ -2,8 +2,6 @@ import React__default from 'react';
2
2
 
3
3
  interface HeadingProps extends React__default.ComponentPropsWithoutRef<'h1'> {
4
4
  level?: '1' | '2' | '3';
5
- mb?: number | string;
6
- size?: string;
7
5
  }
8
6
  declare const Heading: React__default.ForwardRefExoticComponent<HeadingProps & React__default.RefAttributes<HTMLHeadingElement>>;
9
7
 
package/dist/heading.d.ts CHANGED
@@ -2,8 +2,6 @@ import React__default from 'react';
2
2
 
3
3
  interface HeadingProps extends React__default.ComponentPropsWithoutRef<'h1'> {
4
4
  level?: '1' | '2' | '3';
5
- mb?: number | string;
6
- size?: string;
7
5
  }
8
6
  declare const Heading: React__default.ForwardRefExoticComponent<HeadingProps & React__default.RefAttributes<HTMLHeadingElement>>;
9
7
 
package/dist/heading.js CHANGED
@@ -1,33 +1,26 @@
1
1
  "use client";
2
2
  import { H3, H2, H1 } from '@hanzo/gui';
3
3
  import React from 'react';
4
- import { clsx } from 'clsx';
5
- import { twMerge } from 'tailwind-merge';
6
4
  import { jsx } from 'react/jsx-runtime';
7
5
 
8
6
  // src/heading.tsx
9
- function cn(...inputs) {
10
- return twMerge(clsx(inputs));
11
- }
12
- var LEVEL_TAG = { "1": H1, "2": H2, "3": H3 };
13
- var LEVEL_CLASSES = {
14
- "1": "text-[18px] leading-[24px] font-medium lg:text-[32px] lg:leading-[40px] lg:tracking-[-0.5px]",
15
- "2": "text-[16px] leading-[24px] font-medium lg:text-[24px] lg:leading-[32px]",
16
- "3": "text-[14px] leading-[20px] font-semibold lg:text-[18px] lg:leading-[24px] lg:font-medium"
7
+ var TAG = { "1": H1, "2": H2, "3": H3 };
8
+ var RAMP = {
9
+ "1": { fontSize: 18, lineHeight: 24, fontWeight: "500", $lg: { fontSize: 32, lineHeight: 40, letterSpacing: -0.5 } },
10
+ "2": { fontSize: 16, lineHeight: 24, fontWeight: "500", $lg: { fontSize: 24, lineHeight: 32 } },
11
+ "3": { fontSize: 14, lineHeight: 20, fontWeight: "600", $lg: { fontSize: 18, lineHeight: 24, fontWeight: "500" } }
17
12
  };
18
- var BASE_CLASSES = "font-heading text-heading";
19
13
  var Heading = React.forwardRef(
20
- function Heading2({ level, className, mb, size: _size, style: styleProp, ...rest }, ref) {
21
- const Tag = level ? LEVEL_TAG[level] : H2;
22
- const levelClasses = level ? LEVEL_CLASSES[level] : void 0;
23
- const mergedStyle = mb !== void 0 ? { ...styleProp, marginBottom: typeof mb === "number" ? `${mb * 4}px` : mb } : styleProp;
14
+ function Heading2({ level, ...rest }, ref) {
15
+ const Tag = level ? TAG[level] : H2;
24
16
  return /* @__PURE__ */ jsx(
25
17
  Tag,
26
18
  {
27
19
  ref,
28
20
  unstyled: true,
29
- className: cn(BASE_CLASSES, levelClasses, className),
30
- style: mergedStyle,
21
+ fontFamily: "$heading",
22
+ color: "var(--color-heading)",
23
+ ...level ? RAMP[level] : null,
31
24
  ...rest
32
25
  }
33
26
  );
@@ -231,59 +231,74 @@ var IconButtonFrame = gui.styled(gui.View, {
231
231
  size: {
232
232
  "2xs": { width: 20, height: 20, borderRadius: 4 },
233
233
  "2xs_alt": { width: 20, height: 20, borderRadius: 4 },
234
- md: { width: 32, height: 32, borderRadius: "var(--radius-base, 8px)" }
234
+ md: { width: 32, height: 32, borderRadius: 8 }
235
235
  },
236
236
  disabled: {
237
- true: {
238
- opacity: 0.4,
239
- cursor: "not-allowed",
240
- pointerEvents: "none"
241
- }
237
+ true: { opacity: 0.4, cursor: "not-allowed", pointerEvents: "none" }
242
238
  }
243
239
  }
244
240
  });
245
- var VARIANT_CLASSES = {
246
- plain: "bg-transparent text-inherit border-none hover:bg-transparent",
247
- icon_secondary: [
248
- "bg-transparent text-icon-secondary border-none",
249
- "hover:text-hover",
250
- "data-[selected]:bg-selected-control-bg data-[selected]:text-selected-control-text",
251
- "data-[selected]:hover:text-hover",
252
- "data-[expanded]:text-hover"
253
- ].join(" "),
254
- icon_background: [
255
- "bg-[var(--color-button-icon-background-bg)] text-icon-secondary border-none",
256
- "hover:text-hover",
257
- "data-[selected]:bg-selected-control-bg data-[selected]:text-selected-control-text",
258
- "data-[selected]:hover:text-hover",
259
- "data-[expanded]:text-hover"
260
- ].join(" "),
261
- link: [
262
- "bg-transparent text-link-primary border-none font-normal px-0 h-auto",
263
- "hover:bg-transparent hover:text-link-primary-hover",
264
- "disabled:text-text-secondary"
265
- ].join(" "),
266
- dropdown: [
267
- "border-2 border-solid bg-transparent",
268
- "text-[var(--color-button-dropdown-fg)] border-[var(--color-button-dropdown-border)]",
269
- "hover:bg-transparent hover:text-hover hover:border-hover",
270
- "data-[expanded]:bg-transparent data-[expanded]:text-hover data-[expanded]:border-hover",
271
- "data-[selected]:bg-selected-control-bg data-[selected]:text-selected-control-text data-[selected]:border-transparent",
272
- "data-[selected]:hover:text-hover"
273
- ].join(" "),
274
- pagination: [
275
- "border-2 border-solid bg-transparent",
276
- "text-[var(--color-button-pagination-fg)] border-[var(--color-button-pagination-border)]",
277
- "hover:bg-transparent hover:text-hover hover:border-hover",
278
- "data-[selected]:bg-selected-control-bg data-[selected]:text-selected-control-text data-[selected]:border-transparent"
279
- ].join(" ")
280
- };
281
- var ICON_SIZE_CLASSES = {
282
- "2xs": "[&_svg]:size-5",
283
- "2xs_alt": "[&_svg]:size-3",
284
- md: "[&_svg]:size-5"
241
+ var HOVER = "var(--color-hover)";
242
+ var SELECTED_BG = "var(--color-selected-control-bg)";
243
+ var SELECTED_FG = "var(--color-selected-control-text)";
244
+ var VARIANT = {
245
+ plain: {
246
+ rest: { backgroundColor: "transparent", hoverStyle: { backgroundColor: "transparent" } }
247
+ },
248
+ icon_secondary: {
249
+ rest: {
250
+ backgroundColor: "transparent",
251
+ color: "var(--color-icon-secondary)",
252
+ hoverStyle: { color: HOVER }
253
+ },
254
+ selected: { backgroundColor: SELECTED_BG, color: SELECTED_FG, hoverStyle: { color: HOVER } },
255
+ expanded: { color: HOVER }
256
+ },
257
+ icon_background: {
258
+ rest: {
259
+ backgroundColor: "var(--color-button-icon-background-bg)",
260
+ color: "var(--color-icon-secondary)",
261
+ hoverStyle: { color: HOVER }
262
+ },
263
+ selected: { backgroundColor: SELECTED_BG, color: SELECTED_FG, hoverStyle: { color: HOVER } },
264
+ expanded: { color: HOVER }
265
+ },
266
+ link: {
267
+ rest: {
268
+ backgroundColor: "transparent",
269
+ color: "var(--color-link-primary)",
270
+ fontWeight: "400",
271
+ paddingHorizontal: 0,
272
+ height: "auto",
273
+ hoverStyle: { backgroundColor: "transparent", color: "var(--color-link-primary-hover)" },
274
+ disabledStyle: { color: "var(--color-text-secondary)" }
275
+ }
276
+ },
277
+ dropdown: {
278
+ rest: {
279
+ borderWidth: 2,
280
+ borderStyle: "solid",
281
+ backgroundColor: "transparent",
282
+ color: "var(--color-button-dropdown-fg)",
283
+ borderColor: "var(--color-button-dropdown-border)",
284
+ hoverStyle: { backgroundColor: "transparent", color: HOVER, borderColor: HOVER }
285
+ },
286
+ selected: { backgroundColor: SELECTED_BG, color: SELECTED_FG, borderColor: "transparent", hoverStyle: { color: HOVER } },
287
+ expanded: { backgroundColor: "transparent", color: HOVER, borderColor: HOVER }
288
+ },
289
+ pagination: {
290
+ rest: {
291
+ borderWidth: 2,
292
+ borderStyle: "solid",
293
+ backgroundColor: "transparent",
294
+ color: "var(--color-button-pagination-fg)",
295
+ borderColor: "var(--color-button-pagination-border)",
296
+ hoverStyle: { backgroundColor: "transparent", color: HOVER, borderColor: HOVER }
297
+ },
298
+ selected: { backgroundColor: SELECTED_BG, color: SELECTED_FG, borderColor: "transparent" }
299
+ }
285
300
  };
286
- var SP = 4;
301
+ var ICON_SIZE = { "2xs": 20, "2xs_alt": 12, md: 20 };
287
302
  var IconButton = React__namespace.forwardRef(
288
303
  function IconButton2(props, ref) {
289
304
  const {
@@ -297,58 +312,43 @@ var IconButton = React__namespace.forwardRef(
297
312
  disabled,
298
313
  className,
299
314
  children,
300
- as: _as,
315
+ as: asProp,
301
316
  style: styleProp,
302
- // Strip Chakra style props
303
- boxSize: _boxSize,
304
- color: _color,
305
- px: _px,
306
- borderRadius: _borderRadius,
307
- ml: _ml,
308
- mr: _mr,
309
- _hover,
310
- _expanded,
311
317
  ...rest
312
318
  } = props;
313
- const shimStyle = { ...styleProp };
314
- if (_boxSize !== void 0) {
315
- const bs = typeof _boxSize === "number" ? `${_boxSize * SP}px` : _boxSize;
316
- shimStyle.width = bs;
317
- shimStyle.height = bs;
318
- }
319
- if (_color) shimStyle.color = _color;
320
- if (_px !== void 0) {
321
- const v = typeof _px === "number" ? `${_px * SP}px` : _px;
322
- shimStyle.paddingLeft = v;
323
- shimStyle.paddingRight = v;
324
- }
325
- if (_borderRadius) shimStyle.borderRadius = _borderRadius;
326
- if (_ml !== void 0) shimStyle.marginLeft = typeof _ml === "number" ? `${_ml * SP}px` : _ml;
327
- if (_mr !== void 0) shimStyle.marginRight = typeof _mr === "number" ? `${_mr * SP}px` : _mr;
328
- const mergedStyle = Object.keys(shimStyle).length > 0 ? shimStyle : void 0;
329
- const variantClass = VARIANT_CLASSES[variant] ?? VARIANT_CLASSES.plain;
330
- const iconSizeClass = size ? ICON_SIZE_CLASSES[size] ?? "" : "";
331
- const combinedClassName = [variantClass, iconSizeClass, className].filter(Boolean).join(" ");
319
+ const look = VARIANT[variant] ?? VARIANT.plain;
320
+ const iconSize = size ? ICON_SIZE[size] : void 0;
332
321
  const button = /* @__PURE__ */ jsxRuntime.jsx(
333
322
  IconButtonFrame,
334
323
  {
335
324
  ref,
336
325
  size,
337
326
  disabled: !loadingSkeleton && (loading || disabled) || void 0,
338
- render: _as ? React__namespace.createElement(_as) : void 0,
339
- className: combinedClassName,
340
- style: mergedStyle,
327
+ render: asProp ? React__namespace.createElement(asProp) : void 0,
328
+ className: ["lux-icon", className].filter(Boolean).join(" "),
329
+ style: { ...styleProp, ...iconSize ? { "--icon-size": `${iconSize}px` } : null },
330
+ ...look.rest,
331
+ ...selected ? look.selected : null,
332
+ ...expanded ? look.expanded : null,
341
333
  ...expanded ? { "data-expanded": true } : {},
342
334
  ...selected ? { "data-selected": true } : {},
343
335
  ...highlighted ? { "data-highlighted": true } : {},
344
336
  ...loadingSkeleton ? { "data-loading-skeleton": true } : {},
345
337
  ...rest,
346
338
  children: loading ? /* @__PURE__ */ jsxRuntime.jsx(
347
- "span",
339
+ gui.View,
348
340
  {
349
- className: "inline-block size-5 animate-spin rounded-full border-2 border-current border-b-transparent border-l-transparent",
341
+ className: "lux-spin",
342
+ render: /* @__PURE__ */ jsxRuntime.jsx("span", {}),
350
343
  role: "status",
351
- "aria-label": "Loading"
344
+ "aria-label": "Loading",
345
+ width: 20,
346
+ height: 20,
347
+ borderRadius: 1e3,
348
+ borderWidth: 2,
349
+ borderColor: "currentColor",
350
+ borderBottomColor: "transparent",
351
+ borderLeftColor: "transparent"
352
352
  }
353
353
  ) : children
354
354
  }
@@ -1,6 +1,18 @@
1
1
  import * as React from 'react';
2
2
 
3
- type Variant = 'plain' | 'icon_secondary' | 'icon_background' | 'link' | 'dropdown' | 'pagination';
3
+ type Style = Record<string, unknown>;
4
+ /**
5
+ * Resting look, and the looks that replace it while selected or expanded.
6
+ * Merged in that order, so a key set in two of them resolves to the later —
7
+ * which is why `selected` and `expanded` are objects rather than `hoverStyle`
8
+ * entries that would fight the resting value.
9
+ */
10
+ declare const VARIANT: Record<string, {
11
+ rest: Style;
12
+ selected?: Style;
13
+ expanded?: Style;
14
+ }>;
15
+ type Variant = keyof typeof VARIANT;
4
16
  type Size = '2xs' | '2xs_alt' | 'md';
5
17
  interface IconButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'size'> {
6
18
  /** Visual variant */
@@ -11,22 +23,14 @@ interface IconButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
11
23
  loading?: boolean;
12
24
  /** Render a skeleton placeholder instead of the button */
13
25
  loadingSkeleton?: boolean;
14
- /** Maps to data-expanded for popover trigger styling */
26
+ /** Also emitted as data-expanded for consumer styling */
15
27
  expanded?: boolean;
16
- /** Maps to data-selected for toggle styling */
28
+ /** Also emitted as data-selected for consumer styling */
17
29
  selected?: boolean;
18
- /** Maps to data-highlighted */
30
+ /** Also emitted as data-highlighted */
19
31
  highlighted?: boolean;
20
32
  /** Polymorphic element type (e.g. "div") */
21
33
  as?: React.ElementType;
22
- boxSize?: number | string;
23
- color?: string;
24
- px?: string | number;
25
- borderRadius?: string;
26
- ml?: number | string;
27
- mr?: number | string;
28
- _hover?: Record<string, string>;
29
- _expanded?: Record<string, string>;
30
34
  }
31
35
  declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
32
36
 
@@ -1,6 +1,18 @@
1
1
  import * as React from 'react';
2
2
 
3
- type Variant = 'plain' | 'icon_secondary' | 'icon_background' | 'link' | 'dropdown' | 'pagination';
3
+ type Style = Record<string, unknown>;
4
+ /**
5
+ * Resting look, and the looks that replace it while selected or expanded.
6
+ * Merged in that order, so a key set in two of them resolves to the later —
7
+ * which is why `selected` and `expanded` are objects rather than `hoverStyle`
8
+ * entries that would fight the resting value.
9
+ */
10
+ declare const VARIANT: Record<string, {
11
+ rest: Style;
12
+ selected?: Style;
13
+ expanded?: Style;
14
+ }>;
15
+ type Variant = keyof typeof VARIANT;
4
16
  type Size = '2xs' | '2xs_alt' | 'md';
5
17
  interface IconButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'size'> {
6
18
  /** Visual variant */
@@ -11,22 +23,14 @@ interface IconButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElem
11
23
  loading?: boolean;
12
24
  /** Render a skeleton placeholder instead of the button */
13
25
  loadingSkeleton?: boolean;
14
- /** Maps to data-expanded for popover trigger styling */
26
+ /** Also emitted as data-expanded for consumer styling */
15
27
  expanded?: boolean;
16
- /** Maps to data-selected for toggle styling */
28
+ /** Also emitted as data-selected for consumer styling */
17
29
  selected?: boolean;
18
- /** Maps to data-highlighted */
30
+ /** Also emitted as data-highlighted */
19
31
  highlighted?: boolean;
20
32
  /** Polymorphic element type (e.g. "div") */
21
33
  as?: React.ElementType;
22
- boxSize?: number | string;
23
- color?: string;
24
- px?: string | number;
25
- borderRadius?: string;
26
- ml?: number | string;
27
- mr?: number | string;
28
- _hover?: Record<string, string>;
29
- _expanded?: Record<string, string>;
30
34
  }
31
35
  declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<HTMLButtonElement>>;
32
36