fluid-primitives 0.19.1 → 1.0.0-beta.1

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 (67) hide show
  1. package/README.md +9 -0
  2. package/dist/Client-HrMIqv7d.js +1934 -0
  3. package/dist/accordion.d.ts +2 -2
  4. package/dist/accordion.js +25 -29
  5. package/dist/button.d.ts +52 -0
  6. package/dist/button.js +135 -0
  7. package/dist/checkbox-group.d.ts +6 -5
  8. package/dist/checkbox-group.js +36 -20
  9. package/dist/{checkbox-group.registry-CGwuF7SF.js → checkbox-group.registry-D8P8A4LY.js} +13 -8
  10. package/dist/checkbox.d.ts +18 -4
  11. package/dist/checkbox.js +30 -27
  12. package/dist/client.d.ts +2 -2
  13. package/dist/client.js +2 -2
  14. package/dist/clipboard.d.ts +12 -5
  15. package/dist/clipboard.js +14 -16
  16. package/dist/collapsible.d.ts +3 -3
  17. package/dist/collapsible.js +13 -17
  18. package/dist/combobox.d.ts +37 -0
  19. package/dist/combobox.js +151 -0
  20. package/dist/date-picker.d.ts +67 -0
  21. package/dist/date-picker.js +289 -0
  22. package/dist/dialog.d.ts +3 -3
  23. package/dist/dialog.js +11 -12
  24. package/dist/field-array.d.ts +97 -0
  25. package/dist/field-array.js +223 -0
  26. package/dist/field.d.ts +30 -54
  27. package/dist/field.js +589 -175
  28. package/dist/fieldset.d.ts +15 -0
  29. package/dist/fieldset.js +27 -0
  30. package/dist/file-upload.d.ts +85 -0
  31. package/dist/file-upload.js +255 -0
  32. package/dist/form.d.ts +2 -83
  33. package/dist/form.fields-B58TZukv.js +329 -0
  34. package/dist/form.js +263 -276
  35. package/dist/index-B06gIN_k.d.ts +1358 -0
  36. package/dist/input.d.ts +96 -0
  37. package/dist/input.js +233 -0
  38. package/dist/menu.d.ts +55 -0
  39. package/dist/menu.js +144 -0
  40. package/dist/navigation-menu.d.ts +3 -3
  41. package/dist/navigation-menu.js +29 -43
  42. package/dist/number-input.d.ts +13 -4
  43. package/dist/number-input.js +30 -31
  44. package/dist/popover.d.ts +11 -3
  45. package/dist/popover.js +17 -18
  46. package/dist/radio-group.d.ts +4 -4
  47. package/dist/radio-group.js +35 -42
  48. package/dist/scroll-area.d.ts +3 -3
  49. package/dist/scroll-area.js +10 -9
  50. package/dist/select.d.ts +13 -51
  51. package/dist/select.js +62 -55
  52. package/dist/slider.d.ts +27 -0
  53. package/dist/slider.js +71 -0
  54. package/dist/switch.d.ts +4 -4
  55. package/dist/switch.js +24 -33
  56. package/dist/tabs.d.ts +3 -3
  57. package/dist/tabs.js +12 -15
  58. package/dist/textarea.d.ts +101 -0
  59. package/dist/textarea.js +231 -0
  60. package/dist/tooltip.d.ts +11 -3
  61. package/dist/tooltip.js +11 -10
  62. package/package.json +79 -24
  63. package/dist/Client-C51NSHxg.js +0 -248
  64. package/dist/field.dom-CJQXpQbZ.js +0 -11
  65. package/dist/form.registry-Cb8Pvoe8.d.ts +0 -7
  66. package/dist/form.registry-CmpTny_s.js +0 -51
  67. package/dist/index-B8JCdyld.d.ts +0 -118
@@ -0,0 +1,15 @@
1
+ import { c as Machine, z as Component } from "./index-B06gIN_k.js";
2
+ import * as _$_zag_js_types0 from "@zag-js/types";
3
+ import * as fieldset from "@zag-js/fieldset";
4
+
5
+ //#region Resources/Private/Primitives/Fieldset/Fieldset.d.ts
6
+ declare class Fieldset extends Component<fieldset.Props, fieldset.Api> {
7
+ static componentName: string;
8
+ initMachine(props: fieldset.Props): Machine<any>;
9
+ initApi(): fieldset.Api<_$_zag_js_types0.PropTypes<{
10
+ [x: string]: any;
11
+ }>>;
12
+ render(): void;
13
+ }
14
+ //#endregion
15
+ export { Fieldset };
@@ -0,0 +1,27 @@
1
+ import { a as normalizeProps, at as Machine, rt as Component } from "./Client-HrMIqv7d.js";
2
+ import * as fieldset from "@zag-js/fieldset";
3
+
4
+ //#region Resources/Private/Primitives/Fieldset/Fieldset.ts
5
+ var Fieldset = class extends Component {
6
+ static componentName = "fieldset";
7
+ initMachine(props) {
8
+ const [machineProps] = fieldset.splitProps(props);
9
+ return new Machine(fieldset.machine, machineProps);
10
+ }
11
+ initApi() {
12
+ return fieldset.connect(this.machine.service, normalizeProps);
13
+ }
14
+ render() {
15
+ const rootEl = this.hydrator.query("root");
16
+ if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
17
+ const legendEl = this.hydrator.query("legend");
18
+ if (legendEl) this.spreadProps(legendEl, this.api.getLegendProps());
19
+ const helperTextEl = this.hydrator.query("helperText");
20
+ if (helperTextEl) this.spreadProps(helperTextEl, this.api.getHelperTextProps());
21
+ const errorTextEl = this.hydrator.query("errorText");
22
+ if (errorTextEl) this.spreadProps(errorTextEl, this.api.getErrorTextProps());
23
+ }
24
+ };
25
+
26
+ //#endregion
27
+ export { Fieldset };
@@ -0,0 +1,85 @@
1
+ import { X as ConverterMachineProps, b as FieldClientApi, c as Machine, y as FieldAwareComponent } from "./index-B06gIN_k.js";
2
+ import * as _$_zag_js_types0 from "@zag-js/types";
3
+ import * as fileUpload from "@zag-js/file-upload";
4
+
5
+ //#region Resources/Private/Primitives/FileUpload/src/file-upload.translations.d.ts
6
+ /** The translations as PHP ships them: plain strings, `itemPreview` and `deleteFile` with a `%fileName%` placeholder. */
7
+ type FileUploadTranslationTexts = {
8
+ dropzone?: string;
9
+ itemPreview?: string;
10
+ deleteFile?: string;
11
+ };
12
+ //#endregion
13
+ //#region Resources/Private/Primitives/FileUpload/FileUpload.d.ts
14
+ declare const fileUploadPropConverters: {
15
+ accept: (accept: fileUpload.Props["accept"]) => Record<string, string[]> | fileUpload.FileMimeType | fileUpload.FileMimeType[] | undefined;
16
+ };
17
+ declare module 'fluid-primitives' {
18
+ interface HydrationPropsOverrides {
19
+ fileUpload: ConverterMachineProps<typeof fileUploadPropConverters>;
20
+ }
21
+ }
22
+ /**
23
+ * `existingFilesCount` is a plain integer (not a list of `File` objects) precisely so the already-
24
+ * persisted files it represents never enter the machine's own `acceptedFiles` - anything that does
25
+ * also ends up in the hidden input's `FileList` (via the machine's own `syncInputElement` action)
26
+ * and gets resubmitted on the next form post, which would silently overwrite an already-stored file
27
+ * with placeholder content reconstructed from just its name/size. Subtracting the count from
28
+ * `maxFiles` instead gets the same "remaining slots" UX (and the machine's own `TOO_MANY_FILES`
29
+ * rejection) without ever touching a real `File`.
30
+ */
31
+ type FileUploadPrimitiveProps = Omit<fileUpload.Props, 'translations'> & {
32
+ existingFilesCount?: number;
33
+ translations?: FileUploadTranslationTexts;
34
+ };
35
+ /**
36
+ * The stable, per-file identity stamped onto every rendered item's `data-value` (and folded into
37
+ * its `id`) - matches zag-js's own `getFileId` intent (`@zag-js/file-upload`), which does the same
38
+ * thing internally but isn't part of that package's public API (only its main entry and `./anatomy`
39
+ * are exported; the `.dom` module `getFileId` lives in isn't), and returns a hash rather than this
40
+ * plain, readable string. Exported so userland code can go from a rendered item's `data-value` back
41
+ * to the real `File` it represents (e.g. `acceptedFiles.find(f => fileValue(f) === value)`) without
42
+ * reimplementing this exact format - see the FileUpload "Custom Item Layout" docs example.
43
+ */
44
+ declare function fileValue(file: File): string;
45
+ declare class FileUpload extends FieldAwareComponent<FileUploadPrimitiveProps, fileUpload.Api> {
46
+ static componentName: string;
47
+ private previewCleanups;
48
+ private lastAcceptedFiles;
49
+ private lastRejectedFiles;
50
+ propsWithField(props: FileUploadPrimitiveProps, field: FieldClientApi): FileUploadPrimitiveProps;
51
+ initMachine(props: FileUploadPrimitiveProps): Machine<any>;
52
+ initApi(): fileUpload.Api<_$_zag_js_types0.PropTypes<{
53
+ [x: string]: any;
54
+ }>>;
55
+ render(): void;
56
+ private renderItemGroups;
57
+ /**
58
+ * An `itemGroup` is "empty" only once none of its items - machine-managed or existing - are
59
+ * visible, so an edit form pre-populated with existing files never shows the empty state
60
+ * underneath them.
61
+ */
62
+ private updateEmptyState;
63
+ /**
64
+ * Existing items carry their own `ui:fileUploadDeleteCheckbox` (unchecked, hidden) as a
65
+ * sibling of their `itemDeleteTrigger` button - not nested inside it, since a native `<button>`
66
+ * may not contain interactive descendants like `<input>`. Clicking the trigger checks that box
67
+ * (so the deletion is applied on the next form submission) and hides the item, mirroring how a
68
+ * machine-managed item disappears on delete. Wiring is idempotent so it's safe to call on every
69
+ * render.
70
+ */
71
+ private wireExistingItemDeleteTriggers;
72
+ /**
73
+ * `rejectedItemTemplate` is an optional second `ui:template`, letting a consumer author
74
+ * completely different markup for rejected items (e.g. no preview, shown in its own list below
75
+ * the accepted files) instead of reusing `itemTemplate` for both - see the "Custom Item Layout"
76
+ * docs example. Falls back to `itemTemplate` when it isn't present, so existing single-template
77
+ * consumers are unaffected.
78
+ */
79
+ private resolveItemTemplatePart;
80
+ private renderItems;
81
+ private renderPreview;
82
+ destroy(): void;
83
+ }
84
+ //#endregion
85
+ export { FileUpload, fileValue };
@@ -0,0 +1,255 @@
1
+ import { K as registerClientPropConverters, a as normalizeProps, at as Machine, n as Template, o as mergeProps, s as FieldAwareComponent } from "./Client-HrMIqv7d.js";
2
+ import * as fileUpload from "@zag-js/file-upload";
3
+ import { isValidFileType } from "@zag-js/file-utils";
4
+
5
+ //#region Resources/Private/Primitives/FileUpload/src/file-upload.translations.ts
6
+ const FILE_NAME_PLACEHOLDER = "%fileName%";
7
+ /**
8
+ * zag-js's `itemPreview`/`deleteFile` translations are functions (`(file: File) => string`) that
9
+ * interpolate the file's name - but Fluid has no callbacks to hand over, and the actual `File` only
10
+ * ever exists in the browser anyway. `FileUploadContext::getTranslations()` therefore translates
11
+ * them as plain strings containing a literal `%fileName%` placeholder (not `{fileName}` - Fluid's
12
+ * own inline array/object syntax already treats a bare `{...}` inside a string as a nested variable
13
+ * expression, so a curly-brace placeholder breaks the moment someone overrides `translations` from a
14
+ * template); this wraps such a string into the function zag-js actually expects, substituting the
15
+ * placeholder per file. An entry that is not a string is left to Zag's default.
16
+ */
17
+ function resolveTranslations(translations) {
18
+ if (!translations) return void 0;
19
+ const resolved = {};
20
+ for (const [key, text] of Object.entries(translations)) {
21
+ if (typeof text !== "string") continue;
22
+ resolved[key] = key === "itemPreview" || key === "deleteFile" ? (file) => text.replaceAll(FILE_NAME_PLACEHOLDER, file.name) : text;
23
+ }
24
+ return resolved;
25
+ }
26
+
27
+ //#endregion
28
+ //#region Resources/Private/Primitives/FileUpload/FileUpload.ts
29
+ registerClientPropConverters("fileUpload", { accept: (accept) => accept });
30
+ function resolveMaxFiles(props) {
31
+ const existingFilesCount = props.existingFilesCount ?? 0;
32
+ if (existingFilesCount <= 0 || typeof props.maxFiles !== "number") return props.maxFiles;
33
+ return Math.max(0, props.maxFiles - existingFilesCount);
34
+ }
35
+ /**
36
+ * The stable, per-file identity stamped onto every rendered item's `data-value` (and folded into
37
+ * its `id`) - matches zag-js's own `getFileId` intent (`@zag-js/file-upload`), which does the same
38
+ * thing internally but isn't part of that package's public API (only its main entry and `./anatomy`
39
+ * are exported; the `.dom` module `getFileId` lives in isn't), and returns a hash rather than this
40
+ * plain, readable string. Exported so userland code can go from a rendered item's `data-value` back
41
+ * to the real `File` it represents (e.g. `acceptedFiles.find(f => fileValue(f) === value)`) without
42
+ * reimplementing this exact format - see the FileUpload "Custom Item Layout" docs example.
43
+ */
44
+ function fileValue(file) {
45
+ return `${file.name}-${file.size}`;
46
+ }
47
+ /**
48
+ * Whether `file` should use the `itemPreview` variant tagged with `pattern` (e.g. `image/*` or
49
+ * `.pdf`). `.*`/`*`/empty are our own catch-all sentinel for a fallback variant - zag-js's own
50
+ * `isValidFileType` (`@zag-js/file-utils`) has no such "match everything" concept (a leading-dot
51
+ * pattern there means a literal file extension), so that case is handled before delegating.
52
+ * Otherwise reuses `isValidFileType`'s own accept-string matching (wildcard MIME types, exact MIME
53
+ * types, and file extensions) instead of re-implementing it.
54
+ */
55
+ function matchesFileType(pattern, file) {
56
+ if (!pattern || pattern === ".*" || pattern === "*") return true;
57
+ return isValidFileType(file, pattern)[0];
58
+ }
59
+ function fileExtension(fileName) {
60
+ const dotIndex = fileName.lastIndexOf(".");
61
+ return dotIndex === -1 ? "" : fileName.slice(dotIndex + 1).toUpperCase();
62
+ }
63
+ var FileUpload = class extends FieldAwareComponent {
64
+ static componentName = "fileUpload";
65
+ previewCleanups = /* @__PURE__ */ new Map();
66
+ lastAcceptedFiles = null;
67
+ lastRejectedFiles = null;
68
+ propsWithField(props, field) {
69
+ return {
70
+ ...props,
71
+ disabled: props.disabled ?? field.disabled,
72
+ readOnly: props.readOnly ?? field.readOnly,
73
+ required: props.required ?? field.required,
74
+ invalid: props.invalid ?? field.invalid,
75
+ name: props.name ?? field.name
76
+ };
77
+ }
78
+ initMachine(props) {
79
+ props = this.withFieldProps(props);
80
+ const { translations, ...rest } = props;
81
+ const [machineProps] = fileUpload.splitProps(rest);
82
+ return new Machine(fileUpload.machine, {
83
+ ...machineProps,
84
+ maxFiles: resolveMaxFiles(props),
85
+ translations: resolveTranslations(translations)
86
+ });
87
+ }
88
+ initApi() {
89
+ return fileUpload.connect(this.machine.service, normalizeProps);
90
+ }
91
+ render() {
92
+ this.subscribeToFieldService();
93
+ const rootEl = this.hydrator.query("root");
94
+ if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
95
+ const labelEl = this.hydrator.query("label");
96
+ if (labelEl) this.spreadProps(labelEl, this.api.getLabelProps());
97
+ const fieldDescribedBy = { "aria-describedby": this.field?.ariaDescribedby };
98
+ const dropzoneEl = this.hydrator.query("dropzone");
99
+ if (dropzoneEl) this.spreadProps(dropzoneEl, mergeProps(this.api.getDropzoneProps(), fieldDescribedBy));
100
+ const triggerEl = this.hydrator.query("trigger");
101
+ if (triggerEl) this.spreadProps(triggerEl, mergeProps(this.api.getTriggerProps(), fieldDescribedBy));
102
+ const hiddenInputEl = this.hydrator.query("hiddenInput");
103
+ if (hiddenInputEl) this.spreadProps(hiddenInputEl, this.api.getHiddenInputProps());
104
+ const clearTriggerEl = this.hydrator.query("clearTrigger");
105
+ if (clearTriggerEl) this.spreadProps(clearTriggerEl, this.api.getClearTriggerProps());
106
+ this.renderItemGroups();
107
+ }
108
+ renderItemGroups() {
109
+ const acceptedFiles = this.api.acceptedFiles;
110
+ const rejectedFiles = this.api.rejectedFiles;
111
+ const filesChanged = acceptedFiles !== this.lastAcceptedFiles || rejectedFiles !== this.lastRejectedFiles;
112
+ this.hydrator.queryAll("itemGroup").forEach((itemGroupEl) => {
113
+ const type = itemGroupEl.dataset.value || "accepted";
114
+ this.spreadProps(itemGroupEl, this.api.getItemGroupProps({ type }));
115
+ this.wireExistingItemDeleteTriggers(itemGroupEl);
116
+ if (filesChanged) {
117
+ const entries = type === "rejected" ? rejectedFiles.map(({ file, errors }) => ({
118
+ file,
119
+ type,
120
+ errors
121
+ })) : acceptedFiles.map((file) => ({
122
+ file,
123
+ type
124
+ }));
125
+ this.renderItems(itemGroupEl, entries, type);
126
+ }
127
+ this.updateEmptyState(itemGroupEl);
128
+ });
129
+ this.lastAcceptedFiles = acceptedFiles;
130
+ this.lastRejectedFiles = rejectedFiles;
131
+ }
132
+ /**
133
+ * An `itemGroup` is "empty" only once none of its items - machine-managed or existing - are
134
+ * visible, so an edit form pre-populated with existing files never shows the empty state
135
+ * underneath them.
136
+ */
137
+ updateEmptyState(itemGroupEl) {
138
+ const emptyStateEl = this.hydrator.query("emptyState", itemGroupEl);
139
+ if (!emptyStateEl) return;
140
+ emptyStateEl.hidden = this.hydrator.queryAll("item", itemGroupEl).some((el) => !el.hidden);
141
+ }
142
+ /**
143
+ * Existing items carry their own `ui:fileUploadDeleteCheckbox` (unchecked, hidden) as a
144
+ * sibling of their `itemDeleteTrigger` button - not nested inside it, since a native `<button>`
145
+ * may not contain interactive descendants like `<input>`. Clicking the trigger checks that box
146
+ * (so the deletion is applied on the next form submission) and hides the item, mirroring how a
147
+ * machine-managed item disappears on delete. Wiring is idempotent so it's safe to call on every
148
+ * render.
149
+ */
150
+ wireExistingItemDeleteTriggers(itemGroupEl) {
151
+ this.hydrator.queryAll("item", itemGroupEl).filter((el) => el.dataset.type === "existing" && !el.dataset.fileUploadWired).forEach((itemEl) => {
152
+ itemEl.dataset.fileUploadWired = "true";
153
+ const checkboxEl = itemEl.querySelector("input[type=\"checkbox\"]");
154
+ const deleteTriggerEl = this.hydrator.query("itemDeleteTrigger", itemEl);
155
+ if (!checkboxEl || !deleteTriggerEl) return;
156
+ deleteTriggerEl.addEventListener("click", () => {
157
+ if (this.api.disabled || this.api.readOnly) return;
158
+ checkboxEl.checked = true;
159
+ itemEl.hidden = true;
160
+ this.updateEmptyState(itemGroupEl);
161
+ });
162
+ });
163
+ }
164
+ /**
165
+ * `rejectedItemTemplate` is an optional second `ui:template`, letting a consumer author
166
+ * completely different markup for rejected items (e.g. no preview, shown in its own list below
167
+ * the accepted files) instead of reusing `itemTemplate` for both - see the "Custom Item Layout"
168
+ * docs example. Falls back to `itemTemplate` when it isn't present, so existing single-template
169
+ * consumers are unaffected.
170
+ */
171
+ resolveItemTemplatePart(type) {
172
+ if (type === "rejected" && this.hydrator.query("rejectedItemTemplate")) return "rejectedItemTemplate";
173
+ return "itemTemplate";
174
+ }
175
+ renderItems(itemGroupEl, entries, type) {
176
+ this.hydrator.queryAll("item", itemGroupEl).filter((el) => el.dataset.type !== "existing").forEach((el) => {
177
+ this.previewCleanups.get(el)?.();
178
+ this.previewCleanups.delete(el);
179
+ el.remove();
180
+ });
181
+ const templatePart = this.resolveItemTemplatePart(type);
182
+ entries.forEach(({ file, type, errors }) => {
183
+ const instance = new Template(this.hydrator, templatePart, { value: fileValue(file) });
184
+ const itemEl = instance.root;
185
+ this.spreadProps(itemEl, this.api.getItemProps({
186
+ file,
187
+ type
188
+ }));
189
+ const errorEl = instance.query("itemError");
190
+ if (errorEl) {
191
+ errorEl.hidden = !errors?.length;
192
+ errorEl.textContent = errors?.join(", ") ?? "";
193
+ }
194
+ const nameEl = instance.query("itemName");
195
+ if (nameEl) {
196
+ this.spreadProps(nameEl, this.api.getItemNameProps({
197
+ file,
198
+ type
199
+ }));
200
+ nameEl.textContent = file.name;
201
+ }
202
+ const sizeEl = instance.query("itemSizeText");
203
+ if (sizeEl) {
204
+ this.spreadProps(sizeEl, this.api.getItemSizeTextProps({
205
+ file,
206
+ type
207
+ }));
208
+ sizeEl.textContent = this.api.getFileSize(file);
209
+ }
210
+ this.renderPreview(instance, file, type);
211
+ const deleteTriggerEl = instance.query("itemDeleteTrigger");
212
+ if (deleteTriggerEl) this.spreadProps(deleteTriggerEl, this.api.getItemDeleteTriggerProps({
213
+ file,
214
+ type
215
+ }));
216
+ itemGroupEl.appendChild(instance);
217
+ });
218
+ }
219
+ renderPreview(instance, file, type) {
220
+ const previews = instance.queryAll("itemPreview");
221
+ if (previews.length === 0) return;
222
+ const matched = previews.find((el) => matchesFileType(el.dataset.match, file)) ?? previews[previews.length - 1];
223
+ previews.forEach((el) => {
224
+ if (el !== matched) {
225
+ el.remove();
226
+ return;
227
+ }
228
+ this.spreadProps(el, this.api.getItemPreviewProps({
229
+ file,
230
+ type
231
+ }));
232
+ const fallbackEl = this.hydrator.query("itemPreviewFallback", el);
233
+ if (fallbackEl) fallbackEl.textContent = fileExtension(file.name);
234
+ });
235
+ if (!matched) return;
236
+ const imageEl = this.hydrator.query("itemPreviewImage", matched);
237
+ if (!imageEl || !file.type.startsWith("image/")) return;
238
+ const cleanup = this.api.createFileUrl(file, (url) => {
239
+ this.spreadProps(imageEl, this.api.getItemPreviewImageProps({
240
+ file,
241
+ url,
242
+ type
243
+ }));
244
+ });
245
+ this.previewCleanups.set(matched, cleanup);
246
+ }
247
+ destroy() {
248
+ this.previewCleanups.forEach((cleanup) => cleanup());
249
+ this.previewCleanups.clear();
250
+ super.destroy();
251
+ }
252
+ };
253
+
254
+ //#endregion
255
+ export { FileUpload, fileValue };
package/dist/form.d.ts CHANGED
@@ -1,83 +1,2 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
2
- import { t as FieldMachine } from "./form.registry-Cb8Pvoe8.js";
3
- import { EventObject } from "@zag-js/core";
4
- import * as z from "zod";
5
- import { JSX, PropTypes } from "@zag-js/types";
6
-
7
- //#region Resources/Private/Primitives/Form/src/form.types.d.ts
8
- interface FieldError {
9
- messages: string[];
10
- value?: FormDataEntryValue | FormDataEntryValue[] | null;
11
- }
12
- type FormErrors = Record<string, FieldError>;
13
- type FormDirty = Record<string, boolean>;
14
- type FormTouched = Record<string, boolean>;
15
- /**
16
- * Error thrown by post() when server returns 422 validation errors.
17
- * The machine catches this and transitions to 'invalid' state.
18
- */
19
- declare class ValidationError extends Error {
20
- errors: FormErrors;
21
- constructor(errors: FormErrors);
22
- }
23
- type ZodFormSchema = z.ZodObject | undefined;
24
- interface FormProps {
25
- id: string;
26
- schema?: ZodFormSchema;
27
- objectName?: string;
28
- inputDebounceMs?: number;
29
- onSubmit?: ({
30
- formData,
31
- api,
32
- event,
33
- post
34
- }: {
35
- formData: FormData;
36
- api: FormApi;
37
- event: JSX.FormEvent<HTMLElement>;
38
- post: (url: string, data: FormData) => Promise<Response>;
39
- }) => Promise<boolean> | boolean;
40
- render?: (form: Form) => void;
41
- }
42
- interface FormSchema {
43
- props: FormProps;
44
- context: {
45
- values: FormData;
46
- initialValues: FormData;
47
- errors: FormErrors;
48
- dirty: FormDirty;
49
- touched: FormTouched;
50
- };
51
- state: 'invalid' | 'ready' | 'submitting' | 'success' | 'error';
52
- event: EventObject;
53
- action: string;
54
- effect: string;
55
- }
56
- interface FormApi {
57
- isSubmitting: boolean;
58
- isDirty: boolean;
59
- isInvalid: boolean;
60
- isSuccessful: boolean;
61
- isError: boolean;
62
- getFormProps(): PropTypes['element'];
63
- getValues(): FormData;
64
- getErrors(): FormErrors;
65
- getDirty(): FormDirty;
66
- getTouched(): FormTouched;
67
- _userRenderFn: FormProps['render'];
68
- getAllFields(): Map<string, FieldMachine>;
69
- getField(name: string): FieldMachine | undefined;
70
- getFormEl(): HTMLFormElement | null;
71
- getAction(): string;
72
- reset(): void;
73
- }
74
- //#endregion
75
- //#region Resources/Private/Primitives/Form/Form.d.ts
76
- declare class Form extends Component<FormProps, FormApi> {
77
- static name: string;
78
- initMachine(props: FormProps): Machine<FormSchema>;
79
- initApi(): FormApi;
80
- render(): void;
81
- }
82
- //#endregion
83
- export { Form, ValidationError };
1
+ import { A as FormValueTree, D as FormSubmitResult, E as FormProps, M as FormValuesObject, N as Form, O as FormValidation, T as FormErrors, j as FormValues, k as FormValueLeaf, w as FormApi } from "./index-B06gIN_k.js";
2
+ export { Form, FormApi, FormErrors, FormProps, FormSubmitResult, FormValidation, FormValueLeaf, FormValueTree, FormValues, FormValuesObject };