@agentaily/design-system 0.1.1 → 0.3.0

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 (82) hide show
  1. package/DESIGN.md +58 -7
  2. package/README.md +10 -6
  3. package/dist/components/ai/Confirmation.js +58 -22
  4. package/dist/components/ai/Confirmation.js.map +1 -1
  5. package/dist/components/ai/Queue.d.ts +23 -0
  6. package/dist/components/ai/Queue.js +52 -1
  7. package/dist/components/ai/Queue.js.map +1 -1
  8. package/dist/components/ai/ToolCall.js +69 -30
  9. package/dist/components/ai/ToolCall.js.map +1 -1
  10. package/dist/components/auth/AccountControl.d.ts +23 -0
  11. package/dist/components/auth/AccountControl.js +47 -0
  12. package/dist/components/auth/AccountControl.js.map +1 -0
  13. package/dist/components/auth/AuthDialog.d.ts +39 -0
  14. package/dist/components/auth/AuthDialog.js +327 -0
  15. package/dist/components/auth/AuthDialog.js.map +1 -0
  16. package/dist/components/auth/SignInPage.d.ts +48 -0
  17. package/dist/components/auth/SignInPage.js +217 -0
  18. package/dist/components/auth/SignInPage.js.map +1 -0
  19. package/dist/components/chat/CodeBlock.js +3 -2
  20. package/dist/components/chat/CodeBlock.js.map +1 -1
  21. package/dist/components/chat/ConversationThread.d.ts +67 -0
  22. package/dist/components/chat/ConversationThread.js +129 -0
  23. package/dist/components/chat/ConversationThread.js.map +1 -0
  24. package/dist/components/code/Artifact.js +44 -9
  25. package/dist/components/code/Artifact.js.map +1 -1
  26. package/dist/components/code/JSXPreview.js +19 -12
  27. package/dist/components/code/JSXPreview.js.map +1 -1
  28. package/dist/components/code/Snippet.js +2 -2
  29. package/dist/components/code/Snippet.js.map +1 -1
  30. package/dist/components/code/Terminal.js +24 -10
  31. package/dist/components/code/Terminal.js.map +1 -1
  32. package/dist/components/code/WebPreview.js +44 -10
  33. package/dist/components/code/WebPreview.js.map +1 -1
  34. package/dist/components/display/Skeleton.js +17 -4
  35. package/dist/components/display/Skeleton.js.map +1 -1
  36. package/dist/components/display/StatusPill.d.ts +12 -0
  37. package/dist/components/display/StatusPill.js +17 -0
  38. package/dist/components/display/StatusPill.js.map +1 -0
  39. package/dist/components/inputs/Form.d.ts +164 -0
  40. package/dist/components/inputs/Form.js +484 -0
  41. package/dist/components/inputs/Form.js.map +1 -0
  42. package/dist/components/inputs/Input.d.ts +2 -0
  43. package/dist/components/inputs/Input.js +14 -10
  44. package/dist/components/inputs/Input.js.map +1 -1
  45. package/dist/components/inputs/SecretField.d.ts +21 -0
  46. package/dist/components/inputs/SecretField.js +70 -0
  47. package/dist/components/inputs/SecretField.js.map +1 -0
  48. package/dist/components/layout/AppShell.d.ts +30 -0
  49. package/dist/components/layout/AppShell.js +117 -0
  50. package/dist/components/layout/AppShell.js.map +1 -0
  51. package/dist/components/layout/DesignerShell.d.ts +39 -0
  52. package/dist/components/layout/DesignerShell.js +146 -0
  53. package/dist/components/layout/DesignerShell.js.map +1 -0
  54. package/dist/components/layout/DocsLayout.d.ts +24 -0
  55. package/dist/components/layout/DocsLayout.js +113 -0
  56. package/dist/components/layout/DocsLayout.js.map +1 -0
  57. package/dist/components/layout/SettingsPage.d.ts +31 -0
  58. package/dist/components/layout/SettingsPage.js +92 -0
  59. package/dist/components/layout/SettingsPage.js.map +1 -0
  60. package/dist/components/review/MarkupLayer.d.ts +20 -0
  61. package/dist/components/review/MarkupLayer.js +237 -0
  62. package/dist/components/review/MarkupLayer.js.map +1 -0
  63. package/dist/components/settings/HelpSteps.d.ts +20 -0
  64. package/dist/components/settings/HelpSteps.js +40 -0
  65. package/dist/components/settings/HelpSteps.js.map +1 -0
  66. package/dist/components/settings/IntegrationSettings.d.ts +15 -0
  67. package/dist/components/settings/IntegrationSettings.js +630 -0
  68. package/dist/components/settings/IntegrationSettings.js.map +1 -0
  69. package/dist/components/settings/TestRow.d.ts +21 -0
  70. package/dist/components/settings/TestRow.js +66 -0
  71. package/dist/components/settings/TestRow.js.map +1 -0
  72. package/dist/components/utilities/BrandMark.d.ts +17 -0
  73. package/dist/components/utilities/BrandMark.js +43 -0
  74. package/dist/components/utilities/BrandMark.js.map +1 -0
  75. package/dist/components/utilities/Icon.d.ts +28 -0
  76. package/dist/components/utilities/Icon.js +196 -0
  77. package/dist/components/utilities/Icon.js.map +1 -0
  78. package/dist/index.d.ts +23 -0
  79. package/dist/index.js +35 -0
  80. package/dist/index.js.map +1 -1
  81. package/dist/styles.css +67 -64
  82. package/package.json +2 -2
@@ -0,0 +1,484 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useState, useRef, useCallback, useMemo } from "react";
3
+ const AX_FORM_CSS = `
4
+ .ax-form { display: flex; flex-direction: column; gap: var(--space-5, 20px); }
5
+ .ax-form--tight { gap: var(--space-3, 12px); }
6
+ .ax-form--loose { gap: var(--space-6, 28px); }
7
+ .ax-form__actions {
8
+ display: flex; align-items: center; gap: var(--space-3, 12px);
9
+ padding-top: var(--space-2, 8px);
10
+ }
11
+ .ax-form__actions--end { justify-content: flex-end; }
12
+ .ax-form__actions--start { justify-content: flex-start; }
13
+ .ax-form__actions--between { justify-content: space-between; }
14
+ .ax-form__actions--full > * { flex: 1; }
15
+ .ax-form__actions--bordered {
16
+ border-top: 1px solid var(--border-default);
17
+ margin-top: var(--space-2, 8px); padding-top: var(--space-5, 20px);
18
+ }
19
+ `;
20
+ if (typeof document !== "undefined" && !document.getElementById("ax-form-css")) {
21
+ const s = document.createElement("style");
22
+ s.id = "ax-form-css";
23
+ s.textContent = AX_FORM_CSS;
24
+ document.head.appendChild(s);
25
+ }
26
+ function Form({ gap = "normal", onSubmit, children, className = "", ...rest }) {
27
+ const cls = [
28
+ "ax-form",
29
+ gap === "tight" ? "ax-form--tight" : gap === "loose" ? "ax-form--loose" : "",
30
+ className
31
+ ].filter(Boolean).join(" ");
32
+ return /* @__PURE__ */ jsx("form", { className: cls, onSubmit, noValidate: true, ...rest, children });
33
+ }
34
+ function FormActions({
35
+ align = "end",
36
+ bordered = false,
37
+ full = false,
38
+ children,
39
+ className = "",
40
+ ...rest
41
+ }) {
42
+ const cls = [
43
+ "ax-form__actions",
44
+ "ax-form__actions--" + align,
45
+ bordered ? "ax-form__actions--bordered" : "",
46
+ full ? "ax-form__actions--full" : "",
47
+ className
48
+ ].filter(Boolean).join(" ");
49
+ return /* @__PURE__ */ jsx("div", { className: cls, ...rest, children });
50
+ }
51
+ const isEmpty = (v) => v === void 0 || v === null || v === "" || Array.isArray(v) && v.length === 0;
52
+ async function evalRules(rules, value, values) {
53
+ if (!rules) return void 0;
54
+ const { required, minLength, maxLength, min, max, pattern, validate } = rules;
55
+ if (required && (isEmpty(value) || value === false)) {
56
+ return typeof required === "string" ? required : "This field is required.";
57
+ }
58
+ if (isEmpty(value)) return void 0;
59
+ const num = (r) => typeof r === "object" ? r : { value: r, message: void 0 };
60
+ if (minLength != null) {
61
+ const { value: n, message } = num(minLength);
62
+ if (String(value).length < n) return message || `Must be at least ${n} characters.`;
63
+ }
64
+ if (maxLength != null) {
65
+ const { value: n, message } = num(maxLength);
66
+ if (String(value).length > n) return message || `Must be at most ${n} characters.`;
67
+ }
68
+ if (min != null) {
69
+ const { value: n, message } = num(min);
70
+ if (Number(value) < n) return message || `Must be ${n} or more.`;
71
+ }
72
+ if (max != null) {
73
+ const { value: n, message } = num(max);
74
+ if (Number(value) > n) return message || `Must be ${n} or less.`;
75
+ }
76
+ if (pattern) {
77
+ const re = pattern instanceof RegExp ? pattern : pattern.value;
78
+ const message = pattern instanceof RegExp ? void 0 : pattern.message;
79
+ if (re && !re.test(String(value))) return message || "Invalid format.";
80
+ }
81
+ if (validate) {
82
+ const fns = typeof validate === "function" ? { _: validate } : validate;
83
+ for (const key of Object.keys(fns)) {
84
+ const res = await fns[key](value, values);
85
+ if (res === false) return "Invalid value.";
86
+ if (typeof res === "string") return res;
87
+ }
88
+ }
89
+ return void 0;
90
+ }
91
+ function useForm(config = {}) {
92
+ const {
93
+ initialValues = {},
94
+ defaultValues,
95
+ // RHF alias
96
+ validate,
97
+ // schema-style: (values) => ({ field: message }) | Promise
98
+ mode = "onSubmit",
99
+ // onSubmit | onBlur | onChange | onTouched | all
100
+ reValidateMode = "onChange",
101
+ // onChange | onBlur (after first submit)
102
+ onSubmit: onSubmitCfg,
103
+ onInvalid: onInvalidCfg,
104
+ shouldFocusError = true
105
+ } = config;
106
+ const defaults = defaultValues || initialValues;
107
+ const [values, setValuesState] = useState(defaults);
108
+ const [errors, setErrors] = useState({});
109
+ const [touched, setTouched] = useState({});
110
+ const [dirtyFields, setDirtyFields] = useState({});
111
+ const [isSubmitting, setSubmitting] = useState(false);
112
+ const [isSubmitted, setSubmitted] = useState(false);
113
+ const [isSubmitSuccessful, setSubmitSuccessful] = useState(false);
114
+ const [submitCount, setSubmitCount] = useState(0);
115
+ const [isValidating, setValidating] = useState(false);
116
+ const valuesRef = useRef(values);
117
+ valuesRef.current = values;
118
+ const errorsRef = useRef(errors);
119
+ errorsRef.current = errors;
120
+ const rulesRef = useRef({});
121
+ const defaultsRef = useRef(defaults);
122
+ const formElRef = useRef(null);
123
+ const writeValues = useCallback((updater) => {
124
+ setValuesState((prev) => {
125
+ const next = typeof updater === "function" ? updater(prev) : updater;
126
+ valuesRef.current = next;
127
+ return next;
128
+ });
129
+ }, []);
130
+ const runValidation = useCallback(
131
+ async (only) => {
132
+ const vals = valuesRef.current;
133
+ const out = {};
134
+ const names = only ? [only] : Object.keys(rulesRef.current);
135
+ for (const name of names) {
136
+ const msg = await evalRules(rulesRef.current[name], vals[name], vals);
137
+ if (msg) out[name] = msg;
138
+ }
139
+ if (validate) {
140
+ const schema = await validate(vals) || {};
141
+ for (const k of Object.keys(schema)) {
142
+ if (only && k !== only) continue;
143
+ if (!out[k] && schema[k]) out[k] = schema[k];
144
+ }
145
+ }
146
+ return out;
147
+ },
148
+ [validate]
149
+ );
150
+ const revalidateField = useCallback(
151
+ async (name) => {
152
+ setValidating(true);
153
+ const partial = await runValidation(name);
154
+ setErrors((prev) => {
155
+ const next = { ...prev };
156
+ if (partial[name]) next[name] = partial[name];
157
+ else delete next[name];
158
+ errorsRef.current = next;
159
+ return next;
160
+ });
161
+ setValidating(false);
162
+ },
163
+ [runValidation]
164
+ );
165
+ const shouldValidateOn = useCallback(
166
+ (event, name) => {
167
+ if (isSubmitted) return reValidateMode === event;
168
+ switch (mode) {
169
+ case "all":
170
+ return true;
171
+ case "onChange":
172
+ return event === "change";
173
+ case "onBlur":
174
+ return event === "blur";
175
+ case "onTouched":
176
+ return event === "blur" || event === "change" && touched[name];
177
+ case "onSubmit":
178
+ default:
179
+ return false;
180
+ }
181
+ },
182
+ [isSubmitted, reValidateMode, mode, touched]
183
+ );
184
+ const setValue = useCallback(
185
+ (name, value, opts = {}) => {
186
+ writeValues((prev) => ({ ...prev, [name]: value }));
187
+ if (opts.shouldDirty !== false) {
188
+ setDirtyFields((p) => defaultsRef.current[name] === value ? p : { ...p, [name]: true });
189
+ }
190
+ if (opts.shouldTouch) setTouched((p) => ({ ...p, [name]: true }));
191
+ if (opts.shouldValidate) revalidateField(name);
192
+ },
193
+ [writeValues, revalidateField]
194
+ );
195
+ const register = useCallback(
196
+ (name, rules) => {
197
+ if (rules) rulesRef.current[name] = rules;
198
+ else if (!(name in rulesRef.current)) rulesRef.current[name] = void 0;
199
+ const isCheckbox = rules && rules.type === "checkbox";
200
+ const onChange = (e) => {
201
+ const t = e && e.target;
202
+ const next = t ? t.type === "checkbox" ? t.checked : t.value : e;
203
+ writeValues((prev) => ({ ...prev, [name]: next }));
204
+ setDirtyFields((p) => ({ ...p, [name]: true }));
205
+ if (shouldValidateOn("change", name)) revalidateField(name);
206
+ };
207
+ const onBlur = () => {
208
+ setTouched((p) => ({ ...p, [name]: true }));
209
+ if (shouldValidateOn("blur", name)) revalidateField(name);
210
+ };
211
+ const base = { name, onChange, onBlur };
212
+ if (isCheckbox) base.checked = !!values[name];
213
+ else base.value = values[name] ?? "";
214
+ return base;
215
+ },
216
+ [values, writeValues, shouldValidateOn, revalidateField]
217
+ );
218
+ const field = useCallback(
219
+ (name, opts) => {
220
+ const props = register(name, opts);
221
+ props.error = errors[name];
222
+ return props;
223
+ },
224
+ [register, errors]
225
+ );
226
+ const trigger = useCallback(
227
+ async (name) => {
228
+ setValidating(true);
229
+ const errs = await runValidation(name);
230
+ if (name) {
231
+ setErrors((prev) => {
232
+ const next = { ...prev };
233
+ if (errs[name]) next[name] = errs[name];
234
+ else delete next[name];
235
+ errorsRef.current = next;
236
+ return next;
237
+ });
238
+ setValidating(false);
239
+ return !errs[name];
240
+ }
241
+ setErrors(errs);
242
+ errorsRef.current = errs;
243
+ setValidating(false);
244
+ return Object.keys(errs).length === 0;
245
+ },
246
+ [runValidation]
247
+ );
248
+ const setError = useCallback((name, message) => {
249
+ setErrors((prev) => {
250
+ const n = { ...prev, [name]: message };
251
+ errorsRef.current = n;
252
+ return n;
253
+ });
254
+ }, []);
255
+ const clearErrors = useCallback((name) => {
256
+ setErrors((prev) => {
257
+ if (!name) {
258
+ errorsRef.current = {};
259
+ return {};
260
+ }
261
+ const next = { ...prev };
262
+ delete next[name];
263
+ errorsRef.current = next;
264
+ return next;
265
+ });
266
+ }, []);
267
+ const getValues = useCallback((name) => name ? valuesRef.current[name] : valuesRef.current, []);
268
+ const watch = useCallback((name) => name ? values[name] : values, [values]);
269
+ const focusError = useCallback(
270
+ (errs) => {
271
+ if (!shouldFocusError || typeof document === "undefined") return;
272
+ const first = Object.keys(errs)[0];
273
+ if (!first) return;
274
+ const el = (formElRef.current || document).querySelector(`[name="${first}"]`);
275
+ if (el && el.focus) el.focus();
276
+ },
277
+ [shouldFocusError]
278
+ );
279
+ const handleSubmit = useCallback(
280
+ (onValidArg, onInvalidArg) => {
281
+ const runner = async (e) => {
282
+ if (e && e.preventDefault) e.preventDefault();
283
+ if (e && e.currentTarget && e.currentTarget.tagName === "FORM")
284
+ formElRef.current = e.currentTarget;
285
+ setSubmitting(true);
286
+ setValidating(true);
287
+ const errs = await runValidation();
288
+ setErrors(errs);
289
+ errorsRef.current = errs;
290
+ setTouched(() => {
291
+ const all = {};
292
+ [...Object.keys(rulesRef.current), ...Object.keys(valuesRef.current)].forEach(
293
+ (k) => all[k] = true
294
+ );
295
+ return all;
296
+ });
297
+ setSubmitted(true);
298
+ setSubmitCount((c) => c + 1);
299
+ setValidating(false);
300
+ const valid = Object.keys(errs).length === 0;
301
+ if (valid) {
302
+ try {
303
+ await (typeof onValidArg === "function" ? onValidArg : onSubmitCfg)?.(
304
+ valuesRef.current
305
+ );
306
+ setSubmitSuccessful(true);
307
+ } catch (err) {
308
+ setSubmitSuccessful(false);
309
+ throw err;
310
+ } finally {
311
+ setSubmitting(false);
312
+ }
313
+ } else {
314
+ setSubmitSuccessful(false);
315
+ setSubmitting(false);
316
+ (onInvalidArg || onInvalidCfg)?.(errs);
317
+ focusError(errs);
318
+ }
319
+ };
320
+ if (typeof onValidArg === "function") return runner;
321
+ return runner(onValidArg);
322
+ },
323
+ [runValidation, onSubmitCfg, onInvalidCfg, focusError]
324
+ );
325
+ const reset = useCallback(
326
+ (next, opts = {}) => {
327
+ const target = next || defaultsRef.current;
328
+ if (opts.keepDefaultValues !== true) defaultsRef.current = target;
329
+ writeValues(target);
330
+ if (!opts.keepErrors) {
331
+ setErrors({});
332
+ errorsRef.current = {};
333
+ }
334
+ if (!opts.keepTouched) setTouched({});
335
+ if (!opts.keepDirty) setDirtyFields({});
336
+ if (!opts.keepIsSubmitted) {
337
+ setSubmitted(false);
338
+ setSubmitSuccessful(false);
339
+ }
340
+ },
341
+ [writeValues]
342
+ );
343
+ const isDirty = Object.keys(dirtyFields).length > 0;
344
+ const isValid = Object.keys(errors).length === 0;
345
+ const formState = useMemo(
346
+ () => ({
347
+ errors,
348
+ touched,
349
+ dirtyFields,
350
+ isDirty,
351
+ isValid,
352
+ isValidating,
353
+ isSubmitting,
354
+ isSubmitted,
355
+ isSubmitSuccessful,
356
+ submitCount
357
+ }),
358
+ [
359
+ errors,
360
+ touched,
361
+ dirtyFields,
362
+ isDirty,
363
+ isValid,
364
+ isValidating,
365
+ isSubmitting,
366
+ isSubmitted,
367
+ isSubmitSuccessful,
368
+ submitCount
369
+ ]
370
+ );
371
+ return {
372
+ // state
373
+ values,
374
+ errors,
375
+ touched,
376
+ dirtyFields,
377
+ isDirty,
378
+ isValid,
379
+ isValidating,
380
+ isSubmitting,
381
+ isSubmitted,
382
+ isSubmitSuccessful,
383
+ submitCount,
384
+ submitted: isSubmitted,
385
+ formState,
386
+ // binding
387
+ register,
388
+ field,
389
+ // imperative
390
+ setValue,
391
+ setValues: writeValues,
392
+ getValues,
393
+ watch,
394
+ setError,
395
+ clearErrors,
396
+ trigger,
397
+ handleSubmit,
398
+ reset,
399
+ // internal-ish (handy for custom layouts)
400
+ _formElRef: formElRef
401
+ };
402
+ }
403
+ let _faKey = 0;
404
+ function useFieldArray({ form, name }) {
405
+ const keysRef = useRef([]);
406
+ const list = form.getValues(name) || [];
407
+ while (keysRef.current.length < list.length) keysRef.current.push(++_faKey);
408
+ if (keysRef.current.length > list.length) keysRef.current = keysRef.current.slice(0, list.length);
409
+ const fields = list.map((item, i) => ({ ...item, id: keysRef.current[i] }));
410
+ const commit = (next, keys) => {
411
+ keysRef.current = keys;
412
+ form.setValue(name, next, { shouldDirty: true });
413
+ };
414
+ const append = useCallback(
415
+ (item) => {
416
+ const cur = form.getValues(name) || [];
417
+ commit([...cur, item], [...keysRef.current, ++_faKey]);
418
+ },
419
+ [form, name]
420
+ );
421
+ const prepend = useCallback(
422
+ (item) => {
423
+ const cur = form.getValues(name) || [];
424
+ commit([item, ...cur], [++_faKey, ...keysRef.current]);
425
+ },
426
+ [form, name]
427
+ );
428
+ const remove = useCallback(
429
+ (index) => {
430
+ const cur = form.getValues(name) || [];
431
+ commit(
432
+ cur.filter((_, i) => i !== index),
433
+ keysRef.current.filter((_, i) => i !== index)
434
+ );
435
+ },
436
+ [form, name]
437
+ );
438
+ const insert = useCallback(
439
+ (index, item) => {
440
+ const cur = (form.getValues(name) || []).slice();
441
+ const keys = keysRef.current.slice();
442
+ cur.splice(index, 0, item);
443
+ keys.splice(index, 0, ++_faKey);
444
+ commit(cur, keys);
445
+ },
446
+ [form, name]
447
+ );
448
+ const move = useCallback(
449
+ (from, to) => {
450
+ const cur = (form.getValues(name) || []).slice();
451
+ const keys = keysRef.current.slice();
452
+ cur.splice(to, 0, cur.splice(from, 1)[0]);
453
+ keys.splice(to, 0, keys.splice(from, 1)[0]);
454
+ commit(cur, keys);
455
+ },
456
+ [form, name]
457
+ );
458
+ const replace = useCallback(
459
+ (items) => {
460
+ commit(
461
+ items,
462
+ items.map(() => ++_faKey)
463
+ );
464
+ },
465
+ [form, name]
466
+ );
467
+ const update = useCallback(
468
+ (index, item) => {
469
+ const cur = (form.getValues(name) || []).slice();
470
+ cur[index] = item;
471
+ commit(cur, keysRef.current.slice());
472
+ },
473
+ [form, name]
474
+ );
475
+ return { fields, append, prepend, remove, insert, move, replace, update };
476
+ }
477
+ Form.useForm = useForm;
478
+ Form.useFieldArray = useFieldArray;
479
+ Form.Actions = FormActions;
480
+ export {
481
+ Form,
482
+ FormActions
483
+ };
484
+ //# sourceMappingURL=Form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Form.js","sources":["../../../src/components/inputs/Form.jsx"],"sourcesContent":["import React, { useState, useCallback, useRef, useMemo } from \"react\";\n\nconst AX_FORM_CSS = `\n.ax-form { display: flex; flex-direction: column; gap: var(--space-5, 20px); }\n.ax-form--tight { gap: var(--space-3, 12px); }\n.ax-form--loose { gap: var(--space-6, 28px); }\n.ax-form__actions {\n display: flex; align-items: center; gap: var(--space-3, 12px);\n padding-top: var(--space-2, 8px);\n}\n.ax-form__actions--end { justify-content: flex-end; }\n.ax-form__actions--start { justify-content: flex-start; }\n.ax-form__actions--between { justify-content: space-between; }\n.ax-form__actions--full > * { flex: 1; }\n.ax-form__actions--bordered {\n border-top: 1px solid var(--border-default);\n margin-top: var(--space-2, 8px); padding-top: var(--space-5, 20px);\n}\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-form-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-form-css\";\n s.textContent = AX_FORM_CSS;\n document.head.appendChild(s);\n}\n\n/**\n * Form — a thin structural <form> wrapper. Pure layout, no state.\n * Pass form.handleSubmit (from Form.useForm) as onSubmit, then compose controls.\n */\nexport function Form({ gap = \"normal\", onSubmit, children, className = \"\", ...rest }) {\n const cls = [\n \"ax-form\",\n gap === \"tight\" ? \"ax-form--tight\" : gap === \"loose\" ? \"ax-form--loose\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n return (\n <form className={cls} onSubmit={onSubmit} noValidate {...rest}>\n {children}\n </form>\n );\n}\n\n/** FormActions — right-aligned footer row for submit/cancel buttons. */\nexport function FormActions({\n align = \"end\",\n bordered = false,\n full = false,\n children,\n className = \"\",\n ...rest\n}) {\n const cls = [\n \"ax-form__actions\",\n \"ax-form__actions--\" + align,\n bordered ? \"ax-form__actions--bordered\" : \"\",\n full ? \"ax-form__actions--full\" : \"\",\n className,\n ]\n .filter(Boolean)\n .join(\" \");\n return (\n <div className={cls} {...rest}>\n {children}\n </div>\n );\n}\n\n/* ============================================================\n useForm — production controlled form hook (RHF-aligned API).\n Exposed as Form.useForm. Drop it for react-hook-form / TanStack;\n the presentational components never depend on it.\n ============================================================ */\n\nconst isEmpty = (v) =>\n v === undefined || v === null || v === \"\" || (Array.isArray(v) && v.length === 0);\n\n// Evaluate one field's built-in rules. Returns a message string or undefined.\nasync function evalRules(rules, value, values) {\n if (!rules) return undefined;\n const { required, minLength, maxLength, min, max, pattern, validate } = rules;\n\n if (required && (isEmpty(value) || value === false)) {\n return typeof required === \"string\" ? required : \"This field is required.\";\n }\n if (isEmpty(value)) return undefined; // other rules don't apply to empty optional fields\n\n const num = (r) => (typeof r === \"object\" ? r : { value: r, message: undefined });\n\n if (minLength != null) {\n const { value: n, message } = num(minLength);\n if (String(value).length < n) return message || `Must be at least ${n} characters.`;\n }\n if (maxLength != null) {\n const { value: n, message } = num(maxLength);\n if (String(value).length > n) return message || `Must be at most ${n} characters.`;\n }\n if (min != null) {\n const { value: n, message } = num(min);\n if (Number(value) < n) return message || `Must be ${n} or more.`;\n }\n if (max != null) {\n const { value: n, message } = num(max);\n if (Number(value) > n) return message || `Must be ${n} or less.`;\n }\n if (pattern) {\n const re = pattern instanceof RegExp ? pattern : pattern.value;\n const message = pattern instanceof RegExp ? undefined : pattern.message;\n if (re && !re.test(String(value))) return message || \"Invalid format.\";\n }\n if (validate) {\n const fns = typeof validate === \"function\" ? { _: validate } : validate;\n for (const key of Object.keys(fns)) {\n const res = await fns[key](value, values);\n if (res === false) return \"Invalid value.\";\n if (typeof res === \"string\") return res;\n }\n }\n return undefined;\n}\n\nfunction useForm(config = {}) {\n const {\n initialValues = {},\n defaultValues, // RHF alias\n validate, // schema-style: (values) => ({ field: message }) | Promise\n mode = \"onSubmit\", // onSubmit | onBlur | onChange | onTouched | all\n reValidateMode = \"onChange\", // onChange | onBlur (after first submit)\n onSubmit: onSubmitCfg,\n onInvalid: onInvalidCfg,\n shouldFocusError = true,\n } = config;\n\n const defaults = defaultValues || initialValues;\n const [values, setValuesState] = useState(defaults);\n const [errors, setErrors] = useState({});\n const [touched, setTouched] = useState({});\n const [dirtyFields, setDirtyFields] = useState({});\n const [isSubmitting, setSubmitting] = useState(false);\n const [isSubmitted, setSubmitted] = useState(false);\n const [isSubmitSuccessful, setSubmitSuccessful] = useState(false);\n const [submitCount, setSubmitCount] = useState(0);\n const [isValidating, setValidating] = useState(false);\n\n const valuesRef = useRef(values);\n valuesRef.current = values;\n const errorsRef = useRef(errors);\n errorsRef.current = errors;\n const rulesRef = useRef({}); // name -> rules registered via register/field\n const defaultsRef = useRef(defaults);\n const formElRef = useRef(null);\n\n const writeValues = useCallback((updater) => {\n setValuesState((prev) => {\n const next = typeof updater === \"function\" ? updater(prev) : updater;\n valuesRef.current = next;\n return next;\n });\n }, []);\n\n // Validate the whole form (or a single field). Returns a fresh errors map.\n const runValidation = useCallback(\n async (only) => {\n const vals = valuesRef.current;\n const out = {};\n const names = only ? [only] : Object.keys(rulesRef.current);\n for (const name of names) {\n const msg = await evalRules(rulesRef.current[name], vals[name], vals);\n if (msg) out[name] = msg;\n }\n if (validate) {\n const schema = (await validate(vals)) || {};\n for (const k of Object.keys(schema)) {\n if (only && k !== only) continue;\n if (!out[k] && schema[k]) out[k] = schema[k];\n }\n }\n return out;\n },\n [validate],\n );\n\n // Recompute one field's error and merge into state (preserving others).\n const revalidateField = useCallback(\n async (name) => {\n setValidating(true);\n const partial = await runValidation(name);\n setErrors((prev) => {\n const next = { ...prev };\n if (partial[name]) next[name] = partial[name];\n else delete next[name];\n errorsRef.current = next;\n return next;\n });\n setValidating(false);\n },\n [runValidation],\n );\n\n const shouldValidateOn = useCallback(\n (event, name) => {\n if (isSubmitted) return reValidateMode === event;\n switch (mode) {\n case \"all\":\n return true;\n case \"onChange\":\n return event === \"change\";\n case \"onBlur\":\n return event === \"blur\";\n case \"onTouched\":\n return event === \"blur\" || (event === \"change\" && touched[name]);\n case \"onSubmit\":\n default:\n return false;\n }\n },\n [isSubmitted, reValidateMode, mode, touched],\n );\n\n const setValue = useCallback(\n (name, value, opts = {}) => {\n writeValues((prev) => ({ ...prev, [name]: value }));\n if (opts.shouldDirty !== false) {\n setDirtyFields((p) => (defaultsRef.current[name] === value ? p : { ...p, [name]: true }));\n }\n if (opts.shouldTouch) setTouched((p) => ({ ...p, [name]: true }));\n if (opts.shouldValidate) revalidateField(name);\n },\n [writeValues, revalidateField],\n );\n\n // Build the props for a control. `register` is RHF-compatible; `field` adds `error`.\n const register = useCallback(\n (name, rules) => {\n if (rules) rulesRef.current[name] = rules;\n else if (!(name in rulesRef.current)) rulesRef.current[name] = undefined;\n const isCheckbox = rules && rules.type === \"checkbox\";\n const onChange = (e) => {\n const t = e && e.target;\n const next = t ? (t.type === \"checkbox\" ? t.checked : t.value) : e;\n writeValues((prev) => ({ ...prev, [name]: next }));\n setDirtyFields((p) => ({ ...p, [name]: true }));\n if (shouldValidateOn(\"change\", name)) revalidateField(name);\n };\n const onBlur = () => {\n setTouched((p) => ({ ...p, [name]: true }));\n if (shouldValidateOn(\"blur\", name)) revalidateField(name);\n };\n const base = { name, onChange, onBlur };\n if (isCheckbox) base.checked = !!values[name];\n else base.value = values[name] ?? \"\";\n return base;\n },\n [values, writeValues, shouldValidateOn, revalidateField],\n );\n\n const field = useCallback(\n (name, opts) => {\n const props = register(name, opts);\n props.error = errors[name];\n return props;\n },\n [register, errors],\n );\n\n const trigger = useCallback(\n async (name) => {\n setValidating(true);\n const errs = await runValidation(name);\n if (name) {\n setErrors((prev) => {\n const next = { ...prev };\n if (errs[name]) next[name] = errs[name];\n else delete next[name];\n errorsRef.current = next;\n return next;\n });\n setValidating(false);\n return !errs[name];\n }\n setErrors(errs);\n errorsRef.current = errs;\n setValidating(false);\n return Object.keys(errs).length === 0;\n },\n [runValidation],\n );\n\n const setError = useCallback((name, message) => {\n setErrors((prev) => {\n const n = { ...prev, [name]: message };\n errorsRef.current = n;\n return n;\n });\n }, []);\n\n const clearErrors = useCallback((name) => {\n setErrors((prev) => {\n if (!name) {\n errorsRef.current = {};\n return {};\n }\n const next = { ...prev };\n delete next[name];\n errorsRef.current = next;\n return next;\n });\n }, []);\n\n const getValues = useCallback((name) => (name ? valuesRef.current[name] : valuesRef.current), []);\n const watch = useCallback((name) => (name ? values[name] : values), [values]);\n\n const focusError = useCallback(\n (errs) => {\n if (!shouldFocusError || typeof document === \"undefined\") return;\n const first = Object.keys(errs)[0];\n if (!first) return;\n const el = (formElRef.current || document).querySelector(`[name=\"${first}\"]`);\n if (el && el.focus) el.focus();\n },\n [shouldFocusError],\n );\n\n const handleSubmit = useCallback(\n (onValidArg, onInvalidArg) => {\n const runner = async (e) => {\n if (e && e.preventDefault) e.preventDefault();\n if (e && e.currentTarget && e.currentTarget.tagName === \"FORM\")\n formElRef.current = e.currentTarget;\n setSubmitting(true);\n setValidating(true);\n const errs = await runValidation();\n setErrors(errs);\n errorsRef.current = errs;\n setTouched(() => {\n const all = {};\n [...Object.keys(rulesRef.current), ...Object.keys(valuesRef.current)].forEach(\n (k) => (all[k] = true),\n );\n return all;\n });\n setSubmitted(true);\n setSubmitCount((c) => c + 1);\n setValidating(false);\n const valid = Object.keys(errs).length === 0;\n if (valid) {\n try {\n await (typeof onValidArg === \"function\" ? onValidArg : onSubmitCfg)?.(\n valuesRef.current,\n );\n setSubmitSuccessful(true);\n } catch (err) {\n setSubmitSuccessful(false);\n throw err;\n } finally {\n setSubmitting(false);\n }\n } else {\n setSubmitSuccessful(false);\n setSubmitting(false);\n (onInvalidArg || onInvalidCfg)?.(errs);\n focusError(errs);\n }\n };\n // Dual API: handleSubmit(onValid[, onInvalid]) returns a handler (RHF style);\n // handleSubmit(event) runs immediately (use as onSubmit/onClick directly).\n if (typeof onValidArg === \"function\") return runner;\n return runner(onValidArg);\n },\n [runValidation, onSubmitCfg, onInvalidCfg, focusError],\n );\n\n const reset = useCallback(\n (next, opts = {}) => {\n const target = next || defaultsRef.current;\n if (opts.keepDefaultValues !== true) defaultsRef.current = target;\n writeValues(target);\n if (!opts.keepErrors) {\n setErrors({});\n errorsRef.current = {};\n }\n if (!opts.keepTouched) setTouched({});\n if (!opts.keepDirty) setDirtyFields({});\n if (!opts.keepIsSubmitted) {\n setSubmitted(false);\n setSubmitSuccessful(false);\n }\n },\n [writeValues],\n );\n\n const isDirty = Object.keys(dirtyFields).length > 0;\n const isValid = Object.keys(errors).length === 0;\n\n const formState = useMemo(\n () => ({\n errors,\n touched,\n dirtyFields,\n isDirty,\n isValid,\n isValidating,\n isSubmitting,\n isSubmitted,\n isSubmitSuccessful,\n submitCount,\n }),\n [\n errors,\n touched,\n dirtyFields,\n isDirty,\n isValid,\n isValidating,\n isSubmitting,\n isSubmitted,\n isSubmitSuccessful,\n submitCount,\n ],\n );\n\n return {\n // state\n values,\n errors,\n touched,\n dirtyFields,\n isDirty,\n isValid,\n isValidating,\n isSubmitting,\n isSubmitted,\n isSubmitSuccessful,\n submitCount,\n submitted: isSubmitted,\n formState,\n // binding\n register,\n field,\n // imperative\n setValue,\n setValues: writeValues,\n getValues,\n watch,\n setError,\n clearErrors,\n trigger,\n handleSubmit,\n reset,\n // internal-ish (handy for custom layouts)\n _formElRef: formElRef,\n };\n}\n\n/* ============================================================\n useFieldArray — dynamic list fields, RHF-aligned.\n const ta = Form.useFieldArray({ form, name: \"members\" });\n ============================================================ */\nlet _faKey = 0;\nfunction useFieldArray({ form, name }) {\n const keysRef = useRef([]);\n const list = form.getValues(name) || [];\n // keep a stable key per row\n while (keysRef.current.length < list.length) keysRef.current.push(++_faKey);\n if (keysRef.current.length > list.length) keysRef.current = keysRef.current.slice(0, list.length);\n\n const fields = list.map((item, i) => ({ ...item, id: keysRef.current[i] }));\n\n const commit = (next, keys) => {\n keysRef.current = keys;\n form.setValue(name, next, { shouldDirty: true });\n };\n\n const append = useCallback(\n (item) => {\n const cur = form.getValues(name) || [];\n commit([...cur, item], [...keysRef.current, ++_faKey]);\n },\n [form, name],\n );\n const prepend = useCallback(\n (item) => {\n const cur = form.getValues(name) || [];\n commit([item, ...cur], [++_faKey, ...keysRef.current]);\n },\n [form, name],\n );\n const remove = useCallback(\n (index) => {\n const cur = form.getValues(name) || [];\n commit(\n cur.filter((_, i) => i !== index),\n keysRef.current.filter((_, i) => i !== index),\n );\n },\n [form, name],\n );\n const insert = useCallback(\n (index, item) => {\n const cur = (form.getValues(name) || []).slice();\n const keys = keysRef.current.slice();\n cur.splice(index, 0, item);\n keys.splice(index, 0, ++_faKey);\n commit(cur, keys);\n },\n [form, name],\n );\n const move = useCallback(\n (from, to) => {\n const cur = (form.getValues(name) || []).slice();\n const keys = keysRef.current.slice();\n cur.splice(to, 0, cur.splice(from, 1)[0]);\n keys.splice(to, 0, keys.splice(from, 1)[0]);\n commit(cur, keys);\n },\n [form, name],\n );\n const replace = useCallback(\n (items) => {\n commit(\n items,\n items.map(() => ++_faKey),\n );\n },\n [form, name],\n );\n const update = useCallback(\n (index, item) => {\n const cur = (form.getValues(name) || []).slice();\n cur[index] = item;\n commit(cur, keysRef.current.slice());\n },\n [form, name],\n );\n\n return { fields, append, prepend, remove, insert, move, replace, update };\n}\n\nForm.useForm = useForm;\nForm.useFieldArray = useFieldArray;\nForm.Actions = FormActions;\n"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@ export interface InputProps {
8
8
  hint?: string;
9
9
  /** Error message; also paints the border red. */
10
10
  error?: string;
11
+ /** Marks the field required: appends a red asterisk to the label and sets the input's required attribute. @default false */
12
+ required?: boolean;
11
13
  /** Use the mono font for the value (ids, keys, code). @default false */
12
14
  mono?: boolean;
13
15
  placeholder?: string;
@@ -3,10 +3,12 @@ import "react";
3
3
  const AX_FIELD_CSS = `
4
4
  .ax-field { display: flex; flex-direction: column; gap: 6px; }
5
5
  .ax-field__label {
6
+ display: inline-flex; align-items: center; gap: 6px;
6
7
  font-family: var(--font-mono); font-size: var(--text-xs);
7
8
  font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);
8
9
  text-transform: uppercase; color: var(--text-faint);
9
10
  }
11
+ .ax-field__req { color: var(--danger); }
10
12
  /* State priority is declared explicitly via layer order, low -> high.
11
13
  This frees each state rule from fighting specificity, so no :not() chains
12
14
  are needed and source order is no longer load-bearing. Add a new state by
@@ -31,8 +33,11 @@ const AX_FIELD_CSS = `
31
33
  .ax-input:focus { outline: none; border-color: var(--fg-2); box-shadow: 0 0 0 3px var(--focus-soft); }
32
34
  }
33
35
  @layer ax-error {
34
- .ax-input--error { border-color: var(--danger); }
35
- .ax-input--error:focus { box-shadow: 0 0 0 3px var(--danger-dim); }
36
+ /* Outline (not just border-color) so the error ring is robust: it survives
37
+ overlay/instrumentation layers that repaint control borders, and never
38
+ shifts layout. Offset -1px parks it exactly on the border edge. */
39
+ .ax-input--error { border-color: var(--danger); outline: 1px solid var(--danger); outline-offset: -1px; }
40
+ .ax-input--error:focus { box-shadow: 0 0 0 3px var(--danger-dim); outline-color: var(--danger); }
36
41
  }
37
42
  @layer ax-disabled {
38
43
  .ax-input:disabled { opacity: 0.4; cursor: not-allowed; border-color: var(--border-default); }
@@ -50,19 +55,18 @@ function Input({
50
55
  label,
51
56
  hint,
52
57
  error,
58
+ required = false,
53
59
  mono = false,
54
60
  className = "",
55
61
  ...rest
56
62
  }) {
57
- const cls = [
58
- "ax-input",
59
- mono ? "ax-input--mono" : "",
60
- error ? "ax-input--error" : "",
61
- className
62
- ].filter(Boolean).join(" ");
63
+ const cls = ["ax-input", mono ? "ax-input--mono" : "", error ? "ax-input--error" : "", className].filter(Boolean).join(" ");
63
64
  return /* @__PURE__ */ jsxs("label", { className: "ax-field", children: [
64
- label ? /* @__PURE__ */ jsx("span", { className: "ax-field__label", children: label }) : null,
65
- /* @__PURE__ */ jsx("input", { className: cls, ...rest }),
65
+ label ? /* @__PURE__ */ jsxs("span", { className: "ax-field__label", children: [
66
+ label,
67
+ required ? /* @__PURE__ */ jsx("span", { className: "ax-field__req", children: "*" }) : null
68
+ ] }) : null,
69
+ /* @__PURE__ */ jsx("input", { className: cls, required, ...rest }),
66
70
  error ? /* @__PURE__ */ jsx("span", { className: "ax-field__hint ax-field__hint--error", children: error }) : hint ? /* @__PURE__ */ jsx("span", { className: "ax-field__hint", children: hint }) : null
67
71
  ] });
68
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Input.js","sources":["../../../src/components/inputs/Input.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_FIELD_CSS = `\n.ax-field { display: flex; flex-direction: column; gap: 6px; }\n.ax-field__label {\n font-family: var(--font-mono); font-size: var(--text-xs);\n font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);\n text-transform: uppercase; color: var(--text-faint);\n}\n/* State priority is declared explicitly via layer order, low -> high.\n This frees each state rule from fighting specificity, so no :not() chains\n are needed and source order is no longer load-bearing. Add a new state by\n slotting a layer, not by patching every other rule. */\n@layer ax-base, ax-hover, ax-focus, ax-error, ax-disabled;\n\n@layer ax-base {\n .ax-input {\n height: 36px; padding: 0 12px; width: 100%;\n background: var(--surface-card); color: var(--text-body);\n border: 1px solid var(--border-default); border-radius: var(--radius-2);\n font-family: var(--font-body); font-size: var(--text-sm);\n transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out);\n }\n .ax-input::placeholder { color: var(--text-faint); }\n .ax-input--mono { font-family: var(--font-mono); }\n}\n@layer ax-hover {\n .ax-input:hover { border-color: var(--border-strong); }\n}\n@layer ax-focus {\n .ax-input:focus { outline: none; border-color: var(--fg-2); box-shadow: 0 0 0 3px var(--focus-soft); }\n}\n@layer ax-error {\n .ax-input--error { border-color: var(--danger); }\n .ax-input--error:focus { box-shadow: 0 0 0 3px var(--danger-dim); }\n}\n@layer ax-disabled {\n .ax-input:disabled { opacity: 0.4; cursor: not-allowed; border-color: var(--border-default); }\n}\n.ax-field__hint { font-size: var(--text-xs); color: var(--text-faint); }\n.ax-field__hint--error { color: var(--danger); }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-field-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-field-css\";\n s.textContent = AX_FIELD_CSS;\n document.head.appendChild(s);\n}\n\nexport function Input({\n label,\n hint,\n error,\n mono = false,\n className = \"\",\n ...rest\n}) {\n const cls = [\n \"ax-input\",\n mono ? \"ax-input--mono\" : \"\",\n error ? \"ax-input--error\" : \"\",\n className,\n ].filter(Boolean).join(\" \");\n return (\n <label className=\"ax-field\">\n {label ? <span className=\"ax-field__label\">{label}</span> : null}\n <input className={cls} {...rest} />\n {error ? <span className=\"ax-field__hint ax-field__hint--error\">{error}</span> :\n hint ? <span className=\"ax-field__hint\">{hint}</span> : null}\n </label>\n );\n}\n"],"names":[],"mappings":";;AAEA,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyCrB,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,cAAc,GAAG;AAC/E,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,GAAG;AACL,GAAG;AACD,QAAM,MAAM;AAAA,IACV;AAAA,IACA,OAAO,mBAAmB;AAAA,IAC1B,QAAQ,oBAAoB;AAAA,IAC5B;AAAA,EAAA,EACA,OAAO,OAAO,EAAE,KAAK,GAAG;AAC1B,SACE,qBAAC,SAAA,EAAM,WAAU,YACd,UAAA;AAAA,IAAA,QAAQ,oBAAC,QAAA,EAAK,WAAU,mBAAmB,iBAAM,IAAU;AAAA,IAC5D,oBAAC,SAAA,EAAM,WAAW,KAAM,GAAG,KAAA,CAAM;AAAA,IAChC,QAAQ,oBAAC,QAAA,EAAK,WAAU,wCAAwC,UAAA,MAAA,CAAM,IACrE,OAAO,oBAAC,QAAA,EAAK,WAAU,kBAAkB,gBAAK,IAAU;AAAA,EAAA,GAC5D;AAEJ;"}
1
+ {"version":3,"file":"Input.js","sources":["../../../src/components/inputs/Input.jsx"],"sourcesContent":["import React from \"react\";\n\nconst AX_FIELD_CSS = `\n.ax-field { display: flex; flex-direction: column; gap: 6px; }\n.ax-field__label {\n display: inline-flex; align-items: center; gap: 6px;\n font-family: var(--font-mono); font-size: var(--text-xs);\n font-weight: var(--weight-medium); letter-spacing: var(--tracking-label);\n text-transform: uppercase; color: var(--text-faint);\n}\n.ax-field__req { color: var(--danger); }\n/* State priority is declared explicitly via layer order, low -> high.\n This frees each state rule from fighting specificity, so no :not() chains\n are needed and source order is no longer load-bearing. Add a new state by\n slotting a layer, not by patching every other rule. */\n@layer ax-base, ax-hover, ax-focus, ax-error, ax-disabled;\n\n@layer ax-base {\n .ax-input {\n height: 36px; padding: 0 12px; width: 100%;\n background: var(--surface-card); color: var(--text-body);\n border: 1px solid var(--border-default); border-radius: var(--radius-2);\n font-family: var(--font-body); font-size: var(--text-sm);\n transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out);\n }\n .ax-input::placeholder { color: var(--text-faint); }\n .ax-input--mono { font-family: var(--font-mono); }\n}\n@layer ax-hover {\n .ax-input:hover { border-color: var(--border-strong); }\n}\n@layer ax-focus {\n .ax-input:focus { outline: none; border-color: var(--fg-2); box-shadow: 0 0 0 3px var(--focus-soft); }\n}\n@layer ax-error {\n /* Outline (not just border-color) so the error ring is robust: it survives\n overlay/instrumentation layers that repaint control borders, and never\n shifts layout. Offset -1px parks it exactly on the border edge. */\n .ax-input--error { border-color: var(--danger); outline: 1px solid var(--danger); outline-offset: -1px; }\n .ax-input--error:focus { box-shadow: 0 0 0 3px var(--danger-dim); outline-color: var(--danger); }\n}\n@layer ax-disabled {\n .ax-input:disabled { opacity: 0.4; cursor: not-allowed; border-color: var(--border-default); }\n}\n.ax-field__hint { font-size: var(--text-xs); color: var(--text-faint); }\n.ax-field__hint--error { color: var(--danger); }\n`;\n\nif (typeof document !== \"undefined\" && !document.getElementById(\"ax-field-css\")) {\n const s = document.createElement(\"style\");\n s.id = \"ax-field-css\";\n s.textContent = AX_FIELD_CSS;\n document.head.appendChild(s);\n}\n\nexport function Input({\n label,\n hint,\n error,\n required = false,\n mono = false,\n className = \"\",\n ...rest\n}) {\n const cls = [\"ax-input\", mono ? \"ax-input--mono\" : \"\", error ? \"ax-input--error\" : \"\", className]\n .filter(Boolean)\n .join(\" \");\n return (\n <label className=\"ax-field\">\n {label ? (\n <span className=\"ax-field__label\">\n {label}\n {required ? <span className=\"ax-field__req\">*</span> : null}\n </span>\n ) : null}\n <input className={cls} required={required} {...rest} />\n {error ? (\n <span className=\"ax-field__hint ax-field__hint--error\">{error}</span>\n ) : hint ? (\n <span className=\"ax-field__hint\">{hint}</span>\n ) : null}\n </label>\n );\n}\n"],"names":[],"mappings":";;AAEA,MAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8CrB,IAAI,OAAO,aAAa,eAAe,CAAC,SAAS,eAAe,cAAc,GAAG;AAC/E,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEO,SAAS,MAAM;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,GAAG;AACL,GAAG;AACD,QAAM,MAAM,CAAC,YAAY,OAAO,mBAAmB,IAAI,QAAQ,oBAAoB,IAAI,SAAS,EAC7F,OAAO,OAAO,EACd,KAAK,GAAG;AACX,SACE,qBAAC,SAAA,EAAM,WAAU,YACd,UAAA;AAAA,IAAA,QACC,qBAAC,QAAA,EAAK,WAAU,mBACb,UAAA;AAAA,MAAA;AAAA,MACA,WAAW,oBAAC,QAAA,EAAK,WAAU,iBAAgB,eAAC,IAAU;AAAA,IAAA,EAAA,CACzD,IACE;AAAA,wBACH,SAAA,EAAM,WAAW,KAAK,UAAqB,GAAG,MAAM;AAAA,IACpD,QACC,oBAAC,QAAA,EAAK,WAAU,wCAAwC,UAAA,MAAA,CAAM,IAC5D,OACF,oBAAC,QAAA,EAAK,WAAU,kBAAkB,gBAAK,IACrC;AAAA,EAAA,GACN;AAEJ;"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Masked credential input with show/hide toggle. Mono by default (keys read
3
+ * better in mono). Pairs with a mono ALL-CAPS label and an optional hint /
4
+ * error line. Built on the bundle's `.ax-input`.
5
+ */
6
+ export interface SecretFieldProps {
7
+ /** Mono ALL-CAPS label above the field. */
8
+ label?: string;
9
+ value: string;
10
+ onChange?: (value: string) => void;
11
+ placeholder?: string;
12
+ /** Helper line below the field (hidden when `error` is set). */
13
+ hint?: React.ReactNode;
14
+ /** Error line below the field; also flags the input red. */
15
+ error?: string;
16
+ /** Mono input font. @default true */
17
+ mono?: boolean;
18
+ /** @default "off" */
19
+ autoComplete?: string;
20
+ }
21
+ export declare function SecretField(props: SecretFieldProps): JSX.Element;