@zag-js/radio-group 1.35.3 → 1.36.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.
|
@@ -216,14 +216,18 @@ function connect(service, normalize) {
|
|
|
216
216
|
},
|
|
217
217
|
getIndicatorProps() {
|
|
218
218
|
const rect = context.get("indicatorRect");
|
|
219
|
-
const
|
|
219
|
+
const animateIndicator = context.get("animateIndicator");
|
|
220
220
|
return normalize.element({
|
|
221
221
|
id: dom.getIndicatorId(scope),
|
|
222
222
|
...import_radio_group.parts.indicator.attrs,
|
|
223
223
|
dir: prop("dir"),
|
|
224
|
-
hidden: context.get("value") == null ||
|
|
224
|
+
hidden: context.get("value") == null || isRectEmpty(rect),
|
|
225
225
|
"data-disabled": (0, import_dom_query.dataAttr)(groupDisabled),
|
|
226
226
|
"data-orientation": prop("orientation"),
|
|
227
|
+
onTransitionEnd(event) {
|
|
228
|
+
if ((0, import_dom_query.getEventTarget)(event) !== event.currentTarget) return;
|
|
229
|
+
send({ type: "INDICATOR_TRANSITION_END" });
|
|
230
|
+
},
|
|
227
231
|
style: {
|
|
228
232
|
"--transition-property": "left, top, width, height",
|
|
229
233
|
"--left": (0, import_utils.toPx)(rect?.x),
|
|
@@ -231,9 +235,9 @@ function connect(service, normalize) {
|
|
|
231
235
|
"--width": (0, import_utils.toPx)(rect?.width),
|
|
232
236
|
"--height": (0, import_utils.toPx)(rect?.height),
|
|
233
237
|
position: "absolute",
|
|
234
|
-
willChange: "var(--transition-property)",
|
|
235
|
-
transitionProperty: "var(--transition-property)",
|
|
236
|
-
transitionDuration: "var(--transition-duration, 150ms)",
|
|
238
|
+
willChange: animateIndicator ? "var(--transition-property)" : "auto",
|
|
239
|
+
transitionProperty: animateIndicator ? "var(--transition-property)" : "none",
|
|
240
|
+
transitionDuration: animateIndicator ? "var(--transition-duration, 150ms)" : "0ms",
|
|
237
241
|
transitionTimingFunction: "var(--transition-timing-function)",
|
|
238
242
|
[prop("orientation") === "horizontal" ? "left" : "top"]: prop("orientation") === "horizontal" ? "var(--left)" : "var(--top)"
|
|
239
243
|
}
|
|
@@ -241,6 +245,7 @@ function connect(service, normalize) {
|
|
|
241
245
|
}
|
|
242
246
|
};
|
|
243
247
|
}
|
|
248
|
+
var isRectEmpty = (rect) => rect == null || rect.width === 0 && rect.height === 0 && rect.x === 0 && rect.y === 0;
|
|
244
249
|
// Annotate the CommonJS export names for ESM import in node:
|
|
245
250
|
0 && (module.exports = {
|
|
246
251
|
connect
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/radio-group.connect.ts
|
|
2
|
-
import { dataAttr, isLeftClick, isSafari, visuallyHiddenStyle } from "@zag-js/dom-query";
|
|
2
|
+
import { dataAttr, getEventTarget, isLeftClick, isSafari, visuallyHiddenStyle } from "@zag-js/dom-query";
|
|
3
3
|
import { isFocusVisible } from "@zag-js/focus-visible";
|
|
4
4
|
import { toPx } from "@zag-js/utils";
|
|
5
5
|
import { parts } from "./radio-group.anatomy.mjs";
|
|
@@ -182,14 +182,18 @@ function connect(service, normalize) {
|
|
|
182
182
|
},
|
|
183
183
|
getIndicatorProps() {
|
|
184
184
|
const rect = context.get("indicatorRect");
|
|
185
|
-
const
|
|
185
|
+
const animateIndicator = context.get("animateIndicator");
|
|
186
186
|
return normalize.element({
|
|
187
187
|
id: dom.getIndicatorId(scope),
|
|
188
188
|
...parts.indicator.attrs,
|
|
189
189
|
dir: prop("dir"),
|
|
190
|
-
hidden: context.get("value") == null ||
|
|
190
|
+
hidden: context.get("value") == null || isRectEmpty(rect),
|
|
191
191
|
"data-disabled": dataAttr(groupDisabled),
|
|
192
192
|
"data-orientation": prop("orientation"),
|
|
193
|
+
onTransitionEnd(event) {
|
|
194
|
+
if (getEventTarget(event) !== event.currentTarget) return;
|
|
195
|
+
send({ type: "INDICATOR_TRANSITION_END" });
|
|
196
|
+
},
|
|
193
197
|
style: {
|
|
194
198
|
"--transition-property": "left, top, width, height",
|
|
195
199
|
"--left": toPx(rect?.x),
|
|
@@ -197,9 +201,9 @@ function connect(service, normalize) {
|
|
|
197
201
|
"--width": toPx(rect?.width),
|
|
198
202
|
"--height": toPx(rect?.height),
|
|
199
203
|
position: "absolute",
|
|
200
|
-
willChange: "var(--transition-property)",
|
|
201
|
-
transitionProperty: "var(--transition-property)",
|
|
202
|
-
transitionDuration: "var(--transition-duration, 150ms)",
|
|
204
|
+
willChange: animateIndicator ? "var(--transition-property)" : "auto",
|
|
205
|
+
transitionProperty: animateIndicator ? "var(--transition-property)" : "none",
|
|
206
|
+
transitionDuration: animateIndicator ? "var(--transition-duration, 150ms)" : "0ms",
|
|
203
207
|
transitionTimingFunction: "var(--transition-timing-function)",
|
|
204
208
|
[prop("orientation") === "horizontal" ? "left" : "top"]: prop("orientation") === "horizontal" ? "var(--left)" : "var(--top)"
|
|
205
209
|
}
|
|
@@ -207,6 +211,7 @@ function connect(service, normalize) {
|
|
|
207
211
|
}
|
|
208
212
|
};
|
|
209
213
|
}
|
|
214
|
+
var isRectEmpty = (rect) => rect == null || rect.width === 0 && rect.height === 0 && rect.x === 0 && rect.y === 0;
|
|
210
215
|
export {
|
|
211
216
|
connect
|
|
212
217
|
};
|
|
@@ -72,6 +72,9 @@ var machine = (0, import_core.createMachine)({
|
|
|
72
72
|
indicatorRect: bindable(() => ({
|
|
73
73
|
defaultValue: null
|
|
74
74
|
})),
|
|
75
|
+
animateIndicator: bindable(() => ({
|
|
76
|
+
defaultValue: false
|
|
77
|
+
})),
|
|
75
78
|
fieldsetDisabled: bindable(() => ({
|
|
76
79
|
defaultValue: false
|
|
77
80
|
})),
|
|
@@ -83,18 +86,19 @@ var machine = (0, import_core.createMachine)({
|
|
|
83
86
|
refs() {
|
|
84
87
|
return {
|
|
85
88
|
indicatorCleanup: null,
|
|
86
|
-
focusVisibleValue: null
|
|
89
|
+
focusVisibleValue: null,
|
|
90
|
+
prevValue: null
|
|
87
91
|
};
|
|
88
92
|
},
|
|
89
93
|
computed: {
|
|
90
94
|
isDisabled: ({ prop, context }) => !!prop("disabled") || context.get("fieldsetDisabled")
|
|
91
95
|
},
|
|
92
|
-
entry: ["syncIndicatorRect", "syncSsr"],
|
|
96
|
+
entry: ["syncPrevValue", "syncIndicatorRect", "syncSsr"],
|
|
93
97
|
exit: ["cleanupObserver"],
|
|
94
98
|
effects: ["trackFormControlState", "trackFocusVisible"],
|
|
95
99
|
watch({ track, action, context }) {
|
|
96
100
|
track([() => context.get("value")], () => {
|
|
97
|
-
action(["syncIndicatorRect", "syncInputElements"]);
|
|
101
|
+
action(["syncIndicatorAnimation", "syncIndicatorRect", "syncInputElements"]);
|
|
98
102
|
});
|
|
99
103
|
},
|
|
100
104
|
on: {
|
|
@@ -115,6 +119,9 @@ var machine = (0, import_core.createMachine)({
|
|
|
115
119
|
},
|
|
116
120
|
SET_FOCUSED: {
|
|
117
121
|
actions: ["setFocused"]
|
|
122
|
+
},
|
|
123
|
+
INDICATOR_TRANSITION_END: {
|
|
124
|
+
actions: ["clearIndicatorAnimation"]
|
|
118
125
|
}
|
|
119
126
|
},
|
|
120
127
|
states: {
|
|
@@ -154,6 +161,19 @@ var machine = (0, import_core.createMachine)({
|
|
|
154
161
|
const focusVisibleValue = event.value != null && event.focusVisible ? event.value : null;
|
|
155
162
|
context.set("focusVisibleValue", focusVisibleValue);
|
|
156
163
|
},
|
|
164
|
+
syncPrevValue({ context, refs }) {
|
|
165
|
+
refs.set("prevValue", context.get("value"));
|
|
166
|
+
},
|
|
167
|
+
syncIndicatorAnimation({ context, refs }) {
|
|
168
|
+
const prevValue = refs.get("prevValue");
|
|
169
|
+
const nextValue = context.get("value");
|
|
170
|
+
const animate = prevValue != null && nextValue != null && prevValue !== nextValue;
|
|
171
|
+
context.set("animateIndicator", animate);
|
|
172
|
+
refs.set("prevValue", nextValue);
|
|
173
|
+
},
|
|
174
|
+
clearIndicatorAnimation({ context }) {
|
|
175
|
+
context.set("animateIndicator", false);
|
|
176
|
+
},
|
|
157
177
|
syncInputElements({ context, scope }) {
|
|
158
178
|
const inputs = dom.getInputEls(scope);
|
|
159
179
|
inputs.forEach((input) => {
|
|
@@ -38,6 +38,9 @@ var machine = createMachine({
|
|
|
38
38
|
indicatorRect: bindable(() => ({
|
|
39
39
|
defaultValue: null
|
|
40
40
|
})),
|
|
41
|
+
animateIndicator: bindable(() => ({
|
|
42
|
+
defaultValue: false
|
|
43
|
+
})),
|
|
41
44
|
fieldsetDisabled: bindable(() => ({
|
|
42
45
|
defaultValue: false
|
|
43
46
|
})),
|
|
@@ -49,18 +52,19 @@ var machine = createMachine({
|
|
|
49
52
|
refs() {
|
|
50
53
|
return {
|
|
51
54
|
indicatorCleanup: null,
|
|
52
|
-
focusVisibleValue: null
|
|
55
|
+
focusVisibleValue: null,
|
|
56
|
+
prevValue: null
|
|
53
57
|
};
|
|
54
58
|
},
|
|
55
59
|
computed: {
|
|
56
60
|
isDisabled: ({ prop, context }) => !!prop("disabled") || context.get("fieldsetDisabled")
|
|
57
61
|
},
|
|
58
|
-
entry: ["syncIndicatorRect", "syncSsr"],
|
|
62
|
+
entry: ["syncPrevValue", "syncIndicatorRect", "syncSsr"],
|
|
59
63
|
exit: ["cleanupObserver"],
|
|
60
64
|
effects: ["trackFormControlState", "trackFocusVisible"],
|
|
61
65
|
watch({ track, action, context }) {
|
|
62
66
|
track([() => context.get("value")], () => {
|
|
63
|
-
action(["syncIndicatorRect", "syncInputElements"]);
|
|
67
|
+
action(["syncIndicatorAnimation", "syncIndicatorRect", "syncInputElements"]);
|
|
64
68
|
});
|
|
65
69
|
},
|
|
66
70
|
on: {
|
|
@@ -81,6 +85,9 @@ var machine = createMachine({
|
|
|
81
85
|
},
|
|
82
86
|
SET_FOCUSED: {
|
|
83
87
|
actions: ["setFocused"]
|
|
88
|
+
},
|
|
89
|
+
INDICATOR_TRANSITION_END: {
|
|
90
|
+
actions: ["clearIndicatorAnimation"]
|
|
84
91
|
}
|
|
85
92
|
},
|
|
86
93
|
states: {
|
|
@@ -120,6 +127,19 @@ var machine = createMachine({
|
|
|
120
127
|
const focusVisibleValue = event.value != null && event.focusVisible ? event.value : null;
|
|
121
128
|
context.set("focusVisibleValue", focusVisibleValue);
|
|
122
129
|
},
|
|
130
|
+
syncPrevValue({ context, refs }) {
|
|
131
|
+
refs.set("prevValue", context.get("value"));
|
|
132
|
+
},
|
|
133
|
+
syncIndicatorAnimation({ context, refs }) {
|
|
134
|
+
const prevValue = refs.get("prevValue");
|
|
135
|
+
const nextValue = context.get("value");
|
|
136
|
+
const animate = prevValue != null && nextValue != null && prevValue !== nextValue;
|
|
137
|
+
context.set("animateIndicator", animate);
|
|
138
|
+
refs.set("prevValue", nextValue);
|
|
139
|
+
},
|
|
140
|
+
clearIndicatorAnimation({ context }) {
|
|
141
|
+
context.set("animateIndicator", false);
|
|
142
|
+
},
|
|
123
143
|
syncInputElements({ context, scope }) {
|
|
124
144
|
const inputs = dom.getInputEls(scope);
|
|
125
145
|
inputs.forEach((input) => {
|
|
@@ -86,6 +86,10 @@ interface PrivateContext {
|
|
|
86
86
|
* The active tab indicator's dom rect
|
|
87
87
|
*/
|
|
88
88
|
indicatorRect: Rect | null;
|
|
89
|
+
/**
|
|
90
|
+
* Whether indicator transitions should be animated
|
|
91
|
+
*/
|
|
92
|
+
animateIndicator: boolean;
|
|
89
93
|
/**
|
|
90
94
|
* Whether the radio group's fieldset is disabled
|
|
91
95
|
*/
|
|
@@ -107,6 +111,10 @@ interface Refs {
|
|
|
107
111
|
* Function to clean up the observer for the active tab's rect
|
|
108
112
|
*/
|
|
109
113
|
indicatorCleanup: VoidFunction | null;
|
|
114
|
+
/**
|
|
115
|
+
* Previous selected value, used to detect real value transitions
|
|
116
|
+
*/
|
|
117
|
+
prevValue: string | null;
|
|
110
118
|
}
|
|
111
119
|
interface RadioGroupSchema {
|
|
112
120
|
state: "idle";
|
|
@@ -86,6 +86,10 @@ interface PrivateContext {
|
|
|
86
86
|
* The active tab indicator's dom rect
|
|
87
87
|
*/
|
|
88
88
|
indicatorRect: Rect | null;
|
|
89
|
+
/**
|
|
90
|
+
* Whether indicator transitions should be animated
|
|
91
|
+
*/
|
|
92
|
+
animateIndicator: boolean;
|
|
89
93
|
/**
|
|
90
94
|
* Whether the radio group's fieldset is disabled
|
|
91
95
|
*/
|
|
@@ -107,6 +111,10 @@ interface Refs {
|
|
|
107
111
|
* Function to clean up the observer for the active tab's rect
|
|
108
112
|
*/
|
|
109
113
|
indicatorCleanup: VoidFunction | null;
|
|
114
|
+
/**
|
|
115
|
+
* Previous selected value, used to detect real value transitions
|
|
116
|
+
*/
|
|
117
|
+
prevValue: string | null;
|
|
110
118
|
}
|
|
111
119
|
interface RadioGroupSchema {
|
|
112
120
|
state: "idle";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/radio-group",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.36.0",
|
|
4
4
|
"description": "Core logic for the radio group widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@zag-js/anatomy": "1.
|
|
31
|
-
"@zag-js/dom-query": "1.
|
|
32
|
-
"@zag-js/focus-visible": "1.
|
|
33
|
-
"@zag-js/utils": "1.
|
|
34
|
-
"@zag-js/core": "1.
|
|
35
|
-
"@zag-js/types": "1.
|
|
30
|
+
"@zag-js/anatomy": "1.36.0",
|
|
31
|
+
"@zag-js/dom-query": "1.36.0",
|
|
32
|
+
"@zag-js/focus-visible": "1.36.0",
|
|
33
|
+
"@zag-js/utils": "1.36.0",
|
|
34
|
+
"@zag-js/core": "1.36.0",
|
|
35
|
+
"@zag-js/types": "1.36.0"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"clean-package": "2.2.0"
|