@drawbridge/components 0.0.51 → 0.0.53

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.
@@ -23,7 +23,7 @@ __export(input_name_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(input_name_exports);
25
25
 
26
- // components/input-group.js
26
+ // components/input-group-error.js
27
27
  var import_react = require("react");
28
28
 
29
29
  // components/icons/warning.js
@@ -52,8 +52,86 @@ var Warning = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
52
52
  );
53
53
  var warning_default = Warning;
54
54
 
55
- // components/input-group.js
55
+ // components/input-group-error.js
56
56
  var import_jsx_runtime2 = require("react/jsx-runtime");
57
+ var InputGroupError = ({
58
+ className,
59
+ error,
60
+ label,
61
+ message,
62
+ style = {}
63
+ }) => {
64
+ var _a, _b, _c, _d;
65
+ if (!(error || message)) {
66
+ return null;
67
+ }
68
+ const classes = [
69
+ "flex items-center justify-start space-x-2 py-1 rounded text-sm"
70
+ ];
71
+ if (error) {
72
+ classes.push("px-1.5");
73
+ }
74
+ if (className) {
75
+ classes.push(className);
76
+ }
77
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
78
+ "p",
79
+ {
80
+ ...{
81
+ className: classes.join(" "),
82
+ ...error && {
83
+ style: {
84
+ backgroundColor: (((_b = (_a = style == null ? void 0 : style.text) == null ? void 0 : _a.color) == null ? void 0 : _b.rgb) || "rgb( 0, 0, 0 )").replace(")", ",.1)"),
85
+ color: ((_d = (_c = style == null ? void 0 : style.text) == null ? void 0 : _c.color) == null ? void 0 : _d.rgb) || "rgb( 0, 0, 0 )"
86
+ }
87
+ }
88
+ },
89
+ children: [
90
+ error && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react.Fragment, { children: [
91
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
92
+ warning_default,
93
+ {
94
+ ...{
95
+ className: "w-4 h-4",
96
+ "aria-hidden": true
97
+ }
98
+ }
99
+ ),
100
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
101
+ "span",
102
+ {
103
+ ...{
104
+ className: "text-[0px] opacity-0 w-0 h-0 absolute"
105
+ },
106
+ children: [
107
+ label ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react.Fragment, { children: [
108
+ label,
109
+ ": "
110
+ ] }) : null,
111
+ error
112
+ ]
113
+ }
114
+ )
115
+ ] }),
116
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
117
+ "span",
118
+ {
119
+ ...{
120
+ ...error && {
121
+ "aria-hidden": true
122
+ }
123
+ },
124
+ children: error || message
125
+ }
126
+ )
127
+ ]
128
+ }
129
+ );
130
+ };
131
+ var input_group_error_default = InputGroupError;
132
+
133
+ // components/input-group.js
134
+ var import_jsx_runtime3 = require("react/jsx-runtime");
57
135
  var InputGroup = ({
58
136
  className,
59
137
  error,
@@ -63,7 +141,6 @@ var InputGroup = ({
63
141
  style = {},
64
142
  ...rest
65
143
  }) => {
66
- var _a, _b, _c, _d;
67
144
  const classes = [
68
145
  "input-group"
69
146
  ];
@@ -73,7 +150,7 @@ var InputGroup = ({
73
150
  if (error) {
74
151
  classes.push("error");
75
152
  }
76
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
153
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
77
154
  "div",
78
155
  {
79
156
  ...{
@@ -84,14 +161,14 @@ var InputGroup = ({
84
161
  }
85
162
  },
86
163
  children: [
87
- label ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
164
+ label ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
88
165
  "div",
89
166
  {
90
167
  ...{
91
168
  className: "space-y-2"
92
169
  },
93
170
  children: [
94
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
171
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
95
172
  "span",
96
173
  {
97
174
  ...{
@@ -104,55 +181,15 @@ var InputGroup = ({
104
181
  ]
105
182
  }
106
183
  ) : input,
107
- (error || message) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
108
- "p",
184
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
185
+ input_group_error_default,
109
186
  {
110
187
  ...{
111
- className: "flex items-center justify-start space-x-2 py-1 rounded text-sm " + (error && "px-1.5"),
112
- ...error && {
113
- style: {
114
- backgroundColor: (((_b = (_a = style == null ? void 0 : style.text) == null ? void 0 : _a.color) == null ? void 0 : _b.rgb) || "rgb( 0, 0, 0 )").replace(")", ",.1)"),
115
- color: ((_d = (_c = style == null ? void 0 : style.text) == null ? void 0 : _c.color) == null ? void 0 : _d.rgb) || "rgb( 0, 0, 0 )"
116
- }
117
- }
118
- },
119
- children: [
120
- error && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react.Fragment, { children: [
121
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
122
- warning_default,
123
- {
124
- ...{
125
- className: "w-4 h-4",
126
- "aria-hidden": true
127
- }
128
- }
129
- ),
130
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
131
- "span",
132
- {
133
- ...{
134
- className: "text-[0px] opacity-0 w-0 h-0 absolute"
135
- },
136
- children: [
137
- label,
138
- ": ",
139
- error
140
- ]
141
- }
142
- )
143
- ] }),
144
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
145
- "span",
146
- {
147
- ...{
148
- ...error && {
149
- "aria-hidden": true
150
- }
151
- },
152
- children: error || message
153
- }
154
- )
155
- ]
188
+ error,
189
+ label,
190
+ message,
191
+ style
192
+ }
156
193
  }
157
194
  )
158
195
  ]
@@ -183,7 +220,7 @@ var inputStyle = (style) => {
183
220
  };
184
221
 
185
222
  // components/input-text.js
186
- var import_jsx_runtime3 = require("react/jsx-runtime");
223
+ var import_jsx_runtime4 = require("react/jsx-runtime");
187
224
  var InputText = ({
188
225
  className,
189
226
  max,
@@ -197,7 +234,7 @@ var InputText = ({
197
234
  classes.push(className);
198
235
  }
199
236
  ;
200
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
237
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
201
238
  "input",
202
239
  {
203
240
  ...{
@@ -213,7 +250,7 @@ var InputText = ({
213
250
  var input_text_default = InputText;
214
251
 
215
252
  // components/input-name.js
216
- var import_jsx_runtime4 = require("react/jsx-runtime");
253
+ var import_jsx_runtime5 = require("react/jsx-runtime");
217
254
  var InputName = ({
218
255
  error,
219
256
  onChange,
@@ -223,12 +260,12 @@ var InputName = ({
223
260
  }) => {
224
261
  var _a, _b, _c;
225
262
  const inputs = {
226
- first: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
263
+ first: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
227
264
  input_group_default,
228
265
  {
229
266
  ...{
230
267
  error: (_a = error == null ? void 0 : error.first) == null ? void 0 : _a.message,
231
- input: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
268
+ input: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
232
269
  input_text_default,
233
270
  {
234
271
  ...{
@@ -247,12 +284,12 @@ var InputName = ({
247
284
  }
248
285
  }
249
286
  ),
250
- last: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
287
+ last: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
251
288
  input_group_default,
252
289
  {
253
290
  ...{
254
291
  error: (_b = error == null ? void 0 : error.last) == null ? void 0 : _b.message,
255
- input: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
292
+ input: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
256
293
  input_text_default,
257
294
  {
258
295
  ...{
@@ -271,12 +308,12 @@ var InputName = ({
271
308
  }
272
309
  }
273
310
  ),
274
- name: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
311
+ name: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
275
312
  input_group_default,
276
313
  {
277
314
  ...{
278
315
  error: (_c = error == null ? void 0 : error.name) == null ? void 0 : _c.message,
279
- input: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
316
+ input: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
280
317
  input_text_default,
281
318
  {
282
319
  ...{
@@ -295,13 +332,13 @@ var InputName = ({
295
332
  }
296
333
  )
297
334
  };
298
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
335
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
299
336
  "div",
300
337
  {
301
338
  ...{
302
339
  className: "flex flex-col space-y-4"
303
340
  },
304
- children: (settings.capture || []).map((input, key) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
341
+ children: (settings.capture || []).map((input, key) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
305
342
  "div",
306
343
  {
307
344
  ...{
@@ -3,7 +3,8 @@ import {
3
3
  } from "./chunk-B6Y2SNRW.mjs";
4
4
  import {
5
5
  input_group_default
6
- } from "./chunk-3SAKIKZP.mjs";
6
+ } from "./chunk-DNK33H3K.mjs";
7
+ import "./chunk-OHJMWJAQ.mjs";
7
8
  import "./chunk-Q3UIVGPQ.mjs";
8
9
  import "./chunk-FJ7PKMAC.mjs";
9
10
 
@@ -107,10 +107,38 @@ var InputNumber = ({
107
107
  min,
108
108
  onChange,
109
109
  small,
110
+ step = 1,
110
111
  style,
111
112
  value,
112
113
  ...rest
113
114
  }) => {
115
+ const decimal = !Number.isInteger(step);
116
+ const [draft, setDraft] = (0, import_react.useState)(
117
+ value === "" || value === null || value === void 0 ? "" : String(value)
118
+ );
119
+ (0, import_react.useEffect)(
120
+ () => {
121
+ const next = value === "" || value === null || value === void 0 ? "" : value;
122
+ if (Number(draft || 0) !== Number(next || 0)) {
123
+ setDraft(next === "" ? "" : String(next));
124
+ }
125
+ ;
126
+ },
127
+ // Intentionally excludes `draft`: this effect only reacts to external
128
+ // value changes, not to our own in-flight edits.
129
+ [value]
130
+ // eslint-disable-line react-hooks/exhaustive-deps
131
+ );
132
+ const handleChange = (0, import_react.useCallback)(
133
+ ({ target }) => {
134
+ const pattern = decimal ? /^-?\d*\.?\d*$/ : /^-?\d*$/;
135
+ if (!pattern.test(target.value)) return;
136
+ setDraft(target.value);
137
+ const numeric = target.value === "" ? 0 : Number(target.value);
138
+ if (!Number.isNaN(numeric)) onChange(numeric);
139
+ },
140
+ [decimal, onChange]
141
+ );
114
142
  const classes = [(inline ? "inline-flex items-center rounded-sm" : "input p-0 flex items-center") + " overflow-hidden"];
115
143
  if (className) {
116
144
  classes.push(className);
@@ -203,9 +231,11 @@ var InputNumber = ({
203
231
  // an inline flex grow rather than a version-specific grow utility, so
204
232
  // this works in BOTH consumers (app-web is Tailwind v3, share is v4).
205
233
  className: "text-inherit bg-transparent focus:outline-none focus:ring-0 " + (small ? "py-1 px-2" : "py-2 px-3") + (inline ? small ? " w-10" : " w-12" : "") + (layout === "split" ? " text-center" : ""),
206
- inputMode: "numeric",
207
- onChange: ({ target }) => onChange(Number(target.value)),
208
- step: 1,
234
+ // `type="text"` (not "number") so in-progress decimal strings survive
235
+ // each render; inputMode still surfaces the numeric/decimal keypad on
236
+ // mobile and handleChange enforces the numeric character set.
237
+ inputMode: decimal ? "decimal" : "numeric",
238
+ onChange: handleChange,
209
239
  // The bordered container is the single visible border; strip the
210
240
  // native number-input border so it doesn't double up.
211
241
  style: {
@@ -215,8 +245,8 @@ var InputNumber = ({
215
245
  minWidth: 0
216
246
  }
217
247
  },
218
- type: "number",
219
- value
248
+ type: "text",
249
+ value: draft
220
250
  }
221
251
  }
222
252
  );
@@ -9,7 +9,7 @@ import {
9
9
  } from "./chunk-FJ7PKMAC.mjs";
10
10
 
11
11
  // components/input-number.js
12
- import { useCallback } from "react";
12
+ import { useCallback, useEffect, useState } from "react";
13
13
  import { jsx, jsxs } from "react/jsx-runtime";
14
14
  var InputNumber = ({
15
15
  className,
@@ -19,10 +19,38 @@ var InputNumber = ({
19
19
  min,
20
20
  onChange,
21
21
  small,
22
+ step = 1,
22
23
  style,
23
24
  value,
24
25
  ...rest
25
26
  }) => {
27
+ const decimal = !Number.isInteger(step);
28
+ const [draft, setDraft] = useState(
29
+ value === "" || value === null || value === void 0 ? "" : String(value)
30
+ );
31
+ useEffect(
32
+ () => {
33
+ const next = value === "" || value === null || value === void 0 ? "" : value;
34
+ if (Number(draft || 0) !== Number(next || 0)) {
35
+ setDraft(next === "" ? "" : String(next));
36
+ }
37
+ ;
38
+ },
39
+ // Intentionally excludes `draft`: this effect only reacts to external
40
+ // value changes, not to our own in-flight edits.
41
+ [value]
42
+ // eslint-disable-line react-hooks/exhaustive-deps
43
+ );
44
+ const handleChange = useCallback(
45
+ ({ target }) => {
46
+ const pattern = decimal ? /^-?\d*\.?\d*$/ : /^-?\d*$/;
47
+ if (!pattern.test(target.value)) return;
48
+ setDraft(target.value);
49
+ const numeric = target.value === "" ? 0 : Number(target.value);
50
+ if (!Number.isNaN(numeric)) onChange(numeric);
51
+ },
52
+ [decimal, onChange]
53
+ );
26
54
  const classes = [(inline ? "inline-flex items-center rounded-sm" : "input p-0 flex items-center") + " overflow-hidden"];
27
55
  if (className) {
28
56
  classes.push(className);
@@ -115,9 +143,11 @@ var InputNumber = ({
115
143
  // an inline flex grow rather than a version-specific grow utility, so
116
144
  // this works in BOTH consumers (app-web is Tailwind v3, share is v4).
117
145
  className: "text-inherit bg-transparent focus:outline-none focus:ring-0 " + (small ? "py-1 px-2" : "py-2 px-3") + (inline ? small ? " w-10" : " w-12" : "") + (layout === "split" ? " text-center" : ""),
118
- inputMode: "numeric",
119
- onChange: ({ target }) => onChange(Number(target.value)),
120
- step: 1,
146
+ // `type="text"` (not "number") so in-progress decimal strings survive
147
+ // each render; inputMode still surfaces the numeric/decimal keypad on
148
+ // mobile and handleChange enforces the numeric character set.
149
+ inputMode: decimal ? "decimal" : "numeric",
150
+ onChange: handleChange,
121
151
  // The bordered container is the single visible border; strip the
122
152
  // native number-input border so it doesn't double up.
123
153
  style: {
@@ -127,8 +157,8 @@ var InputNumber = ({
127
157
  minWidth: 0
128
158
  }
129
159
  },
130
- type: "number",
131
- value
160
+ type: "text",
161
+ value: draft
132
162
  }
133
163
  }
134
164
  );