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
package/dist/clipboard.js CHANGED
@@ -1,34 +1,32 @@
1
- import { a as Machine, i as mergeProps, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as normalizeProps, at as Machine, o as mergeProps, rt as Component } from "./Client-HrMIqv7d.js";
2
2
  import * as clipboard from "@zag-js/clipboard";
3
3
 
4
4
  //#region Resources/Private/Primitives/Clipboard/Clipboard.ts
5
5
  var Clipboard = class extends Component {
6
- static name = "clipboard";
6
+ static componentName = "clipboard";
7
+ translations;
7
8
  initMachine(props) {
8
- return new Machine(clipboard.machine, {
9
- ...props,
10
- translations: void 0
11
- });
9
+ const { translations, ...rest } = props;
10
+ this.translations = translations;
11
+ const [machineProps] = clipboard.contextProps(rest);
12
+ return new Machine(clipboard.machine, machineProps);
12
13
  }
13
14
  initApi() {
14
15
  return clipboard.connect(this.machine.service, normalizeProps);
15
16
  }
16
17
  render() {
17
- const rootEl = this.getElement("root");
18
+ const rootEl = this.hydrator.query("root");
18
19
  if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
19
- const labelEl = this.getElement("label");
20
+ const labelEl = this.hydrator.query("label");
20
21
  if (labelEl) this.spreadProps(labelEl, this.api.getLabelProps());
21
- const controlEl = this.getElement("control");
22
+ const controlEl = this.hydrator.query("control");
22
23
  if (controlEl) this.spreadProps(controlEl, this.api.getControlProps());
23
- const inputEl = this.getElement("input");
24
+ const inputEl = this.hydrator.query("input");
24
25
  if (inputEl) this.spreadProps(inputEl, this.api.getInputProps());
25
- const indicatorCopiedEl = this.getElement("indicator-copied");
26
- if (indicatorCopiedEl) this.spreadProps(indicatorCopiedEl, this.api.getIndicatorProps({ copied: true }));
27
- const indicatorIdleEl = this.getElement("indicator-idle");
28
- if (indicatorIdleEl) this.spreadProps(indicatorIdleEl, this.api.getIndicatorProps({ copied: false }));
29
- const triggerEl = this.getElement("trigger");
26
+ this.spreadPropsByValue("indicator", ({ value }) => this.api.getIndicatorProps({ copied: value === "copied" }));
27
+ const triggerEl = this.hydrator.query("trigger");
30
28
  if (triggerEl) {
31
- const translations = this.userProps?.translations;
29
+ const translations = this.translations;
32
30
  const mergedProps = mergeProps(this.api.getTriggerProps(), { "aria-label": this.api.copied ? translations?.triggerLabelCopied || null : translations?.triggerLabelIdle || null });
33
31
  this.spreadProps(triggerEl, mergedProps);
34
32
  }
@@ -1,10 +1,10 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
2
- import * as collapsible from "@zag-js/collapsible";
1
+ import { c as Machine, z as Component } from "./index-B06gIN_k.js";
3
2
  import * as _$_zag_js_types0 from "@zag-js/types";
3
+ import * as collapsible from "@zag-js/collapsible";
4
4
 
5
5
  //#region Resources/Private/Primitives/Collapsible/Collapsible.d.ts
6
6
  declare class Collapsible extends Component<collapsible.Props, collapsible.Api> {
7
- static name: string;
7
+ static componentName: string;
8
8
  initMachine(props: collapsible.Props): Machine<any>;
9
9
  initApi(): collapsible.Api<_$_zag_js_types0.PropTypes<{
10
10
  [x: string]: any;
@@ -1,34 +1,30 @@
1
- import { a as Machine, p as Component, r as normalizeProps } from "./Client-C51NSHxg.js";
1
+ import { a as normalizeProps, at as Machine, rt as Component } from "./Client-HrMIqv7d.js";
2
2
  import * as collapsible from "@zag-js/collapsible";
3
3
 
4
4
  //#region Resources/Private/Primitives/Collapsible/Collapsible.ts
5
5
  var Collapsible = class extends Component {
6
- static name = "collapsible";
6
+ static componentName = "collapsible";
7
7
  initMachine(props) {
8
- return new Machine(collapsible.machine, props);
8
+ const [machineProps] = collapsible.splitProps(props);
9
+ return new Machine(collapsible.machine, machineProps);
9
10
  }
10
11
  initApi() {
11
12
  return collapsible.connect(this.machine.service, normalizeProps);
12
13
  }
13
14
  render() {
14
- const rootEl = this.getElement("root");
15
+ const rootEl = this.hydrator.query("root");
15
16
  if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
16
- this.getElements("trigger").forEach((triggerEl) => {
17
+ this.hydrator.queryAll("trigger").forEach((triggerEl) => {
17
18
  this.spreadProps(triggerEl, this.api.getTriggerProps());
18
19
  });
19
- this.getElements("indicator-open").forEach((openIndicatorEl) => {
20
- this.spreadProps(openIndicatorEl, normalizeProps.element({
21
- hidden: !this.api.open,
22
- "data-state": "open"
23
- }));
20
+ this.spreadPropsByValue("indicator", ({ value }) => {
21
+ const isActive = value === "open" === this.api.open;
22
+ return normalizeProps.element({
23
+ hidden: isActive ? void 0 : true,
24
+ "data-state": value
25
+ });
24
26
  });
25
- this.getElements("indicator-closed").forEach((closedIndicatorEl) => {
26
- this.spreadProps(closedIndicatorEl, normalizeProps.element({
27
- hidden: this.api.open,
28
- "data-state": "closed"
29
- }));
30
- });
31
- const contentEl = this.getElement("content");
27
+ const contentEl = this.hydrator.query("content");
32
28
  if (contentEl) this.spreadProps(contentEl, this.api.getContentProps());
33
29
  }
34
30
  };
@@ -0,0 +1,37 @@
1
+ import { X as ConverterMachineProps, b as FieldClientApi, c as Machine, h as getListCollectionFromHydrationData, y as FieldAwareComponent } from "./index-B06gIN_k.js";
2
+ import { CollectionItem, ListCollection } from "@zag-js/collection";
3
+ import * as _$_zag_js_types0 from "@zag-js/types";
4
+ import * as combobox from "@zag-js/combobox";
5
+
6
+ //#region Resources/Private/Primitives/Combobox/Combobox.d.ts
7
+ declare const comboboxPropConverters: {
8
+ collection: (collection: Parameters<typeof getListCollectionFromHydrationData>[0] | undefined) => ListCollection<unknown>;
9
+ positioning: (positioning: combobox.Props["positioning"]) => combobox.PositioningOptions | undefined;
10
+ };
11
+ declare module 'fluid-primitives' {
12
+ interface HydrationPropsOverrides {
13
+ combobox: ConverterMachineProps<typeof comboboxPropConverters>;
14
+ }
15
+ }
16
+ declare class Combobox extends FieldAwareComponent<combobox.Props, combobox.Api> {
17
+ static componentName: string;
18
+ private sourceCollection?;
19
+ propsWithField(props: combobox.Props, field: FieldClientApi): combobox.Props;
20
+ transformProps(props: combobox.Props): combobox.Props;
21
+ /**
22
+ * The full, unfiltered collection as it was first passed in - `render()` needs it to tell a
23
+ * static/server-rendered item apart from a dynamically-inserted (async) one (see the item
24
+ * callback below), and a consumer's own `onInputValueChange` needs it as the base to filter
25
+ * from or reset to.
26
+ */
27
+ getSourceCollection<T extends CollectionItem = CollectionItem>(): ListCollection<T>;
28
+ private getHiddenInputProps;
29
+ private syncHiddenInput;
30
+ initMachine(props: combobox.Props): Machine<any>;
31
+ initApi(): combobox.Api<_$_zag_js_types0.PropTypes<{
32
+ [x: string]: any;
33
+ }>, unknown>;
34
+ render(): void;
35
+ }
36
+ //#endregion
37
+ export { Combobox };
@@ -0,0 +1,151 @@
1
+ import { $ as getListCollectionFromHydrationData, K as registerClientPropConverters, a as normalizeProps, at as Machine, o as mergeProps, s as FieldAwareComponent } from "./Client-HrMIqv7d.js";
2
+ import { visuallyHiddenStyle } from "@zag-js/dom-query";
3
+ import * as combobox from "@zag-js/combobox";
4
+
5
+ //#region Resources/Private/Primitives/Combobox/Combobox.ts
6
+ registerClientPropConverters("combobox", {
7
+ collection: (collection) => getListCollectionFromHydrationData(collection ?? { items: [] }),
8
+ positioning: (positioning) => positioning
9
+ });
10
+ var Combobox = class extends FieldAwareComponent {
11
+ static componentName = "combobox";
12
+ sourceCollection;
13
+ propsWithField(props, field) {
14
+ return {
15
+ ...props,
16
+ disabled: props.disabled ?? field.disabled,
17
+ readOnly: props.readOnly ?? field.readOnly,
18
+ required: props.required ?? field.required,
19
+ invalid: props.invalid ?? field.invalid,
20
+ name: props.name ?? field.name
21
+ };
22
+ }
23
+ transformProps(props) {
24
+ return {
25
+ ...props,
26
+ onSelect: (details) => {
27
+ this.hydrator.query("input")?.dispatchEvent(new Event("change", { bubbles: true }));
28
+ props?.onSelect?.(details);
29
+ }
30
+ };
31
+ }
32
+ /**
33
+ * The full, unfiltered collection as it was first passed in - `render()` needs it to tell a
34
+ * static/server-rendered item apart from a dynamically-inserted (async) one (see the item
35
+ * callback below), and a consumer's own `onInputValueChange` needs it as the base to filter
36
+ * from or reset to.
37
+ */
38
+ getSourceCollection() {
39
+ if (this.sourceCollection) return this.sourceCollection;
40
+ const initialCollection = this.machine.prop("collection");
41
+ if (!initialCollection) throw new Error("Combobox source collection is not available.");
42
+ this.sourceCollection = initialCollection;
43
+ return initialCollection;
44
+ }
45
+ getHiddenInputProps(value, attrs) {
46
+ return normalizeProps.input({
47
+ type: "text",
48
+ "aria-hidden": true,
49
+ tabIndex: -1,
50
+ style: visuallyHiddenStyle,
51
+ name: attrs.name,
52
+ form: attrs.form,
53
+ disabled: attrs.disabled,
54
+ value,
55
+ onFocus: () => {
56
+ this.hydrator.query("input")?.focus({ preventScroll: true });
57
+ }
58
+ });
59
+ }
60
+ syncHiddenInput(attrs) {
61
+ const rootEl = this.hydrator.query("root");
62
+ if (!rootEl) return;
63
+ this.hydrator.queryAll("hiddenInput").forEach((el) => el.remove());
64
+ const values = this.api.value;
65
+ const inputValue = this.api.inputValue;
66
+ const isCustomValue = !!this.machine.prop("allowCustomValue") && inputValue.trim() !== "" && inputValue !== this.api.valueAsString;
67
+ (values.length > 0 ? values : isCustomValue ? [inputValue] : [""]).forEach((value) => {
68
+ const inputEl = this.doc.createElement("input");
69
+ this.hydrator.stamp(inputEl, "hiddenInput", value);
70
+ this.spreadProps(inputEl, this.getHiddenInputProps(value, attrs));
71
+ rootEl.appendChild(inputEl);
72
+ });
73
+ }
74
+ initMachine(props) {
75
+ props = this.withFieldProps(props);
76
+ const [machineProps] = combobox.splitProps(props);
77
+ return new Machine(combobox.machine, machineProps);
78
+ }
79
+ initApi() {
80
+ return combobox.connect(this.machine.service, normalizeProps);
81
+ }
82
+ render() {
83
+ this.subscribeToFieldService();
84
+ const rootEl = this.hydrator.query("root");
85
+ if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
86
+ const labelEl = this.hydrator.query("label");
87
+ if (labelEl) this.spreadProps(labelEl, this.api.getLabelProps());
88
+ const controlEl = this.hydrator.query("control");
89
+ if (controlEl) this.spreadProps(controlEl, this.api.getControlProps());
90
+ const { name, form, ...inputProps } = this.api.getInputProps();
91
+ const inputEl = this.hydrator.query("input");
92
+ if (inputEl) {
93
+ const mergedProps = mergeProps(inputProps, { "aria-describedby": this.field?.ariaDescribedby });
94
+ this.spreadProps(inputEl, mergedProps);
95
+ }
96
+ this.syncHiddenInput({
97
+ name,
98
+ form,
99
+ disabled: inputProps.disabled
100
+ });
101
+ const triggerEl = this.hydrator.query("trigger");
102
+ if (triggerEl) this.spreadProps(triggerEl, this.api.getTriggerProps({ focusable: triggerEl.hasAttribute("data-focusable") }));
103
+ const clearTriggerEl = this.hydrator.query("clearTrigger");
104
+ if (clearTriggerEl) this.spreadProps(clearTriggerEl, this.api.getClearTriggerProps());
105
+ const positionerEl = this.hydrator.query("positioner");
106
+ if (positionerEl) this.spreadProps(positionerEl, this.api.getPositionerProps());
107
+ const contentEl = this.hydrator.query("content");
108
+ if (contentEl) this.spreadProps(contentEl, this.api.getContentProps());
109
+ const listEl = this.hydrator.query("list");
110
+ if (listEl) this.spreadProps(listEl, this.api.getListProps());
111
+ this.spreadPropsByValue("itemGroup", ({ value }) => {
112
+ return this.api.getItemGroupProps({ id: value });
113
+ });
114
+ this.spreadPropsByValue("itemGroupLabel", ({ value }) => {
115
+ return this.api.getItemGroupLabelProps({ htmlFor: value });
116
+ });
117
+ const sourceCollection = this.getSourceCollection();
118
+ const resolveItem = (value) => {
119
+ const sourceItem = sourceCollection.find(value);
120
+ return {
121
+ sourceItem,
122
+ item: sourceItem ?? this.api.collection.find(value)
123
+ };
124
+ };
125
+ this.spreadPropsByValue("item", ({ el, value }) => {
126
+ const { sourceItem, item } = resolveItem(value);
127
+ if (!item) return null;
128
+ el.hidden = sourceItem ? !this.api.collection.has(item.value) : false;
129
+ return this.api.getItemProps({ item });
130
+ });
131
+ this.spreadPropsByValue("itemText", ({ value }) => {
132
+ const { item } = resolveItem(value);
133
+ return item ? this.api.getItemTextProps({ item }) : null;
134
+ });
135
+ this.spreadPropsByValue("itemIndicator", ({ value }) => {
136
+ const { item } = resolveItem(value);
137
+ return item ? this.api.getItemIndicatorProps({ item }) : null;
138
+ });
139
+ this.hydrator.queryAll("itemGroup").forEach((itemGroupEl) => {
140
+ itemGroupEl.hidden = !this.hydrator.queryAll("item", itemGroupEl).some((itemEl) => !itemEl.hidden);
141
+ });
142
+ const hasVisibleItems = this.hydrator.queryAll("item").some((itemEl) => !itemEl.hidden);
143
+ if (contentEl) contentEl.toggleAttribute("data-empty", !hasVisibleItems);
144
+ if (listEl) listEl.toggleAttribute("data-empty", !hasVisibleItems);
145
+ const emptyEl = this.hydrator.query("empty");
146
+ if (emptyEl) emptyEl.hidden = hasVisibleItems;
147
+ }
148
+ };
149
+
150
+ //#endregion
151
+ export { Combobox };
@@ -0,0 +1,67 @@
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 datePicker from "@zag-js/date-picker";
4
+ import { DateView, IntlTranslations } from "@zag-js/date-picker";
5
+
6
+ //#region Resources/Private/Primitives/DatePicker/src/date-picker.translations.d.ts
7
+ /**
8
+ * The labels as PHP ships them: texts, with `%placeholders%` for what is only known when the
9
+ * label renders.
10
+ */
11
+ type TranslationTexts = Record<string, string | undefined>;
12
+ /**
13
+ * Zag's translations, plus the role descriptions it hard-codes in English.
14
+ * TODO: chakra-ui/zag#3421 makes them part of Zag's own translations.
15
+ */
16
+ interface DatePickerTranslations extends IntlTranslations {
17
+ roleDescription?: {
18
+ content?: string;
19
+ table?: Partial<Record<DateView, string>>;
20
+ };
21
+ }
22
+ //#endregion
23
+ //#region Resources/Private/Primitives/DatePicker/DatePicker.d.ts
24
+ declare const datePickerPropConverters: {
25
+ min: (date?: string) => datePicker.DateValue | undefined;
26
+ max: (date?: string) => datePicker.DateValue | undefined;
27
+ defaultFocusedValue: (date?: string) => datePicker.DateValue | undefined;
28
+ defaultValue: (dates?: string[]) => datePicker.DateValue[] | undefined;
29
+ timeZone: (timeZone?: string) => string;
30
+ ids: ({
31
+ label,
32
+ input,
33
+ ...ids
34
+ }?: Record<string, string>) => datePicker.ElementIds;
35
+ translations: (texts: TranslationTexts | undefined, props: Record<string, unknown>) => DatePickerTranslations;
36
+ positioning: (positioning: datePicker.Props["positioning"]) => datePicker.PositioningOptions | undefined;
37
+ };
38
+ declare module 'fluid-primitives' {
39
+ interface HydrationPropsOverrides {
40
+ datePicker: ConverterMachineProps<typeof datePickerPropConverters>;
41
+ }
42
+ }
43
+ declare class DatePicker extends FieldAwareComponent<datePicker.Props, datePicker.Api> {
44
+ static componentName: string;
45
+ propsWithField(props: datePicker.Props, field: FieldClientApi): datePicker.Props;
46
+ transformProps(props: datePicker.Props): datePicker.Props;
47
+ initMachine(props: datePicker.Props): Machine<any>;
48
+ initApi(): datePicker.Api<_$_zag_js_types0.PropTypes<{
49
+ [x: string]: any;
50
+ }>>;
51
+ render(): void;
52
+ private renderHiddenInputs;
53
+ private renderTable;
54
+ private renderDayTable;
55
+ /** One `<tr>` per entry of `rows`, paired with the entry it renders. */
56
+ private renderRows;
57
+ private renderCell;
58
+ private renderSelect;
59
+ /**
60
+ * Makes `parentEl` hold exactly `count` children of `tag`: it keeps the ones already there,
61
+ * adds the missing ones and removes the extra ones. A child of another tag (the placeholder
62
+ * rows of a skeleton) is replaced.
63
+ */
64
+ private fitChildren;
65
+ }
66
+ //#endregion
67
+ export { DatePicker };
@@ -0,0 +1,289 @@
1
+ import { K as registerClientPropConverters, a as normalizeProps, at as Machine, o as mergeProps, s as FieldAwareComponent } from "./Client-HrMIqv7d.js";
2
+ import { toZoned } from "@internationalized/date";
3
+ import * as datePicker from "@zag-js/date-picker";
4
+
5
+ //#region Resources/Private/Primitives/DatePicker/src/date-picker.translations.ts
6
+ const capitalize = (word) => word.charAt(0).toUpperCase() + word.slice(1);
7
+ const fill = (text, values) => text ? text.replace(/%(\w+)%/g, (_, key) => String(values[key] ?? "")) : void 0;
8
+ /** `Date.toDateString()`, which is what Zag hands over for a preset, in the language of the locale. */
9
+ const formatDay = (dateString, locale) => {
10
+ const date = new Date(dateString);
11
+ return Number.isNaN(date.getTime()) ? dateString : new Intl.DateTimeFormat(locale, { dateStyle: "long" }).format(date);
12
+ };
13
+ /**
14
+ * Builds the translations Zag takes from the texts of the language file. Most of them are
15
+ * functions of the date or of the view, which is why PHP can't send them as they are.
16
+ */
17
+ function buildTranslations(texts = {}, locale = "en-US") {
18
+ const label = (key, values = {}) => fill(texts[key], values);
19
+ return {
20
+ clearTrigger: label("clearTrigger"),
21
+ monthSelect: label("monthSelect"),
22
+ yearSelect: label("yearSelect"),
23
+ content: label("content"),
24
+ weekColumnHeader: label("weekColumnHeader"),
25
+ trigger: (open) => label(open ? "triggerClose" : "triggerOpen"),
26
+ prevTrigger: (view) => label(`prevTrigger${capitalize(view)}`),
27
+ nextTrigger: (view) => label(`nextTrigger${capitalize(view)}`),
28
+ viewTrigger: (view, nextView) => label(nextView ? `viewTriggerTo${capitalize(nextView)}` : `viewTrigger${capitalize(view)}`),
29
+ presetTrigger: ([start = "", end = ""]) => label("presetTrigger", {
30
+ start: formatDay(start, locale),
31
+ end: formatDay(end, locale)
32
+ }),
33
+ weekNumberCell: (number) => label("weekNumberCell", { number }),
34
+ dayCell: (state) => label(state.unavailable ? "dayCellUnavailable" : state.firstInRange ? "dayCellRangeStart" : state.lastInRange ? "dayCellRangeEnd" : state.inRange ? "dayCellInRange" : state.selected ? "dayCellSelected" : "dayCell", { date: state.valueText }),
35
+ placeholder: () => ({
36
+ day: texts.placeholderDay || "dd",
37
+ month: texts.placeholderMonth || "mm",
38
+ year: texts.placeholderYear || "yyyy"
39
+ }),
40
+ roleDescription: {
41
+ content: texts.contentRoleDescription || void 0,
42
+ table: {
43
+ day: texts.tableRoleDescriptionDay || void 0,
44
+ month: texts.tableRoleDescriptionMonth || void 0,
45
+ year: texts.tableRoleDescriptionYear || void 0
46
+ }
47
+ }
48
+ };
49
+ }
50
+ /**
51
+ * The placeholder of the input: the date pattern of the locale written with the letters of the
52
+ * translation, e.g. `TT.MM.JJJJ`. Zag only knows the English ones.
53
+ */
54
+ function getPlaceholder(translations, locale = "en-US") {
55
+ const letters = translations?.placeholder?.(locale);
56
+ if (!letters) return void 0;
57
+ return new Intl.DateTimeFormat(locale).formatToParts(/* @__PURE__ */ new Date()).map((part) => letters[part.type] ?? part.value).join("");
58
+ }
59
+
60
+ //#endregion
61
+ //#region Resources/Private/Primitives/DatePicker/DatePicker.ts
62
+ const parseDate = (date) => date ? datePicker.parse(date) : void 0;
63
+ const indexedId = (id) => (index) => index === 0 ? id : `${id}:${index}`;
64
+ registerClientPropConverters("datePicker", {
65
+ min: parseDate,
66
+ max: parseDate,
67
+ defaultFocusedValue: parseDate,
68
+ defaultValue: (dates) => dates ? datePicker.parse(dates) : void 0,
69
+ timeZone: (timeZone) => timeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,
70
+ ids: ({ label, input, ...ids } = {}) => ({
71
+ ...ids,
72
+ ...label && { label: indexedId(label) },
73
+ ...input && { input: indexedId(input) }
74
+ }),
75
+ translations: (texts, props) => buildTranslations(texts, props.locale),
76
+ positioning: (positioning) => positioning
77
+ });
78
+ var DatePicker = class extends FieldAwareComponent {
79
+ static componentName = "datePicker";
80
+ propsWithField(props, field) {
81
+ return {
82
+ ...props,
83
+ disabled: props.disabled ?? field.disabled,
84
+ readOnly: props.readOnly ?? field.readOnly,
85
+ required: props.required ?? field.required,
86
+ invalid: props.invalid ?? field.invalid,
87
+ name: props.name ?? field.name
88
+ };
89
+ }
90
+ transformProps(props) {
91
+ return {
92
+ ...props,
93
+ placeholder: props.placeholder ?? getPlaceholder(props.translations, props.locale),
94
+ onValueChange: (details) => {
95
+ this.hydrator.query("input")?.dispatchEvent(new Event("change", { bubbles: true }));
96
+ props.onValueChange?.(details);
97
+ }
98
+ };
99
+ }
100
+ initMachine(props) {
101
+ const [machineProps] = datePicker.splitProps(this.withFieldProps(props));
102
+ return new Machine(datePicker.machine, machineProps);
103
+ }
104
+ initApi() {
105
+ return datePicker.connect(this.machine.service, normalizeProps);
106
+ }
107
+ render() {
108
+ this.subscribeToFieldService();
109
+ const rootEl = this.hydrator.query("root");
110
+ if (rootEl) this.spreadProps(rootEl, this.api.getRootProps());
111
+ this.spreadPropsByOptionalValue("label", ({ value }) => this.api.getLabelProps({ index: Number(value ?? 0) }));
112
+ const controlEl = this.hydrator.query("control");
113
+ if (controlEl) this.spreadProps(controlEl, this.api.getControlProps());
114
+ this.spreadPropsByOptionalValue("input", ({ value }) => {
115
+ const { name, ...inputProps } = this.api.getInputProps({ index: Number(value ?? 0) });
116
+ return mergeProps(inputProps, { "aria-describedby": this.field?.ariaDescribedby });
117
+ });
118
+ this.renderHiddenInputs();
119
+ const clearTriggerEl = this.hydrator.query("clearTrigger");
120
+ if (clearTriggerEl) this.spreadProps(clearTriggerEl, this.api.getClearTriggerProps());
121
+ const triggerEl = this.hydrator.query("trigger");
122
+ if (triggerEl) this.spreadProps(triggerEl, this.api.getTriggerProps());
123
+ const positionerEl = this.hydrator.query("positioner");
124
+ if (positionerEl) {
125
+ const positionerProps = this.api.getPositionerProps();
126
+ if (this.api.inline) delete positionerProps.style;
127
+ this.spreadProps(positionerEl, positionerProps);
128
+ }
129
+ const roleDescription = this.userProps.translations?.roleDescription;
130
+ const contentEl = this.hydrator.query("content");
131
+ if (contentEl) this.spreadProps(contentEl, mergeProps(this.api.getContentProps(), { "aria-roledescription": roleDescription?.content }));
132
+ this.spreadPropsByValue("view", ({ value }) => this.api.getViewProps({ view: value }));
133
+ this.spreadPropsByValue("viewControl", ({ value }) => this.api.getViewControlProps({ view: value }));
134
+ this.spreadPropsByValue("viewTrigger", ({ value }) => this.api.getViewTriggerProps({ view: value }));
135
+ this.spreadPropsByValue("prevTrigger", ({ value }) => this.api.getPrevTriggerProps({ view: value }));
136
+ this.spreadPropsByValue("nextTrigger", ({ value }) => this.api.getNextTriggerProps({ view: value }));
137
+ this.spreadPropsByValue("presetTrigger", ({ value }) => this.api.getPresetTriggerProps({ value }));
138
+ const { start, end } = this.api.visibleRangeText;
139
+ const rangeText = start === end ? start : `${start} - ${end}`;
140
+ this.hydrator.queryAll("rangeText").forEach((rangeTextEl) => {
141
+ this.spreadProps(rangeTextEl, this.api.getRangeTextProps());
142
+ if (rangeTextEl.textContent !== rangeText) rangeTextEl.textContent = rangeText;
143
+ });
144
+ this.hydrator.queryAll("table").forEach((tableEl) => {
145
+ const view = tableEl.dataset.value;
146
+ const offset = Number(tableEl.dataset.offset ?? 0);
147
+ this.spreadProps(tableEl, mergeProps(this.api.getTableProps({
148
+ view,
149
+ id: offset ? String(offset) : void 0
150
+ }), {
151
+ "aria-roledescription": roleDescription?.table?.[view],
152
+ ...view === "day" && { "aria-label": this.api.getOffset({ months: offset }).visibleRangeText.start }
153
+ }));
154
+ const headerEl = this.hydrator.query("tableHeader", tableEl);
155
+ const bodyEl = this.hydrator.query("tableBody", tableEl);
156
+ if (headerEl && bodyEl) this.renderTable(view, offset, headerEl, bodyEl);
157
+ });
158
+ const monthSelectEl = this.hydrator.query("monthSelect");
159
+ if (monthSelectEl) this.renderSelect(monthSelectEl, this.api.getMonthSelectProps(), this.api.getMonths(), this.api.visibleRange.start.month);
160
+ const yearSelectEl = this.hydrator.query("yearSelect");
161
+ if (yearSelectEl) this.renderSelect(yearSelectEl, this.api.getYearSelectProps(), this.api.getYears(), this.api.visibleRange.start.year);
162
+ }
163
+ renderHiddenInputs() {
164
+ const { serverTimeZone } = this.userProps;
165
+ const values = this.api.value.length > 0 ? this.api.value.map((date) => toZoned(date, serverTimeZone).toString().replace(/\[.*\]$/, "")) : [""];
166
+ const inputEls = this.hydrator.queryAll("hiddenInput");
167
+ inputEls.slice(values.length).forEach((inputEl) => inputEl.remove());
168
+ values.forEach((value, i) => {
169
+ let inputEl = inputEls[i];
170
+ if (!inputEl) {
171
+ inputEl = this.doc.createElement("input");
172
+ this.hydrator.stamp(inputEl, "hiddenInput");
173
+ if (i > 0) inputEls[i - 1].after(inputEl);
174
+ else this.hydrator.query("root")?.append(inputEl);
175
+ inputEls[i] = inputEl;
176
+ }
177
+ this.spreadProps(inputEl, normalizeProps.input({
178
+ type: "hidden",
179
+ name: this.machine.prop("name"),
180
+ value,
181
+ disabled: this.api.disabled
182
+ }));
183
+ });
184
+ }
185
+ renderTable(view, offset, headerEl, bodyEl) {
186
+ if (view === "day") {
187
+ this.renderDayTable(offset, headerEl, bodyEl);
188
+ return;
189
+ }
190
+ const grid = view === "month" ? this.api.getMonthsGrid({
191
+ columns: 4,
192
+ format: "short"
193
+ }) : this.api.getYearsGrid({ columns: 4 });
194
+ headerEl.replaceChildren();
195
+ this.renderRows(bodyEl, grid, (rowEl) => {
196
+ this.spreadProps(rowEl, this.api.getTableRowProps({ view }));
197
+ }).forEach(([rowEl, cells]) => {
198
+ this.fitChildren(rowEl, "td", cells.length).forEach((cellEl, i) => {
199
+ const cell = cells[i];
200
+ this.renderCell(cellEl, view === "month" ? this.api.getMonthTableCellProps(cell) : this.api.getYearTableCellProps(cell), view === "month" ? this.api.getMonthTableCellTriggerProps(cell) : this.api.getYearTableCellTriggerProps(cell), cell.label);
201
+ });
202
+ });
203
+ }
204
+ renderDayTable(offset, headerEl, bodyEl) {
205
+ const view = "day";
206
+ const weekNumbers = this.api.showWeekNumbers;
207
+ const { weeks, visibleRange } = this.api.getOffset({ months: offset });
208
+ const [headerRowEl] = this.fitChildren(headerEl, "tr", 1);
209
+ this.spreadProps(headerRowEl, this.api.getTableRowProps({ view }));
210
+ const headEls = this.fitChildren(headerRowEl, "th", this.api.weekDays.length + (weekNumbers ? 1 : 0));
211
+ if (weekNumbers) {
212
+ const weekNumberHeaderEl = headEls.shift();
213
+ this.spreadProps(weekNumberHeaderEl, this.api.getWeekNumberHeaderCellProps({ view }));
214
+ weekNumberHeaderEl.textContent = "";
215
+ }
216
+ this.api.weekDays.forEach((day, i) => {
217
+ this.spreadProps(headEls[i], mergeProps(this.api.getTableHeadProps({ view }), {
218
+ scope: "col",
219
+ "aria-label": day.long
220
+ }));
221
+ if (headEls[i].textContent !== day.narrow) headEls[i].textContent = day.narrow;
222
+ });
223
+ this.renderRows(bodyEl, weeks, (rowEl) => {
224
+ this.spreadProps(rowEl, this.api.getTableRowProps({ view }));
225
+ }).forEach(([rowEl, week], weekIndex) => {
226
+ const cellEls = this.fitChildren(rowEl, "td", week.length + (weekNumbers ? 1 : 0));
227
+ if (weekNumbers) {
228
+ const weekNumberEl = cellEls.shift();
229
+ this.spreadProps(weekNumberEl, this.api.getWeekNumberCellProps({
230
+ weekIndex,
231
+ week
232
+ }));
233
+ weekNumberEl.textContent = String(this.api.getWeekNumber(week));
234
+ }
235
+ week.forEach((value, i) => {
236
+ this.renderCell(cellEls[i], this.api.getDayTableCellProps({
237
+ value,
238
+ visibleRange
239
+ }), this.api.getDayTableCellTriggerProps({
240
+ value,
241
+ visibleRange
242
+ }), String(value.day));
243
+ });
244
+ });
245
+ }
246
+ /** One `<tr>` per entry of `rows`, paired with the entry it renders. */
247
+ renderRows(parentEl, rows, spreadRow) {
248
+ return this.fitChildren(parentEl, "tr", rows.length).map((rowEl, i) => {
249
+ spreadRow(rowEl);
250
+ return [rowEl, rows[i]];
251
+ });
252
+ }
253
+ renderCell(cellEl, cellProps, triggerProps, text) {
254
+ this.spreadProps(cellEl, cellProps);
255
+ const [triggerEl] = this.fitChildren(cellEl, "div", 1);
256
+ this.spreadProps(triggerEl, triggerProps);
257
+ if (triggerEl.textContent !== text) triggerEl.textContent = text;
258
+ }
259
+ renderSelect(selectEl, selectProps, options, selected) {
260
+ this.spreadProps(selectEl, selectProps);
261
+ this.fitChildren(selectEl, "option", options.length).forEach((optionEl, i) => {
262
+ const { label, value, disabled } = options[i];
263
+ if (optionEl.value !== String(value)) optionEl.value = String(value);
264
+ if (optionEl.textContent !== label) optionEl.textContent = label;
265
+ if (optionEl.disabled !== !!disabled) optionEl.disabled = !!disabled;
266
+ });
267
+ selectEl.value = String(selected);
268
+ }
269
+ /**
270
+ * Makes `parentEl` hold exactly `count` children of `tag`: it keeps the ones already there,
271
+ * adds the missing ones and removes the extra ones. A child of another tag (the placeholder
272
+ * rows of a skeleton) is replaced.
273
+ */
274
+ fitChildren(parentEl, tag, count) {
275
+ const children = Array.from(parentEl.children);
276
+ children.slice(count).forEach((child) => child.remove());
277
+ return Array.from({ length: count }, (_, i) => {
278
+ const child = children[i];
279
+ if (child?.localName === tag) return child;
280
+ const el = this.doc.createElement(tag);
281
+ if (child) child.replaceWith(el);
282
+ else parentEl.append(el);
283
+ return el;
284
+ });
285
+ }
286
+ };
287
+
288
+ //#endregion
289
+ export { DatePicker };
package/dist/dialog.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { a as Machine, f as Component } from "./index-B8JCdyld.js";
2
- import * as dialog from "@zag-js/dialog";
1
+ import { c as Machine, z as Component } from "./index-B06gIN_k.js";
3
2
  import * as _$_zag_js_types0 from "@zag-js/types";
3
+ import * as dialog from "@zag-js/dialog";
4
4
 
5
5
  //#region Resources/Private/Primitives/Dialog/Dialog.d.ts
6
6
  declare class Dialog extends Component<dialog.Props, dialog.Api> {
7
- static name: string;
7
+ static componentName: string;
8
8
  initMachine(props: dialog.Props): Machine<any>;
9
9
  initApi(): dialog.Api<_$_zag_js_types0.PropTypes<{
10
10
  [x: string]: any;