@zag-js/tabs 0.10.4 → 0.11.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.
@@ -1,251 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const core = require('@zag-js/core');
6
- const domQuery = require('@zag-js/dom-query');
7
- const elementRect = require('@zag-js/element-rect');
8
- const tabbable = require('@zag-js/tabbable');
9
- const utils = require('@zag-js/utils');
10
- const tabs_dom = require('./tabs.dom.js');
11
-
12
- const { not } = core.guards;
13
- function machine(userContext) {
14
- const ctx = utils.compact(userContext);
15
- return core.createMachine(
16
- {
17
- initial: "idle",
18
- context: {
19
- dir: "ltr",
20
- orientation: "horizontal",
21
- activationMode: "automatic",
22
- value: null,
23
- focusedValue: null,
24
- previousValues: [],
25
- indicatorRect: {
26
- left: "0px",
27
- top: "0px",
28
- width: "0px",
29
- height: "0px"
30
- },
31
- canIndicatorTransition: false,
32
- isIndicatorRendered: false,
33
- loop: true,
34
- translations: {},
35
- ...ctx
36
- },
37
- computed: {
38
- isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
39
- isVertical: (ctx2) => ctx2.orientation === "vertical"
40
- },
41
- created: ["setPrevSelectedTabs"],
42
- entry: ["checkRenderedElements", "syncIndicatorRect", "setContentTabIndex"],
43
- exit: ["cleanupObserver"],
44
- watch: {
45
- focusedValue: "invokeOnFocus",
46
- value: [
47
- "enableIndicatorTransition",
48
- "invokeOnChange",
49
- "setPrevSelectedTabs",
50
- "syncIndicatorRect",
51
- "setContentTabIndex"
52
- ],
53
- dir: ["syncIndicatorRect"],
54
- orientation: ["syncIndicatorRect"]
55
- },
56
- on: {
57
- SET_VALUE: {
58
- actions: "setValue"
59
- },
60
- CLEAR_VALUE: {
61
- actions: "clearValue"
62
- },
63
- SET_INDICATOR_RECT: {
64
- actions: "setIndicatorRect"
65
- }
66
- },
67
- states: {
68
- idle: {
69
- on: {
70
- TAB_FOCUS: [
71
- {
72
- guard: "selectOnFocus",
73
- target: "focused",
74
- actions: ["setFocusedValue", "setValue"]
75
- },
76
- {
77
- target: "focused",
78
- actions: "setFocusedValue"
79
- }
80
- ],
81
- TAB_CLICK: {
82
- target: "focused",
83
- actions: ["setFocusedValue", "setValue"]
84
- }
85
- }
86
- },
87
- focused: {
88
- on: {
89
- TAB_CLICK: {
90
- target: "focused",
91
- actions: ["setFocusedValue", "setValue"]
92
- },
93
- ARROW_LEFT: {
94
- guard: "isHorizontal",
95
- actions: "focusPrevTab"
96
- },
97
- ARROW_RIGHT: {
98
- guard: "isHorizontal",
99
- actions: "focusNextTab"
100
- },
101
- ARROW_UP: {
102
- guard: "isVertical",
103
- actions: "focusPrevTab"
104
- },
105
- ARROW_DOWN: {
106
- guard: "isVertical",
107
- actions: "focusNextTab"
108
- },
109
- HOME: {
110
- actions: "focusFirstTab"
111
- },
112
- END: {
113
- actions: "focusLastTab"
114
- },
115
- ENTER: {
116
- guard: not("selectOnFocus"),
117
- actions: "setValue"
118
- },
119
- TAB_FOCUS: [
120
- {
121
- guard: "selectOnFocus",
122
- actions: ["setFocusedValue", "setValue"]
123
- },
124
- { actions: "setFocusedValue" }
125
- ],
126
- TAB_BLUR: {
127
- target: "idle",
128
- actions: "clearFocusedValue"
129
- }
130
- }
131
- }
132
- }
133
- },
134
- {
135
- guards: {
136
- isVertical: (ctx2) => ctx2.isVertical,
137
- isHorizontal: (ctx2) => ctx2.isHorizontal,
138
- selectOnFocus: (ctx2) => ctx2.activationMode === "automatic"
139
- },
140
- actions: {
141
- setFocusedValue(ctx2, evt) {
142
- ctx2.focusedValue = evt.value;
143
- },
144
- clearFocusedValue(ctx2) {
145
- ctx2.focusedValue = null;
146
- },
147
- setValue(ctx2, evt) {
148
- ctx2.value = evt.value;
149
- },
150
- clearValue(ctx2) {
151
- ctx2.value = null;
152
- },
153
- focusFirstTab(ctx2) {
154
- domQuery.raf(() => tabs_dom.dom.getFirstEl(ctx2)?.focus());
155
- },
156
- focusLastTab(ctx2) {
157
- domQuery.raf(() => tabs_dom.dom.getLastEl(ctx2)?.focus());
158
- },
159
- focusNextTab(ctx2) {
160
- if (!ctx2.focusedValue)
161
- return;
162
- const next = tabs_dom.dom.getNextEl(ctx2, ctx2.focusedValue);
163
- domQuery.raf(() => next?.focus());
164
- },
165
- focusPrevTab(ctx2) {
166
- if (!ctx2.focusedValue)
167
- return;
168
- const prev = tabs_dom.dom.getPrevEl(ctx2, ctx2.focusedValue);
169
- domQuery.raf(() => prev?.focus());
170
- },
171
- checkRenderedElements(ctx2) {
172
- ctx2.isIndicatorRendered = !!tabs_dom.dom.getIndicatorEl(ctx2);
173
- },
174
- invokeOnChange(ctx2) {
175
- ctx2.onChange?.({ value: ctx2.value });
176
- },
177
- invokeOnFocus(ctx2) {
178
- ctx2.onFocus?.({ value: ctx2.focusedValue });
179
- },
180
- setPrevSelectedTabs(ctx2) {
181
- if (ctx2.value != null) {
182
- ctx2.previousValues = pushUnique(ctx2.previousValues, ctx2.value);
183
- }
184
- },
185
- // if tab panel contains focusable elements, remove the tabindex attribute
186
- setContentTabIndex(ctx2) {
187
- domQuery.raf(() => {
188
- const panel = tabs_dom.dom.getActiveContentEl(ctx2);
189
- if (!panel)
190
- return;
191
- const focusables = tabbable.getFocusables(panel);
192
- if (focusables.length > 0) {
193
- panel.removeAttribute("tabindex");
194
- } else {
195
- panel.setAttribute("tabindex", "0");
196
- }
197
- });
198
- },
199
- cleanupObserver(ctx2) {
200
- ctx2.indicatorCleanup?.();
201
- },
202
- enableIndicatorTransition(ctx2) {
203
- ctx2.canIndicatorTransition = true;
204
- },
205
- setIndicatorRect(ctx2, evt) {
206
- const value = evt.id ?? ctx2.value;
207
- if (!ctx2.isIndicatorRendered || !value)
208
- return;
209
- const tabEl = tabs_dom.dom.getTriggerEl(ctx2, value);
210
- if (!tabEl)
211
- return;
212
- ctx2.indicatorRect = tabs_dom.dom.getRectById(ctx2, value);
213
- domQuery.nextTick(() => {
214
- ctx2.canIndicatorTransition = false;
215
- });
216
- },
217
- syncIndicatorRect(ctx2) {
218
- ctx2.indicatorCleanup?.();
219
- const value = ctx2.value;
220
- if (!ctx2.isIndicatorRendered || !value)
221
- return;
222
- const tabEl = tabs_dom.dom.getActiveTabEl(ctx2);
223
- if (!tabEl)
224
- return;
225
- ctx2.indicatorCleanup = elementRect.trackElementRect(tabEl, {
226
- getRect(el) {
227
- return tabs_dom.dom.getOffsetRect(el);
228
- },
229
- onChange(rect) {
230
- ctx2.indicatorRect = tabs_dom.dom.resolveRect(rect, ctx2.orientation);
231
- domQuery.nextTick(() => {
232
- ctx2.canIndicatorTransition = false;
233
- });
234
- }
235
- });
236
- }
237
- }
238
- }
239
- );
240
- }
241
- function pushUnique(arr, value) {
242
- const newArr = Array.from(arr).slice();
243
- const index = newArr.indexOf(value);
244
- if (index > -1) {
245
- newArr.splice(index, 1);
246
- }
247
- newArr.push(value);
248
- return newArr;
249
- }
250
-
251
- exports.machine = machine;
@@ -1,247 +0,0 @@
1
- import { createMachine, guards } from '@zag-js/core';
2
- import { raf, nextTick } from '@zag-js/dom-query';
3
- import { trackElementRect } from '@zag-js/element-rect';
4
- import { getFocusables } from '@zag-js/tabbable';
5
- import { compact } from '@zag-js/utils';
6
- import { dom } from './tabs.dom.mjs';
7
-
8
- const { not } = guards;
9
- function machine(userContext) {
10
- const ctx = compact(userContext);
11
- return createMachine(
12
- {
13
- initial: "idle",
14
- context: {
15
- dir: "ltr",
16
- orientation: "horizontal",
17
- activationMode: "automatic",
18
- value: null,
19
- focusedValue: null,
20
- previousValues: [],
21
- indicatorRect: {
22
- left: "0px",
23
- top: "0px",
24
- width: "0px",
25
- height: "0px"
26
- },
27
- canIndicatorTransition: false,
28
- isIndicatorRendered: false,
29
- loop: true,
30
- translations: {},
31
- ...ctx
32
- },
33
- computed: {
34
- isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
35
- isVertical: (ctx2) => ctx2.orientation === "vertical"
36
- },
37
- created: ["setPrevSelectedTabs"],
38
- entry: ["checkRenderedElements", "syncIndicatorRect", "setContentTabIndex"],
39
- exit: ["cleanupObserver"],
40
- watch: {
41
- focusedValue: "invokeOnFocus",
42
- value: [
43
- "enableIndicatorTransition",
44
- "invokeOnChange",
45
- "setPrevSelectedTabs",
46
- "syncIndicatorRect",
47
- "setContentTabIndex"
48
- ],
49
- dir: ["syncIndicatorRect"],
50
- orientation: ["syncIndicatorRect"]
51
- },
52
- on: {
53
- SET_VALUE: {
54
- actions: "setValue"
55
- },
56
- CLEAR_VALUE: {
57
- actions: "clearValue"
58
- },
59
- SET_INDICATOR_RECT: {
60
- actions: "setIndicatorRect"
61
- }
62
- },
63
- states: {
64
- idle: {
65
- on: {
66
- TAB_FOCUS: [
67
- {
68
- guard: "selectOnFocus",
69
- target: "focused",
70
- actions: ["setFocusedValue", "setValue"]
71
- },
72
- {
73
- target: "focused",
74
- actions: "setFocusedValue"
75
- }
76
- ],
77
- TAB_CLICK: {
78
- target: "focused",
79
- actions: ["setFocusedValue", "setValue"]
80
- }
81
- }
82
- },
83
- focused: {
84
- on: {
85
- TAB_CLICK: {
86
- target: "focused",
87
- actions: ["setFocusedValue", "setValue"]
88
- },
89
- ARROW_LEFT: {
90
- guard: "isHorizontal",
91
- actions: "focusPrevTab"
92
- },
93
- ARROW_RIGHT: {
94
- guard: "isHorizontal",
95
- actions: "focusNextTab"
96
- },
97
- ARROW_UP: {
98
- guard: "isVertical",
99
- actions: "focusPrevTab"
100
- },
101
- ARROW_DOWN: {
102
- guard: "isVertical",
103
- actions: "focusNextTab"
104
- },
105
- HOME: {
106
- actions: "focusFirstTab"
107
- },
108
- END: {
109
- actions: "focusLastTab"
110
- },
111
- ENTER: {
112
- guard: not("selectOnFocus"),
113
- actions: "setValue"
114
- },
115
- TAB_FOCUS: [
116
- {
117
- guard: "selectOnFocus",
118
- actions: ["setFocusedValue", "setValue"]
119
- },
120
- { actions: "setFocusedValue" }
121
- ],
122
- TAB_BLUR: {
123
- target: "idle",
124
- actions: "clearFocusedValue"
125
- }
126
- }
127
- }
128
- }
129
- },
130
- {
131
- guards: {
132
- isVertical: (ctx2) => ctx2.isVertical,
133
- isHorizontal: (ctx2) => ctx2.isHorizontal,
134
- selectOnFocus: (ctx2) => ctx2.activationMode === "automatic"
135
- },
136
- actions: {
137
- setFocusedValue(ctx2, evt) {
138
- ctx2.focusedValue = evt.value;
139
- },
140
- clearFocusedValue(ctx2) {
141
- ctx2.focusedValue = null;
142
- },
143
- setValue(ctx2, evt) {
144
- ctx2.value = evt.value;
145
- },
146
- clearValue(ctx2) {
147
- ctx2.value = null;
148
- },
149
- focusFirstTab(ctx2) {
150
- raf(() => dom.getFirstEl(ctx2)?.focus());
151
- },
152
- focusLastTab(ctx2) {
153
- raf(() => dom.getLastEl(ctx2)?.focus());
154
- },
155
- focusNextTab(ctx2) {
156
- if (!ctx2.focusedValue)
157
- return;
158
- const next = dom.getNextEl(ctx2, ctx2.focusedValue);
159
- raf(() => next?.focus());
160
- },
161
- focusPrevTab(ctx2) {
162
- if (!ctx2.focusedValue)
163
- return;
164
- const prev = dom.getPrevEl(ctx2, ctx2.focusedValue);
165
- raf(() => prev?.focus());
166
- },
167
- checkRenderedElements(ctx2) {
168
- ctx2.isIndicatorRendered = !!dom.getIndicatorEl(ctx2);
169
- },
170
- invokeOnChange(ctx2) {
171
- ctx2.onChange?.({ value: ctx2.value });
172
- },
173
- invokeOnFocus(ctx2) {
174
- ctx2.onFocus?.({ value: ctx2.focusedValue });
175
- },
176
- setPrevSelectedTabs(ctx2) {
177
- if (ctx2.value != null) {
178
- ctx2.previousValues = pushUnique(ctx2.previousValues, ctx2.value);
179
- }
180
- },
181
- // if tab panel contains focusable elements, remove the tabindex attribute
182
- setContentTabIndex(ctx2) {
183
- raf(() => {
184
- const panel = dom.getActiveContentEl(ctx2);
185
- if (!panel)
186
- return;
187
- const focusables = getFocusables(panel);
188
- if (focusables.length > 0) {
189
- panel.removeAttribute("tabindex");
190
- } else {
191
- panel.setAttribute("tabindex", "0");
192
- }
193
- });
194
- },
195
- cleanupObserver(ctx2) {
196
- ctx2.indicatorCleanup?.();
197
- },
198
- enableIndicatorTransition(ctx2) {
199
- ctx2.canIndicatorTransition = true;
200
- },
201
- setIndicatorRect(ctx2, evt) {
202
- const value = evt.id ?? ctx2.value;
203
- if (!ctx2.isIndicatorRendered || !value)
204
- return;
205
- const tabEl = dom.getTriggerEl(ctx2, value);
206
- if (!tabEl)
207
- return;
208
- ctx2.indicatorRect = dom.getRectById(ctx2, value);
209
- nextTick(() => {
210
- ctx2.canIndicatorTransition = false;
211
- });
212
- },
213
- syncIndicatorRect(ctx2) {
214
- ctx2.indicatorCleanup?.();
215
- const value = ctx2.value;
216
- if (!ctx2.isIndicatorRendered || !value)
217
- return;
218
- const tabEl = dom.getActiveTabEl(ctx2);
219
- if (!tabEl)
220
- return;
221
- ctx2.indicatorCleanup = trackElementRect(tabEl, {
222
- getRect(el) {
223
- return dom.getOffsetRect(el);
224
- },
225
- onChange(rect) {
226
- ctx2.indicatorRect = dom.resolveRect(rect, ctx2.orientation);
227
- nextTick(() => {
228
- ctx2.canIndicatorTransition = false;
229
- });
230
- }
231
- });
232
- }
233
- }
234
- }
235
- );
236
- }
237
- function pushUnique(arr, value) {
238
- const newArr = Array.from(arr).slice();
239
- const index = newArr.indexOf(value);
240
- if (index > -1) {
241
- newArr.splice(index, 1);
242
- }
243
- newArr.push(value);
244
- return newArr;
245
- }
246
-
247
- export { machine };