@servicetitan/anvil2 3.11.1 → 3.12.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,5 +1,5 @@
1
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
- import { createContext, forwardRef, useContext, useRef, useState, useEffect, useMemo } from 'react';
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { createContext, useContext, useRef, forwardRef, useLayoutEffect, useId, useState, useEffect, useCallback, useMemo } from 'react';
3
3
  import { c as cx } from './index-De1g9FRV.js';
4
4
  import { S as SvgCheck } from './check-Cf67OWrZ.js';
5
5
  import { I as Icon } from './Icon-B5zwN7GD.js';
@@ -10,15 +10,44 @@ import { u as useLayoutPropsUtil } from './useLayoutPropsUtil-DjqeAJZ9.js';
10
10
  import { m as motion } from './proxy-DEehATlA.js';
11
11
  import { B as Button } from './Button-Dwh_Nd4l.js';
12
12
  import { useTrackingId } from './useTrackingId.js';
13
+ import { u as useOptionallyControlledState } from './useOptionallyControlledState-DbDuos5L.js';
13
14
 
14
- import './Stepper.css';const StepperContext = createContext({
15
- current: 0,
16
- currentId: "",
17
- focus: 0,
18
- setFocus: () => void 0,
19
- setCurrent: () => void 0,
20
- setCurrentId: () => void 0
15
+ import './Stepper.css';const StepperBaseContext = createContext({
16
+ currentIndex: 0,
17
+ interactive: false,
18
+ focusIndex: 0,
19
+ setFocusIndex: () => void 0,
20
+ requestIndexChange: () => void 0,
21
+ registerStep: () => () => void 0,
22
+ getStep: () => void 0,
23
+ getCurrentStep: () => void 0,
24
+ getPanelId: () => void 0,
25
+ registerPanel: () => () => void 0
21
26
  });
27
+ const StepperBaseStepIndexPassContext = createContext(null);
28
+ function useStepperStepIndex() {
29
+ const pass = useContext(StepperBaseStepIndexPassContext);
30
+ const allocated = useRef(null);
31
+ if (!pass) return void 0;
32
+ if (allocated.current?.pass !== pass) {
33
+ allocated.current = { pass, index: pass.allocate() };
34
+ }
35
+ return allocated.current.index;
36
+ }
37
+
38
+ function startIndexPass() {
39
+ let nextIndex = 0;
40
+ return {
41
+ allocate: () => {
42
+ const index = nextIndex;
43
+ nextIndex += 1;
44
+ return index;
45
+ }
46
+ };
47
+ }
48
+ function StepperStepIndexScope({ children }) {
49
+ return /* @__PURE__ */ jsx(StepperBaseStepIndexPassContext.Provider, { value: startIndexPass(), children });
50
+ }
22
51
 
23
52
  const label$1 = "_label_iy9bb_28";
24
53
  const styles$3 = {
@@ -27,48 +56,415 @@ const styles$3 = {
27
56
  label: label$1
28
57
  };
29
58
 
30
- const StepperList = forwardRef(
59
+ const StepperBaseList = forwardRef(
31
60
  (props, ref) => {
32
- const { className, children, onKeyDown, ...rest } = props;
33
- const { current, items } = useContext(StepperContext);
34
- const tabListClassNames = cx(styles$3["stepper-list"], className);
35
- const currentLabel = items?.[current].querySelectorAll("span")[1].textContent;
61
+ const { className, children, ...rest } = props;
62
+ const { getCurrentStep } = useContext(StepperBaseContext);
63
+ const currentLabel = getCurrentStep()?.label;
36
64
  return /* @__PURE__ */ jsxs(
37
65
  "div",
38
66
  {
39
67
  ...rest,
40
- className: tabListClassNames,
41
- "data-anv": "stepper-list",
68
+ className: cx(styles$3["stepper-list"], className),
69
+ "data-anv": "stepper-base-list",
42
70
  ref,
43
71
  role: "tablist",
44
72
  children: [
45
- /* @__PURE__ */ jsx("div", { className: styles$3["stepper-steps"], children }),
73
+ /* @__PURE__ */ jsx("div", { className: styles$3["stepper-steps"], children: /* @__PURE__ */ jsx(StepperStepIndexScope, { children }) }),
46
74
  /* @__PURE__ */ jsx("span", { className: styles$3.label, children: currentLabel })
47
75
  ]
48
76
  }
49
77
  );
50
78
  }
51
79
  );
52
- StepperList.displayName = "StepperList";
80
+ StepperBaseList.displayName = "StepperBaseList";
53
81
 
54
- const bar = "_bar_1p8ur_30";
55
- const label = "_label_1p8ur_49";
56
- const circle = "_circle_1p8ur_62";
82
+ const bar = "_bar_rf27i_30";
83
+ const label = "_label_rf27i_49";
84
+ const circle = "_circle_rf27i_62";
57
85
  const styles$2 = {
58
- "stepper-step": "_stepper-step_1p8ur_1",
86
+ "stepper-step": "_stepper-step_rf27i_1",
59
87
  bar: bar,
60
88
  label: label,
61
89
  circle: circle,
62
- "all-completed": "_all-completed_1p8ur_87",
63
- "can-navigate": "_can-navigate_1p8ur_91"
90
+ "all-completed": "_all-completed_rf27i_87",
91
+ "can-navigate": "_can-navigate_rf27i_91"
64
92
  };
65
93
 
94
+ const StepperBaseStep = forwardRef((props, ref) => {
95
+ const stepRef = useRef(null);
96
+ const index = useStepperStepIndex();
97
+ const {
98
+ currentIndex,
99
+ interactive,
100
+ focusIndex,
101
+ setFocusIndex,
102
+ requestIndexChange,
103
+ registerStep,
104
+ getStep,
105
+ getPanelId
106
+ } = useContext(StepperBaseContext);
107
+ const {
108
+ state = "not started",
109
+ id,
110
+ disabled = false,
111
+ onClick,
112
+ children,
113
+ onKeyDown,
114
+ className,
115
+ "aria-label": ariaLabel,
116
+ ...rest
117
+ } = props;
118
+ const childrenText = typeof children === "string" ? children : typeof children === "number" ? String(children) : void 0;
119
+ const label = childrenText || ariaLabel || "";
120
+ useLayoutEffect(() => {
121
+ if (index === void 0) return;
122
+ return registerStep({
123
+ index,
124
+ id,
125
+ label,
126
+ disabled,
127
+ node: stepRef
128
+ });
129
+ }, [disabled, id, index, label, registerStep]);
130
+ const selected = index === currentIndex;
131
+ const completed = state === "complete";
132
+ const panelId = id ? getPanelId(id) : void 0;
133
+ const onClickHandler = (e) => {
134
+ onClick?.(e, index);
135
+ if (index === void 0) return;
136
+ requestIndexChange(index);
137
+ };
138
+ const onKeyDownHandler = (e) => {
139
+ onKeyDown?.(e);
140
+ if (!interactive || index === void 0) return;
141
+ const activatable = [];
142
+ for (let i = 0; ; i += 1) {
143
+ const step = getStep(i);
144
+ if (!step) break;
145
+ if (!step.disabled) activatable.push(i);
146
+ }
147
+ if (activatable.length === 0) return;
148
+ const currentPos = activatable.indexOf(focusIndex);
149
+ const safePos = currentPos === -1 ? 0 : currentPos;
150
+ switch (e.code) {
151
+ case "Enter":
152
+ case "Space":
153
+ e.preventDefault();
154
+ requestIndexChange(focusIndex);
155
+ break;
156
+ case "ArrowRight": {
157
+ e.preventDefault();
158
+ const next = activatable[(safePos + 1) % activatable.length];
159
+ setFocusIndex(next);
160
+ getStep(next)?.node.current?.focus();
161
+ break;
162
+ }
163
+ case "ArrowLeft": {
164
+ e.preventDefault();
165
+ const prev = activatable[(safePos - 1 + activatable.length) % activatable.length];
166
+ setFocusIndex(prev);
167
+ getStep(prev)?.node.current?.focus();
168
+ break;
169
+ }
170
+ }
171
+ };
172
+ return /* @__PURE__ */ jsxs(
173
+ "button",
174
+ {
175
+ type: "button",
176
+ role: "tab",
177
+ "data-anv": "stepper-base-step",
178
+ "data-state": state,
179
+ "data-completed": completed,
180
+ className: cx(styles$2["stepper-step"], className, {
181
+ [styles$2["can-navigate"]]: interactive
182
+ }),
183
+ "aria-selected": selected,
184
+ "aria-controls": panelId,
185
+ "aria-disabled": disabled || void 0,
186
+ "aria-label": childrenText || ariaLabel,
187
+ tabIndex: interactive && index === focusIndex && !disabled ? 0 : -1,
188
+ onClick: onClickHandler,
189
+ onKeyDown: interactive ? onKeyDownHandler : onKeyDown,
190
+ ...rest,
191
+ id,
192
+ ref: useMergeRefs([stepRef, ref]),
193
+ children: [
194
+ /* @__PURE__ */ jsx("span", { className: styles$2.bar }),
195
+ /* @__PURE__ */ jsxs("span", { className: styles$2.label, children: [
196
+ /* @__PURE__ */ jsx("span", { className: styles$2.circle, children: /* @__PURE__ */ jsx(Icon, { svg: SvgCheck, inherit: true, "aria-hidden": true }) }),
197
+ children
198
+ ] })
199
+ ]
200
+ }
201
+ );
202
+ });
203
+ StepperBaseStep.displayName = "StepperBaseStep";
204
+
205
+ const styles$1 = {
206
+ "stepper-panel": "_stepper-panel_14tpv_1"
207
+ };
208
+
209
+ const StepperBasePanel = forwardRef((props, ref) => {
210
+ const { layoutStyles, componentProps } = useLayoutPropsUtil(props);
211
+ const {
212
+ step,
213
+ id: idProp,
214
+ className,
215
+ style,
216
+ children,
217
+ ...rest
218
+ } = componentProps;
219
+ const generatedId = useId();
220
+ const id = idProp ?? generatedId;
221
+ const { getCurrentStep, registerPanel } = useContext(StepperBaseContext);
222
+ const currentStep = getCurrentStep();
223
+ const isCurrent = currentStep?.id === step;
224
+ useLayoutEffect(() => {
225
+ return registerPanel(step, id);
226
+ }, [id, registerPanel, step]);
227
+ const styleCombined = {
228
+ ...style,
229
+ ...layoutStyles
230
+ };
231
+ if (!isCurrent) {
232
+ return null;
233
+ }
234
+ return /* @__PURE__ */ jsx(
235
+ motion.div,
236
+ {
237
+ style: styleCombined,
238
+ className: cx(styles$1["stepper-panel"], className),
239
+ transition: {
240
+ opacity: {
241
+ duration: +DurationSlow.value.replace("ms", "") / 1e3
242
+ }
243
+ },
244
+ initial: { opacity: 0 },
245
+ animate: { opacity: 1 },
246
+ exit: { opacity: 0 },
247
+ layout: true,
248
+ ...rest,
249
+ role: "tabpanel",
250
+ "data-anv": "stepper-base-panel",
251
+ id,
252
+ ref,
253
+ children: /* @__PURE__ */ jsx(Overflow, { flexGrow: 1, children })
254
+ }
255
+ );
256
+ });
257
+ StepperBasePanel.displayName = "StepperBasePanel";
258
+
259
+ const stepper = "_stepper_4q6gk_1";
260
+ const styles = {
261
+ stepper: stepper
262
+ };
263
+
264
+ const StepperBase = Object.assign(
265
+ forwardRef(
266
+ function StepperBaseInner(props, ref) {
267
+ const { layoutStyles, componentProps } = useLayoutPropsUtil(props);
268
+ const {
269
+ index,
270
+ defaultIndex = 0,
271
+ onIndexChange,
272
+ interactive = false,
273
+ className,
274
+ children,
275
+ style,
276
+ ...rest
277
+ } = componentProps;
278
+ const rootRef = useRef(null);
279
+ const [currentIndex, setCurrentIndex] = useOptionallyControlledState({
280
+ controlledValue: index,
281
+ defaultValue: defaultIndex,
282
+ onChange: onIndexChange
283
+ });
284
+ const [focusIndex, setFocusIndex] = useState(index ?? defaultIndex);
285
+ useEffect(() => {
286
+ setFocusIndex(currentIndex);
287
+ }, [currentIndex]);
288
+ const stepsRef = useRef(/* @__PURE__ */ new Map());
289
+ const [stepsVersion, setStepsVersion] = useState(0);
290
+ const panelsRef = useRef(/* @__PURE__ */ new Map());
291
+ const [panelsVersion, setPanelsVersion] = useState(0);
292
+ const bumpSteps = useCallback(() => {
293
+ setStepsVersion((value2) => value2 + 1);
294
+ }, []);
295
+ const bumpPanels = useCallback(() => {
296
+ setPanelsVersion((value2) => value2 + 1);
297
+ }, []);
298
+ const registerStep = useCallback(
299
+ (info) => {
300
+ stepsRef.current.set(info.index, info);
301
+ bumpSteps();
302
+ return () => {
303
+ const current = stepsRef.current.get(info.index);
304
+ if (current === info) {
305
+ stepsRef.current.delete(info.index);
306
+ bumpSteps();
307
+ }
308
+ };
309
+ },
310
+ [bumpSteps]
311
+ );
312
+ const getStep = useCallback((stepIndex) => {
313
+ return stepsRef.current.get(stepIndex);
314
+ }, []);
315
+ const getCurrentStep = useCallback(() => {
316
+ return stepsRef.current.get(currentIndex);
317
+ }, [currentIndex]);
318
+ const requestIndexChange = useCallback(
319
+ (nextIndex) => {
320
+ if (!interactive) return;
321
+ const target = stepsRef.current.get(nextIndex);
322
+ if (target?.disabled) return;
323
+ setCurrentIndex(nextIndex);
324
+ setFocusIndex(nextIndex);
325
+ },
326
+ [interactive, setCurrentIndex]
327
+ );
328
+ const registerPanel = useCallback(
329
+ (stepId, panelId) => {
330
+ panelsRef.current.set(stepId, panelId);
331
+ bumpPanels();
332
+ return () => {
333
+ if (panelsRef.current.get(stepId) === panelId) {
334
+ panelsRef.current.delete(stepId);
335
+ bumpPanels();
336
+ }
337
+ };
338
+ },
339
+ [bumpPanels]
340
+ );
341
+ const getPanelId = useCallback((stepId) => {
342
+ return panelsRef.current.get(stepId);
343
+ }, []);
344
+ const value = useMemo(
345
+ () => ({
346
+ currentIndex,
347
+ interactive,
348
+ focusIndex,
349
+ setFocusIndex,
350
+ requestIndexChange,
351
+ registerStep,
352
+ getStep,
353
+ getCurrentStep,
354
+ getPanelId,
355
+ registerPanel
356
+ }),
357
+ [
358
+ currentIndex,
359
+ interactive,
360
+ focusIndex,
361
+ requestIndexChange,
362
+ registerStep,
363
+ getStep,
364
+ getCurrentStep,
365
+ getPanelId,
366
+ registerPanel,
367
+ stepsVersion,
368
+ panelsVersion
369
+ ]
370
+ );
371
+ const styleCombined = { ...style, ...layoutStyles };
372
+ return /* @__PURE__ */ jsx(StepperBaseContext.Provider, { value, children: /* @__PURE__ */ jsx(
373
+ motion.div,
374
+ {
375
+ transition: { duration: 0 },
376
+ layout: true,
377
+ className: cx(styles.stepper, className),
378
+ "data-anv": "stepper-base",
379
+ style: styleCombined,
380
+ ...rest,
381
+ ref: useMergeRefs([rootRef, ref]),
382
+ children
383
+ }
384
+ ) });
385
+ }
386
+ ),
387
+ {
388
+ /**
389
+ * Individual step. Outcome is independent of whether the step is current.
390
+ *
391
+ * Features:
392
+ * - state: not started, started, or complete
393
+ * - Optional id when a panel points at this step
394
+ * - Check icon when complete
395
+ *
396
+ * @example
397
+ * <StepperBase.Step state="complete">Approved</StepperBase.Step>
398
+ */
399
+ Step: StepperBaseStep,
400
+ /**
401
+ * Track of steps plus the compact label on small widths.
402
+ *
403
+ * Features:
404
+ * - Lays out StepperBase.Step children
405
+ * - Shows the current step label when the track is narrow
406
+ *
407
+ * @example
408
+ * <StepperBase.List>
409
+ * <StepperBase.Step>Scheduled</StepperBase.Step>
410
+ * </StepperBase.List>
411
+ */
412
+ List: StepperBaseList,
413
+ /**
414
+ * Content for one step. Visible when that step is current.
415
+ *
416
+ * Features:
417
+ * - step is required and must match a Step id
418
+ * - id is optional and generated when omitted
419
+ *
420
+ * @example
421
+ * <StepperBase.Panel step="approved">Details</StepperBase.Panel>
422
+ */
423
+ Panel: StepperBasePanel
424
+ }
425
+ );
426
+ StepperBase.displayName = "StepperBase";
427
+
428
+ const StepperList = forwardRef(
429
+ (props, ref) => {
430
+ const { className, children, onKeyDown: _onKeyDown, ...rest } = props;
431
+ const { getCurrentStep } = useContext(StepperBaseContext);
432
+ const currentLabel = getCurrentStep()?.label;
433
+ const tabListClassNames = cx(styles$3["stepper-list"], className);
434
+ return /* @__PURE__ */ jsxs(
435
+ "div",
436
+ {
437
+ ...rest,
438
+ className: tabListClassNames,
439
+ "data-anv": "stepper-list",
440
+ ref,
441
+ role: "tablist",
442
+ children: [
443
+ /* @__PURE__ */ jsx("div", { className: styles$3["stepper-steps"], children: /* @__PURE__ */ jsx(StepperStepIndexScope, { children }) }),
444
+ /* @__PURE__ */ jsx("span", { className: styles$3.label, children: currentLabel })
445
+ ]
446
+ }
447
+ );
448
+ }
449
+ );
450
+ StepperList.displayName = "StepperList";
451
+
452
+ const StepperContext = createContext({
453
+ current: 0,
454
+ currentId: "",
455
+ focus: 0,
456
+ setFocus: () => void 0,
457
+ setCurrent: () => void 0,
458
+ setCurrentId: () => void 0
459
+ });
460
+
66
461
  const StepperStep = forwardRef(
67
462
  (props, ref) => {
68
463
  const stepRef = useRef(null);
464
+ const index = useStepperStepIndex();
465
+ const { registerStep, getStep } = useContext(StepperBaseContext);
69
466
  const {
70
467
  current,
71
- items,
72
468
  setCurrent,
73
469
  focus,
74
470
  setFocus,
@@ -85,39 +481,40 @@ const StepperStep = forwardRef(
85
481
  "aria-label": ariaLabel,
86
482
  ...rest
87
483
  } = props;
88
- const index = useRef();
89
- const [selected, setSelected] = useState(false);
90
- const [completed, setCompleted] = useState(
91
- // Below is to be used for custom overriding
92
- // completed state for a step
93
- // Check Stepper.stories.tsx#103 for the use case
94
- stepRef.current?.getAttribute("data-completed") === "true" ? true : void 0
95
- );
96
- useEffect(() => {
97
- if (!items) return;
98
- index.current = Array.prototype.indexOf.call(items, stepRef.current);
99
- setCompleted(index.current < current);
100
- setSelected(index.current === current);
101
- }, [current, items]);
484
+ const childrenText = typeof children === "string" ? children : typeof children === "number" ? String(children) : void 0;
485
+ const label = childrenText || ariaLabel || "";
486
+ useLayoutEffect(() => {
487
+ if (index === void 0) return;
488
+ return registerStep({
489
+ index,
490
+ id: controls,
491
+ label,
492
+ disabled: false,
493
+ node: stepRef
494
+ });
495
+ }, [controls, index, label, registerStep]);
496
+ const selected = index === current;
497
+ const completed = index !== void 0 && index < current;
102
498
  const stepClassNames = cx(styles$2["stepper-step"], className, {
103
499
  [styles$2["can-navigate"]]: allowNavigateToPrevStep,
104
500
  [styles$2["all-completed"]]: allCompleted
105
501
  });
106
502
  const onClickHandler = (e) => {
107
- onClick?.(e, index.current);
108
- if (!allowNavigateToPrevStep || selected || index.current === void 0 || !items || index.current > current) {
503
+ onClick?.(e, index);
504
+ if (!allowNavigateToPrevStep || selected || index === void 0 || index > current) {
109
505
  return;
110
506
  }
111
- setCurrent(index.current ?? 0);
112
- setFocus(index.current);
113
- items[index.current].focus();
507
+ setCurrent(index);
508
+ setFocus(index);
509
+ stepRef.current?.focus();
114
510
  };
115
511
  const onKeyDownHandler = (e) => {
116
512
  onKeyDown?.(e);
117
- const focusableItems = Array.prototype.filter.call(
118
- items,
119
- (item) => item.getAttribute("data-completed") === "true" || item.getAttribute("aria-selected") === "true"
120
- );
513
+ const focusableItems = [];
514
+ for (let i = 0; i <= current; i += 1) {
515
+ const node = getStep(i)?.node.current;
516
+ if (node) focusableItems.push(node);
517
+ }
121
518
  const prevFocus = focus - 1;
122
519
  const nextFocus = focus + 1;
123
520
  switch (e.code) {
@@ -131,14 +528,10 @@ const StepperStep = forwardRef(
131
528
  if (nextFocus === focusableItems.length) {
132
529
  setFocus(0);
133
530
  focusableItems[0].focus();
134
- focusableItems[0].setAttribute("tabindex", "0");
135
- stepRef.current?.setAttribute("tabindex", "-1");
136
531
  return;
137
532
  }
138
- stepRef.current?.setAttribute("tabindex", "-1");
139
533
  setFocus(nextFocus);
140
534
  focusableItems[nextFocus].focus();
141
- focusableItems[nextFocus].setAttribute("tabindex", "0");
142
535
  break;
143
536
  case "ArrowLeft":
144
537
  e.preventDefault();
@@ -146,18 +539,13 @@ const StepperStep = forwardRef(
146
539
  const lastItemIndex = focusableItems.length - 1;
147
540
  setFocus(lastItemIndex);
148
541
  focusableItems[lastItemIndex].focus();
149
- focusableItems[lastItemIndex].setAttribute("tabindex", "0");
150
- stepRef.current?.setAttribute("tabindex", "-1");
151
542
  return;
152
543
  }
153
- stepRef.current?.setAttribute("tabindex", "-1");
154
544
  setFocus(prevFocus);
155
545
  focusableItems[prevFocus].focus();
156
- focusableItems[prevFocus].setAttribute("tabindex", "0");
157
546
  break;
158
547
  }
159
548
  };
160
- const childrenText = typeof children === "string" ? children : typeof children === "number" ? String(children) : void 0;
161
549
  return /* @__PURE__ */ jsxs(
162
550
  "button",
163
551
  {
@@ -168,7 +556,7 @@ const StepperStep = forwardRef(
168
556
  "aria-selected": selected,
169
557
  "aria-controls": controls,
170
558
  "aria-label": childrenText || ariaLabel,
171
- tabIndex: allowNavigateToPrevStep && selected ? 0 : -1,
559
+ tabIndex: allowNavigateToPrevStep && index === focus && !allCompleted ? 0 : -1,
172
560
  "data-completed": completed,
173
561
  onClick: onClickHandler,
174
562
  onKeyDown: allowNavigateToPrevStep ? onKeyDownHandler : onKeyDown,
@@ -187,22 +575,19 @@ const StepperStep = forwardRef(
187
575
  );
188
576
  StepperStep.displayName = "StepperStep";
189
577
 
190
- const styles$1 = {
191
- "stepper-panel": "_stepper-panel_14tpv_1"
192
- };
193
-
194
578
  const StepperPanel = forwardRef(
195
579
  (props, ref) => {
196
580
  const { layoutStyles, componentProps } = useLayoutPropsUtil(props);
197
581
  const { id, className, style, children, ...rest } = componentProps;
198
- const { current, items, allCompleted, setCurrentId } = useContext(StepperContext);
199
- const currentId = items?.[current].getAttribute("aria-controls");
200
- const isCurrent = currentId === id;
582
+ const { allCompleted, setCurrentId } = useContext(StepperContext);
583
+ const { getCurrentStep } = useContext(StepperBaseContext);
584
+ const currentStepId = getCurrentStep()?.id;
585
+ const isCurrent = currentStepId === id;
201
586
  useEffect(() => {
202
587
  if (isCurrent && !allCompleted) {
203
- setCurrentId(currentId ?? "");
588
+ setCurrentId(currentStepId ?? "");
204
589
  }
205
- }, [allCompleted, isCurrent, currentId, setCurrentId]);
590
+ }, [allCompleted, isCurrent, currentStepId, setCurrentId]);
206
591
  const tabPanelClassNames = cx(styles$1["stepper-panel"], className);
207
592
  const styleCombined = {
208
593
  ...style,
@@ -279,16 +664,24 @@ const StepperFinalPanel = forwardRef((props, ref) => {
279
664
  });
280
665
  StepperFinalPanel.displayName = "StepperFinalPanel";
281
666
 
667
+ function countRegisteredSteps(getStep) {
668
+ let count = 0;
669
+ while (getStep(count)) count += 1;
670
+ return count;
671
+ }
672
+
282
673
  const StepperNextButton = forwardRef((props, ref) => {
283
674
  const {
284
675
  setAllCompleted,
285
676
  onComplete,
286
677
  setCurrent,
287
678
  setFocus,
288
- items,
289
679
  current,
290
680
  allCompleted
291
681
  } = useContext(StepperContext);
682
+ const { getStep } = useContext(StepperBaseContext);
683
+ const stepCount = countRegisteredSteps(getStep);
684
+ const isLastStep = stepCount > 0 && current === stepCount - 1;
292
685
  const {
293
686
  onClick,
294
687
  onFocus,
@@ -298,8 +691,7 @@ const StepperNextButton = forwardRef((props, ref) => {
298
691
  ...rest
299
692
  } = props;
300
693
  const proceedToNextStep = () => {
301
- if (items && current === items.length - 1) {
302
- items.forEach((item) => item.setAttribute("tabindex", "-1"));
694
+ if (isLastStep) {
303
695
  setAllCompleted?.(true);
304
696
  onComplete?.();
305
697
  return;
@@ -337,29 +729,18 @@ const StepperNextButton = forwardRef((props, ref) => {
337
729
  appearance,
338
730
  ref,
339
731
  ...rest,
340
- children: items && current === items.length - 1 ? completeLabel : nextLabel
732
+ children: isLastStep ? completeLabel : nextLabel
341
733
  }
342
734
  );
343
735
  });
344
736
  StepperNextButton.displayName = "StepperNextButton";
345
737
 
346
738
  const StepperPrevButton = forwardRef((props, ref) => {
347
- const {
348
- setCurrent,
349
- setFocus,
350
- allCompleted,
351
- setAllCompleted,
352
- items,
353
- current,
354
- allowNavigateToPrevStep
355
- } = useContext(StepperContext);
739
+ const { setCurrent, setFocus, allCompleted, setAllCompleted, current } = useContext(StepperContext);
356
740
  const { onClick, label = "Previous", onFocus, ...rest } = props;
357
741
  const onClickHandler = (e) => {
358
742
  if (allCompleted) {
359
743
  setAllCompleted?.(false);
360
- if (allowNavigateToPrevStep) {
361
- items?.[current].setAttribute("tabindex", "0");
362
- }
363
744
  } else {
364
745
  setCurrent(current - 1);
365
746
  setFocus(current - 1);
@@ -388,50 +769,47 @@ const StepperPrevButton = forwardRef((props, ref) => {
388
769
  });
389
770
  StepperPrevButton.displayName = "StepperPrevButton";
390
771
 
391
- const stepper = "_stepper_4q6gk_1";
392
- const styles = {
393
- stepper: stepper
394
- };
772
+ function StepperWizardBootstrap({
773
+ defaultIndex
774
+ }) {
775
+ const { getStep } = useContext(StepperBaseContext);
776
+ const { setAllCompleted, setCurrent, setFocus } = useContext(StepperContext);
777
+ const didBootstrap = useRef(false);
778
+ const hasSteps = !!getStep(0);
779
+ useEffect(() => {
780
+ if (didBootstrap.current || !hasSteps) return;
781
+ didBootstrap.current = true;
782
+ const stepCount = countRegisteredSteps(getStep);
783
+ if (defaultIndex !== void 0 && defaultIndex >= stepCount) {
784
+ const lastIndex = stepCount - 1;
785
+ setAllCompleted?.(true);
786
+ setCurrent(lastIndex);
787
+ setFocus(lastIndex);
788
+ }
789
+ }, [defaultIndex, getStep, hasSteps, setAllCompleted, setCurrent, setFocus]);
790
+ return null;
791
+ }
395
792
 
396
793
  const Stepper = Object.assign(
397
794
  forwardRef(function StepperInner(props, ref) {
398
- const { layoutStyles, componentProps } = useLayoutPropsUtil(props);
399
795
  const {
400
796
  defaultIndex,
401
- className,
402
797
  allowNavigateToPrevStep,
403
798
  children,
404
799
  onChange,
405
800
  onComplete,
406
- style,
407
801
  ...rest
408
- } = componentProps;
409
- const tabRef = useRef(null);
410
- const [items, setItems] = useState();
802
+ } = props;
411
803
  const [allCompleted, setAllCompleted] = useState(false);
412
804
  const [current, setCurrent] = useState(defaultIndex ?? 0);
413
805
  const [currentId, setCurrentId] = useState("");
414
806
  const [focus, setFocus] = useState(defaultIndex ?? 0);
415
- const stepperClassNames = cx(styles["stepper"], className);
416
- useEffect(() => {
417
- const newItems = tabRef.current?.querySelectorAll(
418
- "[role=tab]:not([disabled])"
419
- );
420
- setItems(newItems);
421
- if (defaultIndex !== void 0 && newItems && newItems.length > 0 && defaultIndex >= newItems.length) {
422
- const lastIndex = newItems.length - 1;
423
- setAllCompleted(true);
424
- setCurrent(lastIndex);
425
- setFocus(lastIndex);
426
- }
427
- }, []);
428
807
  useEffect(() => {
429
808
  onChange?.({
430
809
  currentStepId: currentId,
431
810
  currentStepIndex: allCompleted ? void 0 : current
432
811
  });
433
812
  }, [allCompleted, currentId, onChange]);
434
- const styleCombined = { ...style, ...layoutStyles };
435
813
  const value = useMemo(
436
814
  () => ({
437
815
  current,
@@ -441,7 +819,6 @@ const Stepper = Object.assign(
441
819
  focus,
442
820
  setFocus,
443
821
  onComplete,
444
- items,
445
822
  allCompleted,
446
823
  setAllCompleted,
447
824
  allowNavigateToPrevStep
@@ -451,25 +828,24 @@ const Stepper = Object.assign(
451
828
  currentId,
452
829
  focus,
453
830
  onComplete,
454
- items,
455
831
  allCompleted,
456
- setAllCompleted,
457
832
  allowNavigateToPrevStep
458
833
  ]
459
834
  );
460
- return /* @__PURE__ */ jsx(StepperContext.Provider, { value, children: /* @__PURE__ */ jsx(
461
- motion.div,
835
+ return /* @__PURE__ */ jsx(
836
+ StepperBase,
462
837
  {
463
- transition: { duration: 0 },
464
- layout: true,
465
- className: stepperClassNames,
838
+ index: current,
839
+ interactive: false,
466
840
  "data-anv": "stepper",
467
- style: styleCombined,
468
841
  ...rest,
469
- ref: useMergeRefs([tabRef, ref]),
470
- children
842
+ ref,
843
+ children: /* @__PURE__ */ jsxs(StepperContext.Provider, { value, children: [
844
+ /* @__PURE__ */ jsx(StepperWizardBootstrap, { defaultIndex }),
845
+ children
846
+ ] })
471
847
  }
472
- ) });
848
+ );
473
849
  }),
474
850
  {
475
851
  /**
@@ -626,5 +1002,5 @@ const Stepper = Object.assign(
626
1002
  );
627
1003
  Stepper.displayName = "Stepper";
628
1004
 
629
- export { Stepper as S };
630
- //# sourceMappingURL=Stepper-z1y9AfaJ.js.map
1005
+ export { Stepper as S, StepperBase as a };
1006
+ //# sourceMappingURL=Stepper-CCKHWlUr.js.map