@zag-js/radio-group 0.15.0 → 0.17.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.
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as _zag_js_anatomy from '@zag-js/anatomy';
2
- import { PropTypes, RequiredBy, DirectionProperty, CommonProperties, Context, NormalizeProps } from '@zag-js/types';
2
+ import { RequiredBy, PropTypes, DirectionProperty, CommonProperties, Context, NormalizeProps } from '@zag-js/types';
3
3
  import * as _zag_js_core from '@zag-js/core';
4
4
  import { StateMachine } from '@zag-js/core';
5
5
 
6
- declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "radio" | "radioLabel" | "radioControl" | "radioInput" | "indicator">;
6
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "radio" | "radioLabel" | "radioControl" | "indicator">;
7
7
 
8
8
  type ElementIds = Partial<{
9
9
  root: string;
@@ -12,7 +12,7 @@ type ElementIds = Partial<{
12
12
  radio(value: string): string;
13
13
  radioLabel(value: string): string;
14
14
  radioControl(value: string): string;
15
- radioInput(value: string): string;
15
+ radioHiddenInput(value: string): string;
16
16
  }>;
17
17
  type PublicContext = DirectionProperty & CommonProperties & {
18
18
  /**
@@ -52,7 +52,47 @@ type PublicContext = DirectionProperty & CommonProperties & {
52
52
  */
53
53
  orientation?: "horizontal" | "vertical";
54
54
  };
55
- type PublicApi<T extends PropTypes = PropTypes> = {
55
+ type PrivateContext = Context<{}>;
56
+ type UserDefinedContext = RequiredBy<PublicContext, "id">;
57
+ type ComputedContext = Readonly<{
58
+ /**
59
+ * Whether the radio group is disabled
60
+ */
61
+ isDisabled: boolean;
62
+ }>;
63
+ type MachineContext = PublicContext & PrivateContext & ComputedContext;
64
+ type MachineState = {
65
+ value: "idle";
66
+ };
67
+ type State = StateMachine.State<MachineContext, MachineState>;
68
+ type Send = StateMachine.Send<StateMachine.AnyEventObject>;
69
+ type RadioProps = {
70
+ value: string;
71
+ /**
72
+ * If `true`, the radio will be disabled
73
+ */
74
+ disabled?: boolean;
75
+ /**
76
+ * If `true`, the radio will be readonly
77
+ */
78
+ readOnly?: boolean;
79
+ /**
80
+ * If `true`, the radio is marked as invalid.
81
+ */
82
+ invalid?: boolean;
83
+ };
84
+ type InputProps = RadioProps & {
85
+ /**
86
+ * If `true` and `disabled` is passed, the radio will
87
+ * remain tabbable but not interactive
88
+ */
89
+ focusable?: boolean;
90
+ /**
91
+ * If `true`, the radio input is marked as required,
92
+ */
93
+ required?: boolean;
94
+ };
95
+ type MachineApi<T extends PropTypes = PropTypes> = {
56
96
  /**
57
97
  * The current value of the radio group
58
98
  */
@@ -90,47 +130,12 @@ type PublicApi<T extends PropTypes = PropTypes> = {
90
130
  getRadioProps(props: RadioProps): T["label"];
91
131
  getRadioLabelProps(props: RadioProps): T["element"];
92
132
  getRadioControlProps(props: RadioProps): T["element"];
93
- getRadioInputProps(props: InputProps): T["input"];
133
+ getRadioHiddenInputProps(props: InputProps): T["input"];
94
134
  indicatorProps: T["element"];
95
135
  };
96
- type PrivateContext = Context<{}>;
97
- type UserDefinedContext = RequiredBy<PublicContext, "id">;
98
- type ComputedContext = Readonly<{}>;
99
- type MachineContext = PublicContext & PrivateContext & ComputedContext;
100
- type MachineState = {
101
- value: "idle";
102
- };
103
- type State = StateMachine.State<MachineContext, MachineState>;
104
- type Send = StateMachine.Send<StateMachine.AnyEventObject>;
105
- type RadioProps = {
106
- value: string;
107
- /**
108
- * If `true`, the radio will be disabled
109
- */
110
- disabled?: boolean;
111
- /**
112
- * If `true`, the radio will be readonly
113
- */
114
- readOnly?: boolean;
115
- /**
116
- * If `true`, the radio is marked as invalid.
117
- */
118
- invalid?: boolean;
119
- };
120
- type InputProps = RadioProps & {
121
- /**
122
- * If `true` and `disabled` is passed, the radio will
123
- * remain tabbable but not interactive
124
- */
125
- focusable?: boolean;
126
- /**
127
- * If `true`, the radio input is marked as required,
128
- */
129
- required?: boolean;
130
- };
131
136
 
132
- declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): PublicApi<T>;
137
+ declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T>;
133
138
 
134
139
  declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
135
140
 
136
- export { UserDefinedContext as Context, PublicApi, anatomy, connect, machine };
141
+ export { MachineApi as Api, UserDefinedContext as Context, anatomy, connect, machine };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as _zag_js_anatomy from '@zag-js/anatomy';
2
- import { PropTypes, RequiredBy, DirectionProperty, CommonProperties, Context, NormalizeProps } from '@zag-js/types';
2
+ import { RequiredBy, PropTypes, DirectionProperty, CommonProperties, Context, NormalizeProps } from '@zag-js/types';
3
3
  import * as _zag_js_core from '@zag-js/core';
4
4
  import { StateMachine } from '@zag-js/core';
5
5
 
6
- declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "radio" | "radioLabel" | "radioControl" | "radioInput" | "indicator">;
6
+ declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "label" | "radio" | "radioLabel" | "radioControl" | "indicator">;
7
7
 
8
8
  type ElementIds = Partial<{
9
9
  root: string;
@@ -12,7 +12,7 @@ type ElementIds = Partial<{
12
12
  radio(value: string): string;
13
13
  radioLabel(value: string): string;
14
14
  radioControl(value: string): string;
15
- radioInput(value: string): string;
15
+ radioHiddenInput(value: string): string;
16
16
  }>;
17
17
  type PublicContext = DirectionProperty & CommonProperties & {
18
18
  /**
@@ -52,7 +52,47 @@ type PublicContext = DirectionProperty & CommonProperties & {
52
52
  */
53
53
  orientation?: "horizontal" | "vertical";
54
54
  };
55
- type PublicApi<T extends PropTypes = PropTypes> = {
55
+ type PrivateContext = Context<{}>;
56
+ type UserDefinedContext = RequiredBy<PublicContext, "id">;
57
+ type ComputedContext = Readonly<{
58
+ /**
59
+ * Whether the radio group is disabled
60
+ */
61
+ isDisabled: boolean;
62
+ }>;
63
+ type MachineContext = PublicContext & PrivateContext & ComputedContext;
64
+ type MachineState = {
65
+ value: "idle";
66
+ };
67
+ type State = StateMachine.State<MachineContext, MachineState>;
68
+ type Send = StateMachine.Send<StateMachine.AnyEventObject>;
69
+ type RadioProps = {
70
+ value: string;
71
+ /**
72
+ * If `true`, the radio will be disabled
73
+ */
74
+ disabled?: boolean;
75
+ /**
76
+ * If `true`, the radio will be readonly
77
+ */
78
+ readOnly?: boolean;
79
+ /**
80
+ * If `true`, the radio is marked as invalid.
81
+ */
82
+ invalid?: boolean;
83
+ };
84
+ type InputProps = RadioProps & {
85
+ /**
86
+ * If `true` and `disabled` is passed, the radio will
87
+ * remain tabbable but not interactive
88
+ */
89
+ focusable?: boolean;
90
+ /**
91
+ * If `true`, the radio input is marked as required,
92
+ */
93
+ required?: boolean;
94
+ };
95
+ type MachineApi<T extends PropTypes = PropTypes> = {
56
96
  /**
57
97
  * The current value of the radio group
58
98
  */
@@ -90,47 +130,12 @@ type PublicApi<T extends PropTypes = PropTypes> = {
90
130
  getRadioProps(props: RadioProps): T["label"];
91
131
  getRadioLabelProps(props: RadioProps): T["element"];
92
132
  getRadioControlProps(props: RadioProps): T["element"];
93
- getRadioInputProps(props: InputProps): T["input"];
133
+ getRadioHiddenInputProps(props: InputProps): T["input"];
94
134
  indicatorProps: T["element"];
95
135
  };
96
- type PrivateContext = Context<{}>;
97
- type UserDefinedContext = RequiredBy<PublicContext, "id">;
98
- type ComputedContext = Readonly<{}>;
99
- type MachineContext = PublicContext & PrivateContext & ComputedContext;
100
- type MachineState = {
101
- value: "idle";
102
- };
103
- type State = StateMachine.State<MachineContext, MachineState>;
104
- type Send = StateMachine.Send<StateMachine.AnyEventObject>;
105
- type RadioProps = {
106
- value: string;
107
- /**
108
- * If `true`, the radio will be disabled
109
- */
110
- disabled?: boolean;
111
- /**
112
- * If `true`, the radio will be readonly
113
- */
114
- readOnly?: boolean;
115
- /**
116
- * If `true`, the radio is marked as invalid.
117
- */
118
- invalid?: boolean;
119
- };
120
- type InputProps = RadioProps & {
121
- /**
122
- * If `true` and `disabled` is passed, the radio will
123
- * remain tabbable but not interactive
124
- */
125
- focusable?: boolean;
126
- /**
127
- * If `true`, the radio input is marked as required,
128
- */
129
- required?: boolean;
130
- };
131
136
 
132
- declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): PublicApi<T>;
137
+ declare function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T>;
133
138
 
134
139
  declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
135
140
 
136
- export { UserDefinedContext as Context, PublicApi, anatomy, connect, machine };
141
+ export { MachineApi as Api, UserDefinedContext as Context, anatomy, connect, machine };
package/dist/index.js CHANGED
@@ -34,7 +34,6 @@ var anatomy = (0, import_anatomy.createAnatomy)("radio-group").parts(
34
34
  "radio",
35
35
  "radioLabel",
36
36
  "radioControl",
37
- "radioInput",
38
37
  "indicator"
39
38
  );
40
39
  var parts = anatomy.build();
@@ -49,12 +48,12 @@ var dom = (0, import_dom_query.createScope)({
49
48
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
50
49
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
51
50
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
52
- getRadioInputId: (ctx, value) => ctx.ids?.radioInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
51
+ getRadioHiddenInputId: (ctx, value) => ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
53
52
  getRadioControlId: (ctx, value) => ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,
54
53
  getRadioLabelId: (ctx, value) => ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,
55
- getIndicatorId: (ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,
54
+ getIndicatorId: (ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,
56
55
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
57
- getRadioInputEl: (ctx, value) => dom.getById(ctx, dom.getRadioInputId(ctx, value)),
56
+ getRadioHiddenInputEl: (ctx, value) => dom.getById(ctx, dom.getRadioHiddenInputId(ctx, value)),
58
57
  getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
59
58
  getFirstEnabledInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled)"),
60
59
  getFirstEnabledAndCheckedInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled):checked"),
@@ -68,33 +67,29 @@ var dom = (0, import_dom_query.createScope)({
68
67
  return;
69
68
  return dom.getById(ctx, dom.getRadioId(ctx, ctx.value));
70
69
  },
71
- getOffsetRect: (el) => {
72
- return {
73
- left: el?.offsetLeft ?? 0,
74
- top: el?.offsetTop ?? 0,
75
- width: el?.offsetWidth ?? 0,
76
- height: el?.offsetHeight ?? 0
77
- };
78
- },
70
+ getOffsetRect: (el) => ({
71
+ left: el?.offsetLeft ?? 0,
72
+ top: el?.offsetTop ?? 0,
73
+ width: el?.offsetWidth ?? 0,
74
+ height: el?.offsetHeight ?? 0
75
+ }),
79
76
  getRectById: (ctx, id) => {
80
77
  const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id));
81
78
  if (!radioEl)
82
79
  return;
83
80
  return dom.resolveRect(dom.getOffsetRect(radioEl));
84
81
  },
85
- resolveRect(rect) {
86
- return {
87
- width: `${rect.width}px`,
88
- height: `${rect.height}px`,
89
- left: `${rect.left}px`,
90
- top: `${rect.top}px`
91
- };
92
- }
82
+ resolveRect: (rect) => ({
83
+ width: `${rect.width}px`,
84
+ height: `${rect.height}px`,
85
+ left: `${rect.left}px`,
86
+ top: `${rect.top}px`
87
+ })
93
88
  });
94
89
 
95
90
  // src/radio-group.connect.ts
96
91
  function connect(state, send, normalize) {
97
- const isGroupDisabled = state.context.disabled;
92
+ const isGroupDisabled = state.context.isDisabled;
98
93
  function getRadioState(props) {
99
94
  const radioState = {
100
95
  isInvalid: props.invalid,
@@ -141,8 +136,8 @@ function connect(state, send, normalize) {
141
136
  blur() {
142
137
  const focusedElement = dom.getActiveElement(state.context);
143
138
  const inputEls = dom.getInputEls(state.context);
144
- const radioInputIsFocused = inputEls.some((el) => el === focusedElement);
145
- if (radioInputIsFocused)
139
+ const radioHiddenInputIsFocused = inputEls.some((el) => el === focusedElement);
140
+ if (radioHiddenInputIsFocused)
146
141
  focusedElement?.blur();
147
142
  },
148
143
  getRadioState,
@@ -168,7 +163,7 @@ function connect(state, send, normalize) {
168
163
  return normalize.label({
169
164
  ...parts.radio.attrs,
170
165
  id: dom.getRadioId(state.context, props.value),
171
- htmlFor: dom.getRadioInputId(state.context, props.value),
166
+ htmlFor: dom.getRadioHiddenInputId(state.context, props.value),
172
167
  ...getRadioDataAttrs(props),
173
168
  onPointerMove() {
174
169
  if (!rootState.isInteractive)
@@ -212,14 +207,13 @@ function connect(state, send, normalize) {
212
207
  ...getRadioDataAttrs(props)
213
208
  });
214
209
  },
215
- getRadioInputProps(props) {
210
+ getRadioHiddenInputProps(props) {
216
211
  const inputState = getRadioState(props);
217
212
  const isRequired = props.required;
218
213
  const trulyDisabled = inputState.isDisabled && !props.focusable;
219
214
  return normalize.input({
220
- ...parts.radioInput.attrs,
221
215
  "data-ownedby": dom.getRootId(state.context),
222
- id: dom.getRadioInputId(state.context, props.value),
216
+ id: dom.getRadioHiddenInputId(state.context, props.value),
223
217
  type: "radio",
224
218
  name: state.context.name || state.context.id,
225
219
  form: state.context.form,
@@ -294,15 +288,20 @@ function machine(userContext) {
294
288
  activeId: null,
295
289
  focusedId: null,
296
290
  hoveredId: null,
291
+ disabled: false,
292
+ ...ctx,
297
293
  indicatorRect: {},
298
294
  canIndicatorTransition: false,
299
- ...ctx
295
+ fieldsetDisabled: false
296
+ },
297
+ computed: {
298
+ isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled
300
299
  },
301
300
  entry: ["syncIndicatorRect"],
302
301
  exit: ["cleanupObserver"],
303
302
  activities: ["trackFormControlState"],
304
303
  watch: {
305
- value: ["setIndicatorTransition", "invokeOnChange", "syncIndicatorRect", "syncInputElements"]
304
+ value: ["setIndicatorTransition", "syncIndicatorRect", "syncInputElements"]
306
305
  },
307
306
  on: {
308
307
  SET_VALUE: {
@@ -326,8 +325,8 @@ function machine(userContext) {
326
325
  activities: {
327
326
  trackFormControlState(ctx2, _evt, { send, initialContext }) {
328
327
  return (0, import_form_utils.trackFormControl)(dom.getRootEl(ctx2), {
329
- onFieldsetDisabled() {
330
- ctx2.disabled = true;
328
+ onFieldsetDisabledChange(disabled) {
329
+ ctx2.fieldsetDisabled = disabled;
331
330
  },
332
331
  onFormReset() {
333
332
  send({ type: "SET_VALUE", value: initialContext.value });
@@ -337,7 +336,7 @@ function machine(userContext) {
337
336
  },
338
337
  actions: {
339
338
  setValue(ctx2, evt) {
340
- ctx2.value = evt.value;
339
+ set.value(ctx2, evt.value);
341
340
  },
342
341
  setHovered(ctx2, evt) {
343
342
  ctx2.hoveredId = evt.value;
@@ -348,9 +347,6 @@ function machine(userContext) {
348
347
  setFocused(ctx2, evt) {
349
348
  ctx2.focusedId = evt.value;
350
349
  },
351
- invokeOnChange(ctx2, evt) {
352
- ctx2.onChange?.({ value: evt.value });
353
- },
354
350
  syncInputElements(ctx2) {
355
351
  const inputs = dom.getInputEls(ctx2);
356
352
  inputs.forEach((input) => {
@@ -391,6 +387,19 @@ function machine(userContext) {
391
387
  }
392
388
  );
393
389
  }
390
+ var invoke = {
391
+ change: (ctx) => {
392
+ if (ctx.value == null)
393
+ return;
394
+ ctx.onChange?.({ value: ctx.value });
395
+ }
396
+ };
397
+ var set = {
398
+ value: (ctx, value) => {
399
+ ctx.value = value;
400
+ invoke.change(ctx);
401
+ }
402
+ };
394
403
  // Annotate the CommonJS export names for ESM import in node:
395
404
  0 && (module.exports = {
396
405
  anatomy,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/radio-group.anatomy.ts","../src/radio-group.connect.ts","../src/radio-group.dom.ts","../src/radio-group.machine.ts"],"sourcesContent":["export { anatomy } from \"./radio-group.anatomy\"\nexport { connect } from \"./radio-group.connect\"\nexport { machine } from \"./radio-group.machine\"\nexport type { UserDefinedContext as Context, PublicApi } from \"./radio-group.types\"\n","import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"radio-group\").parts(\n \"root\",\n \"label\",\n \"radio\",\n \"radioLabel\",\n \"radioControl\",\n \"radioInput\",\n \"indicator\",\n)\nexport const parts = anatomy.build()\n","import { ariaAttr, dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { visuallyHiddenStyle } from \"@zag-js/visually-hidden\"\nimport { parts } from \"./radio-group.anatomy\"\nimport { dom } from \"./radio-group.dom\"\nimport type { InputProps, PublicApi, RadioProps, Send, State } from \"./radio-group.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): PublicApi<T> {\n const isGroupDisabled = state.context.disabled\n\n function getRadioState<T extends RadioProps>(props: T) {\n const radioState = {\n isInvalid: props.invalid,\n isDisabled: props.disabled || isGroupDisabled,\n isChecked: state.context.value === props.value,\n isFocused: state.context.focusedId === props.value,\n isHovered: state.context.hoveredId === props.value,\n isActive: state.context.activeId === props.value,\n }\n return {\n ...radioState,\n isInteractive: !radioState.isDisabled,\n }\n }\n\n function getRadioDataAttrs<T extends RadioProps>(props: T) {\n const radioState = getRadioState(props)\n return {\n \"data-focus\": dataAttr(radioState.isFocused),\n \"data-disabled\": dataAttr(radioState.isDisabled),\n \"data-state\": radioState.isChecked ? \"checked\" : \"unchecked\",\n \"data-hover\": dataAttr(radioState.isHovered),\n \"data-invalid\": dataAttr(radioState.isInvalid),\n \"data-orientation\": state.context.orientation,\n }\n }\n\n const focus = () => {\n const firstEnabledAndCheckedInput = dom.getFirstEnabledAndCheckedInputEl(state.context)\n\n if (firstEnabledAndCheckedInput) {\n firstEnabledAndCheckedInput.focus()\n return\n }\n\n const firstEnabledInput = dom.getFirstEnabledInputEl(state.context)\n firstEnabledInput?.focus()\n }\n\n return {\n value: state.context.value,\n\n setValue(value: string) {\n send({ type: \"SET_VALUE\", value, manual: true })\n },\n\n clearValue() {\n send({ type: \"SET_VALUE\", value: null, manual: true })\n },\n\n focus,\n\n blur() {\n const focusedElement = dom.getActiveElement(state.context)\n const inputEls = dom.getInputEls(state.context)\n const radioInputIsFocused = inputEls.some((el) => el === focusedElement)\n if (radioInputIsFocused) focusedElement?.blur()\n },\n\n getRadioState,\n\n rootProps: normalize.element({\n ...parts.root.attrs,\n role: \"radiogroup\",\n id: dom.getRootId(state.context),\n \"aria-labelledby\": dom.getLabelId(state.context),\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"aria-orientation\": state.context.orientation,\n dir: state.context.dir,\n }),\n\n labelProps: normalize.element({\n ...parts.label.attrs,\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n id: dom.getLabelId(state.context),\n onClick: focus,\n }),\n\n getRadioProps(props: RadioProps) {\n const rootState = getRadioState(props)\n\n return normalize.label({\n ...parts.radio.attrs,\n id: dom.getRadioId(state.context, props.value),\n htmlFor: dom.getRadioInputId(state.context, props.value),\n ...getRadioDataAttrs(props),\n\n onPointerMove() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: props.value, hovered: true })\n },\n onPointerLeave() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: null })\n },\n onPointerDown(event) {\n if (!rootState.isInteractive) return\n // On pointerdown, the input blurs and returns focus to the `body`,\n // we need to prevent this.\n if (rootState.isFocused && event.pointerType === \"mouse\") {\n event.preventDefault()\n }\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n },\n onPointerUp() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_ACTIVE\", value: null })\n },\n })\n },\n\n getRadioLabelProps(props: RadioProps) {\n return normalize.element({\n ...parts.radioLabel.attrs,\n id: dom.getRadioLabelId(state.context, props.value),\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioControlProps(props: RadioProps) {\n const controlState = getRadioState(props)\n\n return normalize.element({\n ...parts.radioControl.attrs,\n id: dom.getRadioControlId(state.context, props.value),\n \"data-active\": dataAttr(controlState.isActive),\n \"aria-hidden\": true,\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioInputProps(props: InputProps) {\n const inputState = getRadioState(props)\n\n const isRequired = props.required\n const trulyDisabled = inputState.isDisabled && !props.focusable\n\n return normalize.input({\n ...parts.radioInput.attrs,\n \"data-ownedby\": dom.getRootId(state.context),\n id: dom.getRadioInputId(state.context, props.value),\n type: \"radio\",\n name: state.context.name || state.context.id,\n form: state.context.form,\n value: props.value,\n onChange(event) {\n if (inputState.isDisabled) return\n\n if (event.target.checked) {\n send({ type: \"SET_VALUE\", value: props.value })\n }\n },\n onBlur() {\n send({ type: \"SET_FOCUSED\", value: null })\n },\n onFocus() {\n send({ type: \"SET_FOCUSED\", value: props.value, focused: true })\n },\n onKeyDown(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n }\n },\n onKeyUp(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: null })\n }\n },\n disabled: trulyDisabled,\n required: isRequired,\n defaultChecked: inputState.isChecked,\n \"data-disabled\": dataAttr(inputState.isDisabled),\n \"aria-required\": ariaAttr(isRequired),\n \"aria-invalid\": ariaAttr(inputState.isInvalid),\n \"aria-disabled\": ariaAttr(trulyDisabled),\n \"aria-checked\": ariaAttr(inputState.isChecked),\n style: visuallyHiddenStyle,\n })\n },\n\n indicatorProps: normalize.element({\n id: dom.getIndicatorId(state.context),\n ...parts.indicator.attrs,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"data-orientation\": state.context.orientation,\n style: {\n \"--transition-duration\": \"150ms\",\n \"--transition-property\": \"left, top, width, height\",\n position: \"absolute\",\n willChange: \"var(--transition-property)\",\n transitionProperty: \"var(--transition-property)\",\n transitionDuration: state.context.canIndicatorTransition ? \"var(--transition-duration)\" : \"0ms\",\n transitionTimingFunction: \"var(--transition-timing-function)\",\n ...state.context.indicatorRect,\n },\n }),\n }\n}\n","import { createScope, queryAll } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./radio-group.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,\n getRadioId: (ctx: Ctx, value: string) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,\n getRadioInputId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,\n getRadioControlId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,\n getRadioLabelId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,\n getIndicatorId: (ctx: Ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getRadioInputEl: (ctx: Ctx, value: string) => dom.getById<HTMLInputElement>(ctx, dom.getRadioInputId(ctx, value)),\n getIndicatorEl: (ctx: Ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),\n\n getFirstEnabledInputEl: (ctx: Ctx) => dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled)\"),\n getFirstEnabledAndCheckedInputEl: (ctx: Ctx) =>\n dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled):checked\"),\n\n getInputEls: (ctx: Ctx) => {\n const ownerId = CSS.escape(dom.getRootId(ctx))\n const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`\n return queryAll<HTMLInputElement>(dom.getRootEl(ctx), selector)\n },\n\n getActiveRadioEl: (ctx: Ctx) => {\n if (!ctx.value) return\n return dom.getById(ctx, dom.getRadioId(ctx, ctx.value))\n },\n\n getOffsetRect: (el: HTMLElement | undefined) => {\n return {\n left: el?.offsetLeft ?? 0,\n top: el?.offsetTop ?? 0,\n width: el?.offsetWidth ?? 0,\n height: el?.offsetHeight ?? 0,\n }\n },\n\n getRectById: (ctx: Ctx, id: string) => {\n const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id))\n if (!radioEl) return\n return dom.resolveRect(dom.getOffsetRect(radioEl))\n },\n\n resolveRect(rect: Record<\"width\" | \"height\" | \"left\" | \"top\", number>) {\n return {\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n }\n },\n})\n","import { createMachine } from \"@zag-js/core\"\nimport { nextTick } from \"@zag-js/dom-query\"\nimport { trackElementRect } from \"@zag-js/element-rect\"\nimport { trackFormControl } from \"@zag-js/form-utils\"\nimport { compact, isString } from \"@zag-js/utils\"\nimport { dom } from \"./radio-group.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./radio-group.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"radio\",\n initial: \"idle\",\n context: {\n value: null,\n activeId: null,\n focusedId: null,\n hoveredId: null,\n indicatorRect: {},\n canIndicatorTransition: false,\n ...ctx,\n },\n\n entry: [\"syncIndicatorRect\"],\n\n exit: [\"cleanupObserver\"],\n\n activities: [\"trackFormControlState\"],\n\n watch: {\n value: [\"setIndicatorTransition\", \"invokeOnChange\", \"syncIndicatorRect\", \"syncInputElements\"],\n },\n\n on: {\n SET_VALUE: {\n actions: [\"setValue\"],\n },\n SET_HOVERED: {\n actions: \"setHovered\",\n },\n SET_ACTIVE: {\n actions: \"setActive\",\n },\n SET_FOCUSED: {\n actions: \"setFocused\",\n },\n },\n\n states: {\n idle: {},\n },\n },\n\n {\n activities: {\n trackFormControlState(ctx, _evt, { send, initialContext }) {\n return trackFormControl(dom.getRootEl(ctx), {\n onFieldsetDisabled() {\n ctx.disabled = true\n },\n onFormReset() {\n send({ type: \"SET_VALUE\", value: initialContext.value })\n },\n })\n },\n },\n\n actions: {\n setValue(ctx, evt) {\n ctx.value = evt.value\n },\n setHovered(ctx, evt) {\n ctx.hoveredId = evt.value\n },\n setActive(ctx, evt) {\n ctx.activeId = evt.value\n },\n setFocused(ctx, evt) {\n ctx.focusedId = evt.value\n },\n invokeOnChange(ctx, evt) {\n ctx.onChange?.({ value: evt.value })\n },\n syncInputElements(ctx) {\n const inputs = dom.getInputEls(ctx)\n inputs.forEach((input) => {\n input.checked = input.value === ctx.value\n })\n },\n setIndicatorTransition(ctx) {\n ctx.canIndicatorTransition = isString(ctx.value)\n },\n cleanupObserver(ctx) {\n ctx.indicatorCleanup?.()\n },\n syncIndicatorRect(ctx) {\n ctx.indicatorCleanup?.()\n\n if (!dom.getIndicatorEl(ctx)) return\n\n const value = ctx.value\n\n if (value == null) {\n ctx.indicatorRect = {}\n return\n }\n\n const radioEl = dom.getActiveRadioEl(ctx)\n if (!radioEl) return\n\n ctx.indicatorCleanup = trackElementRect(radioEl, {\n getRect(el) {\n return dom.getOffsetRect(el)\n },\n onChange(rect) {\n ctx.indicatorRect = dom.resolveRect(rect)\n nextTick(() => {\n ctx.canIndicatorTransition = false\n })\n },\n })\n },\n },\n },\n )\n}\n"],"mappings":"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","names":["import_dom_query","import_dom_query","ctx"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/radio-group.anatomy.ts","../src/radio-group.connect.ts","../src/radio-group.dom.ts","../src/radio-group.machine.ts"],"sourcesContent":["export { anatomy } from \"./radio-group.anatomy\"\nexport { connect } from \"./radio-group.connect\"\nexport { machine } from \"./radio-group.machine\"\nexport type { UserDefinedContext as Context, MachineApi as Api } from \"./radio-group.types\"\n","import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"radio-group\").parts(\n \"root\",\n \"label\",\n \"radio\",\n \"radioLabel\",\n \"radioControl\",\n \"indicator\",\n)\nexport const parts = anatomy.build()\n","import { ariaAttr, dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { visuallyHiddenStyle } from \"@zag-js/visually-hidden\"\nimport { parts } from \"./radio-group.anatomy\"\nimport { dom } from \"./radio-group.dom\"\nimport type { InputProps, MachineApi, RadioProps, Send, State } from \"./radio-group.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const isGroupDisabled = state.context.isDisabled\n\n function getRadioState<T extends RadioProps>(props: T) {\n const radioState = {\n isInvalid: props.invalid,\n isDisabled: props.disabled || isGroupDisabled,\n isChecked: state.context.value === props.value,\n isFocused: state.context.focusedId === props.value,\n isHovered: state.context.hoveredId === props.value,\n isActive: state.context.activeId === props.value,\n }\n return {\n ...radioState,\n isInteractive: !radioState.isDisabled,\n }\n }\n\n function getRadioDataAttrs<T extends RadioProps>(props: T) {\n const radioState = getRadioState(props)\n return {\n \"data-focus\": dataAttr(radioState.isFocused),\n \"data-disabled\": dataAttr(radioState.isDisabled),\n \"data-state\": radioState.isChecked ? \"checked\" : \"unchecked\",\n \"data-hover\": dataAttr(radioState.isHovered),\n \"data-invalid\": dataAttr(radioState.isInvalid),\n \"data-orientation\": state.context.orientation,\n }\n }\n\n const focus = () => {\n const firstEnabledAndCheckedInput = dom.getFirstEnabledAndCheckedInputEl(state.context)\n\n if (firstEnabledAndCheckedInput) {\n firstEnabledAndCheckedInput.focus()\n return\n }\n\n const firstEnabledInput = dom.getFirstEnabledInputEl(state.context)\n firstEnabledInput?.focus()\n }\n\n return {\n value: state.context.value,\n\n setValue(value: string) {\n send({ type: \"SET_VALUE\", value, manual: true })\n },\n\n clearValue() {\n send({ type: \"SET_VALUE\", value: null, manual: true })\n },\n\n focus,\n\n blur() {\n const focusedElement = dom.getActiveElement(state.context)\n const inputEls = dom.getInputEls(state.context)\n const radioHiddenInputIsFocused = inputEls.some((el) => el === focusedElement)\n if (radioHiddenInputIsFocused) focusedElement?.blur()\n },\n\n getRadioState,\n\n rootProps: normalize.element({\n ...parts.root.attrs,\n role: \"radiogroup\",\n id: dom.getRootId(state.context),\n \"aria-labelledby\": dom.getLabelId(state.context),\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"aria-orientation\": state.context.orientation,\n dir: state.context.dir,\n }),\n\n labelProps: normalize.element({\n ...parts.label.attrs,\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n id: dom.getLabelId(state.context),\n onClick: focus,\n }),\n\n getRadioProps(props: RadioProps) {\n const rootState = getRadioState(props)\n\n return normalize.label({\n ...parts.radio.attrs,\n id: dom.getRadioId(state.context, props.value),\n htmlFor: dom.getRadioHiddenInputId(state.context, props.value),\n ...getRadioDataAttrs(props),\n\n onPointerMove() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: props.value, hovered: true })\n },\n onPointerLeave() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: null })\n },\n onPointerDown(event) {\n if (!rootState.isInteractive) return\n // On pointerdown, the input blurs and returns focus to the `body`,\n // we need to prevent this.\n if (rootState.isFocused && event.pointerType === \"mouse\") {\n event.preventDefault()\n }\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n },\n onPointerUp() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_ACTIVE\", value: null })\n },\n })\n },\n\n getRadioLabelProps(props: RadioProps) {\n return normalize.element({\n ...parts.radioLabel.attrs,\n id: dom.getRadioLabelId(state.context, props.value),\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioControlProps(props: RadioProps) {\n const controlState = getRadioState(props)\n\n return normalize.element({\n ...parts.radioControl.attrs,\n id: dom.getRadioControlId(state.context, props.value),\n \"data-active\": dataAttr(controlState.isActive),\n \"aria-hidden\": true,\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioHiddenInputProps(props: InputProps) {\n const inputState = getRadioState(props)\n\n const isRequired = props.required\n const trulyDisabled = inputState.isDisabled && !props.focusable\n\n return normalize.input({\n \"data-ownedby\": dom.getRootId(state.context),\n id: dom.getRadioHiddenInputId(state.context, props.value),\n type: \"radio\",\n name: state.context.name || state.context.id,\n form: state.context.form,\n value: props.value,\n onChange(event) {\n if (inputState.isDisabled) return\n\n if (event.target.checked) {\n send({ type: \"SET_VALUE\", value: props.value })\n }\n },\n onBlur() {\n send({ type: \"SET_FOCUSED\", value: null })\n },\n onFocus() {\n send({ type: \"SET_FOCUSED\", value: props.value, focused: true })\n },\n onKeyDown(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n }\n },\n onKeyUp(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: null })\n }\n },\n disabled: trulyDisabled,\n required: isRequired,\n defaultChecked: inputState.isChecked,\n \"data-disabled\": dataAttr(inputState.isDisabled),\n \"aria-required\": ariaAttr(isRequired),\n \"aria-invalid\": ariaAttr(inputState.isInvalid),\n \"aria-disabled\": ariaAttr(trulyDisabled),\n \"aria-checked\": ariaAttr(inputState.isChecked),\n style: visuallyHiddenStyle,\n })\n },\n\n indicatorProps: normalize.element({\n id: dom.getIndicatorId(state.context),\n ...parts.indicator.attrs,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"data-orientation\": state.context.orientation,\n style: {\n \"--transition-duration\": \"150ms\",\n \"--transition-property\": \"left, top, width, height\",\n position: \"absolute\",\n willChange: \"var(--transition-property)\",\n transitionProperty: \"var(--transition-property)\",\n transitionDuration: state.context.canIndicatorTransition ? \"var(--transition-duration)\" : \"0ms\",\n transitionTimingFunction: \"var(--transition-timing-function)\",\n ...state.context.indicatorRect,\n },\n }),\n }\n}\n","import { createScope, queryAll } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./radio-group.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,\n getRadioId: (ctx: Ctx, value: string) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,\n getRadioHiddenInputId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,\n getRadioControlId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,\n getRadioLabelId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,\n getIndicatorId: (ctx: Ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getRadioHiddenInputEl: (ctx: Ctx, value: string) =>\n dom.getById<HTMLInputElement>(ctx, dom.getRadioHiddenInputId(ctx, value)),\n getIndicatorEl: (ctx: Ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),\n\n getFirstEnabledInputEl: (ctx: Ctx) => dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled)\"),\n getFirstEnabledAndCheckedInputEl: (ctx: Ctx) =>\n dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled):checked\"),\n\n getInputEls: (ctx: Ctx) => {\n const ownerId = CSS.escape(dom.getRootId(ctx))\n const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`\n return queryAll<HTMLInputElement>(dom.getRootEl(ctx), selector)\n },\n\n getActiveRadioEl: (ctx: Ctx) => {\n if (!ctx.value) return\n return dom.getById(ctx, dom.getRadioId(ctx, ctx.value))\n },\n\n getOffsetRect: (el: HTMLElement | undefined) => ({\n left: el?.offsetLeft ?? 0,\n top: el?.offsetTop ?? 0,\n width: el?.offsetWidth ?? 0,\n height: el?.offsetHeight ?? 0,\n }),\n\n getRectById: (ctx: Ctx, id: string) => {\n const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id))\n if (!radioEl) return\n return dom.resolveRect(dom.getOffsetRect(radioEl))\n },\n\n resolveRect: (rect: Record<\"width\" | \"height\" | \"left\" | \"top\", number>) => ({\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n }),\n})\n","import { createMachine } from \"@zag-js/core\"\nimport { nextTick } from \"@zag-js/dom-query\"\nimport { trackElementRect } from \"@zag-js/element-rect\"\nimport { trackFormControl } from \"@zag-js/form-utils\"\nimport { compact, isString } from \"@zag-js/utils\"\nimport { dom } from \"./radio-group.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./radio-group.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"radio\",\n initial: \"idle\",\n context: {\n value: null,\n activeId: null,\n focusedId: null,\n hoveredId: null,\n disabled: false,\n ...ctx,\n indicatorRect: {},\n canIndicatorTransition: false,\n fieldsetDisabled: false,\n },\n\n computed: {\n isDisabled: (ctx) => !!ctx.disabled || ctx.fieldsetDisabled,\n },\n\n entry: [\"syncIndicatorRect\"],\n\n exit: [\"cleanupObserver\"],\n\n activities: [\"trackFormControlState\"],\n\n watch: {\n value: [\"setIndicatorTransition\", \"syncIndicatorRect\", \"syncInputElements\"],\n },\n\n on: {\n SET_VALUE: {\n actions: [\"setValue\"],\n },\n SET_HOVERED: {\n actions: \"setHovered\",\n },\n SET_ACTIVE: {\n actions: \"setActive\",\n },\n SET_FOCUSED: {\n actions: \"setFocused\",\n },\n },\n\n states: {\n idle: {},\n },\n },\n\n {\n activities: {\n trackFormControlState(ctx, _evt, { send, initialContext }) {\n return trackFormControl(dom.getRootEl(ctx), {\n onFieldsetDisabledChange(disabled) {\n ctx.fieldsetDisabled = disabled\n },\n onFormReset() {\n send({ type: \"SET_VALUE\", value: initialContext.value })\n },\n })\n },\n },\n\n actions: {\n setValue(ctx, evt) {\n set.value(ctx, evt.value)\n },\n setHovered(ctx, evt) {\n ctx.hoveredId = evt.value\n },\n setActive(ctx, evt) {\n ctx.activeId = evt.value\n },\n setFocused(ctx, evt) {\n ctx.focusedId = evt.value\n },\n syncInputElements(ctx) {\n const inputs = dom.getInputEls(ctx)\n inputs.forEach((input) => {\n input.checked = input.value === ctx.value\n })\n },\n setIndicatorTransition(ctx) {\n ctx.canIndicatorTransition = isString(ctx.value)\n },\n cleanupObserver(ctx) {\n ctx.indicatorCleanup?.()\n },\n syncIndicatorRect(ctx) {\n ctx.indicatorCleanup?.()\n\n if (!dom.getIndicatorEl(ctx)) return\n\n const value = ctx.value\n\n if (value == null) {\n ctx.indicatorRect = {}\n return\n }\n\n const radioEl = dom.getActiveRadioEl(ctx)\n if (!radioEl) return\n\n ctx.indicatorCleanup = trackElementRect(radioEl, {\n getRect(el) {\n return dom.getOffsetRect(el)\n },\n onChange(rect) {\n ctx.indicatorRect = dom.resolveRect(rect)\n nextTick(() => {\n ctx.canIndicatorTransition = false\n })\n },\n })\n },\n },\n },\n )\n}\n\nconst invoke = {\n change: (ctx: MachineContext) => {\n if (ctx.value == null) return\n ctx.onChange?.({ value: ctx.value })\n },\n}\n\nconst set = {\n value: (ctx: MachineContext, value: string) => {\n ctx.value = value\n invoke.change(ctx)\n },\n}\n"],"mappings":"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","names":["import_dom_query","import_dom_query","ctx"]}
package/dist/index.mjs CHANGED
@@ -6,7 +6,6 @@ var anatomy = createAnatomy("radio-group").parts(
6
6
  "radio",
7
7
  "radioLabel",
8
8
  "radioControl",
9
- "radioInput",
10
9
  "indicator"
11
10
  );
12
11
  var parts = anatomy.build();
@@ -21,12 +20,12 @@ var dom = createScope({
21
20
  getRootId: (ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
22
21
  getLabelId: (ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
23
22
  getRadioId: (ctx, value) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
24
- getRadioInputId: (ctx, value) => ctx.ids?.radioInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
23
+ getRadioHiddenInputId: (ctx, value) => ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
25
24
  getRadioControlId: (ctx, value) => ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,
26
25
  getRadioLabelId: (ctx, value) => ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,
27
- getIndicatorId: (ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,
26
+ getIndicatorId: (ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,
28
27
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
29
- getRadioInputEl: (ctx, value) => dom.getById(ctx, dom.getRadioInputId(ctx, value)),
28
+ getRadioHiddenInputEl: (ctx, value) => dom.getById(ctx, dom.getRadioHiddenInputId(ctx, value)),
30
29
  getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
31
30
  getFirstEnabledInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled)"),
32
31
  getFirstEnabledAndCheckedInputEl: (ctx) => dom.getRootEl(ctx)?.querySelector("input:not(:disabled):checked"),
@@ -40,33 +39,29 @@ var dom = createScope({
40
39
  return;
41
40
  return dom.getById(ctx, dom.getRadioId(ctx, ctx.value));
42
41
  },
43
- getOffsetRect: (el) => {
44
- return {
45
- left: el?.offsetLeft ?? 0,
46
- top: el?.offsetTop ?? 0,
47
- width: el?.offsetWidth ?? 0,
48
- height: el?.offsetHeight ?? 0
49
- };
50
- },
42
+ getOffsetRect: (el) => ({
43
+ left: el?.offsetLeft ?? 0,
44
+ top: el?.offsetTop ?? 0,
45
+ width: el?.offsetWidth ?? 0,
46
+ height: el?.offsetHeight ?? 0
47
+ }),
51
48
  getRectById: (ctx, id) => {
52
49
  const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id));
53
50
  if (!radioEl)
54
51
  return;
55
52
  return dom.resolveRect(dom.getOffsetRect(radioEl));
56
53
  },
57
- resolveRect(rect) {
58
- return {
59
- width: `${rect.width}px`,
60
- height: `${rect.height}px`,
61
- left: `${rect.left}px`,
62
- top: `${rect.top}px`
63
- };
64
- }
54
+ resolveRect: (rect) => ({
55
+ width: `${rect.width}px`,
56
+ height: `${rect.height}px`,
57
+ left: `${rect.left}px`,
58
+ top: `${rect.top}px`
59
+ })
65
60
  });
66
61
 
67
62
  // src/radio-group.connect.ts
68
63
  function connect(state, send, normalize) {
69
- const isGroupDisabled = state.context.disabled;
64
+ const isGroupDisabled = state.context.isDisabled;
70
65
  function getRadioState(props) {
71
66
  const radioState = {
72
67
  isInvalid: props.invalid,
@@ -113,8 +108,8 @@ function connect(state, send, normalize) {
113
108
  blur() {
114
109
  const focusedElement = dom.getActiveElement(state.context);
115
110
  const inputEls = dom.getInputEls(state.context);
116
- const radioInputIsFocused = inputEls.some((el) => el === focusedElement);
117
- if (radioInputIsFocused)
111
+ const radioHiddenInputIsFocused = inputEls.some((el) => el === focusedElement);
112
+ if (radioHiddenInputIsFocused)
118
113
  focusedElement?.blur();
119
114
  },
120
115
  getRadioState,
@@ -140,7 +135,7 @@ function connect(state, send, normalize) {
140
135
  return normalize.label({
141
136
  ...parts.radio.attrs,
142
137
  id: dom.getRadioId(state.context, props.value),
143
- htmlFor: dom.getRadioInputId(state.context, props.value),
138
+ htmlFor: dom.getRadioHiddenInputId(state.context, props.value),
144
139
  ...getRadioDataAttrs(props),
145
140
  onPointerMove() {
146
141
  if (!rootState.isInteractive)
@@ -184,14 +179,13 @@ function connect(state, send, normalize) {
184
179
  ...getRadioDataAttrs(props)
185
180
  });
186
181
  },
187
- getRadioInputProps(props) {
182
+ getRadioHiddenInputProps(props) {
188
183
  const inputState = getRadioState(props);
189
184
  const isRequired = props.required;
190
185
  const trulyDisabled = inputState.isDisabled && !props.focusable;
191
186
  return normalize.input({
192
- ...parts.radioInput.attrs,
193
187
  "data-ownedby": dom.getRootId(state.context),
194
- id: dom.getRadioInputId(state.context, props.value),
188
+ id: dom.getRadioHiddenInputId(state.context, props.value),
195
189
  type: "radio",
196
190
  name: state.context.name || state.context.id,
197
191
  form: state.context.form,
@@ -266,15 +260,20 @@ function machine(userContext) {
266
260
  activeId: null,
267
261
  focusedId: null,
268
262
  hoveredId: null,
263
+ disabled: false,
264
+ ...ctx,
269
265
  indicatorRect: {},
270
266
  canIndicatorTransition: false,
271
- ...ctx
267
+ fieldsetDisabled: false
268
+ },
269
+ computed: {
270
+ isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled
272
271
  },
273
272
  entry: ["syncIndicatorRect"],
274
273
  exit: ["cleanupObserver"],
275
274
  activities: ["trackFormControlState"],
276
275
  watch: {
277
- value: ["setIndicatorTransition", "invokeOnChange", "syncIndicatorRect", "syncInputElements"]
276
+ value: ["setIndicatorTransition", "syncIndicatorRect", "syncInputElements"]
278
277
  },
279
278
  on: {
280
279
  SET_VALUE: {
@@ -298,8 +297,8 @@ function machine(userContext) {
298
297
  activities: {
299
298
  trackFormControlState(ctx2, _evt, { send, initialContext }) {
300
299
  return trackFormControl(dom.getRootEl(ctx2), {
301
- onFieldsetDisabled() {
302
- ctx2.disabled = true;
300
+ onFieldsetDisabledChange(disabled) {
301
+ ctx2.fieldsetDisabled = disabled;
303
302
  },
304
303
  onFormReset() {
305
304
  send({ type: "SET_VALUE", value: initialContext.value });
@@ -309,7 +308,7 @@ function machine(userContext) {
309
308
  },
310
309
  actions: {
311
310
  setValue(ctx2, evt) {
312
- ctx2.value = evt.value;
311
+ set.value(ctx2, evt.value);
313
312
  },
314
313
  setHovered(ctx2, evt) {
315
314
  ctx2.hoveredId = evt.value;
@@ -320,9 +319,6 @@ function machine(userContext) {
320
319
  setFocused(ctx2, evt) {
321
320
  ctx2.focusedId = evt.value;
322
321
  },
323
- invokeOnChange(ctx2, evt) {
324
- ctx2.onChange?.({ value: evt.value });
325
- },
326
322
  syncInputElements(ctx2) {
327
323
  const inputs = dom.getInputEls(ctx2);
328
324
  inputs.forEach((input) => {
@@ -363,6 +359,19 @@ function machine(userContext) {
363
359
  }
364
360
  );
365
361
  }
362
+ var invoke = {
363
+ change: (ctx) => {
364
+ if (ctx.value == null)
365
+ return;
366
+ ctx.onChange?.({ value: ctx.value });
367
+ }
368
+ };
369
+ var set = {
370
+ value: (ctx, value) => {
371
+ ctx.value = value;
372
+ invoke.change(ctx);
373
+ }
374
+ };
366
375
  export {
367
376
  anatomy,
368
377
  connect,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/radio-group.anatomy.ts","../src/radio-group.connect.ts","../src/radio-group.dom.ts","../src/radio-group.machine.ts"],"sourcesContent":["import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"radio-group\").parts(\n \"root\",\n \"label\",\n \"radio\",\n \"radioLabel\",\n \"radioControl\",\n \"radioInput\",\n \"indicator\",\n)\nexport const parts = anatomy.build()\n","import { ariaAttr, dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { visuallyHiddenStyle } from \"@zag-js/visually-hidden\"\nimport { parts } from \"./radio-group.anatomy\"\nimport { dom } from \"./radio-group.dom\"\nimport type { InputProps, PublicApi, RadioProps, Send, State } from \"./radio-group.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): PublicApi<T> {\n const isGroupDisabled = state.context.disabled\n\n function getRadioState<T extends RadioProps>(props: T) {\n const radioState = {\n isInvalid: props.invalid,\n isDisabled: props.disabled || isGroupDisabled,\n isChecked: state.context.value === props.value,\n isFocused: state.context.focusedId === props.value,\n isHovered: state.context.hoveredId === props.value,\n isActive: state.context.activeId === props.value,\n }\n return {\n ...radioState,\n isInteractive: !radioState.isDisabled,\n }\n }\n\n function getRadioDataAttrs<T extends RadioProps>(props: T) {\n const radioState = getRadioState(props)\n return {\n \"data-focus\": dataAttr(radioState.isFocused),\n \"data-disabled\": dataAttr(radioState.isDisabled),\n \"data-state\": radioState.isChecked ? \"checked\" : \"unchecked\",\n \"data-hover\": dataAttr(radioState.isHovered),\n \"data-invalid\": dataAttr(radioState.isInvalid),\n \"data-orientation\": state.context.orientation,\n }\n }\n\n const focus = () => {\n const firstEnabledAndCheckedInput = dom.getFirstEnabledAndCheckedInputEl(state.context)\n\n if (firstEnabledAndCheckedInput) {\n firstEnabledAndCheckedInput.focus()\n return\n }\n\n const firstEnabledInput = dom.getFirstEnabledInputEl(state.context)\n firstEnabledInput?.focus()\n }\n\n return {\n value: state.context.value,\n\n setValue(value: string) {\n send({ type: \"SET_VALUE\", value, manual: true })\n },\n\n clearValue() {\n send({ type: \"SET_VALUE\", value: null, manual: true })\n },\n\n focus,\n\n blur() {\n const focusedElement = dom.getActiveElement(state.context)\n const inputEls = dom.getInputEls(state.context)\n const radioInputIsFocused = inputEls.some((el) => el === focusedElement)\n if (radioInputIsFocused) focusedElement?.blur()\n },\n\n getRadioState,\n\n rootProps: normalize.element({\n ...parts.root.attrs,\n role: \"radiogroup\",\n id: dom.getRootId(state.context),\n \"aria-labelledby\": dom.getLabelId(state.context),\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"aria-orientation\": state.context.orientation,\n dir: state.context.dir,\n }),\n\n labelProps: normalize.element({\n ...parts.label.attrs,\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n id: dom.getLabelId(state.context),\n onClick: focus,\n }),\n\n getRadioProps(props: RadioProps) {\n const rootState = getRadioState(props)\n\n return normalize.label({\n ...parts.radio.attrs,\n id: dom.getRadioId(state.context, props.value),\n htmlFor: dom.getRadioInputId(state.context, props.value),\n ...getRadioDataAttrs(props),\n\n onPointerMove() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: props.value, hovered: true })\n },\n onPointerLeave() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: null })\n },\n onPointerDown(event) {\n if (!rootState.isInteractive) return\n // On pointerdown, the input blurs and returns focus to the `body`,\n // we need to prevent this.\n if (rootState.isFocused && event.pointerType === \"mouse\") {\n event.preventDefault()\n }\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n },\n onPointerUp() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_ACTIVE\", value: null })\n },\n })\n },\n\n getRadioLabelProps(props: RadioProps) {\n return normalize.element({\n ...parts.radioLabel.attrs,\n id: dom.getRadioLabelId(state.context, props.value),\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioControlProps(props: RadioProps) {\n const controlState = getRadioState(props)\n\n return normalize.element({\n ...parts.radioControl.attrs,\n id: dom.getRadioControlId(state.context, props.value),\n \"data-active\": dataAttr(controlState.isActive),\n \"aria-hidden\": true,\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioInputProps(props: InputProps) {\n const inputState = getRadioState(props)\n\n const isRequired = props.required\n const trulyDisabled = inputState.isDisabled && !props.focusable\n\n return normalize.input({\n ...parts.radioInput.attrs,\n \"data-ownedby\": dom.getRootId(state.context),\n id: dom.getRadioInputId(state.context, props.value),\n type: \"radio\",\n name: state.context.name || state.context.id,\n form: state.context.form,\n value: props.value,\n onChange(event) {\n if (inputState.isDisabled) return\n\n if (event.target.checked) {\n send({ type: \"SET_VALUE\", value: props.value })\n }\n },\n onBlur() {\n send({ type: \"SET_FOCUSED\", value: null })\n },\n onFocus() {\n send({ type: \"SET_FOCUSED\", value: props.value, focused: true })\n },\n onKeyDown(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n }\n },\n onKeyUp(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: null })\n }\n },\n disabled: trulyDisabled,\n required: isRequired,\n defaultChecked: inputState.isChecked,\n \"data-disabled\": dataAttr(inputState.isDisabled),\n \"aria-required\": ariaAttr(isRequired),\n \"aria-invalid\": ariaAttr(inputState.isInvalid),\n \"aria-disabled\": ariaAttr(trulyDisabled),\n \"aria-checked\": ariaAttr(inputState.isChecked),\n style: visuallyHiddenStyle,\n })\n },\n\n indicatorProps: normalize.element({\n id: dom.getIndicatorId(state.context),\n ...parts.indicator.attrs,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"data-orientation\": state.context.orientation,\n style: {\n \"--transition-duration\": \"150ms\",\n \"--transition-property\": \"left, top, width, height\",\n position: \"absolute\",\n willChange: \"var(--transition-property)\",\n transitionProperty: \"var(--transition-property)\",\n transitionDuration: state.context.canIndicatorTransition ? \"var(--transition-duration)\" : \"0ms\",\n transitionTimingFunction: \"var(--transition-timing-function)\",\n ...state.context.indicatorRect,\n },\n }),\n }\n}\n","import { createScope, queryAll } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./radio-group.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,\n getRadioId: (ctx: Ctx, value: string) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,\n getRadioInputId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,\n getRadioControlId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,\n getRadioLabelId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,\n getIndicatorId: (ctx: Ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getRadioInputEl: (ctx: Ctx, value: string) => dom.getById<HTMLInputElement>(ctx, dom.getRadioInputId(ctx, value)),\n getIndicatorEl: (ctx: Ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),\n\n getFirstEnabledInputEl: (ctx: Ctx) => dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled)\"),\n getFirstEnabledAndCheckedInputEl: (ctx: Ctx) =>\n dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled):checked\"),\n\n getInputEls: (ctx: Ctx) => {\n const ownerId = CSS.escape(dom.getRootId(ctx))\n const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`\n return queryAll<HTMLInputElement>(dom.getRootEl(ctx), selector)\n },\n\n getActiveRadioEl: (ctx: Ctx) => {\n if (!ctx.value) return\n return dom.getById(ctx, dom.getRadioId(ctx, ctx.value))\n },\n\n getOffsetRect: (el: HTMLElement | undefined) => {\n return {\n left: el?.offsetLeft ?? 0,\n top: el?.offsetTop ?? 0,\n width: el?.offsetWidth ?? 0,\n height: el?.offsetHeight ?? 0,\n }\n },\n\n getRectById: (ctx: Ctx, id: string) => {\n const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id))\n if (!radioEl) return\n return dom.resolveRect(dom.getOffsetRect(radioEl))\n },\n\n resolveRect(rect: Record<\"width\" | \"height\" | \"left\" | \"top\", number>) {\n return {\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n }\n },\n})\n","import { createMachine } from \"@zag-js/core\"\nimport { nextTick } from \"@zag-js/dom-query\"\nimport { trackElementRect } from \"@zag-js/element-rect\"\nimport { trackFormControl } from \"@zag-js/form-utils\"\nimport { compact, isString } from \"@zag-js/utils\"\nimport { dom } from \"./radio-group.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./radio-group.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"radio\",\n initial: \"idle\",\n context: {\n value: null,\n activeId: null,\n focusedId: null,\n hoveredId: null,\n indicatorRect: {},\n canIndicatorTransition: false,\n ...ctx,\n },\n\n entry: [\"syncIndicatorRect\"],\n\n exit: [\"cleanupObserver\"],\n\n activities: [\"trackFormControlState\"],\n\n watch: {\n value: [\"setIndicatorTransition\", \"invokeOnChange\", \"syncIndicatorRect\", \"syncInputElements\"],\n },\n\n on: {\n SET_VALUE: {\n actions: [\"setValue\"],\n },\n SET_HOVERED: {\n actions: \"setHovered\",\n },\n SET_ACTIVE: {\n actions: \"setActive\",\n },\n SET_FOCUSED: {\n actions: \"setFocused\",\n },\n },\n\n states: {\n idle: {},\n },\n },\n\n {\n activities: {\n trackFormControlState(ctx, _evt, { send, initialContext }) {\n return trackFormControl(dom.getRootEl(ctx), {\n onFieldsetDisabled() {\n ctx.disabled = true\n },\n onFormReset() {\n send({ type: \"SET_VALUE\", value: initialContext.value })\n },\n })\n },\n },\n\n actions: {\n setValue(ctx, evt) {\n ctx.value = evt.value\n },\n setHovered(ctx, evt) {\n ctx.hoveredId = evt.value\n },\n setActive(ctx, evt) {\n ctx.activeId = evt.value\n },\n setFocused(ctx, evt) {\n ctx.focusedId = evt.value\n },\n invokeOnChange(ctx, evt) {\n ctx.onChange?.({ value: evt.value })\n },\n syncInputElements(ctx) {\n const inputs = dom.getInputEls(ctx)\n inputs.forEach((input) => {\n input.checked = input.value === ctx.value\n })\n },\n setIndicatorTransition(ctx) {\n ctx.canIndicatorTransition = isString(ctx.value)\n },\n cleanupObserver(ctx) {\n ctx.indicatorCleanup?.()\n },\n syncIndicatorRect(ctx) {\n ctx.indicatorCleanup?.()\n\n if (!dom.getIndicatorEl(ctx)) return\n\n const value = ctx.value\n\n if (value == null) {\n ctx.indicatorRect = {}\n return\n }\n\n const radioEl = dom.getActiveRadioEl(ctx)\n if (!radioEl) return\n\n ctx.indicatorCleanup = trackElementRect(radioEl, {\n getRect(el) {\n return dom.getOffsetRect(el)\n },\n onChange(rect) {\n ctx.indicatorRect = dom.resolveRect(rect)\n nextTick(() => {\n ctx.canIndicatorTransition = false\n })\n },\n })\n },\n },\n },\n )\n}\n"],"mappings":"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","names":["ctx"]}
1
+ {"version":3,"sources":["../src/radio-group.anatomy.ts","../src/radio-group.connect.ts","../src/radio-group.dom.ts","../src/radio-group.machine.ts"],"sourcesContent":["import { createAnatomy } from \"@zag-js/anatomy\"\n\nexport const anatomy = createAnatomy(\"radio-group\").parts(\n \"root\",\n \"label\",\n \"radio\",\n \"radioLabel\",\n \"radioControl\",\n \"indicator\",\n)\nexport const parts = anatomy.build()\n","import { ariaAttr, dataAttr } from \"@zag-js/dom-query\"\nimport type { NormalizeProps, PropTypes } from \"@zag-js/types\"\nimport { visuallyHiddenStyle } from \"@zag-js/visually-hidden\"\nimport { parts } from \"./radio-group.anatomy\"\nimport { dom } from \"./radio-group.dom\"\nimport type { InputProps, MachineApi, RadioProps, Send, State } from \"./radio-group.types\"\n\nexport function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {\n const isGroupDisabled = state.context.isDisabled\n\n function getRadioState<T extends RadioProps>(props: T) {\n const radioState = {\n isInvalid: props.invalid,\n isDisabled: props.disabled || isGroupDisabled,\n isChecked: state.context.value === props.value,\n isFocused: state.context.focusedId === props.value,\n isHovered: state.context.hoveredId === props.value,\n isActive: state.context.activeId === props.value,\n }\n return {\n ...radioState,\n isInteractive: !radioState.isDisabled,\n }\n }\n\n function getRadioDataAttrs<T extends RadioProps>(props: T) {\n const radioState = getRadioState(props)\n return {\n \"data-focus\": dataAttr(radioState.isFocused),\n \"data-disabled\": dataAttr(radioState.isDisabled),\n \"data-state\": radioState.isChecked ? \"checked\" : \"unchecked\",\n \"data-hover\": dataAttr(radioState.isHovered),\n \"data-invalid\": dataAttr(radioState.isInvalid),\n \"data-orientation\": state.context.orientation,\n }\n }\n\n const focus = () => {\n const firstEnabledAndCheckedInput = dom.getFirstEnabledAndCheckedInputEl(state.context)\n\n if (firstEnabledAndCheckedInput) {\n firstEnabledAndCheckedInput.focus()\n return\n }\n\n const firstEnabledInput = dom.getFirstEnabledInputEl(state.context)\n firstEnabledInput?.focus()\n }\n\n return {\n value: state.context.value,\n\n setValue(value: string) {\n send({ type: \"SET_VALUE\", value, manual: true })\n },\n\n clearValue() {\n send({ type: \"SET_VALUE\", value: null, manual: true })\n },\n\n focus,\n\n blur() {\n const focusedElement = dom.getActiveElement(state.context)\n const inputEls = dom.getInputEls(state.context)\n const radioHiddenInputIsFocused = inputEls.some((el) => el === focusedElement)\n if (radioHiddenInputIsFocused) focusedElement?.blur()\n },\n\n getRadioState,\n\n rootProps: normalize.element({\n ...parts.root.attrs,\n role: \"radiogroup\",\n id: dom.getRootId(state.context),\n \"aria-labelledby\": dom.getLabelId(state.context),\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"aria-orientation\": state.context.orientation,\n dir: state.context.dir,\n }),\n\n labelProps: normalize.element({\n ...parts.label.attrs,\n \"data-orientation\": state.context.orientation,\n \"data-disabled\": dataAttr(isGroupDisabled),\n id: dom.getLabelId(state.context),\n onClick: focus,\n }),\n\n getRadioProps(props: RadioProps) {\n const rootState = getRadioState(props)\n\n return normalize.label({\n ...parts.radio.attrs,\n id: dom.getRadioId(state.context, props.value),\n htmlFor: dom.getRadioHiddenInputId(state.context, props.value),\n ...getRadioDataAttrs(props),\n\n onPointerMove() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: props.value, hovered: true })\n },\n onPointerLeave() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_HOVERED\", value: null })\n },\n onPointerDown(event) {\n if (!rootState.isInteractive) return\n // On pointerdown, the input blurs and returns focus to the `body`,\n // we need to prevent this.\n if (rootState.isFocused && event.pointerType === \"mouse\") {\n event.preventDefault()\n }\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n },\n onPointerUp() {\n if (!rootState.isInteractive) return\n send({ type: \"SET_ACTIVE\", value: null })\n },\n })\n },\n\n getRadioLabelProps(props: RadioProps) {\n return normalize.element({\n ...parts.radioLabel.attrs,\n id: dom.getRadioLabelId(state.context, props.value),\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioControlProps(props: RadioProps) {\n const controlState = getRadioState(props)\n\n return normalize.element({\n ...parts.radioControl.attrs,\n id: dom.getRadioControlId(state.context, props.value),\n \"data-active\": dataAttr(controlState.isActive),\n \"aria-hidden\": true,\n ...getRadioDataAttrs(props),\n })\n },\n\n getRadioHiddenInputProps(props: InputProps) {\n const inputState = getRadioState(props)\n\n const isRequired = props.required\n const trulyDisabled = inputState.isDisabled && !props.focusable\n\n return normalize.input({\n \"data-ownedby\": dom.getRootId(state.context),\n id: dom.getRadioHiddenInputId(state.context, props.value),\n type: \"radio\",\n name: state.context.name || state.context.id,\n form: state.context.form,\n value: props.value,\n onChange(event) {\n if (inputState.isDisabled) return\n\n if (event.target.checked) {\n send({ type: \"SET_VALUE\", value: props.value })\n }\n },\n onBlur() {\n send({ type: \"SET_FOCUSED\", value: null })\n },\n onFocus() {\n send({ type: \"SET_FOCUSED\", value: props.value, focused: true })\n },\n onKeyDown(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: props.value, active: true })\n }\n },\n onKeyUp(event) {\n if (event.key === \" \") {\n send({ type: \"SET_ACTIVE\", value: null })\n }\n },\n disabled: trulyDisabled,\n required: isRequired,\n defaultChecked: inputState.isChecked,\n \"data-disabled\": dataAttr(inputState.isDisabled),\n \"aria-required\": ariaAttr(isRequired),\n \"aria-invalid\": ariaAttr(inputState.isInvalid),\n \"aria-disabled\": ariaAttr(trulyDisabled),\n \"aria-checked\": ariaAttr(inputState.isChecked),\n style: visuallyHiddenStyle,\n })\n },\n\n indicatorProps: normalize.element({\n id: dom.getIndicatorId(state.context),\n ...parts.indicator.attrs,\n \"data-disabled\": dataAttr(isGroupDisabled),\n \"data-orientation\": state.context.orientation,\n style: {\n \"--transition-duration\": \"150ms\",\n \"--transition-property\": \"left, top, width, height\",\n position: \"absolute\",\n willChange: \"var(--transition-property)\",\n transitionProperty: \"var(--transition-property)\",\n transitionDuration: state.context.canIndicatorTransition ? \"var(--transition-duration)\" : \"0ms\",\n transitionTimingFunction: \"var(--transition-timing-function)\",\n ...state.context.indicatorRect,\n },\n }),\n }\n}\n","import { createScope, queryAll } from \"@zag-js/dom-query\"\nimport type { MachineContext as Ctx } from \"./radio-group.types\"\n\nexport const dom = createScope({\n getRootId: (ctx: Ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,\n getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,\n getRadioId: (ctx: Ctx, value: string) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,\n getRadioHiddenInputId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,\n getRadioControlId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,\n getRadioLabelId: (ctx: Ctx, value: string) =>\n ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,\n getIndicatorId: (ctx: Ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,\n\n getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),\n getRadioHiddenInputEl: (ctx: Ctx, value: string) =>\n dom.getById<HTMLInputElement>(ctx, dom.getRadioHiddenInputId(ctx, value)),\n getIndicatorEl: (ctx: Ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),\n\n getFirstEnabledInputEl: (ctx: Ctx) => dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled)\"),\n getFirstEnabledAndCheckedInputEl: (ctx: Ctx) =>\n dom.getRootEl(ctx)?.querySelector<HTMLInputElement>(\"input:not(:disabled):checked\"),\n\n getInputEls: (ctx: Ctx) => {\n const ownerId = CSS.escape(dom.getRootId(ctx))\n const selector = `input[type=radio][data-ownedby='${ownerId}']:not([disabled])`\n return queryAll<HTMLInputElement>(dom.getRootEl(ctx), selector)\n },\n\n getActiveRadioEl: (ctx: Ctx) => {\n if (!ctx.value) return\n return dom.getById(ctx, dom.getRadioId(ctx, ctx.value))\n },\n\n getOffsetRect: (el: HTMLElement | undefined) => ({\n left: el?.offsetLeft ?? 0,\n top: el?.offsetTop ?? 0,\n width: el?.offsetWidth ?? 0,\n height: el?.offsetHeight ?? 0,\n }),\n\n getRectById: (ctx: Ctx, id: string) => {\n const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id))\n if (!radioEl) return\n return dom.resolveRect(dom.getOffsetRect(radioEl))\n },\n\n resolveRect: (rect: Record<\"width\" | \"height\" | \"left\" | \"top\", number>) => ({\n width: `${rect.width}px`,\n height: `${rect.height}px`,\n left: `${rect.left}px`,\n top: `${rect.top}px`,\n }),\n})\n","import { createMachine } from \"@zag-js/core\"\nimport { nextTick } from \"@zag-js/dom-query\"\nimport { trackElementRect } from \"@zag-js/element-rect\"\nimport { trackFormControl } from \"@zag-js/form-utils\"\nimport { compact, isString } from \"@zag-js/utils\"\nimport { dom } from \"./radio-group.dom\"\nimport type { MachineContext, MachineState, UserDefinedContext } from \"./radio-group.types\"\n\nexport function machine(userContext: UserDefinedContext) {\n const ctx = compact(userContext)\n return createMachine<MachineContext, MachineState>(\n {\n id: \"radio\",\n initial: \"idle\",\n context: {\n value: null,\n activeId: null,\n focusedId: null,\n hoveredId: null,\n disabled: false,\n ...ctx,\n indicatorRect: {},\n canIndicatorTransition: false,\n fieldsetDisabled: false,\n },\n\n computed: {\n isDisabled: (ctx) => !!ctx.disabled || ctx.fieldsetDisabled,\n },\n\n entry: [\"syncIndicatorRect\"],\n\n exit: [\"cleanupObserver\"],\n\n activities: [\"trackFormControlState\"],\n\n watch: {\n value: [\"setIndicatorTransition\", \"syncIndicatorRect\", \"syncInputElements\"],\n },\n\n on: {\n SET_VALUE: {\n actions: [\"setValue\"],\n },\n SET_HOVERED: {\n actions: \"setHovered\",\n },\n SET_ACTIVE: {\n actions: \"setActive\",\n },\n SET_FOCUSED: {\n actions: \"setFocused\",\n },\n },\n\n states: {\n idle: {},\n },\n },\n\n {\n activities: {\n trackFormControlState(ctx, _evt, { send, initialContext }) {\n return trackFormControl(dom.getRootEl(ctx), {\n onFieldsetDisabledChange(disabled) {\n ctx.fieldsetDisabled = disabled\n },\n onFormReset() {\n send({ type: \"SET_VALUE\", value: initialContext.value })\n },\n })\n },\n },\n\n actions: {\n setValue(ctx, evt) {\n set.value(ctx, evt.value)\n },\n setHovered(ctx, evt) {\n ctx.hoveredId = evt.value\n },\n setActive(ctx, evt) {\n ctx.activeId = evt.value\n },\n setFocused(ctx, evt) {\n ctx.focusedId = evt.value\n },\n syncInputElements(ctx) {\n const inputs = dom.getInputEls(ctx)\n inputs.forEach((input) => {\n input.checked = input.value === ctx.value\n })\n },\n setIndicatorTransition(ctx) {\n ctx.canIndicatorTransition = isString(ctx.value)\n },\n cleanupObserver(ctx) {\n ctx.indicatorCleanup?.()\n },\n syncIndicatorRect(ctx) {\n ctx.indicatorCleanup?.()\n\n if (!dom.getIndicatorEl(ctx)) return\n\n const value = ctx.value\n\n if (value == null) {\n ctx.indicatorRect = {}\n return\n }\n\n const radioEl = dom.getActiveRadioEl(ctx)\n if (!radioEl) return\n\n ctx.indicatorCleanup = trackElementRect(radioEl, {\n getRect(el) {\n return dom.getOffsetRect(el)\n },\n onChange(rect) {\n ctx.indicatorRect = dom.resolveRect(rect)\n nextTick(() => {\n ctx.canIndicatorTransition = false\n })\n },\n })\n },\n },\n },\n )\n}\n\nconst invoke = {\n change: (ctx: MachineContext) => {\n if (ctx.value == null) return\n ctx.onChange?.({ value: ctx.value })\n },\n}\n\nconst set = {\n value: (ctx: MachineContext, value: string) => {\n ctx.value = value\n invoke.change(ctx)\n },\n}\n"],"mappings":";AAAA,SAAS,qBAAqB;AAEvB,IAAM,UAAU,cAAc,aAAa,EAAE;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AACO,IAAM,QAAQ,QAAQ,MAAM;;;ACVnC,SAAS,UAAU,gBAAgB;AAEnC,SAAS,2BAA2B;;;ACFpC,SAAS,aAAa,gBAAgB;AAG/B,IAAM,MAAM,YAAY;AAAA,EAC7B,WAAW,CAAC,QAAa,IAAI,KAAK,QAAQ,eAAe,IAAI,EAAE;AAAA,EAC/D,YAAY,CAAC,QAAa,IAAI,KAAK,SAAS,eAAe,IAAI,EAAE;AAAA,EACjE,YAAY,CAAC,KAAU,UAAkB,IAAI,KAAK,QAAQ,KAAK,KAAK,eAAe,IAAI,EAAE,UAAU,KAAK;AAAA,EACxG,uBAAuB,CAAC,KAAU,UAChC,IAAI,KAAK,mBAAmB,KAAK,KAAK,eAAe,IAAI,EAAE,gBAAgB,KAAK;AAAA,EAClF,mBAAmB,CAAC,KAAU,UAC5B,IAAI,KAAK,eAAe,KAAK,KAAK,eAAe,IAAI,EAAE,kBAAkB,KAAK;AAAA,EAChF,iBAAiB,CAAC,KAAU,UAC1B,IAAI,KAAK,aAAa,KAAK,KAAK,eAAe,IAAI,EAAE,gBAAgB,KAAK;AAAA,EAC5E,gBAAgB,CAAC,QAAa,IAAI,KAAK,aAAa,eAAe,IAAI,EAAE;AAAA,EAEzE,WAAW,CAAC,QAAa,IAAI,QAAQ,KAAK,IAAI,UAAU,GAAG,CAAC;AAAA,EAC5D,uBAAuB,CAAC,KAAU,UAChC,IAAI,QAA0B,KAAK,IAAI,sBAAsB,KAAK,KAAK,CAAC;AAAA,EAC1E,gBAAgB,CAAC,QAAa,IAAI,QAAQ,KAAK,IAAI,eAAe,GAAG,CAAC;AAAA,EAEtE,wBAAwB,CAAC,QAAa,IAAI,UAAU,GAAG,GAAG,cAAgC,sBAAsB;AAAA,EAChH,kCAAkC,CAAC,QACjC,IAAI,UAAU,GAAG,GAAG,cAAgC,8BAA8B;AAAA,EAEpF,aAAa,CAAC,QAAa;AACzB,UAAM,UAAU,IAAI,OAAO,IAAI,UAAU,GAAG,CAAC;AAC7C,UAAM,WAAW,mCAAmC,OAAO;AAC3D,WAAO,SAA2B,IAAI,UAAU,GAAG,GAAG,QAAQ;AAAA,EAChE;AAAA,EAEA,kBAAkB,CAAC,QAAa;AAC9B,QAAI,CAAC,IAAI;AAAO;AAChB,WAAO,IAAI,QAAQ,KAAK,IAAI,WAAW,KAAK,IAAI,KAAK,CAAC;AAAA,EACxD;AAAA,EAEA,eAAe,CAAC,QAAiC;AAAA,IAC/C,MAAM,IAAI,cAAc;AAAA,IACxB,KAAK,IAAI,aAAa;AAAA,IACtB,OAAO,IAAI,eAAe;AAAA,IAC1B,QAAQ,IAAI,gBAAgB;AAAA,EAC9B;AAAA,EAEA,aAAa,CAAC,KAAU,OAAe;AACrC,UAAM,UAAU,IAAI,QAAQ,KAAK,IAAI,WAAW,KAAK,EAAE,CAAC;AACxD,QAAI,CAAC;AAAS;AACd,WAAO,IAAI,YAAY,IAAI,cAAc,OAAO,CAAC;AAAA,EACnD;AAAA,EAEA,aAAa,CAAC,UAA+D;AAAA,IAC3E,OAAO,GAAG,KAAK,KAAK;AAAA,IACpB,QAAQ,GAAG,KAAK,MAAM;AAAA,IACtB,MAAM,GAAG,KAAK,IAAI;AAAA,IAClB,KAAK,GAAG,KAAK,GAAG;AAAA,EAClB;AACF,CAAC;;;AD/CM,SAAS,QAA6B,OAAc,MAAY,WAA6C;AAClH,QAAM,kBAAkB,MAAM,QAAQ;AAEtC,WAAS,cAAoC,OAAU;AACrD,UAAM,aAAa;AAAA,MACjB,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM,YAAY;AAAA,MAC9B,WAAW,MAAM,QAAQ,UAAU,MAAM;AAAA,MACzC,WAAW,MAAM,QAAQ,cAAc,MAAM;AAAA,MAC7C,WAAW,MAAM,QAAQ,cAAc,MAAM;AAAA,MAC7C,UAAU,MAAM,QAAQ,aAAa,MAAM;AAAA,IAC7C;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,eAAe,CAAC,WAAW;AAAA,IAC7B;AAAA,EACF;AAEA,WAAS,kBAAwC,OAAU;AACzD,UAAM,aAAa,cAAc,KAAK;AACtC,WAAO;AAAA,MACL,cAAc,SAAS,WAAW,SAAS;AAAA,MAC3C,iBAAiB,SAAS,WAAW,UAAU;AAAA,MAC/C,cAAc,WAAW,YAAY,YAAY;AAAA,MACjD,cAAc,SAAS,WAAW,SAAS;AAAA,MAC3C,gBAAgB,SAAS,WAAW,SAAS;AAAA,MAC7C,oBAAoB,MAAM,QAAQ;AAAA,IACpC;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM;AAClB,UAAM,8BAA8B,IAAI,iCAAiC,MAAM,OAAO;AAEtF,QAAI,6BAA6B;AAC/B,kCAA4B,MAAM;AAClC;AAAA,IACF;AAEA,UAAM,oBAAoB,IAAI,uBAAuB,MAAM,OAAO;AAClE,uBAAmB,MAAM;AAAA,EAC3B;AAEA,SAAO;AAAA,IACL,OAAO,MAAM,QAAQ;AAAA,IAErB,SAAS,OAAe;AACtB,WAAK,EAAE,MAAM,aAAa,OAAO,QAAQ,KAAK,CAAC;AAAA,IACjD;AAAA,IAEA,aAAa;AACX,WAAK,EAAE,MAAM,aAAa,OAAO,MAAM,QAAQ,KAAK,CAAC;AAAA,IACvD;AAAA,IAEA;AAAA,IAEA,OAAO;AACL,YAAM,iBAAiB,IAAI,iBAAiB,MAAM,OAAO;AACzD,YAAM,WAAW,IAAI,YAAY,MAAM,OAAO;AAC9C,YAAM,4BAA4B,SAAS,KAAK,CAAC,OAAO,OAAO,cAAc;AAC7E,UAAI;AAA2B,wBAAgB,KAAK;AAAA,IACtD;AAAA,IAEA;AAAA,IAEA,WAAW,UAAU,QAAQ;AAAA,MAC3B,GAAG,MAAM,KAAK;AAAA,MACd,MAAM;AAAA,MACN,IAAI,IAAI,UAAU,MAAM,OAAO;AAAA,MAC/B,mBAAmB,IAAI,WAAW,MAAM,OAAO;AAAA,MAC/C,oBAAoB,MAAM,QAAQ;AAAA,MAClC,iBAAiB,SAAS,eAAe;AAAA,MACzC,oBAAoB,MAAM,QAAQ;AAAA,MAClC,KAAK,MAAM,QAAQ;AAAA,IACrB,CAAC;AAAA,IAED,YAAY,UAAU,QAAQ;AAAA,MAC5B,GAAG,MAAM,MAAM;AAAA,MACf,oBAAoB,MAAM,QAAQ;AAAA,MAClC,iBAAiB,SAAS,eAAe;AAAA,MACzC,IAAI,IAAI,WAAW,MAAM,OAAO;AAAA,MAChC,SAAS;AAAA,IACX,CAAC;AAAA,IAED,cAAc,OAAmB;AAC/B,YAAM,YAAY,cAAc,KAAK;AAErC,aAAO,UAAU,MAAM;AAAA,QACrB,GAAG,MAAM,MAAM;AAAA,QACf,IAAI,IAAI,WAAW,MAAM,SAAS,MAAM,KAAK;AAAA,QAC7C,SAAS,IAAI,sBAAsB,MAAM,SAAS,MAAM,KAAK;AAAA,QAC7D,GAAG,kBAAkB,KAAK;AAAA,QAE1B,gBAAgB;AACd,cAAI,CAAC,UAAU;AAAe;AAC9B,eAAK,EAAE,MAAM,eAAe,OAAO,MAAM,OAAO,SAAS,KAAK,CAAC;AAAA,QACjE;AAAA,QACA,iBAAiB;AACf,cAAI,CAAC,UAAU;AAAe;AAC9B,eAAK,EAAE,MAAM,eAAe,OAAO,KAAK,CAAC;AAAA,QAC3C;AAAA,QACA,cAAc,OAAO;AACnB,cAAI,CAAC,UAAU;AAAe;AAG9B,cAAI,UAAU,aAAa,MAAM,gBAAgB,SAAS;AACxD,kBAAM,eAAe;AAAA,UACvB;AACA,eAAK,EAAE,MAAM,cAAc,OAAO,MAAM,OAAO,QAAQ,KAAK,CAAC;AAAA,QAC/D;AAAA,QACA,cAAc;AACZ,cAAI,CAAC,UAAU;AAAe;AAC9B,eAAK,EAAE,MAAM,cAAc,OAAO,KAAK,CAAC;AAAA,QAC1C;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,mBAAmB,OAAmB;AACpC,aAAO,UAAU,QAAQ;AAAA,QACvB,GAAG,MAAM,WAAW;AAAA,QACpB,IAAI,IAAI,gBAAgB,MAAM,SAAS,MAAM,KAAK;AAAA,QAClD,GAAG,kBAAkB,KAAK;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,IAEA,qBAAqB,OAAmB;AACtC,YAAM,eAAe,cAAc,KAAK;AAExC,aAAO,UAAU,QAAQ;AAAA,QACvB,GAAG,MAAM,aAAa;AAAA,QACtB,IAAI,IAAI,kBAAkB,MAAM,SAAS,MAAM,KAAK;AAAA,QACpD,eAAe,SAAS,aAAa,QAAQ;AAAA,QAC7C,eAAe;AAAA,QACf,GAAG,kBAAkB,KAAK;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,IAEA,yBAAyB,OAAmB;AAC1C,YAAM,aAAa,cAAc,KAAK;AAEtC,YAAM,aAAa,MAAM;AACzB,YAAM,gBAAgB,WAAW,cAAc,CAAC,MAAM;AAEtD,aAAO,UAAU,MAAM;AAAA,QACrB,gBAAgB,IAAI,UAAU,MAAM,OAAO;AAAA,QAC3C,IAAI,IAAI,sBAAsB,MAAM,SAAS,MAAM,KAAK;AAAA,QACxD,MAAM;AAAA,QACN,MAAM,MAAM,QAAQ,QAAQ,MAAM,QAAQ;AAAA,QAC1C,MAAM,MAAM,QAAQ;AAAA,QACpB,OAAO,MAAM;AAAA,QACb,SAAS,OAAO;AACd,cAAI,WAAW;AAAY;AAE3B,cAAI,MAAM,OAAO,SAAS;AACxB,iBAAK,EAAE,MAAM,aAAa,OAAO,MAAM,MAAM,CAAC;AAAA,UAChD;AAAA,QACF;AAAA,QACA,SAAS;AACP,eAAK,EAAE,MAAM,eAAe,OAAO,KAAK,CAAC;AAAA,QAC3C;AAAA,QACA,UAAU;AACR,eAAK,EAAE,MAAM,eAAe,OAAO,MAAM,OAAO,SAAS,KAAK,CAAC;AAAA,QACjE;AAAA,QACA,UAAU,OAAO;AACf,cAAI,MAAM,QAAQ,KAAK;AACrB,iBAAK,EAAE,MAAM,cAAc,OAAO,MAAM,OAAO,QAAQ,KAAK,CAAC;AAAA,UAC/D;AAAA,QACF;AAAA,QACA,QAAQ,OAAO;AACb,cAAI,MAAM,QAAQ,KAAK;AACrB,iBAAK,EAAE,MAAM,cAAc,OAAO,KAAK,CAAC;AAAA,UAC1C;AAAA,QACF;AAAA,QACA,UAAU;AAAA,QACV,UAAU;AAAA,QACV,gBAAgB,WAAW;AAAA,QAC3B,iBAAiB,SAAS,WAAW,UAAU;AAAA,QAC/C,iBAAiB,SAAS,UAAU;AAAA,QACpC,gBAAgB,SAAS,WAAW,SAAS;AAAA,QAC7C,iBAAiB,SAAS,aAAa;AAAA,QACvC,gBAAgB,SAAS,WAAW,SAAS;AAAA,QAC7C,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IAEA,gBAAgB,UAAU,QAAQ;AAAA,MAChC,IAAI,IAAI,eAAe,MAAM,OAAO;AAAA,MACpC,GAAG,MAAM,UAAU;AAAA,MACnB,iBAAiB,SAAS,eAAe;AAAA,MACzC,oBAAoB,MAAM,QAAQ;AAAA,MAClC,OAAO;AAAA,QACL,yBAAyB;AAAA,QACzB,yBAAyB;AAAA,QACzB,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,oBAAoB;AAAA,QACpB,oBAAoB,MAAM,QAAQ,yBAAyB,+BAA+B;AAAA,QAC1F,0BAA0B;AAAA,QAC1B,GAAG,MAAM,QAAQ;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AEhNA,SAAS,qBAAqB;AAC9B,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AACjC,SAAS,wBAAwB;AACjC,SAAS,SAAS,gBAAgB;AAI3B,SAAS,QAAQ,aAAiC;AACvD,QAAM,MAAM,QAAQ,WAAW;AAC/B,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,SAAS;AAAA,QACP,OAAO;AAAA,QACP,UAAU;AAAA,QACV,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,GAAG;AAAA,QACH,eAAe,CAAC;AAAA,QAChB,wBAAwB;AAAA,QACxB,kBAAkB;AAAA,MACpB;AAAA,MAEA,UAAU;AAAA,QACR,YAAY,CAACA,SAAQ,CAAC,CAACA,KAAI,YAAYA,KAAI;AAAA,MAC7C;AAAA,MAEA,OAAO,CAAC,mBAAmB;AAAA,MAE3B,MAAM,CAAC,iBAAiB;AAAA,MAExB,YAAY,CAAC,uBAAuB;AAAA,MAEpC,OAAO;AAAA,QACL,OAAO,CAAC,0BAA0B,qBAAqB,mBAAmB;AAAA,MAC5E;AAAA,MAEA,IAAI;AAAA,QACF,WAAW;AAAA,UACT,SAAS,CAAC,UAAU;AAAA,QACtB;AAAA,QACA,aAAa;AAAA,UACX,SAAS;AAAA,QACX;AAAA,QACA,YAAY;AAAA,UACV,SAAS;AAAA,QACX;AAAA,QACA,aAAa;AAAA,UACX,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MAEA,QAAQ;AAAA,QACN,MAAM,CAAC;AAAA,MACT;AAAA,IACF;AAAA,IAEA;AAAA,MACE,YAAY;AAAA,QACV,sBAAsBA,MAAK,MAAM,EAAE,MAAM,eAAe,GAAG;AACzD,iBAAO,iBAAiB,IAAI,UAAUA,IAAG,GAAG;AAAA,YAC1C,yBAAyB,UAAU;AACjC,cAAAA,KAAI,mBAAmB;AAAA,YACzB;AAAA,YACA,cAAc;AACZ,mBAAK,EAAE,MAAM,aAAa,OAAO,eAAe,MAAM,CAAC;AAAA,YACzD;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MAEA,SAAS;AAAA,QACP,SAASA,MAAK,KAAK;AACjB,cAAI,MAAMA,MAAK,IAAI,KAAK;AAAA,QAC1B;AAAA,QACA,WAAWA,MAAK,KAAK;AACnB,UAAAA,KAAI,YAAY,IAAI;AAAA,QACtB;AAAA,QACA,UAAUA,MAAK,KAAK;AAClB,UAAAA,KAAI,WAAW,IAAI;AAAA,QACrB;AAAA,QACA,WAAWA,MAAK,KAAK;AACnB,UAAAA,KAAI,YAAY,IAAI;AAAA,QACtB;AAAA,QACA,kBAAkBA,MAAK;AACrB,gBAAM,SAAS,IAAI,YAAYA,IAAG;AAClC,iBAAO,QAAQ,CAAC,UAAU;AACxB,kBAAM,UAAU,MAAM,UAAUA,KAAI;AAAA,UACtC,CAAC;AAAA,QACH;AAAA,QACA,uBAAuBA,MAAK;AAC1B,UAAAA,KAAI,yBAAyB,SAASA,KAAI,KAAK;AAAA,QACjD;AAAA,QACA,gBAAgBA,MAAK;AACnB,UAAAA,KAAI,mBAAmB;AAAA,QACzB;AAAA,QACA,kBAAkBA,MAAK;AACrB,UAAAA,KAAI,mBAAmB;AAEvB,cAAI,CAAC,IAAI,eAAeA,IAAG;AAAG;AAE9B,gBAAM,QAAQA,KAAI;AAElB,cAAI,SAAS,MAAM;AACjB,YAAAA,KAAI,gBAAgB,CAAC;AACrB;AAAA,UACF;AAEA,gBAAM,UAAU,IAAI,iBAAiBA,IAAG;AACxC,cAAI,CAAC;AAAS;AAEd,UAAAA,KAAI,mBAAmB,iBAAiB,SAAS;AAAA,YAC/C,QAAQ,IAAI;AACV,qBAAO,IAAI,cAAc,EAAE;AAAA,YAC7B;AAAA,YACA,SAAS,MAAM;AACb,cAAAA,KAAI,gBAAgB,IAAI,YAAY,IAAI;AACxC,uBAAS,MAAM;AACb,gBAAAA,KAAI,yBAAyB;AAAA,cAC/B,CAAC;AAAA,YACH;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,SAAS;AAAA,EACb,QAAQ,CAAC,QAAwB;AAC/B,QAAI,IAAI,SAAS;AAAM;AACvB,QAAI,WAAW,EAAE,OAAO,IAAI,MAAM,CAAC;AAAA,EACrC;AACF;AAEA,IAAM,MAAM;AAAA,EACV,OAAO,CAAC,KAAqB,UAAkB;AAC7C,QAAI,QAAQ;AACZ,WAAO,OAAO,GAAG;AAAA,EACnB;AACF;","names":["ctx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zag-js/radio-group",
3
- "version": "0.15.0",
3
+ "version": "0.17.0",
4
4
  "description": "Core logic for the radio group widget implemented as a state machine",
5
5
  "keywords": [
6
6
  "js",
@@ -28,14 +28,14 @@
28
28
  "url": "https://github.com/chakra-ui/zag/issues"
29
29
  },
30
30
  "dependencies": {
31
- "@zag-js/anatomy": "0.15.0",
32
- "@zag-js/dom-query": "0.15.0",
33
- "@zag-js/element-rect": "0.15.0",
34
- "@zag-js/form-utils": "0.15.0",
35
- "@zag-js/visually-hidden": "0.15.0",
36
- "@zag-js/utils": "0.15.0",
37
- "@zag-js/core": "0.15.0",
38
- "@zag-js/types": "0.15.0"
31
+ "@zag-js/anatomy": "0.17.0",
32
+ "@zag-js/dom-query": "0.17.0",
33
+ "@zag-js/element-rect": "0.17.0",
34
+ "@zag-js/form-utils": "0.17.0",
35
+ "@zag-js/visually-hidden": "0.17.0",
36
+ "@zag-js/utils": "0.17.0",
37
+ "@zag-js/core": "0.17.0",
38
+ "@zag-js/types": "0.17.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "clean-package": "2.2.0"
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { anatomy } from "./radio-group.anatomy"
2
2
  export { connect } from "./radio-group.connect"
3
3
  export { machine } from "./radio-group.machine"
4
- export type { UserDefinedContext as Context, PublicApi } from "./radio-group.types"
4
+ export type { UserDefinedContext as Context, MachineApi as Api } from "./radio-group.types"
@@ -6,7 +6,6 @@ export const anatomy = createAnatomy("radio-group").parts(
6
6
  "radio",
7
7
  "radioLabel",
8
8
  "radioControl",
9
- "radioInput",
10
9
  "indicator",
11
10
  )
12
11
  export const parts = anatomy.build()
@@ -3,10 +3,10 @@ import type { NormalizeProps, PropTypes } from "@zag-js/types"
3
3
  import { visuallyHiddenStyle } from "@zag-js/visually-hidden"
4
4
  import { parts } from "./radio-group.anatomy"
5
5
  import { dom } from "./radio-group.dom"
6
- import type { InputProps, PublicApi, RadioProps, Send, State } from "./radio-group.types"
6
+ import type { InputProps, MachineApi, RadioProps, Send, State } from "./radio-group.types"
7
7
 
8
- export function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): PublicApi<T> {
9
- const isGroupDisabled = state.context.disabled
8
+ export function connect<T extends PropTypes>(state: State, send: Send, normalize: NormalizeProps<T>): MachineApi<T> {
9
+ const isGroupDisabled = state.context.isDisabled
10
10
 
11
11
  function getRadioState<T extends RadioProps>(props: T) {
12
12
  const radioState = {
@@ -63,8 +63,8 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
63
63
  blur() {
64
64
  const focusedElement = dom.getActiveElement(state.context)
65
65
  const inputEls = dom.getInputEls(state.context)
66
- const radioInputIsFocused = inputEls.some((el) => el === focusedElement)
67
- if (radioInputIsFocused) focusedElement?.blur()
66
+ const radioHiddenInputIsFocused = inputEls.some((el) => el === focusedElement)
67
+ if (radioHiddenInputIsFocused) focusedElement?.blur()
68
68
  },
69
69
 
70
70
  getRadioState,
@@ -94,7 +94,7 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
94
94
  return normalize.label({
95
95
  ...parts.radio.attrs,
96
96
  id: dom.getRadioId(state.context, props.value),
97
- htmlFor: dom.getRadioInputId(state.context, props.value),
97
+ htmlFor: dom.getRadioHiddenInputId(state.context, props.value),
98
98
  ...getRadioDataAttrs(props),
99
99
 
100
100
  onPointerMove() {
@@ -141,16 +141,15 @@ export function connect<T extends PropTypes>(state: State, send: Send, normalize
141
141
  })
142
142
  },
143
143
 
144
- getRadioInputProps(props: InputProps) {
144
+ getRadioHiddenInputProps(props: InputProps) {
145
145
  const inputState = getRadioState(props)
146
146
 
147
147
  const isRequired = props.required
148
148
  const trulyDisabled = inputState.isDisabled && !props.focusable
149
149
 
150
150
  return normalize.input({
151
- ...parts.radioInput.attrs,
152
151
  "data-ownedby": dom.getRootId(state.context),
153
- id: dom.getRadioInputId(state.context, props.value),
152
+ id: dom.getRadioHiddenInputId(state.context, props.value),
154
153
  type: "radio",
155
154
  name: state.context.name || state.context.id,
156
155
  form: state.context.form,
@@ -5,16 +5,17 @@ export const dom = createScope({
5
5
  getRootId: (ctx: Ctx) => ctx.ids?.root ?? `radio-group:${ctx.id}`,
6
6
  getLabelId: (ctx: Ctx) => ctx.ids?.label ?? `radio-group:${ctx.id}:label`,
7
7
  getRadioId: (ctx: Ctx, value: string) => ctx.ids?.radio?.(value) ?? `radio-group:${ctx.id}:radio:${value}`,
8
- getRadioInputId: (ctx: Ctx, value: string) =>
9
- ctx.ids?.radioInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
8
+ getRadioHiddenInputId: (ctx: Ctx, value: string) =>
9
+ ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
10
10
  getRadioControlId: (ctx: Ctx, value: string) =>
11
11
  ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,
12
12
  getRadioLabelId: (ctx: Ctx, value: string) =>
13
13
  ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,
14
- getIndicatorId: (ctx: Ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,
14
+ getIndicatorId: (ctx: Ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,
15
15
 
16
16
  getRootEl: (ctx: Ctx) => dom.getById(ctx, dom.getRootId(ctx)),
17
- getRadioInputEl: (ctx: Ctx, value: string) => dom.getById<HTMLInputElement>(ctx, dom.getRadioInputId(ctx, value)),
17
+ getRadioHiddenInputEl: (ctx: Ctx, value: string) =>
18
+ dom.getById<HTMLInputElement>(ctx, dom.getRadioHiddenInputId(ctx, value)),
18
19
  getIndicatorEl: (ctx: Ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
19
20
 
20
21
  getFirstEnabledInputEl: (ctx: Ctx) => dom.getRootEl(ctx)?.querySelector<HTMLInputElement>("input:not(:disabled)"),
@@ -32,14 +33,12 @@ export const dom = createScope({
32
33
  return dom.getById(ctx, dom.getRadioId(ctx, ctx.value))
33
34
  },
34
35
 
35
- getOffsetRect: (el: HTMLElement | undefined) => {
36
- return {
37
- left: el?.offsetLeft ?? 0,
38
- top: el?.offsetTop ?? 0,
39
- width: el?.offsetWidth ?? 0,
40
- height: el?.offsetHeight ?? 0,
41
- }
42
- },
36
+ getOffsetRect: (el: HTMLElement | undefined) => ({
37
+ left: el?.offsetLeft ?? 0,
38
+ top: el?.offsetTop ?? 0,
39
+ width: el?.offsetWidth ?? 0,
40
+ height: el?.offsetHeight ?? 0,
41
+ }),
43
42
 
44
43
  getRectById: (ctx: Ctx, id: string) => {
45
44
  const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id))
@@ -47,12 +46,10 @@ export const dom = createScope({
47
46
  return dom.resolveRect(dom.getOffsetRect(radioEl))
48
47
  },
49
48
 
50
- resolveRect(rect: Record<"width" | "height" | "left" | "top", number>) {
51
- return {
52
- width: `${rect.width}px`,
53
- height: `${rect.height}px`,
54
- left: `${rect.left}px`,
55
- top: `${rect.top}px`,
56
- }
57
- },
49
+ resolveRect: (rect: Record<"width" | "height" | "left" | "top", number>) => ({
50
+ width: `${rect.width}px`,
51
+ height: `${rect.height}px`,
52
+ left: `${rect.left}px`,
53
+ top: `${rect.top}px`,
54
+ }),
58
55
  })
@@ -17,9 +17,15 @@ export function machine(userContext: UserDefinedContext) {
17
17
  activeId: null,
18
18
  focusedId: null,
19
19
  hoveredId: null,
20
+ disabled: false,
21
+ ...ctx,
20
22
  indicatorRect: {},
21
23
  canIndicatorTransition: false,
22
- ...ctx,
24
+ fieldsetDisabled: false,
25
+ },
26
+
27
+ computed: {
28
+ isDisabled: (ctx) => !!ctx.disabled || ctx.fieldsetDisabled,
23
29
  },
24
30
 
25
31
  entry: ["syncIndicatorRect"],
@@ -29,7 +35,7 @@ export function machine(userContext: UserDefinedContext) {
29
35
  activities: ["trackFormControlState"],
30
36
 
31
37
  watch: {
32
- value: ["setIndicatorTransition", "invokeOnChange", "syncIndicatorRect", "syncInputElements"],
38
+ value: ["setIndicatorTransition", "syncIndicatorRect", "syncInputElements"],
33
39
  },
34
40
 
35
41
  on: {
@@ -56,8 +62,8 @@ export function machine(userContext: UserDefinedContext) {
56
62
  activities: {
57
63
  trackFormControlState(ctx, _evt, { send, initialContext }) {
58
64
  return trackFormControl(dom.getRootEl(ctx), {
59
- onFieldsetDisabled() {
60
- ctx.disabled = true
65
+ onFieldsetDisabledChange(disabled) {
66
+ ctx.fieldsetDisabled = disabled
61
67
  },
62
68
  onFormReset() {
63
69
  send({ type: "SET_VALUE", value: initialContext.value })
@@ -68,7 +74,7 @@ export function machine(userContext: UserDefinedContext) {
68
74
 
69
75
  actions: {
70
76
  setValue(ctx, evt) {
71
- ctx.value = evt.value
77
+ set.value(ctx, evt.value)
72
78
  },
73
79
  setHovered(ctx, evt) {
74
80
  ctx.hoveredId = evt.value
@@ -79,9 +85,6 @@ export function machine(userContext: UserDefinedContext) {
79
85
  setFocused(ctx, evt) {
80
86
  ctx.focusedId = evt.value
81
87
  },
82
- invokeOnChange(ctx, evt) {
83
- ctx.onChange?.({ value: evt.value })
84
- },
85
88
  syncInputElements(ctx) {
86
89
  const inputs = dom.getInputEls(ctx)
87
90
  inputs.forEach((input) => {
@@ -125,3 +128,17 @@ export function machine(userContext: UserDefinedContext) {
125
128
  },
126
129
  )
127
130
  }
131
+
132
+ const invoke = {
133
+ change: (ctx: MachineContext) => {
134
+ if (ctx.value == null) return
135
+ ctx.onChange?.({ value: ctx.value })
136
+ },
137
+ }
138
+
139
+ const set = {
140
+ value: (ctx: MachineContext, value: string) => {
141
+ ctx.value = value
142
+ invoke.change(ctx)
143
+ },
144
+ }
@@ -8,7 +8,7 @@ type ElementIds = Partial<{
8
8
  radio(value: string): string
9
9
  radioLabel(value: string): string
10
10
  radioControl(value: string): string
11
- radioInput(value: string): string
11
+ radioHiddenInput(value: string): string
12
12
  }>
13
13
 
14
14
  type PublicContext = DirectionProperty &
@@ -49,49 +49,6 @@ type PublicContext = DirectionProperty &
49
49
  */
50
50
  orientation?: "horizontal" | "vertical"
51
51
  }
52
- export type PublicApi<T extends PropTypes = PropTypes> = {
53
- /**
54
- * The current value of the radio group
55
- */
56
- value: string | null
57
- /**
58
- * Function to set the value of the radio group
59
- */
60
- setValue(value: string): void
61
- /**
62
- * Function to clear the value of the radio group
63
- */
64
- clearValue(): void
65
- /**
66
- * Function to focus the radio group
67
- */
68
- focus: () => void
69
- /**
70
- * Function to blur the currently focused radio input in the radio group
71
- */
72
- blur(): void
73
- /**
74
- * Returns the state details of a radio input
75
- */
76
- getRadioState: <T_1 extends RadioProps>(
77
- props: T_1,
78
- ) => {
79
- isInteractive: boolean
80
- isInvalid: boolean | undefined
81
- isDisabled: boolean | undefined
82
- isChecked: boolean
83
- isFocused: boolean
84
- isHovered: boolean
85
- isActive: boolean
86
- }
87
- rootProps: T["element"]
88
- labelProps: T["element"]
89
- getRadioProps(props: RadioProps): T["label"]
90
- getRadioLabelProps(props: RadioProps): T["element"]
91
- getRadioControlProps(props: RadioProps): T["element"]
92
- getRadioInputProps(props: InputProps): T["input"]
93
- indicatorProps: T["element"]
94
- }
95
52
 
96
53
  type PrivateContext = Context<{
97
54
  /**
@@ -124,11 +81,21 @@ type PrivateContext = Context<{
124
81
  * Function to clean up the observer for the active tab's rect
125
82
  */
126
83
  indicatorCleanup?: VoidFunction | null
84
+ /**
85
+ * @internal
86
+ * Whether the radio group's fieldset is disabled
87
+ */
88
+ fieldsetDisabled: boolean
127
89
  }>
128
90
 
129
91
  export type UserDefinedContext = RequiredBy<PublicContext, "id">
130
92
 
131
- type ComputedContext = Readonly<{}>
93
+ type ComputedContext = Readonly<{
94
+ /**
95
+ * Whether the radio group is disabled
96
+ */
97
+ isDisabled: boolean
98
+ }>
132
99
 
133
100
  export type MachineContext = PublicContext & PrivateContext & ComputedContext
134
101
 
@@ -167,3 +134,47 @@ export type InputProps = RadioProps & {
167
134
  */
168
135
  required?: boolean
169
136
  }
137
+
138
+ export type MachineApi<T extends PropTypes = PropTypes> = {
139
+ /**
140
+ * The current value of the radio group
141
+ */
142
+ value: string | null
143
+ /**
144
+ * Function to set the value of the radio group
145
+ */
146
+ setValue(value: string): void
147
+ /**
148
+ * Function to clear the value of the radio group
149
+ */
150
+ clearValue(): void
151
+ /**
152
+ * Function to focus the radio group
153
+ */
154
+ focus: () => void
155
+ /**
156
+ * Function to blur the currently focused radio input in the radio group
157
+ */
158
+ blur(): void
159
+ /**
160
+ * Returns the state details of a radio input
161
+ */
162
+ getRadioState: <T_1 extends RadioProps>(
163
+ props: T_1,
164
+ ) => {
165
+ isInteractive: boolean
166
+ isInvalid: boolean | undefined
167
+ isDisabled: boolean | undefined
168
+ isChecked: boolean
169
+ isFocused: boolean
170
+ isHovered: boolean
171
+ isActive: boolean
172
+ }
173
+ rootProps: T["element"]
174
+ labelProps: T["element"]
175
+ getRadioProps(props: RadioProps): T["label"]
176
+ getRadioLabelProps(props: RadioProps): T["element"]
177
+ getRadioControlProps(props: RadioProps): T["element"]
178
+ getRadioHiddenInputProps(props: InputProps): T["input"]
179
+ indicatorProps: T["element"]
180
+ }