@luxfi/ui 7.4.10 → 7.4.12

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 (137) 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/alert.cjs +68 -46
  6. package/dist/alert.js +69 -46
  7. package/dist/avatar.cjs +49 -46
  8. package/dist/avatar.js +52 -48
  9. package/dist/badge.cjs +82 -49
  10. package/dist/badge.js +83 -50
  11. package/dist/checkbox.cjs +42 -75
  12. package/dist/checkbox.js +43 -76
  13. package/dist/chrome.cjs +196 -386
  14. package/dist/chrome.js +198 -386
  15. package/dist/close-button.cjs +3 -7
  16. package/dist/close-button.js +3 -7
  17. package/dist/collapsible.cjs +35 -26
  18. package/dist/collapsible.d.cts +2 -1
  19. package/dist/collapsible.d.ts +2 -1
  20. package/dist/collapsible.js +34 -24
  21. package/dist/dialog.cjs +3 -7
  22. package/dist/dialog.d.cts +1 -1
  23. package/dist/dialog.d.ts +1 -1
  24. package/dist/dialog.js +3 -7
  25. package/dist/drawer.cjs +95 -122
  26. package/dist/drawer.d.cts +43 -10
  27. package/dist/drawer.d.ts +43 -10
  28. package/dist/drawer.js +97 -122
  29. package/dist/empty-state.cjs +13 -13
  30. package/dist/empty-state.js +13 -13
  31. package/dist/expiration-selector.cjs +58 -63
  32. package/dist/expiration-selector.js +58 -63
  33. package/dist/field.cjs +60 -109
  34. package/dist/field.d.cts +0 -1
  35. package/dist/field.d.ts +0 -1
  36. package/dist/field.js +61 -109
  37. package/dist/greeks-display.cjs +48 -39
  38. package/dist/greeks-display.js +48 -39
  39. package/dist/heading.cjs +10 -17
  40. package/dist/heading.d.cts +0 -2
  41. package/dist/heading.d.ts +0 -2
  42. package/dist/heading.js +10 -17
  43. package/dist/icon-button.cjs +82 -82
  44. package/dist/icon-button.d.cts +16 -12
  45. package/dist/icon-button.d.ts +16 -12
  46. package/dist/icon-button.js +82 -82
  47. package/dist/index.cjs +1812 -2105
  48. package/dist/index.d.cts +1 -5
  49. package/dist/index.d.ts +1 -5
  50. package/dist/index.js +1814 -2100
  51. package/dist/input-group.cjs +11 -12
  52. package/dist/input-group.js +11 -12
  53. package/dist/input.cjs +27 -27
  54. package/dist/input.d.cts +21 -1
  55. package/dist/input.d.ts +21 -1
  56. package/dist/input.js +25 -28
  57. package/dist/menu.cjs +160 -271
  58. package/dist/menu.d.cts +41 -57
  59. package/dist/menu.d.ts +41 -57
  60. package/dist/menu.js +161 -251
  61. package/dist/option-chain.cjs +89 -67
  62. package/dist/option-chain.js +89 -67
  63. package/dist/option-position.cjs +88 -85
  64. package/dist/option-position.js +88 -85
  65. package/dist/pnl-diagram.cjs +20 -20
  66. package/dist/pnl-diagram.js +20 -20
  67. package/dist/popover.cjs +4 -8
  68. package/dist/popover.js +4 -8
  69. package/dist/progress.cjs +15 -22
  70. package/dist/progress.d.cts +6 -6
  71. package/dist/progress.d.ts +6 -6
  72. package/dist/progress.js +15 -22
  73. package/dist/radio.cjs +35 -67
  74. package/dist/radio.d.cts +18 -18
  75. package/dist/radio.d.ts +18 -18
  76. package/dist/radio.js +36 -68
  77. package/dist/select.cjs +40 -39
  78. package/dist/select.d.cts +35 -4
  79. package/dist/select.d.ts +35 -4
  80. package/dist/select.js +40 -38
  81. package/dist/separator.cjs +8 -33
  82. package/dist/separator.js +8 -33
  83. package/dist/slider.cjs +33 -49
  84. package/dist/slider.js +34 -50
  85. package/dist/switch.cjs +48 -55
  86. package/dist/switch.js +49 -56
  87. package/dist/tabs.cjs +108 -197
  88. package/dist/tabs.d.cts +16 -60
  89. package/dist/tabs.d.ts +16 -60
  90. package/dist/tabs.js +109 -196
  91. package/dist/tag.cjs +112 -69
  92. package/dist/tag.js +113 -69
  93. package/dist/textarea.cjs +56 -27
  94. package/dist/textarea.js +57 -28
  95. package/dist/toaster.cjs +97 -79
  96. package/dist/toaster.d.cts +7 -8
  97. package/dist/toaster.d.ts +7 -8
  98. package/dist/toaster.js +78 -80
  99. package/dist/tooltip.cjs +28 -17
  100. package/dist/tooltip.js +30 -18
  101. package/package.json +2 -16
  102. package/src/accordion.tsx +173 -227
  103. package/src/alert.tsx +78 -45
  104. package/src/avatar.tsx +54 -37
  105. package/src/badge.tsx +65 -44
  106. package/src/checkbox.tsx +70 -89
  107. package/src/close-button.tsx +3 -8
  108. package/src/collapsible.tsx +55 -52
  109. package/src/drawer.tsx +123 -115
  110. package/src/empty-state.tsx +21 -17
  111. package/src/expiration-selector.tsx +84 -66
  112. package/src/field.tsx +68 -124
  113. package/src/greeks-display.tsx +59 -51
  114. package/src/heading.tsx +22 -26
  115. package/src/icon-button.tsx +134 -141
  116. package/src/ink.tsx +37 -0
  117. package/src/input-group.tsx +59 -36
  118. package/src/input.tsx +41 -32
  119. package/src/menu.tsx +224 -397
  120. package/src/option-chain.tsx +154 -104
  121. package/src/option-position.tsx +136 -114
  122. package/src/pin-input.tsx +37 -29
  123. package/src/pnl-diagram.tsx +36 -28
  124. package/src/popover.tsx +1 -1
  125. package/src/progress.tsx +17 -21
  126. package/src/radio.tsx +56 -75
  127. package/src/select.tsx +80 -59
  128. package/src/separator.tsx +13 -34
  129. package/src/slider.tsx +43 -44
  130. package/src/strategy-builder.tsx +245 -156
  131. package/src/switch.tsx +63 -64
  132. package/src/tabs.tsx +166 -296
  133. package/src/tag.tsx +89 -51
  134. package/src/textarea.tsx +19 -29
  135. package/src/toaster.tsx +118 -86
  136. package/src/tooltip.tsx +21 -13
  137. package/tokens.css +79 -0
@@ -1,12 +1,8 @@
1
1
  "use client";
2
+ import { YStack, Text, XStack } from '@hanzo/gui';
2
3
  import * as React from 'react';
3
- import { clsx } from 'clsx';
4
- import { twMerge } from 'tailwind-merge';
5
4
  import { jsx, jsxs } from 'react/jsx-runtime';
6
5
 
7
- function cn(...inputs) {
8
- return twMerge(clsx(inputs));
9
- }
10
6
  function formatExpDate(date) {
11
7
  const d = new Date(date);
12
8
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
@@ -17,28 +13,53 @@ var GROUP_LABELS = {
17
13
  monthly: "Monthly",
18
14
  quarterly: "Quarterly"
19
15
  };
16
+ var SHAPE = {
17
+ selected: {
18
+ borderColor: "transparent",
19
+ backgroundColor: "var(--color-selected-control-bg)",
20
+ color: "var(--color-selected-control-text)"
21
+ },
22
+ resting: {
23
+ borderColor: "var(--color-border-divider)",
24
+ backgroundColor: "var(--card)",
25
+ color: "var(--color-text-secondary)",
26
+ hoverStyle: { borderColor: "var(--color-hover)", color: "var(--color-hover)" }
27
+ }
28
+ };
20
29
  function ExpirationPill({ exp, isSelected, onClick }) {
30
+ const shape = isSelected ? SHAPE.selected : SHAPE.resting;
31
+ const dteColor = exp.dte <= 7 && !isSelected ? "var(--color-status-warn)" : isSelected ? "var(--color-selected-control-text)" : "var(--muted-foreground)";
21
32
  return /* @__PURE__ */ jsxs(
22
- "button",
33
+ YStack,
23
34
  {
24
- type: "button",
35
+ unstyled: true,
36
+ render: /* @__PURE__ */ jsx("button", { type: "button" }),
25
37
  onClick,
26
- className: cn(
27
- "flex flex-col items-center gap-0.5 rounded-md px-3 py-1.5 transition-colors shrink-0",
28
- "border text-xs",
29
- isSelected ? "border-blue-500/60 bg-blue-900/30 text-blue-300" : "border-zinc-800 bg-zinc-900/50 text-zinc-400 hover:border-zinc-600 hover:text-zinc-200"
30
- ),
38
+ alignItems: "center",
39
+ gap: 2,
40
+ borderRadius: 6,
41
+ paddingHorizontal: 12,
42
+ paddingVertical: 6,
43
+ flexShrink: 0,
44
+ borderWidth: 1,
45
+ borderStyle: "solid",
46
+ cursor: "pointer",
47
+ ...shape,
31
48
  children: [
32
- /* @__PURE__ */ jsx("span", { className: "font-medium whitespace-nowrap", children: formatExpDate(exp.date) }),
33
- /* @__PURE__ */ jsxs("span", { className: cn(
34
- "font-mono tabular-nums text-[10px]",
35
- isSelected ? "text-[var(--foreground)]" : "text-[var(--muted-foreground)]",
36
- // Near expiry is a notice, and a notice in Lux is the loudest neutral.
37
- exp.dte <= 7 && !isSelected && "text-[var(--color-status-warn)]"
38
- ), children: [
39
- exp.dte,
40
- "d"
41
- ] })
49
+ /* @__PURE__ */ jsx(Text, { unstyled: true, fontSize: 12, fontWeight: "500", style: { whiteSpace: "nowrap" }, children: formatExpDate(exp.date) }),
50
+ /* @__PURE__ */ jsxs(
51
+ Text,
52
+ {
53
+ fontVariant: ["tabular-nums"],
54
+ style: { fontFamily: "monospace" },
55
+ fontSize: 10,
56
+ color: dteColor,
57
+ children: [
58
+ exp.dte,
59
+ "d"
60
+ ]
61
+ }
62
+ )
42
63
  ]
43
64
  }
44
65
  );
@@ -68,49 +89,23 @@ var ExpirationSelector = React.forwardRef(
68
89
  label: GROUP_LABELS[type],
69
90
  items: expirations.filter((e) => e.type === type)
70
91
  })).filter((g) => g.items.length > 0);
71
- return /* @__PURE__ */ jsx(
72
- "div",
73
- {
74
- ref,
75
- className: cn("flex flex-col gap-2", className),
76
- ...rest,
77
- children: grouped.map((group) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
78
- /* @__PURE__ */ jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wider text-zinc-600 px-1", children: group.label }),
79
- /* @__PURE__ */ jsx("div", { className: "flex gap-1.5 overflow-x-auto no-scrollbar", children: group.items.map((exp) => /* @__PURE__ */ jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsx(
80
- ExpirationPill,
81
- {
82
- exp,
83
- isSelected: exp.date === selected,
84
- onClick: () => onSelect(exp.date)
85
- }
86
- ) }, exp.date)) })
87
- ] }, group.type))
88
- }
89
- );
90
- }
91
- return /* @__PURE__ */ jsx(
92
- "div",
93
- {
94
- ref,
95
- className: cn("flex items-center gap-1", className),
96
- ...rest,
97
- children: /* @__PURE__ */ jsx(
98
- "div",
92
+ return /* @__PURE__ */ jsx(YStack, { ref, gap: 8, className, ...rest, children: grouped.map((group) => /* @__PURE__ */ jsxs(YStack, { gap: 4, children: [
93
+ /* @__PURE__ */ jsx(
94
+ Text,
99
95
  {
100
- ref: scrollRef,
101
- className: "flex gap-1.5 overflow-x-auto no-scrollbar",
102
- children: expirations.map((exp) => /* @__PURE__ */ jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsx(
103
- ExpirationPill,
104
- {
105
- exp,
106
- isSelected: exp.date === selected,
107
- onClick: () => onSelect(exp.date)
108
- }
109
- ) }, exp.date))
96
+ fontSize: 10,
97
+ fontWeight: "600",
98
+ textTransform: "uppercase",
99
+ letterSpacing: 0.5,
100
+ paddingHorizontal: 4,
101
+ color: "var(--color-text-secondary)",
102
+ children: group.label
110
103
  }
111
- )
112
- }
113
- );
104
+ ),
105
+ /* @__PURE__ */ jsx(XStack, { gap: 6, overflowX: "auto", overflowY: "hidden", className: "lux-no-scrollbar", children: group.items.map((exp) => /* @__PURE__ */ jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsx(ExpirationPill, { exp, isSelected: exp.date === selected, onClick: () => onSelect(exp.date) }) }, exp.date)) })
106
+ ] }, group.type)) });
107
+ }
108
+ return /* @__PURE__ */ jsx(XStack, { ref, alignItems: "center", gap: 4, className, ...rest, children: /* @__PURE__ */ jsx(XStack, { ref: scrollRef, gap: 6, overflowX: "auto", overflowY: "hidden", className: "lux-no-scrollbar", children: expirations.map((exp) => /* @__PURE__ */ jsx("div", { "data-selected": exp.date === selected || void 0, children: /* @__PURE__ */ jsx(ExpirationPill, { exp, isSelected: exp.date === selected, onClick: () => onSelect(exp.date) }) }, exp.date)) }) });
114
109
  }
115
110
  );
116
111
 
package/dist/field.cjs CHANGED
@@ -1,10 +1,8 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var LabelPrimitive = require('@radix-ui/react-label');
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 _interopNamespace(e) {
@@ -25,19 +23,26 @@ function _interopNamespace(e) {
25
23
  return Object.freeze(n);
26
24
  }
27
25
 
28
- var LabelPrimitive__namespace = /*#__PURE__*/_interopNamespace(LabelPrimitive);
29
26
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
30
27
 
31
28
  // src/field.tsx
32
- function cn(...inputs) {
33
- return tailwindMerge.twMerge(clsx.clsx(inputs));
34
- }
35
29
  var space = String.fromCharCode(32);
36
30
  function getComponentDisplayName(type) {
37
31
  if (typeof type === "string") return void 0;
38
32
  if ("displayName" in type) return type.displayName;
39
33
  return void 0;
40
34
  }
35
+ var ERROR = "var(--color-text-error)";
36
+ var MUTED = "var(--color-text-secondary)";
37
+ var Marks = ({ required, optionalText, errorText }) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
38
+ required && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { color: ERROR, "aria-hidden": true, children: "*" }),
39
+ !required && optionalText && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 14, color: MUTED, children: optionalText }),
40
+ errorText && /* @__PURE__ */ jsxRuntime.jsxs(gui.Text, { fontSize: 14, color: ERROR, children: [
41
+ "-",
42
+ space,
43
+ errorText
44
+ ] })
45
+ ] });
41
46
  var Field = React__namespace.forwardRef(
42
47
  function Field2(props, ref) {
43
48
  const {
@@ -56,127 +61,73 @@ var Field = React__namespace.forwardRef(
56
61
  className,
57
62
  style
58
63
  } = props;
64
+ const flags = {
65
+ "data-disabled": disabled || void 0,
66
+ "data-readonly": readOnly || void 0,
67
+ "data-invalid": invalid || void 0
68
+ };
59
69
  if (floating && label) {
60
- const injectedProps2 = {
61
- className: "peer",
62
- placeholder: " ",
63
- size,
64
- floating,
65
- disabled,
66
- readOnly
67
- };
70
+ const injectedProps = { className: "lux-field-control", placeholder: " ", size, floating, disabled, readOnly };
68
71
  const labelElement = /* @__PURE__ */ jsxRuntime.jsxs(
69
- LabelPrimitive__namespace.Root,
72
+ gui.Label,
70
73
  {
71
- className: cn(
72
- "absolute left-3 top-1/2 -translate-y-1/2",
73
- "text-[var(--color-input-placeholder,theme(colors.gray.400))]",
74
- "pointer-events-none select-none",
75
- "origin-top-left transition-all duration-150",
76
- "peer-focus:top-1 peer-focus:translate-y-0 peer-focus:scale-75",
77
- "peer-[:not(:placeholder-shown)]:top-1 peer-[:not(:placeholder-shown)]:translate-y-0 peer-[:not(:placeholder-shown)]:scale-75"
78
- ),
79
74
  htmlFor: id,
75
+ position: "absolute",
76
+ left: 12,
77
+ top: "50%",
78
+ pointerEvents: "none",
79
+ userSelect: "none",
80
+ flexDirection: "row",
81
+ gap: 4,
82
+ color: "var(--color-input-placeholder)",
83
+ className: "lux-field-float",
80
84
  children: [
81
85
  label,
82
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-[var(--color-fg-error,theme(colors.red.500))]", "aria-hidden": "true", children: "*" }),
83
- !required && optionalText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[var(--color-text-secondary,theme(colors.gray.400))] text-sm", children: optionalText }),
84
- errorText && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-0.5 text-[var(--color-fg-error,theme(colors.red.500))] text-sm", children: [
85
- "-",
86
- space,
87
- errorText
88
- ] })
86
+ /* @__PURE__ */ jsxRuntime.jsx(Marks, { required, optionalText, errorText })
89
87
  ]
90
88
  }
91
89
  );
92
- const helperTextElement = helperText ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1.5 text-xs text-[var(--color-text-secondary,theme(colors.gray.400))]", children: helperText }) : null;
90
+ const helperTextElement = helperText ? /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { marginTop: 6, fontSize: 12, color: MUTED, children: helperText }) : null;
93
91
  const child2 = React__namespace.Children.only(children);
94
92
  const isInputGroup = getComponentDisplayName(child2.type) === "InputGroup";
95
93
  if (isInputGroup) {
96
- const inputElement2 = React__namespace.cloneElement(
94
+ const inputElement = React__namespace.cloneElement(
97
95
  React__namespace.Children.only(child2.props.children),
98
- injectedProps2
99
- );
100
- const groupInputElement = React__namespace.cloneElement(
101
- child2,
102
- {},
103
- inputElement2,
104
- labelElement
105
- );
106
- return /* @__PURE__ */ jsxRuntime.jsxs(
107
- "div",
108
- {
109
- ref,
110
- id,
111
- className: cn("relative w-full", className),
112
- style,
113
- "data-disabled": disabled || void 0,
114
- "data-readonly": readOnly || void 0,
115
- "data-invalid": invalid || void 0,
116
- children: [
117
- groupInputElement,
118
- helperTextElement
119
- ]
120
- }
96
+ injectedProps
121
97
  );
98
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { ref, id, position: "relative", width: "100%", className, style, ...flags, children: [
99
+ React__namespace.cloneElement(child2, {}, inputElement, labelElement),
100
+ helperTextElement
101
+ ] });
122
102
  }
123
- const inputElement = React__namespace.cloneElement(child2, injectedProps2);
124
- return /* @__PURE__ */ jsxRuntime.jsxs(
125
- "div",
103
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { ref, id, position: "relative", width: "100%", className, style, ...flags, children: [
104
+ React__namespace.cloneElement(child2, injectedProps),
105
+ labelElement,
106
+ helperTextElement
107
+ ] });
108
+ }
109
+ const child = React__namespace.Children.only(children);
110
+ return /* @__PURE__ */ jsxRuntime.jsxs(gui.YStack, { ref, id, gap: 4, className, style, ...flags, children: [
111
+ label && /* @__PURE__ */ jsxRuntime.jsxs(
112
+ gui.Label,
126
113
  {
127
- ref,
128
- id,
129
- className: cn("relative w-full", className),
130
- style,
131
- "data-disabled": disabled || void 0,
132
- "data-readonly": readOnly || void 0,
133
- "data-invalid": invalid || void 0,
114
+ htmlFor: id,
115
+ flexDirection: "row",
116
+ gap: 4,
117
+ fontSize: 14,
118
+ fontWeight: "500",
119
+ color: "var(--color-text-primary)",
120
+ opacity: disabled ? 0.4 : 1,
134
121
  children: [
135
- inputElement,
136
- labelElement,
137
- helperTextElement
122
+ label,
123
+ /* @__PURE__ */ jsxRuntime.jsx(Marks, { required, optionalText })
138
124
  ]
139
125
  }
140
- );
141
- }
142
- const injectedProps = {
143
- size
144
- };
145
- const child = React__namespace.Children.only(children);
146
- const clonedChild = React__namespace.cloneElement(child, injectedProps);
147
- return /* @__PURE__ */ jsxRuntime.jsxs(
148
- "div",
149
- {
150
- ref,
151
- id,
152
- className: cn("flex flex-col gap-1", className),
153
- style,
154
- "data-disabled": disabled || void 0,
155
- "data-readonly": readOnly || void 0,
156
- "data-invalid": invalid || void 0,
157
- children: [
158
- label && /* @__PURE__ */ jsxRuntime.jsxs(
159
- LabelPrimitive__namespace.Root,
160
- {
161
- className: cn(
162
- "text-sm font-medium text-[var(--color-field-label,theme(colors.gray.700))]",
163
- "dark:text-[var(--color-field-label,theme(colors.gray.300))]",
164
- disabled && "opacity-40"
165
- ),
166
- htmlFor: id,
167
- children: [
168
- label,
169
- required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-0.5 text-[var(--color-fg-error,theme(colors.red.500))]", "aria-hidden": "true", children: "*" }),
170
- !required && optionalText && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-1 text-[var(--color-text-secondary,theme(colors.gray.400))] text-sm font-normal", children: optionalText })
171
- ]
172
- }
173
- ),
174
- clonedChild,
175
- helperText && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-[var(--color-text-secondary,theme(colors.gray.400))]", children: helperText }),
176
- errorText && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-[var(--color-fg-error,theme(colors.red.500))]", children: errorText })
177
- ]
178
- }
179
- );
126
+ ),
127
+ React__namespace.cloneElement(child, { size }),
128
+ helperText && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 12, color: MUTED, children: helperText }),
129
+ errorText && /* @__PURE__ */ jsxRuntime.jsx(gui.Text, { fontSize: 12, color: ERROR, children: errorText })
130
+ ] });
180
131
  }
181
132
  );
182
133
 
package/dist/field.d.cts CHANGED
@@ -14,7 +14,6 @@ interface FieldProps {
14
14
  readonly readOnly?: boolean;
15
15
  readonly invalid?: boolean;
16
16
  readonly floating?: boolean;
17
- readonly bgColor?: string | Record<string, string>;
18
17
  readonly id?: string;
19
18
  readonly className?: string;
20
19
  readonly style?: React.CSSProperties;
package/dist/field.d.ts CHANGED
@@ -14,7 +14,6 @@ interface FieldProps {
14
14
  readonly readOnly?: boolean;
15
15
  readonly invalid?: boolean;
16
16
  readonly floating?: boolean;
17
- readonly bgColor?: string | Record<string, string>;
18
17
  readonly id?: string;
19
18
  readonly className?: string;
20
19
  readonly style?: React.CSSProperties;
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