fluid-primitives 0.19.0 → 0.19.1-next.17.ea6daa2

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 (42) hide show
  1. package/dist/{Client-C51NSHxg.js → Client-DAEIDEy9.js} +1 -1
  2. package/dist/accordion.d.ts +1 -1
  3. package/dist/accordion.js +1 -1
  4. package/dist/checkbox-group.d.ts +2 -2
  5. package/dist/checkbox-group.js +2 -2
  6. package/dist/checkbox.d.ts +1 -1
  7. package/dist/checkbox.js +2 -2
  8. package/dist/client.d.ts +1 -1
  9. package/dist/client.js +1 -1
  10. package/dist/clipboard.d.ts +1 -1
  11. package/dist/clipboard.js +1 -1
  12. package/dist/collapsible.d.ts +1 -1
  13. package/dist/collapsible.js +1 -1
  14. package/dist/dialog.d.ts +1 -1
  15. package/dist/dialog.js +1 -1
  16. package/dist/field.d.ts +2 -2
  17. package/dist/field.dom-CtHP2v1P.js +25 -0
  18. package/dist/field.js +2 -2
  19. package/dist/form.d.ts +6 -2
  20. package/dist/form.js +135 -44
  21. package/dist/{form.registry-Cb8Pvoe8.d.ts → form.registry-QMa3fDPK.d.ts} +1 -1
  22. package/dist/{index-B8JCdyld.d.ts → index-DjXeW-h1.d.ts} +2 -2
  23. package/dist/navigation-menu.d.ts +1 -1
  24. package/dist/navigation-menu.js +1 -1
  25. package/dist/number-input.d.ts +1 -1
  26. package/dist/number-input.js +2 -2
  27. package/dist/popover.d.ts +1 -1
  28. package/dist/popover.js +1 -1
  29. package/dist/radio-group.d.ts +1 -1
  30. package/dist/radio-group.js +1 -1
  31. package/dist/scroll-area.d.ts +1 -1
  32. package/dist/scroll-area.js +1 -1
  33. package/dist/select.d.ts +1 -1
  34. package/dist/select.js +2 -2
  35. package/dist/switch.d.ts +1 -1
  36. package/dist/switch.js +2 -2
  37. package/dist/tabs.d.ts +1 -1
  38. package/dist/tabs.js +1 -1
  39. package/dist/tooltip.d.ts +1 -1
  40. package/dist/tooltip.js +1 -1
  41. package/package.json +1 -1
  42. package/dist/field.dom-CJQXpQbZ.js +0 -11
@@ -164,7 +164,7 @@ function mount(componentName, callback) {
164
164
  }
165
165
  function mountControlled(componentName, rootId, callback) {
166
166
  const hydrationData = getHydrationData(componentName, rootId);
167
- if (!hydrationData) return;
167
+ if (!hydrationData) return void 0;
168
168
  return callback({
169
169
  ...hydrationData,
170
170
  createHydrator: () => new ComponentHydrator(componentName, rootId, hydrationData.props.ids)
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as accordion from "@zag-js/accordion";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/accordion.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as accordion from "@zag-js/accordion";
3
3
 
4
4
  //#region Resources/Private/Primitives/Accordion/Accordion.ts
@@ -1,5 +1,5 @@
1
- import { a as Machine, u as FieldAwareComponent } from "./index-B8JCdyld.js";
2
- import { t as FieldMachine } from "./form.registry-Cb8Pvoe8.js";
1
+ import { a as Machine, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
+ import { t as FieldMachine } from "./form.registry-QMa3fDPK.js";
3
3
  import { EventObject } from "@zag-js/core";
4
4
  import { PropTypes } from "@zag-js/types";
5
5
 
@@ -1,6 +1,6 @@
1
- import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import { i as connect, n as registerCheckboxGroup, r as unregisterCheckboxGroup } from "./checkbox-group.registry-CGwuF7SF.js";
3
- import { a as getLabelId } from "./field.dom-CJQXpQbZ.js";
3
+ import { s as getLabelId } from "./field.dom-CtHP2v1P.js";
4
4
  import { createMachine } from "@zag-js/core";
5
5
 
6
6
  //#region Resources/Private/Primitives/CheckboxGroup/src/checkbox-group.machine.ts
@@ -1,4 +1,4 @@
1
- import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-B8JCdyld.js";
1
+ import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
2
  import * as checkbox from "@zag-js/checkbox";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/checkbox.js CHANGED
@@ -1,6 +1,6 @@
1
- import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import { i as connect, t as getCheckboxGroupMachineFor } from "./checkbox-group.registry-CGwuF7SF.js";
3
- import { a as getLabelId, t as getControlId } from "./field.dom-CJQXpQbZ.js";
3
+ import { r as getControlId, s as getLabelId } from "./field.dom-CtHP2v1P.js";
4
4
  import * as checkbox from "@zag-js/checkbox";
5
5
 
6
6
  //#region Resources/Private/Primitives/Checkbox/Checkbox.ts
package/dist/client.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as Machine, c as mount, f as Component, h as FluidPrimitivesGlobals, i as mergeProps, l as mountControlled, m as ComponentInterface, n as spreadProps, o as ComponentHydrator, p as ComponentHydrationData, r as normalizeProps, s as getHydrationData, t as uid, u as FieldAwareComponent } from "./index-B8JCdyld.js";
1
+ import { a as Machine, c as mount, f as Component, h as FluidPrimitivesGlobals, i as mergeProps, l as mountControlled, m as ComponentInterface, n as spreadProps, o as ComponentHydrator, p as ComponentHydrationData, r as normalizeProps, s as getHydrationData, t as uid, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
2
  export { Component, ComponentHydrationData, ComponentHydrator, ComponentInterface, FieldAwareComponent, FluidPrimitivesGlobals, Machine, getHydrationData, mergeProps, mount, mountControlled, normalizeProps, spreadProps, uid };
package/dist/client.js CHANGED
@@ -1,3 +1,3 @@
1
- import { a as Machine, d as FieldAwareComponent, i as mergeProps, l as mount, n as spreadProps, o as ComponentHydrator, p as Component, r as normalizeProps, s as getHydrationData, t as uid, u as mountControlled } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, d as FieldAwareComponent, i as mergeProps, l as mount, n as spreadProps, o as ComponentHydrator, p as Component, r as normalizeProps, s as getHydrationData, t as uid, u as mountControlled } from "./Client-DAEIDEy9.js";
2
2
 
3
3
  export { Component, ComponentHydrator, FieldAwareComponent, Machine, getHydrationData, mergeProps, mount, mountControlled, normalizeProps, spreadProps, uid };
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as clipboard from "@zag-js/clipboard";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/clipboard.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, i as mergeProps, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, i as mergeProps, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as clipboard from "@zag-js/clipboard";
3
3
 
4
4
  //#region Resources/Private/Primitives/Clipboard/Clipboard.ts
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as collapsible from "@zag-js/collapsible";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as collapsible from "@zag-js/collapsible";
3
3
 
4
4
  //#region Resources/Private/Primitives/Collapsible/Collapsible.ts
package/dist/dialog.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as dialog from "@zag-js/dialog";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/dialog.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as dialog from "@zag-js/dialog";
3
3
 
4
4
  //#region Resources/Private/Primitives/Dialog/Dialog.ts
package/dist/field.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
2
- import { n as FormMachine } from "./form.registry-Cb8Pvoe8.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
+ import { n as FormMachine } from "./form.registry-QMa3fDPK.js";
3
3
  import { EventObject } from "@zag-js/core";
4
4
  import { PropTypes } from "@zag-js/types";
5
5
 
@@ -0,0 +1,25 @@
1
+ //#region Resources/Private/Primitives/Field/src/field.dom.ts
2
+ const getRootId = (scope) => scope.ids?.root ?? `field:${scope.id}:root`;
3
+ const getLabelId = (scope) => scope.ids?.label ?? `field:${scope.id}:label`;
4
+ const getControlId = (scope) => scope.ids?.control ?? `field:${scope.id}:control`;
5
+ const getErrorId = (scope) => scope.ids?.error ?? `field:${scope.id}:error`;
6
+ const getDescriptionId = (scope) => scope.ids?.description ?? `field:${scope.id}:description`;
7
+ const getRootEl = (scope) => scope.getById(getRootId(scope));
8
+ const getDescriptionEl = (scope) => scope.getById(getDescriptionId(scope));
9
+ const getClosestFieldRoot = (target) => {
10
+ return target?.closest("[data-scope=\"field\"][data-part=\"root\"]") ?? null;
11
+ };
12
+ const getClosestFieldName = (target) => {
13
+ if (!target) return;
14
+ if ("name" in target && typeof target.name === "string" && target.name) return target.name;
15
+ return getClosestFieldRoot(target)?.getAttribute("data-name") || void 0;
16
+ };
17
+ const isFocusMovingWithinSameField = (target, relatedTarget) => {
18
+ if (!(relatedTarget instanceof Element)) return false;
19
+ const currentField = getClosestFieldRoot(target);
20
+ const nextField = getClosestFieldRoot(relatedTarget);
21
+ return !!currentField && currentField === nextField;
22
+ };
23
+
24
+ //#endregion
25
+ export { getDescriptionId as a, getRootEl as c, getDescriptionEl as i, getRootId as l, getClosestFieldRoot as n, getErrorId as o, getControlId as r, getLabelId as s, getClosestFieldName as t, isFocusMovingWithinSameField as u };
package/dist/field.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Machine, f as registerFieldMachine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
2
- import { a as getLabelId, i as getErrorId, n as getDescriptionEl, o as getRootEl, r as getDescriptionId, s as getRootId, t as getControlId } from "./field.dom-CJQXpQbZ.js";
1
+ import { a as Machine, f as registerFieldMachine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
+ import { a as getDescriptionId, c as getRootEl, i as getDescriptionEl, l as getRootId, o as getErrorId, r as getControlId, s as getLabelId } from "./field.dom-CtHP2v1P.js";
3
3
  import { n as getFormMachineFor, r as registerFieldMachineForForm } from "./form.registry-CmpTny_s.js";
4
4
  import { createMachine } from "@zag-js/core";
5
5
  import { createAnatomy } from "@zag-js/anatomy";
package/dist/form.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
2
- import { t as FieldMachine } from "./form.registry-Cb8Pvoe8.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
+ import { t as FieldMachine } from "./form.registry-QMa3fDPK.js";
3
3
  import { EventObject } from "@zag-js/core";
4
4
  import * as z from "zod";
5
5
  import { JSX, PropTypes } from "@zag-js/types";
@@ -48,6 +48,10 @@ interface FormSchema {
48
48
  dirty: FormDirty;
49
49
  touched: FormTouched;
50
50
  };
51
+ refs: {
52
+ submitCount: number;
53
+ serverErrors: FormErrors;
54
+ };
51
55
  state: 'invalid' | 'ready' | 'submitting' | 'success' | 'error';
52
56
  event: EventObject;
53
57
  action: string;
package/dist/form.js CHANGED
@@ -1,4 +1,5 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
+ import { n as getClosestFieldRoot, t as getClosestFieldName, u as isFocusMovingWithinSameField } from "./field.dom-CtHP2v1P.js";
2
3
  import { i as registerFormMachine, t as getFieldMachinesFor } from "./form.registry-CmpTny_s.js";
3
4
  import { debounce } from "@zag-js/utils";
4
5
  import { createMachine } from "@zag-js/core";
@@ -86,8 +87,9 @@ function connect(service, normalize) {
86
87
  "data-invalid": isInvalid ? "" : void 0,
87
88
  "data-dirty": isDirty ? "" : void 0,
88
89
  "data-touched": isTouched ? "" : void 0,
89
- onSubmit: async (event) => {
90
+ onSubmit: (event) => {
90
91
  event.preventDefault();
92
+ if (isSubmitting) return;
91
93
  const form = event.currentTarget;
92
94
  context.set("values", new FormData(form));
93
95
  send({
@@ -111,7 +113,18 @@ function connect(service, normalize) {
111
113
  const target = event.target;
112
114
  if (!(target instanceof HTMLInputElement) && !(target instanceof HTMLTextAreaElement) && !(target instanceof HTMLSelectElement) && !(target instanceof HTMLButtonElement && target.getAttribute("data-scope") === "select")) return;
113
115
  send({
114
- type: "BLUR",
116
+ type: "FIELD_BLUR",
117
+ detail: {
118
+ target,
119
+ relatedTarget: event.relatedTarget
120
+ }
121
+ });
122
+ },
123
+ onFocus: (event) => {
124
+ const target = event.target;
125
+ if (!getClosestFieldRoot(target)) return;
126
+ send({
127
+ type: "FIELD_FOCUS",
115
128
  detail: { target }
116
129
  });
117
130
  }
@@ -147,7 +160,7 @@ function validateWithSchema(schema, formData) {
147
160
  if (!flat[key]) continue;
148
161
  errors[key] = {
149
162
  messages: flat[key],
150
- value: getFormDataValue(formData, key)
163
+ value: getFieldValue(formData, key)
151
164
  };
152
165
  }
153
166
  return errors;
@@ -159,11 +172,57 @@ function errorsFromServer(responseErrors, objectName, formData) {
159
172
  if (objectName) newKey = newKey.replace(objectName + ".", "");
160
173
  out[newKey] = {
161
174
  messages: responseErrors[key],
162
- value: getFormDataValue(formData, newKey)
175
+ value: getFieldValue(formData, newKey)
163
176
  };
164
177
  }
165
178
  return out;
166
179
  }
180
+ function normalizeFieldName(fieldName) {
181
+ return fieldName.replace(/\[\]$/, "");
182
+ }
183
+ function withCurrentValues(errors, formData) {
184
+ return Object.fromEntries(Object.entries(errors).map(([fieldName, error]) => [normalizeFieldName(fieldName), {
185
+ ...error,
186
+ value: error.value ?? getFieldValue(formData, fieldName)
187
+ }]));
188
+ }
189
+ function getErrorsForCurrentValues(serverErrors, formData) {
190
+ const errors = {};
191
+ for (const fieldName in serverErrors) {
192
+ const error = getErrorForValue(serverErrors, fieldName, getFieldValue(formData, fieldName));
193
+ if (error) errors[fieldName] = error;
194
+ }
195
+ return errors;
196
+ }
197
+ function getErrorForValue(errors, fieldName, currentValue) {
198
+ const error = errors[normalizeFieldName(fieldName)];
199
+ if (!error || error.value === void 0) return;
200
+ return serializeFieldValue(currentValue) === serializeFieldValue(error.value) ? error : void 0;
201
+ }
202
+ function getFieldValue(formData, fieldName) {
203
+ const normalizedFieldName = normalizeFieldName(fieldName);
204
+ const arrayEntries = formData.getAll(`${normalizedFieldName}[]`);
205
+ const values = formData.getAll(normalizedFieldName);
206
+ const entries = values.length > 0 ? values : arrayEntries;
207
+ if (fieldName.endsWith("[]") || arrayEntries.length > 0 || entries.length > 1) return entries;
208
+ return entries[0] ?? null;
209
+ }
210
+ function getFieldElement(form, fieldName) {
211
+ return form.querySelector(`[name="${CSS.escape(fieldName)}"], [name="${CSS.escape(fieldName)}[]"]`);
212
+ }
213
+ function serializeFieldValue(value) {
214
+ return JSON.stringify(toSerializableFieldValue(value));
215
+ }
216
+ function toSerializableFieldValue(value) {
217
+ if (Array.isArray(value)) return value.map(toSerializableFieldValue);
218
+ if (value instanceof File) return {
219
+ name: value.name,
220
+ size: value.size,
221
+ type: value.type,
222
+ lastModified: value.lastModified
223
+ };
224
+ return value;
225
+ }
167
226
  function getInputValue(target) {
168
227
  const el = target;
169
228
  if (!el || !("type" in el)) return void 0;
@@ -191,11 +250,9 @@ function getInputValue(target) {
191
250
  if (el instanceof HTMLSelectElement && el.multiple) return Array.from(el.selectedOptions).map((o) => o.value);
192
251
  return el.value;
193
252
  }
194
- function getFormDataValue(formData, fieldName) {
195
- return formData.getAll(fieldName).length > 1 || fieldName.endsWith("[]") ? formData.getAll(fieldName) : formData.get(fieldName);
196
- }
197
253
  function formDataToObject(formData) {
198
- return Object.fromEntries(Array.from(formData.keys()).map((key) => [key.endsWith("[]") ? key.slice(0, -2) : key, getFormDataValue(formData, key) ?? ""]));
254
+ const fieldNames = new Set(Array.from(formData.keys(), normalizeFieldName));
255
+ return Object.fromEntries(Array.from(fieldNames, (fieldName) => [fieldName, getFieldValue(formData, fieldName) ?? ""]));
199
256
  }
200
257
  function prefixFieldName(fieldName, prefix, objectName) {
201
258
  if (fieldName === "") return "";
@@ -224,6 +281,12 @@ const machine = createMachine({
224
281
  touched: bindable(() => ({ defaultValue: {} }))
225
282
  };
226
283
  },
284
+ refs() {
285
+ return {
286
+ submitCount: 0,
287
+ serverErrors: {}
288
+ };
289
+ },
227
290
  states: {
228
291
  ready: {},
229
292
  invalid: {},
@@ -240,7 +303,8 @@ const machine = createMachine({
240
303
  VALIDATE_FIELD: { actions: ["validateField"] },
241
304
  INVALID: { target: "invalid" },
242
305
  INPUT: { actions: ["handleInput"] },
243
- BLUR: { actions: ["handleBlur"] },
306
+ FIELD_FOCUS: { actions: ["handleFocus"] },
307
+ FIELD_BLUR: { actions: ["handleBlur"] },
244
308
  RESET: {
245
309
  target: "ready",
246
310
  actions: ["resetForm"]
@@ -253,17 +317,25 @@ const machine = createMachine({
253
317
  },
254
318
  entry: ["setupFormListeners"],
255
319
  implementations: { actions: {
256
- validateAll({ context, send, prop, state, action, event, scope }) {
320
+ validateAll({ context, send, prop, state, action, event, scope, refs }) {
257
321
  const submitting = state.matches("submitting");
258
322
  const schema = prop("schema");
259
- if (schema) {
260
- const errs = validateWithSchema(schema, context.get("values"));
261
- context.set("errors", errs);
262
- if (Object.keys(errs).length > 0) {
263
- send({ type: "INVALID" });
264
- if (submitting) action(["focusFirstInvalid"]);
265
- return;
266
- }
323
+ const formData = context.get("values");
324
+ if (submitting) {
325
+ const submitCount = refs.get("submitCount");
326
+ refs.set("submitCount", submitCount + 1);
327
+ }
328
+ const cachedServerErrors = getErrorsForCurrentValues(refs.get("serverErrors"), formData);
329
+ let errs = cachedServerErrors;
330
+ if (schema) errs = {
331
+ ...cachedServerErrors,
332
+ ...validateWithSchema(schema, formData)
333
+ };
334
+ context.set("errors", errs);
335
+ if (Object.keys(errs).length > 0) {
336
+ send({ type: "INVALID" });
337
+ if (submitting) action(["focusFirstInvalid"]);
338
+ return;
267
339
  }
268
340
  if (!submitting) {
269
341
  state.set("ready");
@@ -302,7 +374,12 @@ const machine = createMachine({
302
374
  else send({ type: "ERROR" });
303
375
  } catch (error) {
304
376
  if (error instanceof ValidationError) {
305
- context.set("errors", error.errors);
377
+ const errors = withCurrentValues(error.errors, context.get("values"));
378
+ refs.set("serverErrors", {
379
+ ...refs.get("serverErrors"),
380
+ ...errors
381
+ });
382
+ context.set("errors", errors);
306
383
  send({ type: "INVALID" });
307
384
  action(["focusFirstInvalid"]);
308
385
  return;
@@ -311,24 +388,29 @@ const machine = createMachine({
311
388
  }
312
389
  })();
313
390
  },
314
- validateField({ context, prop, event }) {
315
- const schema = prop("schema");
316
- if (!schema) return;
317
- let fieldName = event.detail?.fieldName;
391
+ validateField({ context, prop, event, refs }) {
392
+ const fieldName = event.detail?.fieldName;
318
393
  if (!fieldName) return;
394
+ const normalizedFieldName = normalizeFieldName(fieldName);
319
395
  const formData = context.get("values");
320
396
  const currentErrors = context.get("errors");
321
- const existingError = currentErrors[fieldName];
322
- const currentValue = getFormDataValue(formData, fieldName);
323
- if (existingError) {
324
- const errorValue = existingError.value;
325
- if (JSON.stringify(currentValue) === JSON.stringify(errorValue)) return;
397
+ const currentValue = getFieldValue(formData, fieldName);
398
+ const updatedErrors = { ...currentErrors };
399
+ const serverError = getErrorForValue(refs.get("serverErrors"), normalizedFieldName, currentValue);
400
+ if (serverError) {
401
+ updatedErrors[normalizedFieldName] = serverError;
402
+ context.set("errors", updatedErrors);
403
+ return;
404
+ }
405
+ delete updatedErrors[normalizedFieldName];
406
+ const schema = prop("schema");
407
+ if (!schema) {
408
+ context.set("errors", updatedErrors);
409
+ return;
326
410
  }
327
411
  const allErrors = validateWithSchema(schema, formData);
328
- const updatedErrors = { ...currentErrors };
329
- const fieldNameWithoutSuffix = fieldName.replace(/\[\]$/, "");
330
- if (allErrors[fieldNameWithoutSuffix]) updatedErrors[fieldNameWithoutSuffix] = allErrors[fieldNameWithoutSuffix];
331
- else delete updatedErrors[fieldNameWithoutSuffix];
412
+ if (allErrors[normalizedFieldName]) updatedErrors[normalizedFieldName] = allErrors[normalizedFieldName];
413
+ else delete updatedErrors[normalizedFieldName];
332
414
  context.set("errors", updatedErrors);
333
415
  },
334
416
  handleInput({ context, event, send }) {
@@ -346,38 +428,46 @@ const machine = createMachine({
346
428
  context.set("dirty", dirty);
347
429
  const currentErrors = context.get("errors");
348
430
  const touched = context.get("touched");
349
- const hasFieldError = !!currentErrors[name];
350
- const fieldTouched = !!touched[name];
431
+ const normalizedName = normalizeFieldName(name);
432
+ const hasFieldError = !!currentErrors[normalizedName];
433
+ const fieldTouched = !!touched[normalizedName];
351
434
  if (hasFieldError || fieldTouched) send({
352
435
  type: "VALIDATE_FIELD",
353
436
  detail: { fieldName: name }
354
437
  });
355
438
  },
356
- handleBlur({ context, send, prop, event }) {
357
- const target = event?.detail?.target;
358
- let name = target?.name;
359
- if (!name) name = target?.closest("[data-scope=\"field\"]")?.getAttribute("name") || void 0;
439
+ handleFocus({ context, event }) {
440
+ const e = event;
441
+ const name = getClosestFieldName(e?.detail?.target ?? e?.target ?? e?.currentTarget);
360
442
  if (!name) return;
361
443
  const touched = { ...context.get("touched") };
362
- touched[name] = true;
444
+ touched[normalizeFieldName(name)] = true;
363
445
  context.set("touched", touched);
446
+ },
447
+ handleBlur({ context, send, prop, event }) {
448
+ const e = event;
449
+ const target = e?.detail?.target;
450
+ const name = getClosestFieldName(target);
451
+ if (!name) return;
364
452
  const form = target.form;
365
453
  if (form) {
366
454
  const values = new FormData(form);
367
455
  context.set("values", values);
368
456
  }
369
- if (prop("schema")) send({
457
+ if (isFocusMovingWithinSameField(target, e?.detail?.relatedTarget)) return;
458
+ if (prop("schema") || context.get("errors")[normalizeFieldName(name)]) send({
370
459
  type: "VALIDATE_FIELD",
371
460
  detail: { fieldName: name }
372
461
  });
373
462
  },
374
- resetForm({ context, scope, event }) {
463
+ resetForm({ context, scope, event, refs }) {
375
464
  const form = getFormEl(scope);
376
465
  if (form && !event?.detail?.omitManualReset) form.reset();
377
466
  const initial = form ? new FormData(form) : context.get("initialValues");
378
467
  context.set("values", initial);
379
468
  context.set("initialValues", initial);
380
469
  context.set("errors", {});
470
+ refs.set("serverErrors", {});
381
471
  context.set("touched", {});
382
472
  context.set("dirty", {});
383
473
  },
@@ -387,7 +477,7 @@ const machine = createMachine({
387
477
  if (!firstKey) return;
388
478
  const form = getFormEl(scope);
389
479
  if (!form) return;
390
- const invalidEl = form.querySelector(`[name="${CSS.escape(firstKey)}"]`);
480
+ const invalidEl = getFieldElement(form, firstKey);
391
481
  invalidEl?.focus();
392
482
  if (invalidEl instanceof HTMLInputElement || invalidEl instanceof HTMLTextAreaElement) invalidEl.select();
393
483
  },
@@ -401,8 +491,9 @@ const machine = createMachine({
401
491
  });
402
492
  }, true);
403
493
  },
404
- clearErrors({ context }) {
494
+ clearErrors({ context, refs }) {
405
495
  context.set("errors", {});
496
+ refs.set("serverErrors", {});
406
497
  context.set("touched", {});
407
498
  }
408
499
  } }
@@ -1,4 +1,4 @@
1
- import { a as Machine } from "./index-B8JCdyld.js";
1
+ import { a as Machine } from "./index-DjXeW-h1.js";
2
2
 
3
3
  //#region Resources/Private/Primitives/Form/src/form.registry.d.ts
4
4
  type FormMachine = Machine<any>;
@@ -91,9 +91,9 @@ declare function getHydrationData(component: string, id: string): ComponentHydra
91
91
  declare function mount(componentName: string, callback: (data: ComponentHydrationData & {
92
92
  createHydrator: () => ComponentHydrator;
93
93
  }) => Component<unknown, unknown> | void): void;
94
- declare function mountControlled(componentName: string, rootId: string, callback: (data: ComponentHydrationData & {
94
+ declare function mountControlled<T>(componentName: string, rootId: string, callback: (data: ComponentHydrationData & {
95
95
  createHydrator: () => ComponentHydrator;
96
- }) => Component<unknown, unknown> | void): void | Component<unknown, unknown>;
96
+ }) => T): T | undefined;
97
97
  declare class ComponentHydrator {
98
98
  componentName: string;
99
99
  doc: Document;
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as navigationMenu from "@zag-js/navigation-menu";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as navigationMenu from "@zag-js/navigation-menu";
3
3
 
4
4
  //#region Resources/Private/Primitives/NavigationMenu/NavigationMenu.ts
@@ -1,4 +1,4 @@
1
- import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-B8JCdyld.js";
1
+ import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
2
  import * as numberInput from "@zag-js/number-input";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
@@ -1,5 +1,5 @@
1
- import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-C51NSHxg.js";
2
- import { a as getLabelId, t as getControlId } from "./field.dom-CJQXpQbZ.js";
1
+ import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
+ import { r as getControlId, s as getLabelId } from "./field.dom-CtHP2v1P.js";
3
3
  import * as numberInput from "@zag-js/number-input";
4
4
 
5
5
  //#region Resources/Private/Primitives/NumberInput/NumberInput.ts
package/dist/popover.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as popover from "@zag-js/popover";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/popover.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, i as mergeProps, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, i as mergeProps, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as popover from "@zag-js/popover";
3
3
 
4
4
  //#region Resources/Private/Primitives/Popover/Popover.ts
@@ -1,4 +1,4 @@
1
- import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-B8JCdyld.js";
1
+ import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
2
  import * as radioGroup from "@zag-js/radio-group";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
@@ -1,4 +1,4 @@
1
- import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as radioGroup from "@zag-js/radio-group";
3
3
 
4
4
  //#region Resources/Private/Primitives/RadioGroup/RadioGroup.ts
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as scrollArea from "@zag-js/scroll-area";
3
3
  import { PropTypes } from "@zag-js/types";
4
4
 
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as scrollArea from "@zag-js/scroll-area";
3
3
 
4
4
  //#region Resources/Private/Primitives/ScrollArea/ScrollArea.ts
package/dist/select.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-B8JCdyld.js";
1
+ import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
2
  import * as _$_zag_js_collection0 from "@zag-js/collection";
3
3
  import * as select from "@zag-js/select";
4
4
  import * as _$_zag_js_types0 from "@zag-js/types";
package/dist/select.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Machine, c as getListCollectionFromHydrationData, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-C51NSHxg.js";
2
- import { a as getLabelId, t as getControlId } from "./field.dom-CJQXpQbZ.js";
1
+ import { a as Machine, c as getListCollectionFromHydrationData, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
+ import { r as getControlId, s as getLabelId } from "./field.dom-CtHP2v1P.js";
3
3
  import * as select from "@zag-js/select";
4
4
 
5
5
  //#region Resources/Private/Primitives/Select/Select.ts
package/dist/switch.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-B8JCdyld.js";
1
+ import { a as Machine, d as FieldMachine, u as FieldAwareComponent } from "./index-DjXeW-h1.js";
2
2
  import * as zagSwitch from "@zag-js/switch";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/switch.js CHANGED
@@ -1,5 +1,5 @@
1
- import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-C51NSHxg.js";
2
- import { a as getLabelId, t as getControlId } from "./field.dom-CJQXpQbZ.js";
1
+ import { a as Machine, d as FieldAwareComponent, i as mergeProps, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
+ import { r as getControlId, s as getLabelId } from "./field.dom-CtHP2v1P.js";
3
3
  import * as zagSwitch from "@zag-js/switch";
4
4
 
5
5
  //#region Resources/Private/Primitives/Switch/Switch.ts
package/dist/tabs.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as tabs from "@zag-js/tabs";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/tabs.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as tabs from "@zag-js/tabs";
3
3
 
4
4
  //#region Resources/Private/Primitives/Tabs/Tabs.ts
package/dist/tooltip.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
1
+ import { a as Machine, f as Component } from "./index-DjXeW-h1.js";
2
2
  import * as tooltip from "@zag-js/tooltip";
3
3
  import * as _$_zag_js_types0 from "@zag-js/types";
4
4
 
package/dist/tooltip.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as Machine, p as Component, r as normalizeProps } from "./Client-DAEIDEy9.js";
2
2
  import * as tooltip from "@zag-js/tooltip";
3
3
 
4
4
  //#region Resources/Private/Primitives/Tooltip/Tooltip.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluid-primitives",
3
- "version": "0.19.0",
3
+ "version": "0.19.1-next.17.ea6daa2",
4
4
  "description": "Client-side library for Fluid Primitives.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,11 +0,0 @@
1
- //#region Resources/Private/Primitives/Field/src/field.dom.ts
2
- const getRootId = (scope) => scope.ids?.root ?? `field:${scope.id}:root`;
3
- const getLabelId = (scope) => scope.ids?.label ?? `field:${scope.id}:label`;
4
- const getControlId = (scope) => scope.ids?.control ?? `field:${scope.id}:control`;
5
- const getErrorId = (scope) => scope.ids?.error ?? `field:${scope.id}:error`;
6
- const getDescriptionId = (scope) => scope.ids?.description ?? `field:${scope.id}:description`;
7
- const getRootEl = (scope) => scope.getById(getRootId(scope));
8
- const getDescriptionEl = (scope) => scope.getById(getDescriptionId(scope));
9
-
10
- //#endregion
11
- export { getLabelId as a, getErrorId as i, getDescriptionEl as n, getRootEl as o, getDescriptionId as r, getRootId as s, getControlId as t };