@zag-js/radio-group 0.1.11 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,31 +3,11 @@ import {
3
3
  } from "./chunk-MGLN5L3R.mjs";
4
4
  import {
5
5
  dom
6
- } from "./chunk-CYVZAWTC.mjs";
7
-
8
- // ../../utilities/dom/src/attrs.ts
9
- var dataAttr = (guard) => {
10
- return guard ? "" : void 0;
11
- };
12
- var ariaAttr = (guard) => {
13
- return guard ? "true" : void 0;
14
- };
15
-
16
- // ../../utilities/dom/src/visually-hidden.ts
17
- var visuallyHiddenStyle = {
18
- border: "0",
19
- clip: "rect(0 0 0 0)",
20
- height: "1px",
21
- margin: "-1px",
22
- overflow: "hidden",
23
- padding: "0",
24
- position: "absolute",
25
- width: "1px",
26
- whiteSpace: "nowrap",
27
- wordWrap: "normal"
28
- };
6
+ } from "./chunk-ITVKBCBK.mjs";
29
7
 
30
8
  // src/radio-group.connect.ts
9
+ import { ariaAttr, dataAttr } from "@zag-js/dom-query";
10
+ import { visuallyHiddenStyle } from "@zag-js/visually-hidden";
31
11
  function connect(state, send, normalize) {
32
12
  const isGroupDisabled = state.context.disabled;
33
13
  const isGroupReadOnly = state.context.readOnly;
@@ -67,11 +47,29 @@ function connect(state, send, normalize) {
67
47
  firstEnabledInput?.focus();
68
48
  };
69
49
  return {
50
+ /**
51
+ * The current value of the radio group
52
+ */
70
53
  value: state.context.value,
54
+ /**
55
+ * Function to set the value of the radio group
56
+ */
71
57
  setValue(value) {
72
58
  send({ type: "SET_VALUE", value, manual: true });
73
59
  },
60
+ /**
61
+ * Function to clear the value of the radio group
62
+ */
63
+ clearValue() {
64
+ send({ type: "SET_VALUE", value: null, manual: true });
65
+ },
66
+ /**
67
+ * Function to focus the radio group
68
+ */
74
69
  focus,
70
+ /**
71
+ * Function to blur the currently focused radio input in the radio group
72
+ */
75
73
  blur() {
76
74
  const focusedElement = dom.getActiveElement(state.context);
77
75
  const inputEls = dom.getInputEls(state.context);
@@ -79,10 +77,15 @@ function connect(state, send, normalize) {
79
77
  if (radioInputIsFocused)
80
78
  focusedElement?.blur();
81
79
  },
80
+ /**
81
+ * Returns the state details of a radio input
82
+ */
83
+ getRadioState,
82
84
  rootProps: normalize.element({
83
85
  ...parts.root.attrs,
84
86
  role: "radiogroup",
85
87
  id: dom.getRootId(state.context),
88
+ "aria-labelledby": dom.getLabelId(state.context),
86
89
  "data-orientation": state.context.orientation,
87
90
  "aria-orientation": state.context.orientation,
88
91
  dir: state.context.dir
@@ -0,0 +1,97 @@
1
+ import {
2
+ dom
3
+ } from "./chunk-ITVKBCBK.mjs";
4
+
5
+ // src/radio-group.machine.ts
6
+ import { createMachine } from "@zag-js/core";
7
+ import { dispatchInputCheckedEvent, trackFormControl } from "@zag-js/form-utils";
8
+ import { compact } from "@zag-js/utils";
9
+ function machine(userContext) {
10
+ const ctx = compact(userContext);
11
+ return createMachine(
12
+ {
13
+ id: "radio",
14
+ initial: "idle",
15
+ context: {
16
+ value: null,
17
+ initialValue: null,
18
+ activeId: null,
19
+ focusedId: null,
20
+ hoveredId: null,
21
+ ...ctx
22
+ },
23
+ activities: ["trackFormControlState"],
24
+ on: {
25
+ SET_VALUE: {
26
+ actions: ["setValue"]
27
+ },
28
+ SET_HOVERED: {
29
+ actions: "setHovered"
30
+ },
31
+ SET_ACTIVE: {
32
+ actions: "setActive"
33
+ },
34
+ SET_FOCUSED: {
35
+ actions: "setFocused"
36
+ }
37
+ },
38
+ watch: {
39
+ value: ["dispatchChangeEvent", "invokeOnChange", "syncInputElements"]
40
+ },
41
+ entry: ["checkValue"],
42
+ states: {
43
+ idle: {}
44
+ }
45
+ },
46
+ {
47
+ activities: {
48
+ trackFormControlState(ctx2, _evt, { send }) {
49
+ return trackFormControl(dom.getRootEl(ctx2), {
50
+ onFieldsetDisabled() {
51
+ ctx2.disabled = true;
52
+ },
53
+ onFormReset() {
54
+ send({ type: "SET_VALUE", value: ctx2.initialValue });
55
+ }
56
+ });
57
+ }
58
+ },
59
+ actions: {
60
+ checkValue(ctx2) {
61
+ ctx2.initialValue = ctx2.value;
62
+ },
63
+ setValue(ctx2, evt) {
64
+ ctx2.value = evt.value;
65
+ },
66
+ setHovered(ctx2, evt) {
67
+ ctx2.hoveredId = evt.value;
68
+ },
69
+ setActive(ctx2, evt) {
70
+ ctx2.activeId = evt.value;
71
+ },
72
+ setFocused(ctx2, evt) {
73
+ ctx2.focusedId = evt.value;
74
+ },
75
+ invokeOnChange(ctx2, evt) {
76
+ ctx2.onChange?.({ value: evt.value });
77
+ },
78
+ dispatchChangeEvent(ctx2, evt) {
79
+ if (!evt.manual)
80
+ return;
81
+ const el = dom.getRadioInputEl(ctx2, evt.value);
82
+ dispatchInputCheckedEvent(el, !!evt.value);
83
+ },
84
+ syncInputElements(ctx2) {
85
+ const inputs = dom.getInputEls(ctx2);
86
+ inputs.forEach((input) => {
87
+ input.checked = input.value === ctx2.value;
88
+ });
89
+ }
90
+ }
91
+ }
92
+ );
93
+ }
94
+
95
+ export {
96
+ machine
97
+ };
@@ -1,41 +1,6 @@
1
- // ../../utilities/dom/src/query.ts
2
- function isDocument(el) {
3
- return el.nodeType === Node.DOCUMENT_NODE;
4
- }
5
- function isWindow(value) {
6
- return value?.toString() === "[object Window]";
7
- }
8
- function getDocument(el) {
9
- if (isWindow(el))
10
- return el.document;
11
- if (isDocument(el))
12
- return el;
13
- return el?.ownerDocument ?? document;
14
- }
15
- function getWindow(el) {
16
- return el?.ownerDocument.defaultView ?? window;
17
- }
18
- function defineDomHelpers(helpers) {
19
- const dom2 = {
20
- getRootNode: (ctx) => ctx.getRootNode?.() ?? document,
21
- getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
22
- getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
23
- getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
24
- getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
25
- };
26
- return {
27
- ...dom2,
28
- ...helpers
29
- };
30
- }
31
-
32
- // ../../utilities/dom/src/nodelist.ts
33
- function queryAll(root, selector) {
34
- return Array.from(root?.querySelectorAll(selector) ?? []);
35
- }
36
-
37
1
  // src/radio-group.dom.ts
38
- var dom = defineDomHelpers({
2
+ import { createScope, queryAll } from "@zag-js/dom-query";
3
+ var dom = createScope({
39
4
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
40
5
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
41
6
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
@@ -54,6 +19,5 @@ var dom = defineDomHelpers({
54
19
  });
55
20
 
56
21
  export {
57
- getWindow,
58
22
  dom
59
23
  };
package/dist/index.js CHANGED
@@ -38,96 +38,13 @@ var anatomy = (0, import_anatomy.createAnatomy)("radio-group").parts(
38
38
  );
39
39
  var parts = anatomy.build();
40
40
 
41
- // ../../utilities/dom/src/attrs.ts
42
- var dataAttr = (guard) => {
43
- return guard ? "" : void 0;
44
- };
45
- var ariaAttr = (guard) => {
46
- return guard ? "true" : void 0;
47
- };
48
-
49
- // ../../utilities/core/src/guard.ts
50
- var isArray = (v) => Array.isArray(v);
51
- var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
52
-
53
- // ../../utilities/core/src/object.ts
54
- function compact(obj) {
55
- if (obj === void 0)
56
- return obj;
57
- return Object.fromEntries(
58
- Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
59
- );
60
- }
61
-
62
- // ../../utilities/dom/src/query.ts
63
- function isDocument(el) {
64
- return el.nodeType === Node.DOCUMENT_NODE;
65
- }
66
- function isWindow(value) {
67
- return value?.toString() === "[object Window]";
68
- }
69
- function getDocument(el) {
70
- if (isWindow(el))
71
- return el.document;
72
- if (isDocument(el))
73
- return el;
74
- return el?.ownerDocument ?? document;
75
- }
76
- function getWindow(el) {
77
- return el?.ownerDocument.defaultView ?? window;
78
- }
79
- function defineDomHelpers(helpers) {
80
- const dom2 = {
81
- getRootNode: (ctx) => ctx.getRootNode?.() ?? document,
82
- getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
83
- getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
84
- getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
85
- getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
86
- };
87
- return {
88
- ...dom2,
89
- ...helpers
90
- };
91
- }
92
-
93
- // ../../utilities/dom/src/mutation-observer.ts
94
- function observeAttributes(node, attributes, fn) {
95
- if (!node)
96
- return;
97
- const attrs = Array.isArray(attributes) ? attributes : [attributes];
98
- const win = node.ownerDocument.defaultView || window;
99
- const obs = new win.MutationObserver((changes) => {
100
- for (const change of changes) {
101
- if (change.type === "attributes" && change.attributeName && attrs.includes(change.attributeName)) {
102
- fn(change);
103
- }
104
- }
105
- });
106
- obs.observe(node, { attributes: true, attributeFilter: attrs });
107
- return () => obs.disconnect();
108
- }
109
-
110
- // ../../utilities/dom/src/nodelist.ts
111
- function queryAll(root, selector) {
112
- return Array.from(root?.querySelectorAll(selector) ?? []);
113
- }
114
-
115
- // ../../utilities/dom/src/visually-hidden.ts
116
- var visuallyHiddenStyle = {
117
- border: "0",
118
- clip: "rect(0 0 0 0)",
119
- height: "1px",
120
- margin: "-1px",
121
- overflow: "hidden",
122
- padding: "0",
123
- position: "absolute",
124
- width: "1px",
125
- whiteSpace: "nowrap",
126
- wordWrap: "normal"
127
- };
41
+ // src/radio-group.connect.ts
42
+ var import_dom_query2 = require("@zag-js/dom-query");
43
+ var import_visually_hidden = require("@zag-js/visually-hidden");
128
44
 
129
45
  // src/radio-group.dom.ts
130
- var dom = defineDomHelpers({
46
+ var import_dom_query = require("@zag-js/dom-query");
47
+ var dom = (0, import_dom_query.createScope)({
131
48
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
132
49
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
133
50
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
@@ -141,7 +58,7 @@ var dom = defineDomHelpers({
141
58
  getInputEls: (ctx) => {
142
59
  const ownerId = CSS.escape(dom.getRootId(ctx));
143
60
  const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`;
144
- return queryAll(dom.getRootEl(ctx), selector);
61
+ return (0, import_dom_query.queryAll)(dom.getRootEl(ctx), selector);
145
62
  }
146
63
  });
147
64
 
@@ -167,12 +84,12 @@ function connect(state, send, normalize) {
167
84
  function getRadioDataSet(props) {
168
85
  const radioState = getRadioState(props);
169
86
  return {
170
- "data-focus": dataAttr(radioState.isFocused),
171
- "data-disabled": dataAttr(radioState.isDisabled),
172
- "data-checked": dataAttr(radioState.isChecked),
173
- "data-hover": dataAttr(radioState.isHovered),
174
- "data-invalid": dataAttr(radioState.isInvalid),
175
- "data-readonly": dataAttr(radioState.isReadOnly)
87
+ "data-focus": (0, import_dom_query2.dataAttr)(radioState.isFocused),
88
+ "data-disabled": (0, import_dom_query2.dataAttr)(radioState.isDisabled),
89
+ "data-checked": (0, import_dom_query2.dataAttr)(radioState.isChecked),
90
+ "data-hover": (0, import_dom_query2.dataAttr)(radioState.isHovered),
91
+ "data-invalid": (0, import_dom_query2.dataAttr)(radioState.isInvalid),
92
+ "data-readonly": (0, import_dom_query2.dataAttr)(radioState.isReadOnly)
176
93
  };
177
94
  }
178
95
  const focus = () => {
@@ -185,11 +102,29 @@ function connect(state, send, normalize) {
185
102
  firstEnabledInput?.focus();
186
103
  };
187
104
  return {
105
+ /**
106
+ * The current value of the radio group
107
+ */
188
108
  value: state.context.value,
109
+ /**
110
+ * Function to set the value of the radio group
111
+ */
189
112
  setValue(value) {
190
113
  send({ type: "SET_VALUE", value, manual: true });
191
114
  },
115
+ /**
116
+ * Function to clear the value of the radio group
117
+ */
118
+ clearValue() {
119
+ send({ type: "SET_VALUE", value: null, manual: true });
120
+ },
121
+ /**
122
+ * Function to focus the radio group
123
+ */
192
124
  focus,
125
+ /**
126
+ * Function to blur the currently focused radio input in the radio group
127
+ */
193
128
  blur() {
194
129
  const focusedElement = dom.getActiveElement(state.context);
195
130
  const inputEls = dom.getInputEls(state.context);
@@ -197,10 +132,15 @@ function connect(state, send, normalize) {
197
132
  if (radioInputIsFocused)
198
133
  focusedElement?.blur();
199
134
  },
135
+ /**
136
+ * Returns the state details of a radio input
137
+ */
138
+ getRadioState,
200
139
  rootProps: normalize.element({
201
140
  ...parts.root.attrs,
202
141
  role: "radiogroup",
203
142
  id: dom.getRootId(state.context),
143
+ "aria-labelledby": dom.getLabelId(state.context),
204
144
  "data-orientation": state.context.orientation,
205
145
  "aria-orientation": state.context.orientation,
206
146
  dir: state.context.dir
@@ -253,7 +193,7 @@ function connect(state, send, normalize) {
253
193
  return normalize.element({
254
194
  ...parts.radioControl.attrs,
255
195
  id: dom.getRadioControlId(state.context, props.value),
256
- "data-active": dataAttr(controlState.isActive),
196
+ "data-active": (0, import_dom_query2.dataAttr)(controlState.isActive),
257
197
  "aria-hidden": true,
258
198
  ...getRadioDataSet(props)
259
199
  });
@@ -297,14 +237,14 @@ function connect(state, send, normalize) {
297
237
  disabled: trulyDisabled,
298
238
  required: isRequired,
299
239
  defaultChecked: inputState.isChecked,
300
- "data-disabled": dataAttr(inputState.isDisabled),
301
- "aria-required": ariaAttr(isRequired),
302
- "aria-invalid": ariaAttr(inputState.isInvalid),
240
+ "data-disabled": (0, import_dom_query2.dataAttr)(inputState.isDisabled),
241
+ "aria-required": (0, import_dom_query2.ariaAttr)(isRequired),
242
+ "aria-invalid": (0, import_dom_query2.ariaAttr)(inputState.isInvalid),
303
243
  readOnly: inputState.isReadOnly,
304
- "data-readonly": dataAttr(inputState.isReadOnly),
305
- "aria-disabled": ariaAttr(trulyDisabled),
306
- "aria-checked": ariaAttr(inputState.isChecked),
307
- style: visuallyHiddenStyle
244
+ "data-readonly": (0, import_dom_query2.dataAttr)(inputState.isReadOnly),
245
+ "aria-disabled": (0, import_dom_query2.ariaAttr)(trulyDisabled),
246
+ "aria-checked": (0, import_dom_query2.ariaAttr)(inputState.isChecked),
247
+ style: import_visually_hidden.visuallyHiddenStyle
308
248
  });
309
249
  }
310
250
  };
@@ -312,70 +252,10 @@ function connect(state, send, normalize) {
312
252
 
313
253
  // src/radio-group.machine.ts
314
254
  var import_core = require("@zag-js/core");
315
-
316
- // ../../utilities/form-utils/src/input-event.ts
317
- function getDescriptor(el, options) {
318
- const { type, property = "value" } = options;
319
- const proto = getWindow(el)[type].prototype;
320
- return Object.getOwnPropertyDescriptor(proto, property) ?? {};
321
- }
322
- function dispatchInputCheckedEvent(el, checked) {
323
- if (!el)
324
- return;
325
- const win = getWindow(el);
326
- if (!(el instanceof win.HTMLInputElement))
327
- return;
328
- const desc = getDescriptor(el, { type: "HTMLInputElement", property: "checked" });
329
- desc.set?.call(el, checked);
330
- const event = new win.Event("click", { bubbles: true });
331
- el.dispatchEvent(event);
332
- }
333
-
334
- // ../../utilities/form-utils/src/form.ts
335
- function getClosestForm(el) {
336
- if (isFormElement(el))
337
- return el.form;
338
- else
339
- return el.closest("form");
340
- }
341
- function isFormElement(el) {
342
- return el.matches("textarea, input, select, button");
343
- }
344
- function trackFormReset(el, callback) {
345
- if (!el)
346
- return;
347
- const form = getClosestForm(el);
348
- form?.addEventListener("reset", callback, { passive: true });
349
- return () => {
350
- form?.removeEventListener("reset", callback);
351
- };
352
- }
353
- function trackFieldsetDisabled(el, callback) {
354
- const fieldset = el?.closest("fieldset");
355
- if (!fieldset)
356
- return;
357
- callback(fieldset.disabled);
358
- return observeAttributes(fieldset, ["disabled"], () => callback(fieldset.disabled));
359
- }
360
- function trackFormControl(el, options) {
361
- if (!el)
362
- return;
363
- const { onFieldsetDisabled, onFormReset } = options;
364
- const cleanups = [
365
- trackFormReset(el, onFormReset),
366
- trackFieldsetDisabled(el, (disabled) => {
367
- if (disabled)
368
- onFieldsetDisabled();
369
- })
370
- ];
371
- return () => {
372
- cleanups.forEach((cleanup) => cleanup?.());
373
- };
374
- }
375
-
376
- // src/radio-group.machine.ts
255
+ var import_form_utils = require("@zag-js/form-utils");
256
+ var import_utils = require("@zag-js/utils");
377
257
  function machine(userContext) {
378
- const ctx = compact(userContext);
258
+ const ctx = (0, import_utils.compact)(userContext);
379
259
  return (0, import_core.createMachine)(
380
260
  {
381
261
  id: "radio",
@@ -404,7 +284,7 @@ function machine(userContext) {
404
284
  }
405
285
  },
406
286
  watch: {
407
- value: ["dispatchChangeEvent", "invokeOnChange"]
287
+ value: ["dispatchChangeEvent", "invokeOnChange", "syncInputElements"]
408
288
  },
409
289
  entry: ["checkValue"],
410
290
  states: {
@@ -414,7 +294,7 @@ function machine(userContext) {
414
294
  {
415
295
  activities: {
416
296
  trackFormControlState(ctx2, _evt, { send }) {
417
- return trackFormControl(dom.getRootEl(ctx2), {
297
+ return (0, import_form_utils.trackFormControl)(dom.getRootEl(ctx2), {
418
298
  onFieldsetDisabled() {
419
299
  ctx2.disabled = true;
420
300
  },
@@ -447,7 +327,13 @@ function machine(userContext) {
447
327
  if (!evt.manual)
448
328
  return;
449
329
  const el = dom.getRadioInputEl(ctx2, evt.value);
450
- dispatchInputCheckedEvent(el, !!evt.value);
330
+ (0, import_form_utils.dispatchInputCheckedEvent)(el, !!evt.value);
331
+ },
332
+ syncInputElements(ctx2) {
333
+ const inputs = dom.getInputEls(ctx2);
334
+ inputs.forEach((input) => {
335
+ input.checked = input.value === ctx2.value;
336
+ });
451
337
  }
452
338
  }
453
339
  }
package/dist/index.mjs CHANGED
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-F57UWPRI.mjs";
3
+ } from "./chunk-57ZUFOAP.mjs";
4
4
  import {
5
5
  anatomy
6
6
  } from "./chunk-MGLN5L3R.mjs";
7
7
  import {
8
8
  machine
9
- } from "./chunk-IKYBQJIH.mjs";
10
- import "./chunk-CYVZAWTC.mjs";
9
+ } from "./chunk-DYVEYVKH.mjs";
10
+ import "./chunk-ITVKBCBK.mjs";
11
11
  export {
12
12
  anatomy,
13
13
  connect,
@@ -3,10 +3,39 @@ import { State, Send, RadioProps, InputProps } from './radio-group.types.js';
3
3
  import '@zag-js/core';
4
4
 
5
5
  declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): {
6
+ /**
7
+ * The current value of the radio group
8
+ */
6
9
  value: string | null;
10
+ /**
11
+ * Function to set the value of the radio group
12
+ */
7
13
  setValue(value: string): void;
14
+ /**
15
+ * Function to clear the value of the radio group
16
+ */
17
+ clearValue(): void;
18
+ /**
19
+ * Function to focus the radio group
20
+ */
8
21
  focus: () => void;
22
+ /**
23
+ * Function to blur the currently focused radio input in the radio group
24
+ */
9
25
  blur(): void;
26
+ /**
27
+ * Returns the state details of a radio input
28
+ */
29
+ getRadioState: <T_1 extends RadioProps>(props: T_1) => {
30
+ isInteractive: boolean;
31
+ isReadOnly: boolean | undefined;
32
+ isInvalid: boolean | undefined;
33
+ isDisabled: boolean | undefined;
34
+ isChecked: boolean;
35
+ isFocused: boolean;
36
+ isHovered: boolean;
37
+ isActive: boolean;
38
+ };
10
39
  rootProps: T["element"];
11
40
  labelProps: T["element"];
12
41
  getRadioProps(props: RadioProps): T["label"];
@@ -23,61 +23,8 @@ __export(radio_group_connect_exports, {
23
23
  connect: () => connect
24
24
  });
25
25
  module.exports = __toCommonJS(radio_group_connect_exports);
26
-
27
- // ../../utilities/dom/src/attrs.ts
28
- var dataAttr = (guard) => {
29
- return guard ? "" : void 0;
30
- };
31
- var ariaAttr = (guard) => {
32
- return guard ? "true" : void 0;
33
- };
34
-
35
- // ../../utilities/dom/src/query.ts
36
- function isDocument(el) {
37
- return el.nodeType === Node.DOCUMENT_NODE;
38
- }
39
- function isWindow(value) {
40
- return value?.toString() === "[object Window]";
41
- }
42
- function getDocument(el) {
43
- if (isWindow(el))
44
- return el.document;
45
- if (isDocument(el))
46
- return el;
47
- return el?.ownerDocument ?? document;
48
- }
49
- function defineDomHelpers(helpers) {
50
- const dom2 = {
51
- getRootNode: (ctx) => ctx.getRootNode?.() ?? document,
52
- getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
53
- getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
54
- getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
55
- getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
56
- };
57
- return {
58
- ...dom2,
59
- ...helpers
60
- };
61
- }
62
-
63
- // ../../utilities/dom/src/nodelist.ts
64
- function queryAll(root, selector) {
65
- return Array.from(root?.querySelectorAll(selector) ?? []);
66
- }
67
-
68
- // ../../utilities/dom/src/visually-hidden.ts
69
- var visuallyHiddenStyle = {
70
- border: "0",
71
- clip: "rect(0 0 0 0)",
72
- height: "1px",
73
- margin: "-1px",
74
- overflow: "hidden",
75
- padding: "0",
76
- position: "absolute",
77
- width: "1px",
78
- whiteSpace: "nowrap",
79
- wordWrap: "normal"
80
- };
26
+ var import_dom_query2 = require("@zag-js/dom-query");
27
+ var import_visually_hidden = require("@zag-js/visually-hidden");
81
28
 
82
29
  // src/radio-group.anatomy.ts
83
30
  var import_anatomy = require("@zag-js/anatomy");
@@ -92,7 +39,8 @@ var anatomy = (0, import_anatomy.createAnatomy)("radio-group").parts(
92
39
  var parts = anatomy.build();
93
40
 
94
41
  // src/radio-group.dom.ts
95
- var dom = defineDomHelpers({
42
+ var import_dom_query = require("@zag-js/dom-query");
43
+ var dom = (0, import_dom_query.createScope)({
96
44
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
97
45
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
98
46
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
@@ -106,7 +54,7 @@ var dom = defineDomHelpers({
106
54
  getInputEls: (ctx) => {
107
55
  const ownerId = CSS.escape(dom.getRootId(ctx));
108
56
  const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`;
109
- return queryAll(dom.getRootEl(ctx), selector);
57
+ return (0, import_dom_query.queryAll)(dom.getRootEl(ctx), selector);
110
58
  }
111
59
  });
112
60
 
@@ -132,12 +80,12 @@ function connect(state, send, normalize) {
132
80
  function getRadioDataSet(props) {
133
81
  const radioState = getRadioState(props);
134
82
  return {
135
- "data-focus": dataAttr(radioState.isFocused),
136
- "data-disabled": dataAttr(radioState.isDisabled),
137
- "data-checked": dataAttr(radioState.isChecked),
138
- "data-hover": dataAttr(radioState.isHovered),
139
- "data-invalid": dataAttr(radioState.isInvalid),
140
- "data-readonly": dataAttr(radioState.isReadOnly)
83
+ "data-focus": (0, import_dom_query2.dataAttr)(radioState.isFocused),
84
+ "data-disabled": (0, import_dom_query2.dataAttr)(radioState.isDisabled),
85
+ "data-checked": (0, import_dom_query2.dataAttr)(radioState.isChecked),
86
+ "data-hover": (0, import_dom_query2.dataAttr)(radioState.isHovered),
87
+ "data-invalid": (0, import_dom_query2.dataAttr)(radioState.isInvalid),
88
+ "data-readonly": (0, import_dom_query2.dataAttr)(radioState.isReadOnly)
141
89
  };
142
90
  }
143
91
  const focus = () => {
@@ -150,11 +98,29 @@ function connect(state, send, normalize) {
150
98
  firstEnabledInput?.focus();
151
99
  };
152
100
  return {
101
+ /**
102
+ * The current value of the radio group
103
+ */
153
104
  value: state.context.value,
105
+ /**
106
+ * Function to set the value of the radio group
107
+ */
154
108
  setValue(value) {
155
109
  send({ type: "SET_VALUE", value, manual: true });
156
110
  },
111
+ /**
112
+ * Function to clear the value of the radio group
113
+ */
114
+ clearValue() {
115
+ send({ type: "SET_VALUE", value: null, manual: true });
116
+ },
117
+ /**
118
+ * Function to focus the radio group
119
+ */
157
120
  focus,
121
+ /**
122
+ * Function to blur the currently focused radio input in the radio group
123
+ */
158
124
  blur() {
159
125
  const focusedElement = dom.getActiveElement(state.context);
160
126
  const inputEls = dom.getInputEls(state.context);
@@ -162,10 +128,15 @@ function connect(state, send, normalize) {
162
128
  if (radioInputIsFocused)
163
129
  focusedElement?.blur();
164
130
  },
131
+ /**
132
+ * Returns the state details of a radio input
133
+ */
134
+ getRadioState,
165
135
  rootProps: normalize.element({
166
136
  ...parts.root.attrs,
167
137
  role: "radiogroup",
168
138
  id: dom.getRootId(state.context),
139
+ "aria-labelledby": dom.getLabelId(state.context),
169
140
  "data-orientation": state.context.orientation,
170
141
  "aria-orientation": state.context.orientation,
171
142
  dir: state.context.dir
@@ -218,7 +189,7 @@ function connect(state, send, normalize) {
218
189
  return normalize.element({
219
190
  ...parts.radioControl.attrs,
220
191
  id: dom.getRadioControlId(state.context, props.value),
221
- "data-active": dataAttr(controlState.isActive),
192
+ "data-active": (0, import_dom_query2.dataAttr)(controlState.isActive),
222
193
  "aria-hidden": true,
223
194
  ...getRadioDataSet(props)
224
195
  });
@@ -262,14 +233,14 @@ function connect(state, send, normalize) {
262
233
  disabled: trulyDisabled,
263
234
  required: isRequired,
264
235
  defaultChecked: inputState.isChecked,
265
- "data-disabled": dataAttr(inputState.isDisabled),
266
- "aria-required": ariaAttr(isRequired),
267
- "aria-invalid": ariaAttr(inputState.isInvalid),
236
+ "data-disabled": (0, import_dom_query2.dataAttr)(inputState.isDisabled),
237
+ "aria-required": (0, import_dom_query2.ariaAttr)(isRequired),
238
+ "aria-invalid": (0, import_dom_query2.ariaAttr)(inputState.isInvalid),
268
239
  readOnly: inputState.isReadOnly,
269
- "data-readonly": dataAttr(inputState.isReadOnly),
270
- "aria-disabled": ariaAttr(trulyDisabled),
271
- "aria-checked": ariaAttr(inputState.isChecked),
272
- style: visuallyHiddenStyle
240
+ "data-readonly": (0, import_dom_query2.dataAttr)(inputState.isReadOnly),
241
+ "aria-disabled": (0, import_dom_query2.ariaAttr)(trulyDisabled),
242
+ "aria-checked": (0, import_dom_query2.ariaAttr)(inputState.isChecked),
243
+ style: import_visually_hidden.visuallyHiddenStyle
273
244
  });
274
245
  }
275
246
  };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  connect
3
- } from "./chunk-F57UWPRI.mjs";
3
+ } from "./chunk-57ZUFOAP.mjs";
4
4
  import "./chunk-MGLN5L3R.mjs";
5
- import "./chunk-CYVZAWTC.mjs";
5
+ import "./chunk-ITVKBCBK.mjs";
6
6
  export {
7
7
  connect
8
8
  };
@@ -15,9 +15,12 @@ declare const dom: {
15
15
  getActiveElement: (ctx: {
16
16
  getRootNode?: (() => Node | Document | ShadowRoot) | undefined;
17
17
  }) => HTMLElement | null;
18
- getById: <T = HTMLElement>(ctx: {
18
+ getById: <T extends HTMLElement = HTMLElement>(ctx: {
19
19
  getRootNode?: (() => Node | Document | ShadowRoot) | undefined;
20
20
  }, id: string) => T | null;
21
+ queryById: <T_1 extends HTMLElement = HTMLElement>(ctx: {
22
+ getRootNode?: (() => Node | Document | ShadowRoot) | undefined;
23
+ }, id: string) => T_1;
21
24
  } & {
22
25
  getRootId: (ctx: MachineContext) => string;
23
26
  getLabelId: (ctx: MachineContext) => string;
@@ -29,7 +32,7 @@ declare const dom: {
29
32
  getRadioInputEl: (ctx: MachineContext, value: string) => HTMLInputElement | null;
30
33
  getFirstEnabledInputEl: (ctx: MachineContext) => HTMLInputElement | null | undefined;
31
34
  getFirstEnabledAndCheckedInputEl: (ctx: MachineContext) => HTMLInputElement | null | undefined;
32
- getInputEls: (ctx: MachineContext) => HTMLElement[];
35
+ getInputEls: (ctx: MachineContext) => HTMLInputElement[];
33
36
  };
34
37
 
35
38
  export { dom };
@@ -23,42 +23,8 @@ __export(radio_group_dom_exports, {
23
23
  dom: () => dom
24
24
  });
25
25
  module.exports = __toCommonJS(radio_group_dom_exports);
26
-
27
- // ../../utilities/dom/src/query.ts
28
- function isDocument(el) {
29
- return el.nodeType === Node.DOCUMENT_NODE;
30
- }
31
- function isWindow(value) {
32
- return value?.toString() === "[object Window]";
33
- }
34
- function getDocument(el) {
35
- if (isWindow(el))
36
- return el.document;
37
- if (isDocument(el))
38
- return el;
39
- return el?.ownerDocument ?? document;
40
- }
41
- function defineDomHelpers(helpers) {
42
- const dom2 = {
43
- getRootNode: (ctx) => ctx.getRootNode?.() ?? document,
44
- getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
45
- getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
46
- getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
47
- getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
48
- };
49
- return {
50
- ...dom2,
51
- ...helpers
52
- };
53
- }
54
-
55
- // ../../utilities/dom/src/nodelist.ts
56
- function queryAll(root, selector) {
57
- return Array.from(root?.querySelectorAll(selector) ?? []);
58
- }
59
-
60
- // src/radio-group.dom.ts
61
- var dom = defineDomHelpers({
26
+ var import_dom_query = require("@zag-js/dom-query");
27
+ var dom = (0, import_dom_query.createScope)({
62
28
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
63
29
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
64
30
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
@@ -72,7 +38,7 @@ var dom = defineDomHelpers({
72
38
  getInputEls: (ctx) => {
73
39
  const ownerId = CSS.escape(dom.getRootId(ctx));
74
40
  const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`;
75
- return queryAll(dom.getRootEl(ctx), selector);
41
+ return (0, import_dom_query.queryAll)(dom.getRootEl(ctx), selector);
76
42
  }
77
43
  });
78
44
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  dom
3
- } from "./chunk-CYVZAWTC.mjs";
3
+ } from "./chunk-ITVKBCBK.mjs";
4
4
  export {
5
5
  dom
6
6
  };
@@ -24,135 +24,12 @@ __export(radio_group_machine_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(radio_group_machine_exports);
26
26
  var import_core = require("@zag-js/core");
27
-
28
- // ../../utilities/core/src/guard.ts
29
- var isArray = (v) => Array.isArray(v);
30
- var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
31
-
32
- // ../../utilities/core/src/object.ts
33
- function compact(obj) {
34
- if (obj === void 0)
35
- return obj;
36
- return Object.fromEntries(
37
- Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
38
- );
39
- }
40
-
41
- // ../../utilities/dom/src/query.ts
42
- function isDocument(el) {
43
- return el.nodeType === Node.DOCUMENT_NODE;
44
- }
45
- function isWindow(value) {
46
- return value?.toString() === "[object Window]";
47
- }
48
- function getDocument(el) {
49
- if (isWindow(el))
50
- return el.document;
51
- if (isDocument(el))
52
- return el;
53
- return el?.ownerDocument ?? document;
54
- }
55
- function getWindow(el) {
56
- return el?.ownerDocument.defaultView ?? window;
57
- }
58
- function defineDomHelpers(helpers) {
59
- const dom2 = {
60
- getRootNode: (ctx) => ctx.getRootNode?.() ?? document,
61
- getDoc: (ctx) => getDocument(dom2.getRootNode(ctx)),
62
- getWin: (ctx) => dom2.getDoc(ctx).defaultView ?? window,
63
- getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
64
- getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
65
- };
66
- return {
67
- ...dom2,
68
- ...helpers
69
- };
70
- }
71
-
72
- // ../../utilities/dom/src/mutation-observer.ts
73
- function observeAttributes(node, attributes, fn) {
74
- if (!node)
75
- return;
76
- const attrs = Array.isArray(attributes) ? attributes : [attributes];
77
- const win = node.ownerDocument.defaultView || window;
78
- const obs = new win.MutationObserver((changes) => {
79
- for (const change of changes) {
80
- if (change.type === "attributes" && change.attributeName && attrs.includes(change.attributeName)) {
81
- fn(change);
82
- }
83
- }
84
- });
85
- obs.observe(node, { attributes: true, attributeFilter: attrs });
86
- return () => obs.disconnect();
87
- }
88
-
89
- // ../../utilities/dom/src/nodelist.ts
90
- function queryAll(root, selector) {
91
- return Array.from(root?.querySelectorAll(selector) ?? []);
92
- }
93
-
94
- // ../../utilities/form-utils/src/input-event.ts
95
- function getDescriptor(el, options) {
96
- const { type, property = "value" } = options;
97
- const proto = getWindow(el)[type].prototype;
98
- return Object.getOwnPropertyDescriptor(proto, property) ?? {};
99
- }
100
- function dispatchInputCheckedEvent(el, checked) {
101
- if (!el)
102
- return;
103
- const win = getWindow(el);
104
- if (!(el instanceof win.HTMLInputElement))
105
- return;
106
- const desc = getDescriptor(el, { type: "HTMLInputElement", property: "checked" });
107
- desc.set?.call(el, checked);
108
- const event = new win.Event("click", { bubbles: true });
109
- el.dispatchEvent(event);
110
- }
111
-
112
- // ../../utilities/form-utils/src/form.ts
113
- function getClosestForm(el) {
114
- if (isFormElement(el))
115
- return el.form;
116
- else
117
- return el.closest("form");
118
- }
119
- function isFormElement(el) {
120
- return el.matches("textarea, input, select, button");
121
- }
122
- function trackFormReset(el, callback) {
123
- if (!el)
124
- return;
125
- const form = getClosestForm(el);
126
- form?.addEventListener("reset", callback, { passive: true });
127
- return () => {
128
- form?.removeEventListener("reset", callback);
129
- };
130
- }
131
- function trackFieldsetDisabled(el, callback) {
132
- const fieldset = el?.closest("fieldset");
133
- if (!fieldset)
134
- return;
135
- callback(fieldset.disabled);
136
- return observeAttributes(fieldset, ["disabled"], () => callback(fieldset.disabled));
137
- }
138
- function trackFormControl(el, options) {
139
- if (!el)
140
- return;
141
- const { onFieldsetDisabled, onFormReset } = options;
142
- const cleanups = [
143
- trackFormReset(el, onFormReset),
144
- trackFieldsetDisabled(el, (disabled) => {
145
- if (disabled)
146
- onFieldsetDisabled();
147
- })
148
- ];
149
- return () => {
150
- cleanups.forEach((cleanup) => cleanup?.());
151
- };
152
- }
27
+ var import_form_utils = require("@zag-js/form-utils");
28
+ var import_utils = require("@zag-js/utils");
153
29
 
154
30
  // src/radio-group.dom.ts
155
- var dom = defineDomHelpers({
31
+ var import_dom_query = require("@zag-js/dom-query");
32
+ var dom = (0, import_dom_query.createScope)({
156
33
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
157
34
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
158
35
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
@@ -166,13 +43,13 @@ var dom = defineDomHelpers({
166
43
  getInputEls: (ctx) => {
167
44
  const ownerId = CSS.escape(dom.getRootId(ctx));
168
45
  const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`;
169
- return queryAll(dom.getRootEl(ctx), selector);
46
+ return (0, import_dom_query.queryAll)(dom.getRootEl(ctx), selector);
170
47
  }
171
48
  });
172
49
 
173
50
  // src/radio-group.machine.ts
174
51
  function machine(userContext) {
175
- const ctx = compact(userContext);
52
+ const ctx = (0, import_utils.compact)(userContext);
176
53
  return (0, import_core.createMachine)(
177
54
  {
178
55
  id: "radio",
@@ -201,7 +78,7 @@ function machine(userContext) {
201
78
  }
202
79
  },
203
80
  watch: {
204
- value: ["dispatchChangeEvent", "invokeOnChange"]
81
+ value: ["dispatchChangeEvent", "invokeOnChange", "syncInputElements"]
205
82
  },
206
83
  entry: ["checkValue"],
207
84
  states: {
@@ -211,7 +88,7 @@ function machine(userContext) {
211
88
  {
212
89
  activities: {
213
90
  trackFormControlState(ctx2, _evt, { send }) {
214
- return trackFormControl(dom.getRootEl(ctx2), {
91
+ return (0, import_form_utils.trackFormControl)(dom.getRootEl(ctx2), {
215
92
  onFieldsetDisabled() {
216
93
  ctx2.disabled = true;
217
94
  },
@@ -244,7 +121,13 @@ function machine(userContext) {
244
121
  if (!evt.manual)
245
122
  return;
246
123
  const el = dom.getRadioInputEl(ctx2, evt.value);
247
- dispatchInputCheckedEvent(el, !!evt.value);
124
+ (0, import_form_utils.dispatchInputCheckedEvent)(el, !!evt.value);
125
+ },
126
+ syncInputElements(ctx2) {
127
+ const inputs = dom.getInputEls(ctx2);
128
+ inputs.forEach((input) => {
129
+ input.checked = input.value === ctx2.value;
130
+ });
248
131
  }
249
132
  }
250
133
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  machine
3
- } from "./chunk-IKYBQJIH.mjs";
4
- import "./chunk-CYVZAWTC.mjs";
3
+ } from "./chunk-DYVEYVKH.mjs";
4
+ import "./chunk-ITVKBCBK.mjs";
5
5
  export {
6
6
  machine
7
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/radio-group",
3
- "version": "0.1.11",
3
+ "version": "0.2.0",
4
4
  "description": "Core logic for the radio group widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -27,15 +27,16 @@
27
27
  "url": "https://github.com/chakra-ui/zag/issues"
28
28
  },
29
29
  "dependencies": {
30
+ "@zag-js/dom-query": "0.1.3",
30
31
  "@zag-js/anatomy": "0.1.4",
31
- "@zag-js/core": "0.2.8",
32
+ "@zag-js/core": "0.2.10",
33
+ "@zag-js/form-utils": "0.2.5",
34
+ "@zag-js/visually-hidden": "0.0.1",
35
+ "@zag-js/utils": "0.3.3",
32
36
  "@zag-js/types": "0.3.4"
33
37
  },
34
38
  "devDependencies": {
35
- "clean-package": "2.2.0",
36
- "@zag-js/dom-utils": "0.2.4",
37
- "@zag-js/form-utils": "0.2.4",
38
- "@zag-js/utils": "0.3.3"
39
+ "clean-package": "2.2.0"
39
40
  },
40
41
  "clean-package": "../../../clean-package.config.json",
41
42
  "main": "dist/index.js",
@@ -1,182 +0,0 @@
1
- import {
2
- dom,
3
- getWindow
4
- } from "./chunk-CYVZAWTC.mjs";
5
-
6
- // src/radio-group.machine.ts
7
- import { createMachine } from "@zag-js/core";
8
-
9
- // ../../utilities/core/src/guard.ts
10
- var isArray = (v) => Array.isArray(v);
11
- var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
12
-
13
- // ../../utilities/core/src/object.ts
14
- function compact(obj) {
15
- if (obj === void 0)
16
- return obj;
17
- return Object.fromEntries(
18
- Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
19
- );
20
- }
21
-
22
- // ../../utilities/dom/src/mutation-observer.ts
23
- function observeAttributes(node, attributes, fn) {
24
- if (!node)
25
- return;
26
- const attrs = Array.isArray(attributes) ? attributes : [attributes];
27
- const win = node.ownerDocument.defaultView || window;
28
- const obs = new win.MutationObserver((changes) => {
29
- for (const change of changes) {
30
- if (change.type === "attributes" && change.attributeName && attrs.includes(change.attributeName)) {
31
- fn(change);
32
- }
33
- }
34
- });
35
- obs.observe(node, { attributes: true, attributeFilter: attrs });
36
- return () => obs.disconnect();
37
- }
38
-
39
- // ../../utilities/form-utils/src/input-event.ts
40
- function getDescriptor(el, options) {
41
- const { type, property = "value" } = options;
42
- const proto = getWindow(el)[type].prototype;
43
- return Object.getOwnPropertyDescriptor(proto, property) ?? {};
44
- }
45
- function dispatchInputCheckedEvent(el, checked) {
46
- if (!el)
47
- return;
48
- const win = getWindow(el);
49
- if (!(el instanceof win.HTMLInputElement))
50
- return;
51
- const desc = getDescriptor(el, { type: "HTMLInputElement", property: "checked" });
52
- desc.set?.call(el, checked);
53
- const event = new win.Event("click", { bubbles: true });
54
- el.dispatchEvent(event);
55
- }
56
-
57
- // ../../utilities/form-utils/src/form.ts
58
- function getClosestForm(el) {
59
- if (isFormElement(el))
60
- return el.form;
61
- else
62
- return el.closest("form");
63
- }
64
- function isFormElement(el) {
65
- return el.matches("textarea, input, select, button");
66
- }
67
- function trackFormReset(el, callback) {
68
- if (!el)
69
- return;
70
- const form = getClosestForm(el);
71
- form?.addEventListener("reset", callback, { passive: true });
72
- return () => {
73
- form?.removeEventListener("reset", callback);
74
- };
75
- }
76
- function trackFieldsetDisabled(el, callback) {
77
- const fieldset = el?.closest("fieldset");
78
- if (!fieldset)
79
- return;
80
- callback(fieldset.disabled);
81
- return observeAttributes(fieldset, ["disabled"], () => callback(fieldset.disabled));
82
- }
83
- function trackFormControl(el, options) {
84
- if (!el)
85
- return;
86
- const { onFieldsetDisabled, onFormReset } = options;
87
- const cleanups = [
88
- trackFormReset(el, onFormReset),
89
- trackFieldsetDisabled(el, (disabled) => {
90
- if (disabled)
91
- onFieldsetDisabled();
92
- })
93
- ];
94
- return () => {
95
- cleanups.forEach((cleanup) => cleanup?.());
96
- };
97
- }
98
-
99
- // src/radio-group.machine.ts
100
- function machine(userContext) {
101
- const ctx = compact(userContext);
102
- return createMachine(
103
- {
104
- id: "radio",
105
- initial: "idle",
106
- context: {
107
- value: null,
108
- initialValue: null,
109
- activeId: null,
110
- focusedId: null,
111
- hoveredId: null,
112
- ...ctx
113
- },
114
- activities: ["trackFormControlState"],
115
- on: {
116
- SET_VALUE: {
117
- actions: ["setValue"]
118
- },
119
- SET_HOVERED: {
120
- actions: "setHovered"
121
- },
122
- SET_ACTIVE: {
123
- actions: "setActive"
124
- },
125
- SET_FOCUSED: {
126
- actions: "setFocused"
127
- }
128
- },
129
- watch: {
130
- value: ["dispatchChangeEvent", "invokeOnChange"]
131
- },
132
- entry: ["checkValue"],
133
- states: {
134
- idle: {}
135
- }
136
- },
137
- {
138
- activities: {
139
- trackFormControlState(ctx2, _evt, { send }) {
140
- return trackFormControl(dom.getRootEl(ctx2), {
141
- onFieldsetDisabled() {
142
- ctx2.disabled = true;
143
- },
144
- onFormReset() {
145
- send({ type: "SET_VALUE", value: ctx2.initialValue });
146
- }
147
- });
148
- }
149
- },
150
- actions: {
151
- checkValue(ctx2) {
152
- ctx2.initialValue = ctx2.value;
153
- },
154
- setValue(ctx2, evt) {
155
- ctx2.value = evt.value;
156
- },
157
- setHovered(ctx2, evt) {
158
- ctx2.hoveredId = evt.value;
159
- },
160
- setActive(ctx2, evt) {
161
- ctx2.activeId = evt.value;
162
- },
163
- setFocused(ctx2, evt) {
164
- ctx2.focusedId = evt.value;
165
- },
166
- invokeOnChange(ctx2, evt) {
167
- ctx2.onChange?.({ value: evt.value });
168
- },
169
- dispatchChangeEvent(ctx2, evt) {
170
- if (!evt.manual)
171
- return;
172
- const el = dom.getRadioInputEl(ctx2, evt.value);
173
- dispatchInputCheckedEvent(el, !!evt.value);
174
- }
175
- }
176
- }
177
- );
178
- }
179
-
180
- export {
181
- machine
182
- };