@zag-js/tabs 0.48.0 → 0.50.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 +26 -15
- package/dist/index.d.ts +26 -15
- package/dist/index.js +163 -110
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +164 -111
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -9
- package/src/tabs.connect.ts +40 -16
- package/src/tabs.dom.ts +6 -6
- package/src/tabs.machine.ts +113 -92
- package/src/tabs.props.ts +1 -0
- package/src/tabs.types.ts +32 -25
package/dist/index.d.mts
CHANGED
|
@@ -29,7 +29,7 @@ interface PublicContext extends DirectionProperty, CommonProperties {
|
|
|
29
29
|
/**
|
|
30
30
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
31
31
|
*/
|
|
32
|
-
translations
|
|
32
|
+
translations?: IntlTranslations;
|
|
33
33
|
/**
|
|
34
34
|
* Whether the keyboard navigation will loop from last tab to first, and vice versa.
|
|
35
35
|
* @default true
|
|
@@ -51,6 +51,7 @@ interface PublicContext extends DirectionProperty, CommonProperties {
|
|
|
51
51
|
* The activation mode of the tabs. Can be `manual` or `automatic`
|
|
52
52
|
* - `manual`: Tabs are activated when clicked or press `enter` key.
|
|
53
53
|
* - `automatic`: Tabs are activated when receiving focus
|
|
54
|
+
*
|
|
54
55
|
* @default "automatic"
|
|
55
56
|
*/
|
|
56
57
|
activationMode?: "manual" | "automatic";
|
|
@@ -62,20 +63,13 @@ interface PublicContext extends DirectionProperty, CommonProperties {
|
|
|
62
63
|
* Callback to be called when the focused tab changes
|
|
63
64
|
*/
|
|
64
65
|
onFocusChange?: (details: FocusChangeDetails) => void;
|
|
65
|
-
}
|
|
66
|
-
type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
67
|
-
type ComputedContext = Readonly<{
|
|
68
|
-
/**
|
|
69
|
-
* @computed
|
|
70
|
-
* Whether the tab is in the horizontal orientation
|
|
71
|
-
*/
|
|
72
|
-
isHorizontal: boolean;
|
|
73
66
|
/**
|
|
74
|
-
*
|
|
75
|
-
* Whether the tab is in the vertical orientation
|
|
67
|
+
* Whether the tab is composite
|
|
76
68
|
*/
|
|
77
|
-
|
|
78
|
-
}
|
|
69
|
+
composite: boolean;
|
|
70
|
+
}
|
|
71
|
+
type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
72
|
+
type ComputedContext = Readonly<{}>;
|
|
79
73
|
interface PrivateContext {
|
|
80
74
|
}
|
|
81
75
|
interface MachineContext extends PublicContext, ComputedContext, PrivateContext {
|
|
@@ -136,6 +130,23 @@ interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
136
130
|
* Sets the indicator rect to the tab with the given value
|
|
137
131
|
*/
|
|
138
132
|
setIndicatorRect(value: string): void;
|
|
133
|
+
/**
|
|
134
|
+
* Synchronizes the tab index of the content element.
|
|
135
|
+
* Useful when rendering tabs within a select or combobox
|
|
136
|
+
*/
|
|
137
|
+
syncTabIndex(): void;
|
|
138
|
+
/**
|
|
139
|
+
* Set focus on the selected tab trigger
|
|
140
|
+
*/
|
|
141
|
+
focus(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Selects the next tab
|
|
144
|
+
*/
|
|
145
|
+
selectNext(fromValue?: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* Selects the previous tab
|
|
148
|
+
*/
|
|
149
|
+
selectPrev(fromValue?: string): void;
|
|
139
150
|
/**
|
|
140
151
|
* Returns the state of the trigger with the given props
|
|
141
152
|
*/
|
|
@@ -151,8 +162,8 @@ declare function connect<T extends PropTypes>(state: State, send: Send, normaliz
|
|
|
151
162
|
|
|
152
163
|
declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
|
|
153
164
|
|
|
154
|
-
declare const props: ("value" | "dir" | "id" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "
|
|
155
|
-
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "value" | "dir" | "id" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "
|
|
165
|
+
declare const props: ("value" | "dir" | "id" | "getRootNode" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "composite")[];
|
|
166
|
+
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "value" | "dir" | "id" | "getRootNode" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "composite">];
|
|
156
167
|
declare const triggerProps: (keyof TriggerProps)[];
|
|
157
168
|
declare const splitTriggerProps: <Props extends TriggerProps>(props: Props) => [TriggerProps, Omit<Props, keyof TriggerProps>];
|
|
158
169
|
declare const contentProps: "value"[];
|
package/dist/index.d.ts
CHANGED
|
@@ -29,7 +29,7 @@ interface PublicContext extends DirectionProperty, CommonProperties {
|
|
|
29
29
|
/**
|
|
30
30
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
31
31
|
*/
|
|
32
|
-
translations
|
|
32
|
+
translations?: IntlTranslations;
|
|
33
33
|
/**
|
|
34
34
|
* Whether the keyboard navigation will loop from last tab to first, and vice versa.
|
|
35
35
|
* @default true
|
|
@@ -51,6 +51,7 @@ interface PublicContext extends DirectionProperty, CommonProperties {
|
|
|
51
51
|
* The activation mode of the tabs. Can be `manual` or `automatic`
|
|
52
52
|
* - `manual`: Tabs are activated when clicked or press `enter` key.
|
|
53
53
|
* - `automatic`: Tabs are activated when receiving focus
|
|
54
|
+
*
|
|
54
55
|
* @default "automatic"
|
|
55
56
|
*/
|
|
56
57
|
activationMode?: "manual" | "automatic";
|
|
@@ -62,20 +63,13 @@ interface PublicContext extends DirectionProperty, CommonProperties {
|
|
|
62
63
|
* Callback to be called when the focused tab changes
|
|
63
64
|
*/
|
|
64
65
|
onFocusChange?: (details: FocusChangeDetails) => void;
|
|
65
|
-
}
|
|
66
|
-
type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
67
|
-
type ComputedContext = Readonly<{
|
|
68
|
-
/**
|
|
69
|
-
* @computed
|
|
70
|
-
* Whether the tab is in the horizontal orientation
|
|
71
|
-
*/
|
|
72
|
-
isHorizontal: boolean;
|
|
73
66
|
/**
|
|
74
|
-
*
|
|
75
|
-
* Whether the tab is in the vertical orientation
|
|
67
|
+
* Whether the tab is composite
|
|
76
68
|
*/
|
|
77
|
-
|
|
78
|
-
}
|
|
69
|
+
composite: boolean;
|
|
70
|
+
}
|
|
71
|
+
type UserDefinedContext = RequiredBy<PublicContext, "id">;
|
|
72
|
+
type ComputedContext = Readonly<{}>;
|
|
79
73
|
interface PrivateContext {
|
|
80
74
|
}
|
|
81
75
|
interface MachineContext extends PublicContext, ComputedContext, PrivateContext {
|
|
@@ -136,6 +130,23 @@ interface MachineApi<T extends PropTypes = PropTypes> {
|
|
|
136
130
|
* Sets the indicator rect to the tab with the given value
|
|
137
131
|
*/
|
|
138
132
|
setIndicatorRect(value: string): void;
|
|
133
|
+
/**
|
|
134
|
+
* Synchronizes the tab index of the content element.
|
|
135
|
+
* Useful when rendering tabs within a select or combobox
|
|
136
|
+
*/
|
|
137
|
+
syncTabIndex(): void;
|
|
138
|
+
/**
|
|
139
|
+
* Set focus on the selected tab trigger
|
|
140
|
+
*/
|
|
141
|
+
focus(): void;
|
|
142
|
+
/**
|
|
143
|
+
* Selects the next tab
|
|
144
|
+
*/
|
|
145
|
+
selectNext(fromValue?: string): void;
|
|
146
|
+
/**
|
|
147
|
+
* Selects the previous tab
|
|
148
|
+
*/
|
|
149
|
+
selectPrev(fromValue?: string): void;
|
|
139
150
|
/**
|
|
140
151
|
* Returns the state of the trigger with the given props
|
|
141
152
|
*/
|
|
@@ -151,8 +162,8 @@ declare function connect<T extends PropTypes>(state: State, send: Send, normaliz
|
|
|
151
162
|
|
|
152
163
|
declare function machine(userContext: UserDefinedContext): _zag_js_core.Machine<MachineContext, MachineState, _zag_js_core.StateMachine.AnyEventObject>;
|
|
153
164
|
|
|
154
|
-
declare const props: ("value" | "dir" | "id" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "
|
|
155
|
-
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "value" | "dir" | "id" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "
|
|
165
|
+
declare const props: ("value" | "dir" | "id" | "getRootNode" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "composite")[];
|
|
166
|
+
declare const splitProps: <Props extends Partial<UserDefinedContext>>(props: Props) => [Partial<UserDefinedContext>, Omit<Props, "value" | "dir" | "id" | "getRootNode" | "orientation" | "ids" | "translations" | "loopFocus" | "activationMode" | "onValueChange" | "onFocusChange" | "composite">];
|
|
156
167
|
declare const triggerProps: (keyof TriggerProps)[];
|
|
157
168
|
declare const splitTriggerProps: <Props extends TriggerProps>(props: Props) => [TriggerProps, Omit<Props, keyof TriggerProps>];
|
|
158
169
|
declare const contentProps: "value"[];
|
package/dist/index.js
CHANGED
|
@@ -59,16 +59,16 @@ var dom = (0, import_dom_query.createScope)({
|
|
|
59
59
|
const selector = `[role=tab][data-ownedby='${ownerId}']:not([disabled])`;
|
|
60
60
|
return (0, import_dom_query.queryAll)(dom.getListEl(ctx), selector);
|
|
61
61
|
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
getFirstTriggerEl: (ctx) => (0, import_utils.first)(dom.getElements(ctx)),
|
|
63
|
+
getLastTriggerEl: (ctx) => (0, import_utils.last)(dom.getElements(ctx)),
|
|
64
|
+
getNextTriggerEl: (ctx, id) => (0, import_dom_query.nextById)(dom.getElements(ctx), dom.getTriggerId(ctx, id), ctx.loopFocus),
|
|
65
|
+
getPrevTriggerEl: (ctx, id) => (0, import_dom_query.prevById)(dom.getElements(ctx), dom.getTriggerId(ctx, id), ctx.loopFocus),
|
|
66
|
+
getSelectedContentEl: (ctx) => {
|
|
67
67
|
if (!ctx.value)
|
|
68
68
|
return;
|
|
69
69
|
return dom.getContentEl(ctx, ctx.value);
|
|
70
70
|
},
|
|
71
|
-
|
|
71
|
+
getSelectedTriggerEl: (ctx) => {
|
|
72
72
|
if (!ctx.value)
|
|
73
73
|
return;
|
|
74
74
|
return dom.getTriggerEl(ctx, ctx.value);
|
|
@@ -97,6 +97,10 @@ var dom = (0, import_dom_query.createScope)({
|
|
|
97
97
|
function connect(state, send, normalize) {
|
|
98
98
|
const translations = state.context.translations;
|
|
99
99
|
const focused = state.matches("focused");
|
|
100
|
+
const isVertical = state.context.orientation === "vertical";
|
|
101
|
+
const isHorizontal = state.context.orientation === "horizontal";
|
|
102
|
+
const composite = state.context.composite;
|
|
103
|
+
const indicator = state.context.indicatorState;
|
|
100
104
|
function getTriggerState(props2) {
|
|
101
105
|
return {
|
|
102
106
|
selected: state.context.value === props2.value,
|
|
@@ -117,6 +121,20 @@ function connect(state, send, normalize) {
|
|
|
117
121
|
const id = dom.getTriggerId(state.context, value);
|
|
118
122
|
send({ type: "SET_INDICATOR_RECT", id });
|
|
119
123
|
},
|
|
124
|
+
syncTabIndex() {
|
|
125
|
+
send("SYNC_TAB_INDEX");
|
|
126
|
+
},
|
|
127
|
+
selectNext(fromValue) {
|
|
128
|
+
send({ type: "TAB_FOCUS", value: fromValue, src: "selectNext" });
|
|
129
|
+
send({ type: "ARROW_NEXT", src: "selectNext" });
|
|
130
|
+
},
|
|
131
|
+
selectPrev(fromValue) {
|
|
132
|
+
send({ type: "TAB_FOCUS", value: fromValue, src: "selectPrev" });
|
|
133
|
+
send({ type: "ARROW_PREV", src: "selectPrev" });
|
|
134
|
+
},
|
|
135
|
+
focus() {
|
|
136
|
+
dom.getSelectedTriggerEl(state.context)?.focus();
|
|
137
|
+
},
|
|
120
138
|
getTriggerState,
|
|
121
139
|
rootProps: normalize.element({
|
|
122
140
|
...parts.root.attrs,
|
|
@@ -133,25 +151,35 @@ function connect(state, send, normalize) {
|
|
|
133
151
|
"data-focus": (0, import_dom_query2.dataAttr)(focused),
|
|
134
152
|
"aria-orientation": state.context.orientation,
|
|
135
153
|
"data-orientation": state.context.orientation,
|
|
136
|
-
"aria-label": translations
|
|
154
|
+
"aria-label": translations?.listLabel,
|
|
137
155
|
onKeyDown(event) {
|
|
138
156
|
if (event.defaultPrevented)
|
|
139
157
|
return;
|
|
140
158
|
const evt = (0, import_dom_event.getNativeEvent)(event);
|
|
141
159
|
if (!(0, import_dom_query2.isSelfTarget)(evt))
|
|
142
160
|
return;
|
|
161
|
+
if (evt.isComposing)
|
|
162
|
+
return;
|
|
143
163
|
const keyMap = {
|
|
144
164
|
ArrowDown() {
|
|
145
|
-
|
|
165
|
+
if (isHorizontal)
|
|
166
|
+
return;
|
|
167
|
+
send({ type: "ARROW_NEXT", key: "ArrowDown" });
|
|
146
168
|
},
|
|
147
169
|
ArrowUp() {
|
|
148
|
-
|
|
170
|
+
if (isHorizontal)
|
|
171
|
+
return;
|
|
172
|
+
send({ type: "ARROW_PREV", key: "ArrowUp" });
|
|
149
173
|
},
|
|
150
174
|
ArrowLeft() {
|
|
151
|
-
|
|
175
|
+
if (isVertical)
|
|
176
|
+
return;
|
|
177
|
+
send({ type: "ARROW_PREV", key: "ArrowLeft" });
|
|
152
178
|
},
|
|
153
179
|
ArrowRight() {
|
|
154
|
-
|
|
180
|
+
if (isVertical)
|
|
181
|
+
return;
|
|
182
|
+
send({ type: "ARROW_NEXT", key: "ArrowRight" });
|
|
155
183
|
},
|
|
156
184
|
Home() {
|
|
157
185
|
send("HOME");
|
|
@@ -160,7 +188,7 @@ function connect(state, send, normalize) {
|
|
|
160
188
|
send("END");
|
|
161
189
|
},
|
|
162
190
|
Enter() {
|
|
163
|
-
send({ type: "ENTER"
|
|
191
|
+
send({ type: "ENTER" });
|
|
164
192
|
}
|
|
165
193
|
};
|
|
166
194
|
let key = (0, import_dom_event.getEventKey)(event, state.context);
|
|
@@ -187,10 +215,10 @@ function connect(state, send, normalize) {
|
|
|
187
215
|
"aria-selected": triggerState.selected,
|
|
188
216
|
"data-selected": (0, import_dom_query2.dataAttr)(triggerState.selected),
|
|
189
217
|
"data-focus": (0, import_dom_query2.dataAttr)(triggerState.focused),
|
|
190
|
-
"aria-controls": dom.getContentId(state.context, value),
|
|
218
|
+
"aria-controls": triggerState.selected ? dom.getContentId(state.context, value) : void 0,
|
|
191
219
|
"data-ownedby": dom.getListId(state.context),
|
|
192
220
|
id: dom.getTriggerId(state.context, value),
|
|
193
|
-
tabIndex: triggerState.selected ? 0 : -1,
|
|
221
|
+
tabIndex: triggerState.selected && composite ? 0 : -1,
|
|
194
222
|
onFocus() {
|
|
195
223
|
send({ type: "TAB_FOCUS", value });
|
|
196
224
|
},
|
|
@@ -219,7 +247,7 @@ function connect(state, send, normalize) {
|
|
|
219
247
|
...parts.content.attrs,
|
|
220
248
|
dir: state.context.dir,
|
|
221
249
|
id: dom.getContentId(state.context, value),
|
|
222
|
-
tabIndex: 0,
|
|
250
|
+
tabIndex: composite ? 0 : -1,
|
|
223
251
|
"aria-labelledby": dom.getTriggerId(state.context, value),
|
|
224
252
|
role: "tabpanel",
|
|
225
253
|
"data-ownedby": dom.getListId(state.context),
|
|
@@ -235,16 +263,16 @@ function connect(state, send, normalize) {
|
|
|
235
263
|
"data-orientation": state.context.orientation,
|
|
236
264
|
style: {
|
|
237
265
|
"--transition-property": "left, right, top, bottom, width, height",
|
|
238
|
-
"--left":
|
|
239
|
-
"--top":
|
|
240
|
-
"--width":
|
|
241
|
-
"--height":
|
|
266
|
+
"--left": indicator.rect?.left,
|
|
267
|
+
"--top": indicator.rect?.top,
|
|
268
|
+
"--width": indicator.rect?.width,
|
|
269
|
+
"--height": indicator.rect?.height,
|
|
242
270
|
position: "absolute",
|
|
243
271
|
willChange: "var(--transition-property)",
|
|
244
272
|
transitionProperty: "var(--transition-property)",
|
|
245
|
-
transitionDuration:
|
|
273
|
+
transitionDuration: indicator.transition ? "var(--transition-duration, 150ms)" : "0ms",
|
|
246
274
|
transitionTimingFunction: "var(--transition-timing-function)",
|
|
247
|
-
[
|
|
275
|
+
[isHorizontal ? "left" : "top"]: isHorizontal ? "var(--left)" : "var(--top)"
|
|
248
276
|
}
|
|
249
277
|
})
|
|
250
278
|
};
|
|
@@ -255,7 +283,6 @@ var import_core = require("@zag-js/core");
|
|
|
255
283
|
var import_dom_event2 = require("@zag-js/dom-event");
|
|
256
284
|
var import_dom_query3 = require("@zag-js/dom-query");
|
|
257
285
|
var import_element_rect = require("@zag-js/element-rect");
|
|
258
|
-
var import_tabbable = require("@zag-js/tabbable");
|
|
259
286
|
var import_utils2 = require("@zag-js/utils");
|
|
260
287
|
var { not } = import_core.guards;
|
|
261
288
|
function machine(userContext) {
|
|
@@ -268,27 +295,18 @@ function machine(userContext) {
|
|
|
268
295
|
orientation: "horizontal",
|
|
269
296
|
activationMode: "automatic",
|
|
270
297
|
value: null,
|
|
271
|
-
focusedValue: null,
|
|
272
|
-
indicatorRect: {
|
|
273
|
-
left: "0px",
|
|
274
|
-
top: "0px",
|
|
275
|
-
width: "0px",
|
|
276
|
-
height: "0px"
|
|
277
|
-
},
|
|
278
|
-
canIndicatorTransition: false,
|
|
279
|
-
isIndicatorRendered: false,
|
|
280
298
|
loopFocus: true,
|
|
281
|
-
|
|
282
|
-
...ctx
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
299
|
+
composite: true,
|
|
300
|
+
...ctx,
|
|
301
|
+
focusedValue: ctx.value ?? null,
|
|
302
|
+
indicatorState: {
|
|
303
|
+
rendered: false,
|
|
304
|
+
transition: false,
|
|
305
|
+
rect: { left: "0px", top: "0px", width: "0px", height: "0px" }
|
|
306
|
+
}
|
|
287
307
|
},
|
|
288
|
-
entry: ["checkRenderedElements", "syncIndicatorRect", "setContentTabIndex"],
|
|
289
|
-
exit: ["cleanupObserver"],
|
|
290
308
|
watch: {
|
|
291
|
-
value: ["
|
|
309
|
+
value: ["allowIndicatorTransition", "syncIndicatorRect", "syncTabIndex", "clickIfLink"],
|
|
292
310
|
dir: ["syncIndicatorRect"],
|
|
293
311
|
orientation: ["syncIndicatorRect"]
|
|
294
312
|
},
|
|
@@ -301,22 +319,21 @@ function machine(userContext) {
|
|
|
301
319
|
},
|
|
302
320
|
SET_INDICATOR_RECT: {
|
|
303
321
|
actions: "setIndicatorRect"
|
|
322
|
+
},
|
|
323
|
+
SYNC_TAB_INDEX: {
|
|
324
|
+
actions: "syncTabIndex"
|
|
304
325
|
}
|
|
305
326
|
},
|
|
327
|
+
created: ["syncFocusedValue"],
|
|
328
|
+
entry: ["checkRenderedElements", "syncIndicatorRect", "syncTabIndex"],
|
|
329
|
+
exit: ["cleanupObserver"],
|
|
306
330
|
states: {
|
|
307
331
|
idle: {
|
|
308
332
|
on: {
|
|
309
|
-
TAB_FOCUS:
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
actions: ["setFocusedValue", "setValue"]
|
|
314
|
-
},
|
|
315
|
-
{
|
|
316
|
-
target: "focused",
|
|
317
|
-
actions: "setFocusedValue"
|
|
318
|
-
}
|
|
319
|
-
],
|
|
333
|
+
TAB_FOCUS: {
|
|
334
|
+
target: "focused",
|
|
335
|
+
actions: "setFocusedValue"
|
|
336
|
+
},
|
|
320
337
|
TAB_CLICK: {
|
|
321
338
|
target: "focused",
|
|
322
339
|
actions: ["setFocusedValue", "setValue"]
|
|
@@ -329,39 +346,49 @@ function machine(userContext) {
|
|
|
329
346
|
target: "focused",
|
|
330
347
|
actions: ["setFocusedValue", "setValue"]
|
|
331
348
|
},
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
349
|
+
ARROW_PREV: [
|
|
350
|
+
{
|
|
351
|
+
guard: "selectOnFocus",
|
|
352
|
+
actions: ["focusPrevTab", "selectFocusedTab"]
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
actions: "focusPrevTab"
|
|
356
|
+
}
|
|
357
|
+
],
|
|
358
|
+
ARROW_NEXT: [
|
|
359
|
+
{
|
|
360
|
+
guard: "selectOnFocus",
|
|
361
|
+
actions: ["focusNextTab", "selectFocusedTab"]
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
actions: "focusNextTab"
|
|
365
|
+
}
|
|
366
|
+
],
|
|
367
|
+
HOME: [
|
|
368
|
+
{
|
|
369
|
+
guard: "selectOnFocus",
|
|
370
|
+
actions: ["focusFirstTab", "selectFocusedTab"]
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
actions: "focusFirstTab"
|
|
374
|
+
}
|
|
375
|
+
],
|
|
376
|
+
END: [
|
|
359
377
|
{
|
|
360
378
|
guard: "selectOnFocus",
|
|
361
|
-
actions: ["
|
|
379
|
+
actions: ["focusLastTab", "selectFocusedTab"]
|
|
362
380
|
},
|
|
363
|
-
{
|
|
381
|
+
{
|
|
382
|
+
actions: "focusLastTab"
|
|
383
|
+
}
|
|
364
384
|
],
|
|
385
|
+
ENTER: {
|
|
386
|
+
guard: not("selectOnFocus"),
|
|
387
|
+
actions: "selectFocusedTab"
|
|
388
|
+
},
|
|
389
|
+
TAB_FOCUS: {
|
|
390
|
+
actions: ["setFocusedValue"]
|
|
391
|
+
},
|
|
365
392
|
TAB_BLUR: {
|
|
366
393
|
target: "idle",
|
|
367
394
|
actions: "clearFocusedValue"
|
|
@@ -372,12 +399,22 @@ function machine(userContext) {
|
|
|
372
399
|
},
|
|
373
400
|
{
|
|
374
401
|
guards: {
|
|
375
|
-
isVertical: (ctx2) => ctx2.isVertical,
|
|
376
|
-
isHorizontal: (ctx2) => ctx2.isHorizontal,
|
|
377
402
|
selectOnFocus: (ctx2) => ctx2.activationMode === "automatic"
|
|
378
403
|
},
|
|
379
404
|
actions: {
|
|
405
|
+
syncFocusedValue(ctx2) {
|
|
406
|
+
if (ctx2.value != null && ctx2.focusedValue == null) {
|
|
407
|
+
ctx2.focusedValue = ctx2.value;
|
|
408
|
+
}
|
|
409
|
+
},
|
|
410
|
+
selectFocusedTab(ctx2) {
|
|
411
|
+
(0, import_dom_query3.raf)(() => {
|
|
412
|
+
set.value(ctx2, ctx2.focusedValue);
|
|
413
|
+
});
|
|
414
|
+
},
|
|
380
415
|
setFocusedValue(ctx2, evt) {
|
|
416
|
+
if (evt.value == null)
|
|
417
|
+
return;
|
|
381
418
|
set.focusedValue(ctx2, evt.value);
|
|
382
419
|
},
|
|
383
420
|
clearFocusedValue(ctx2) {
|
|
@@ -390,80 +427,95 @@ function machine(userContext) {
|
|
|
390
427
|
set.value(ctx2, null);
|
|
391
428
|
},
|
|
392
429
|
focusFirstTab(ctx2) {
|
|
393
|
-
(0, import_dom_query3.raf)(() =>
|
|
430
|
+
(0, import_dom_query3.raf)(() => {
|
|
431
|
+
dom.getFirstTriggerEl(ctx2)?.focus();
|
|
432
|
+
});
|
|
394
433
|
},
|
|
395
434
|
focusLastTab(ctx2) {
|
|
396
|
-
(0, import_dom_query3.raf)(() =>
|
|
435
|
+
(0, import_dom_query3.raf)(() => {
|
|
436
|
+
dom.getLastTriggerEl(ctx2)?.focus();
|
|
437
|
+
});
|
|
397
438
|
},
|
|
398
439
|
focusNextTab(ctx2) {
|
|
399
440
|
if (!ctx2.focusedValue)
|
|
400
441
|
return;
|
|
401
|
-
const
|
|
402
|
-
(0, import_dom_query3.raf)(() =>
|
|
442
|
+
const triggerEl = dom.getNextTriggerEl(ctx2, ctx2.focusedValue);
|
|
443
|
+
(0, import_dom_query3.raf)(() => {
|
|
444
|
+
if (ctx2.composite) {
|
|
445
|
+
triggerEl?.focus();
|
|
446
|
+
} else if (triggerEl?.dataset.value != null) {
|
|
447
|
+
set.focusedValue(ctx2, triggerEl.dataset.value);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
403
450
|
},
|
|
404
451
|
focusPrevTab(ctx2) {
|
|
405
452
|
if (!ctx2.focusedValue)
|
|
406
453
|
return;
|
|
407
|
-
const
|
|
408
|
-
(0, import_dom_query3.raf)(() =>
|
|
454
|
+
const triggerEl = dom.getPrevTriggerEl(ctx2, ctx2.focusedValue);
|
|
455
|
+
(0, import_dom_query3.raf)(() => {
|
|
456
|
+
if (ctx2.composite) {
|
|
457
|
+
triggerEl?.focus();
|
|
458
|
+
} else if (triggerEl?.dataset.value != null) {
|
|
459
|
+
set.focusedValue(ctx2, triggerEl.dataset.value);
|
|
460
|
+
}
|
|
461
|
+
});
|
|
409
462
|
},
|
|
410
463
|
checkRenderedElements(ctx2) {
|
|
411
|
-
ctx2.
|
|
464
|
+
ctx2.indicatorState.rendered = !!dom.getIndicatorEl(ctx2);
|
|
412
465
|
},
|
|
413
|
-
|
|
414
|
-
setContentTabIndex(ctx2) {
|
|
466
|
+
syncTabIndex(ctx2) {
|
|
415
467
|
(0, import_dom_query3.raf)(() => {
|
|
416
|
-
const
|
|
417
|
-
if (!
|
|
468
|
+
const contentEl = dom.getSelectedContentEl(ctx2);
|
|
469
|
+
if (!contentEl)
|
|
418
470
|
return;
|
|
419
|
-
const focusables = (0,
|
|
471
|
+
const focusables = (0, import_dom_query3.getFocusables)(contentEl);
|
|
420
472
|
if (focusables.length > 0) {
|
|
421
|
-
|
|
473
|
+
contentEl.removeAttribute("tabindex");
|
|
422
474
|
} else {
|
|
423
|
-
|
|
475
|
+
contentEl.setAttribute("tabindex", "0");
|
|
424
476
|
}
|
|
425
477
|
});
|
|
426
478
|
},
|
|
427
479
|
cleanupObserver(ctx2) {
|
|
428
480
|
ctx2.indicatorCleanup?.();
|
|
429
481
|
},
|
|
430
|
-
|
|
431
|
-
ctx2.
|
|
482
|
+
allowIndicatorTransition(ctx2) {
|
|
483
|
+
ctx2.indicatorState.transition = true;
|
|
432
484
|
},
|
|
433
485
|
setIndicatorRect(ctx2, evt) {
|
|
434
486
|
const value = evt.id ?? ctx2.value;
|
|
435
|
-
if (!ctx2.
|
|
487
|
+
if (!ctx2.indicatorState.rendered || !value)
|
|
436
488
|
return;
|
|
437
|
-
const
|
|
438
|
-
if (!
|
|
489
|
+
const triggerEl = dom.getTriggerEl(ctx2, value);
|
|
490
|
+
if (!triggerEl)
|
|
439
491
|
return;
|
|
440
|
-
ctx2.
|
|
492
|
+
ctx2.indicatorState.rect = dom.getRectById(ctx2, value);
|
|
441
493
|
(0, import_dom_query3.nextTick)(() => {
|
|
442
|
-
ctx2.
|
|
494
|
+
ctx2.indicatorState.transition = false;
|
|
443
495
|
});
|
|
444
496
|
},
|
|
445
497
|
syncIndicatorRect(ctx2) {
|
|
446
498
|
ctx2.indicatorCleanup?.();
|
|
447
499
|
const value = ctx2.value;
|
|
448
|
-
if (!ctx2.
|
|
500
|
+
if (!ctx2.indicatorState.rendered || !value)
|
|
449
501
|
return;
|
|
450
|
-
const
|
|
451
|
-
if (!
|
|
502
|
+
const triggerEl = dom.getSelectedTriggerEl(ctx2);
|
|
503
|
+
if (!triggerEl)
|
|
452
504
|
return;
|
|
453
|
-
ctx2.indicatorCleanup = (0, import_element_rect.trackElementRect)(
|
|
505
|
+
ctx2.indicatorCleanup = (0, import_element_rect.trackElementRect)(triggerEl, {
|
|
454
506
|
getRect(el) {
|
|
455
507
|
return dom.getOffsetRect(el);
|
|
456
508
|
},
|
|
457
509
|
onChange(rect) {
|
|
458
|
-
ctx2.
|
|
510
|
+
ctx2.indicatorState.rect = dom.resolveRect(rect);
|
|
459
511
|
(0, import_dom_query3.nextTick)(() => {
|
|
460
|
-
ctx2.
|
|
512
|
+
ctx2.indicatorState.transition = false;
|
|
461
513
|
});
|
|
462
514
|
}
|
|
463
515
|
});
|
|
464
516
|
},
|
|
465
517
|
clickIfLink(ctx2) {
|
|
466
|
-
(0, import_dom_event2.clickIfLink)(dom.
|
|
518
|
+
(0, import_dom_event2.clickIfLink)(dom.getSelectedTriggerEl(ctx2));
|
|
467
519
|
}
|
|
468
520
|
}
|
|
469
521
|
}
|
|
@@ -501,6 +553,7 @@ var import_types = require("@zag-js/types");
|
|
|
501
553
|
var import_utils3 = require("@zag-js/utils");
|
|
502
554
|
var props = (0, import_types.createProps)()([
|
|
503
555
|
"activationMode",
|
|
556
|
+
"composite",
|
|
504
557
|
"dir",
|
|
505
558
|
"getRootNode",
|
|
506
559
|
"id",
|