@zag-js/radio-group 0.16.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,5 +1,5 @@
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
 
@@ -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
  */
@@ -93,44 +133,9 @@ type PublicApi<T extends PropTypes = PropTypes> = {
93
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,5 +1,5 @@
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
 
@@ -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
  */
@@ -93,44 +133,9 @@ type PublicApi<T extends PropTypes = PropTypes> = {
93
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
@@ -51,7 +51,7 @@ var dom = (0, import_dom_query.createScope)({
51
51
  getRadioHiddenInputId: (ctx, value) => ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
52
52
  getRadioControlId: (ctx, value) => ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,
53
53
  getRadioLabelId: (ctx, value) => ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,
54
- getIndicatorId: (ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,
54
+ getIndicatorId: (ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,
55
55
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
56
56
  getRadioHiddenInputEl: (ctx, value) => dom.getById(ctx, dom.getRadioHiddenInputId(ctx, value)),
57
57
  getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
@@ -67,33 +67,29 @@ var dom = (0, import_dom_query.createScope)({
67
67
  return;
68
68
  return dom.getById(ctx, dom.getRadioId(ctx, ctx.value));
69
69
  },
70
- getOffsetRect: (el) => {
71
- return {
72
- left: el?.offsetLeft ?? 0,
73
- top: el?.offsetTop ?? 0,
74
- width: el?.offsetWidth ?? 0,
75
- height: el?.offsetHeight ?? 0
76
- };
77
- },
70
+ getOffsetRect: (el) => ({
71
+ left: el?.offsetLeft ?? 0,
72
+ top: el?.offsetTop ?? 0,
73
+ width: el?.offsetWidth ?? 0,
74
+ height: el?.offsetHeight ?? 0
75
+ }),
78
76
  getRectById: (ctx, id) => {
79
77
  const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id));
80
78
  if (!radioEl)
81
79
  return;
82
80
  return dom.resolveRect(dom.getOffsetRect(radioEl));
83
81
  },
84
- resolveRect(rect) {
85
- return {
86
- width: `${rect.width}px`,
87
- height: `${rect.height}px`,
88
- left: `${rect.left}px`,
89
- top: `${rect.top}px`
90
- };
91
- }
82
+ resolveRect: (rect) => ({
83
+ width: `${rect.width}px`,
84
+ height: `${rect.height}px`,
85
+ left: `${rect.left}px`,
86
+ top: `${rect.top}px`
87
+ })
92
88
  });
93
89
 
94
90
  // src/radio-group.connect.ts
95
91
  function connect(state, send, normalize) {
96
- const isGroupDisabled = state.context.disabled;
92
+ const isGroupDisabled = state.context.isDisabled;
97
93
  function getRadioState(props) {
98
94
  const radioState = {
99
95
  isInvalid: props.invalid,
@@ -292,15 +288,20 @@ function machine(userContext) {
292
288
  activeId: null,
293
289
  focusedId: null,
294
290
  hoveredId: null,
291
+ disabled: false,
292
+ ...ctx,
295
293
  indicatorRect: {},
296
294
  canIndicatorTransition: false,
297
- ...ctx
295
+ fieldsetDisabled: false
296
+ },
297
+ computed: {
298
+ isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled
298
299
  },
299
300
  entry: ["syncIndicatorRect"],
300
301
  exit: ["cleanupObserver"],
301
302
  activities: ["trackFormControlState"],
302
303
  watch: {
303
- value: ["setIndicatorTransition", "invokeOnChange", "syncIndicatorRect", "syncInputElements"]
304
+ value: ["setIndicatorTransition", "syncIndicatorRect", "syncInputElements"]
304
305
  },
305
306
  on: {
306
307
  SET_VALUE: {
@@ -324,8 +325,8 @@ function machine(userContext) {
324
325
  activities: {
325
326
  trackFormControlState(ctx2, _evt, { send, initialContext }) {
326
327
  return (0, import_form_utils.trackFormControl)(dom.getRootEl(ctx2), {
327
- onFieldsetDisabled() {
328
- ctx2.disabled = true;
328
+ onFieldsetDisabledChange(disabled) {
329
+ ctx2.fieldsetDisabled = disabled;
329
330
  },
330
331
  onFormReset() {
331
332
  send({ type: "SET_VALUE", value: initialContext.value });
@@ -335,7 +336,7 @@ function machine(userContext) {
335
336
  },
336
337
  actions: {
337
338
  setValue(ctx2, evt) {
338
- ctx2.value = evt.value;
339
+ set.value(ctx2, evt.value);
339
340
  },
340
341
  setHovered(ctx2, evt) {
341
342
  ctx2.hoveredId = evt.value;
@@ -346,9 +347,6 @@ function machine(userContext) {
346
347
  setFocused(ctx2, evt) {
347
348
  ctx2.focusedId = evt.value;
348
349
  },
349
- invokeOnChange(ctx2, evt) {
350
- ctx2.onChange?.({ value: evt.value });
351
- },
352
350
  syncInputElements(ctx2) {
353
351
  const inputs = dom.getInputEls(ctx2);
354
352
  inputs.forEach((input) => {
@@ -389,6 +387,19 @@ function machine(userContext) {
389
387
  }
390
388
  );
391
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
+ };
392
403
  // Annotate the CommonJS export names for ESM import in node:
393
404
  0 && (module.exports = {
394
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 \"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 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 ?? `tabs:${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 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
@@ -23,7 +23,7 @@ var dom = createScope({
23
23
  getRadioHiddenInputId: (ctx, value) => ctx.ids?.radioHiddenInput?.(value) ?? `radio-group:${ctx.id}:radio:input:${value}`,
24
24
  getRadioControlId: (ctx, value) => ctx.ids?.radioControl?.(value) ?? `radio-group:${ctx.id}:radio:control:${value}`,
25
25
  getRadioLabelId: (ctx, value) => ctx.ids?.radioLabel?.(value) ?? `radio-group:${ctx.id}:radio:label:${value}`,
26
- getIndicatorId: (ctx) => ctx.ids?.indicator ?? `tabs:${ctx.id}:indicator`,
26
+ getIndicatorId: (ctx) => ctx.ids?.indicator ?? `radio-group:${ctx.id}:indicator`,
27
27
  getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
28
28
  getRadioHiddenInputEl: (ctx, value) => dom.getById(ctx, dom.getRadioHiddenInputId(ctx, value)),
29
29
  getIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx)),
@@ -39,33 +39,29 @@ var dom = createScope({
39
39
  return;
40
40
  return dom.getById(ctx, dom.getRadioId(ctx, ctx.value));
41
41
  },
42
- getOffsetRect: (el) => {
43
- return {
44
- left: el?.offsetLeft ?? 0,
45
- top: el?.offsetTop ?? 0,
46
- width: el?.offsetWidth ?? 0,
47
- height: el?.offsetHeight ?? 0
48
- };
49
- },
42
+ getOffsetRect: (el) => ({
43
+ left: el?.offsetLeft ?? 0,
44
+ top: el?.offsetTop ?? 0,
45
+ width: el?.offsetWidth ?? 0,
46
+ height: el?.offsetHeight ?? 0
47
+ }),
50
48
  getRectById: (ctx, id) => {
51
49
  const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id));
52
50
  if (!radioEl)
53
51
  return;
54
52
  return dom.resolveRect(dom.getOffsetRect(radioEl));
55
53
  },
56
- resolveRect(rect) {
57
- return {
58
- width: `${rect.width}px`,
59
- height: `${rect.height}px`,
60
- left: `${rect.left}px`,
61
- top: `${rect.top}px`
62
- };
63
- }
54
+ resolveRect: (rect) => ({
55
+ width: `${rect.width}px`,
56
+ height: `${rect.height}px`,
57
+ left: `${rect.left}px`,
58
+ top: `${rect.top}px`
59
+ })
64
60
  });
65
61
 
66
62
  // src/radio-group.connect.ts
67
63
  function connect(state, send, normalize) {
68
- const isGroupDisabled = state.context.disabled;
64
+ const isGroupDisabled = state.context.isDisabled;
69
65
  function getRadioState(props) {
70
66
  const radioState = {
71
67
  isInvalid: props.invalid,
@@ -264,15 +260,20 @@ function machine(userContext) {
264
260
  activeId: null,
265
261
  focusedId: null,
266
262
  hoveredId: null,
263
+ disabled: false,
264
+ ...ctx,
267
265
  indicatorRect: {},
268
266
  canIndicatorTransition: false,
269
- ...ctx
267
+ fieldsetDisabled: false
268
+ },
269
+ computed: {
270
+ isDisabled: (ctx2) => !!ctx2.disabled || ctx2.fieldsetDisabled
270
271
  },
271
272
  entry: ["syncIndicatorRect"],
272
273
  exit: ["cleanupObserver"],
273
274
  activities: ["trackFormControlState"],
274
275
  watch: {
275
- value: ["setIndicatorTransition", "invokeOnChange", "syncIndicatorRect", "syncInputElements"]
276
+ value: ["setIndicatorTransition", "syncIndicatorRect", "syncInputElements"]
276
277
  },
277
278
  on: {
278
279
  SET_VALUE: {
@@ -296,8 +297,8 @@ function machine(userContext) {
296
297
  activities: {
297
298
  trackFormControlState(ctx2, _evt, { send, initialContext }) {
298
299
  return trackFormControl(dom.getRootEl(ctx2), {
299
- onFieldsetDisabled() {
300
- ctx2.disabled = true;
300
+ onFieldsetDisabledChange(disabled) {
301
+ ctx2.fieldsetDisabled = disabled;
301
302
  },
302
303
  onFormReset() {
303
304
  send({ type: "SET_VALUE", value: initialContext.value });
@@ -307,7 +308,7 @@ function machine(userContext) {
307
308
  },
308
309
  actions: {
309
310
  setValue(ctx2, evt) {
310
- ctx2.value = evt.value;
311
+ set.value(ctx2, evt.value);
311
312
  },
312
313
  setHovered(ctx2, evt) {
313
314
  ctx2.hoveredId = evt.value;
@@ -318,9 +319,6 @@ function machine(userContext) {
318
319
  setFocused(ctx2, evt) {
319
320
  ctx2.focusedId = evt.value;
320
321
  },
321
- invokeOnChange(ctx2, evt) {
322
- ctx2.onChange?.({ value: evt.value });
323
- },
324
322
  syncInputElements(ctx2) {
325
323
  const inputs = dom.getInputEls(ctx2);
326
324
  inputs.forEach((input) => {
@@ -361,6 +359,19 @@ function machine(userContext) {
361
359
  }
362
360
  );
363
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
+ };
364
375
  export {
365
376
  anatomy,
366
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 \"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 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 ?? `tabs:${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 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.16.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.16.0",
32
- "@zag-js/dom-query": "0.16.0",
33
- "@zag-js/element-rect": "0.16.0",
34
- "@zag-js/form-utils": "0.16.0",
35
- "@zag-js/visually-hidden": "0.16.0",
36
- "@zag-js/utils": "0.16.0",
37
- "@zag-js/core": "0.16.0",
38
- "@zag-js/types": "0.16.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"
@@ -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 = {
@@ -11,7 +11,7 @@ export const dom = createScope({
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
17
  getRadioHiddenInputEl: (ctx: Ctx, value: string) =>
@@ -33,14 +33,12 @@ export const dom = createScope({
33
33
  return dom.getById(ctx, dom.getRadioId(ctx, ctx.value))
34
34
  },
35
35
 
36
- getOffsetRect: (el: HTMLElement | undefined) => {
37
- return {
38
- left: el?.offsetLeft ?? 0,
39
- top: el?.offsetTop ?? 0,
40
- width: el?.offsetWidth ?? 0,
41
- height: el?.offsetHeight ?? 0,
42
- }
43
- },
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
+ }),
44
42
 
45
43
  getRectById: (ctx: Ctx, id: string) => {
46
44
  const radioEl = dom.getById(ctx, dom.getRadioId(ctx, id))
@@ -48,12 +46,10 @@ export const dom = createScope({
48
46
  return dom.resolveRect(dom.getOffsetRect(radioEl))
49
47
  },
50
48
 
51
- resolveRect(rect: Record<"width" | "height" | "left" | "top", number>) {
52
- return {
53
- width: `${rect.width}px`,
54
- height: `${rect.height}px`,
55
- left: `${rect.left}px`,
56
- top: `${rect.top}px`,
57
- }
58
- },
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
+ }),
59
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
+ }
@@ -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
- getRadioHiddenInputProps(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
+ }