@ttoss/react-wizard 0.3.17 → 0.4.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/README.md CHANGED
@@ -35,6 +35,13 @@ const MyWizard = () => {
35
35
  <Wizard
36
36
  steps={steps}
37
37
  layout="top"
38
+ variant="spotlight-accent"
39
+ labels={{
40
+ previous: 'Voltar',
41
+ next: 'Avançar',
42
+ finish: 'Concluir',
43
+ cancel: 'Sair',
44
+ }}
38
45
  onComplete={() => console.log('Done!')}
39
46
  onCancel={() => console.log('Cancelled')}
40
47
  />
@@ -42,17 +49,21 @@ const MyWizard = () => {
42
49
  };
43
50
  ```
44
51
 
52
+ Labels are customizable, so applications can localize them as needed.
53
+
45
54
  ## Props
46
55
 
47
- | Prop | Type | Default | Description |
48
- | ---------------- | ----------------------------------------- | ------- | ------------------------------------------------------ |
49
- | `steps` | `WizardStep[]` | — | Array of step definitions. |
50
- | `layout` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'top'` | Position of the step list relative to content. |
51
- | `onComplete` | `() => void` | | Called when the user finishes the last step. |
52
- | `onCancel` | `() => void` | — | Called on cancel. If omitted, cancel button is hidden. |
53
- | `onStepChange` | `(params: { stepIndex: number }) => void` | — | Called when the active step changes. |
54
- | `initialStep` | `number` | `0` | The initially active step index. |
55
- | `allowStepClick` | `boolean` | `true` | Allow clicking completed steps to navigate back. |
56
+ | Prop | Type | Default | Description |
57
+ | ---------------- | ----------------------------------------------------------------------------------- | -------------------- | --------------------------------------------------------------- |
58
+ | `steps` | `WizardStep[]` | — | Array of step definitions. |
59
+ | `layout` | `'top' \| 'right' \| 'bottom' \| 'left'` | `'top'` | Position of the step list relative to content. |
60
+ | `variant` | `'spotlight-accent' \| 'spotlight-primary' \| 'primary' \| 'secondary' \| 'accent'` | `'spotlight-accent'` | Visual variant for the shell, step accents, and primary action. |
61
+ | `onComplete` | `() => void` | — | Called when the user finishes the last step. |
62
+ | `onCancel` | `() => void` | — | Called on cancel. If omitted, cancel button is hidden. |
63
+ | `onStepChange` | `(params: { stepIndex: number }) => void` | | Called when the active step changes. |
64
+ | `initialStep` | `number` | `0` | The initially active step index. |
65
+ | `allowStepClick` | `boolean` | `true` | Allow clicking completed steps to navigate back. |
66
+ | `labels` | `Partial<{ previous: string; next: string; finish: string; cancel: string }>` | — | Override the built-in navigation labels. |
56
67
 
57
68
  ## WizardStep
58
69
 
package/dist/esm/index.js CHANGED
@@ -11,6 +11,170 @@ import { defineMessages, useI18n } from "@ttoss/react-i18n";
11
11
  import { Box as Box2, Button, Flex as Flex2 } from "@ttoss/ui";
12
12
  import * as React3 from "react";
13
13
 
14
+ // src/Wizard.styles.ts
15
+ import { keyframes } from "@ttoss/ui";
16
+ var gradientFlow = keyframes({
17
+ "0%": {
18
+ backgroundPosition: "0% 50%"
19
+ },
20
+ "50%": {
21
+ backgroundPosition: "100% 50%"
22
+ },
23
+ "100%": {
24
+ backgroundPosition: "0% 50%"
25
+ }
26
+ });
27
+ var getAccentGradientBackground = /* @__PURE__ */__name(t => {
28
+ const theme = t;
29
+ const start = theme.colors?.action?.background?.accent?.default || theme.colors?.input?.background?.accent?.default;
30
+ if (!start) return void 0;
31
+ const middle = theme.colors?.action?.background?.accent?.active || theme.colors?.input?.background?.accent?.active || start;
32
+ return `linear-gradient(270deg, ${start}, ${middle}, ${start})`;
33
+ }, "getAccentGradientBackground");
34
+ var getPrimaryGradientBackground = /* @__PURE__ */__name(t => {
35
+ const theme = t;
36
+ const start = theme.colors?.action?.background?.primary?.default;
37
+ if (!start) return void 0;
38
+ const middle = theme.colors?.action?.background?.secondary?.default || start;
39
+ return `linear-gradient(270deg, ${start}, ${middle}, ${start})`;
40
+ }, "getPrimaryGradientBackground");
41
+ var getVariantStyles = /* @__PURE__ */__name((variantType = "spotlight-accent") => {
42
+ const variants = {
43
+ "spotlight-accent": {
44
+ accentColor: "action.background.accent.default",
45
+ accentTextColor: "action.text.accent.default",
46
+ borderColor: "display.border.muted.default",
47
+ primaryButtonVariant: "accent",
48
+ gradientBackground: getAccentGradientBackground
49
+ },
50
+ "spotlight-primary": {
51
+ accentColor: "action.background.primary.default",
52
+ accentTextColor: "display.text.accent.default",
53
+ borderColor: "display.border.muted.default",
54
+ primaryButtonVariant: "primary",
55
+ gradientBackground: getPrimaryGradientBackground
56
+ },
57
+ primary: {
58
+ accentColor: "action.background.primary.default",
59
+ accentTextColor: "action.text.primary.default",
60
+ borderColor: "display.border.muted.default",
61
+ primaryButtonVariant: "primary"
62
+ },
63
+ secondary: {
64
+ accentColor: "action.background.secondary.default",
65
+ accentTextColor: "action.text.primary.default",
66
+ borderColor: "display.border.muted.default",
67
+ primaryButtonVariant: "secondary"
68
+ },
69
+ accent: {
70
+ accentColor: "action.background.accent.default",
71
+ accentTextColor: "action.text.accent.default",
72
+ borderColor: "display.border.muted.default",
73
+ primaryButtonVariant: "accent"
74
+ }
75
+ };
76
+ return variants[variantType] ?? variants["spotlight-accent"];
77
+ }, "getVariantStyles");
78
+ var getWizardShellSx = /* @__PURE__ */__name((variant = "spotlight-accent") => {
79
+ const variantStyles = getVariantStyles(variant);
80
+ return {
81
+ width: "100%",
82
+ minHeight: "300px",
83
+ border: "1px solid",
84
+ borderColor: variantStyles.borderColor,
85
+ borderRadius: "8px",
86
+ overflow: "hidden"
87
+ };
88
+ }, "getWizardShellSx");
89
+ var getWizardStepListSx = /* @__PURE__ */__name(({
90
+ layout,
91
+ variant = "spotlight-accent"
92
+ }) => {
93
+ const isHorizontal = layout === "top" || layout === "bottom";
94
+ const isSpotlight = variant.startsWith("spotlight-");
95
+ const variantStyles = getVariantStyles(variant);
96
+ return {
97
+ position: "relative",
98
+ padding: "6",
99
+ backgroundColor: variantStyles.accentColor,
100
+ ...(isSpotlight ? {
101
+ background: variantStyles.gradientBackground,
102
+ backgroundSize: "400% 400%",
103
+ animation: `${gradientFlow} 6s ease infinite`
104
+ } : {}),
105
+ ...(isHorizontal ? {
106
+ width: "100%"
107
+ } : {
108
+ minWidth: "200px"
109
+ })
110
+ };
111
+ }, "getWizardStepListSx");
112
+ var getWizardStepIndicatorSx = /* @__PURE__ */__name(({
113
+ status,
114
+ variant = "spotlight-accent",
115
+ isClickable
116
+ }) => {
117
+ const variantStyles = getVariantStyles(variant);
118
+ const isCompleted = status === "completed";
119
+ const isUpcoming = status === "upcoming";
120
+ return {
121
+ borderColor: variantStyles.accentTextColor,
122
+ backgroundColor: isCompleted ? variantStyles.accentTextColor : "transparent",
123
+ color: isCompleted ? variantStyles.accentColor : variantStyles.accentTextColor,
124
+ opacity: isUpcoming ? 0.4 : 1,
125
+ transition: "all 0.2s ease",
126
+ ...(isClickable ? {
127
+ _hover: {
128
+ opacity: 1
129
+ }
130
+ } : {})
131
+ };
132
+ }, "getWizardStepIndicatorSx");
133
+ var getWizardStepSeparatorSx = /* @__PURE__ */__name(({
134
+ isCompleted,
135
+ variant = "spotlight-accent"
136
+ }) => {
137
+ const variantStyles = getVariantStyles(variant);
138
+ return {
139
+ backgroundColor: variantStyles.accentTextColor,
140
+ opacity: isCompleted ? 1 : 0.4
141
+ };
142
+ }, "getWizardStepSeparatorSx");
143
+ var getWizardStepTitleSx = /* @__PURE__ */__name(({
144
+ status,
145
+ variant = "spotlight-accent"
146
+ }) => {
147
+ const variantStyles = getVariantStyles(variant);
148
+ return {
149
+ color: variantStyles.accentTextColor,
150
+ textAlign: "center",
151
+ fontWeight: status === "active" ? "bold" : "normal",
152
+ opacity: status === "upcoming" ? 0.4 : 1
153
+ };
154
+ }, "getWizardStepTitleSx");
155
+ var getWizardStepDescriptionSx = /* @__PURE__ */__name(({
156
+ status,
157
+ variant = "spotlight-accent"
158
+ }) => {
159
+ const variantStyles = getVariantStyles(variant);
160
+ return {
161
+ color: variantStyles.accentTextColor,
162
+ textAlign: "center",
163
+ opacity: status === "upcoming" ? 0.4 : 1
164
+ };
165
+ }, "getWizardStepDescriptionSx");
166
+ var WizardStepDescriptionFlexSx = {
167
+ flexDirection: "row",
168
+ alignItems: "center",
169
+ justifyContent: "center"
170
+ };
171
+ var WizardStepTextWrapperSx = {
172
+ textAlign: "center"
173
+ };
174
+ var getWizardPrimaryButtonVariant = /* @__PURE__ */__name((variant = "spotlight-accent") => {
175
+ return getVariantStyles(variant).primaryButtonVariant;
176
+ }, "getWizardPrimaryButtonVariant");
177
+
14
178
  // src/WizardContext.ts
15
179
  import * as React2 from "react";
16
180
  var WizardContext = React2.createContext(null);
@@ -29,6 +193,7 @@ var WizardStepList = /* @__PURE__ */__name(({
29
193
  steps,
30
194
  currentStep,
31
195
  layout,
196
+ variant,
32
197
  allowStepClick,
33
198
  getStepStatus,
34
199
  onStepClick
@@ -38,21 +203,11 @@ var WizardStepList = /* @__PURE__ */__name(({
38
203
  return /* @__PURE__ */React.createElement(Flex, {
39
204
  role: "navigation",
40
205
  "aria-label": "Wizard steps",
41
- sx: {
42
- padding: "6",
43
- backgroundColor: "navigation.background.muted.default",
44
- ...(isHorizontal ? {
45
- width: "100%",
46
- borderBottom: layout === "top" ? "1px solid" : void 0,
47
- borderTop: layout === "bottom" ? "1px solid" : void 0,
48
- borderColor: "display.border.muted.default"
49
- } : {
50
- minWidth: "200px",
51
- borderRight: layout === "left" ? "1px solid" : void 0,
52
- borderLeft: layout === "right" ? "1px solid" : void 0,
53
- borderColor: "display.border.muted.default"
54
- })
55
- }
206
+ "data-variant": variant,
207
+ sx: getWizardStepListSx({
208
+ layout,
209
+ variant
210
+ })
56
211
  }, /* @__PURE__ */React.createElement(Steps.Root, {
57
212
  step: currentStep,
58
213
  count: steps.length,
@@ -93,10 +248,35 @@ var WizardStepList = /* @__PURE__ */__name(({
93
248
  sx: {
94
249
  cursor: isClickable ? "pointer" : "default"
95
250
  }
96
- }, /* @__PURE__ */React.createElement(Steps.Indicator, null, /* @__PURE__ */React.createElement(Steps.Status, {
251
+ }, /* @__PURE__ */React.createElement(Steps.Indicator, {
252
+ css: getWizardStepIndicatorSx({
253
+ status,
254
+ variant,
255
+ isClickable
256
+ })
257
+ }, /* @__PURE__ */React.createElement(Steps.Status, {
97
258
  complete: "\u2713",
98
259
  incomplete: /* @__PURE__ */React.createElement(Steps.Number, null)
99
- }))), (step.title || step.description) && /* @__PURE__ */React.createElement(Box, null, step.title && /* @__PURE__ */React.createElement(Steps.Title, null, step.title), step.description && /* @__PURE__ */React.createElement(Steps.Description, null, step.description))), index < steps.length - 1 && /* @__PURE__ */React.createElement(Steps.Separator, null));
260
+ }))), (step.title || step.description) && /* @__PURE__ */React.createElement(Box, {
261
+ sx: WizardStepTextWrapperSx
262
+ }, step.title && /* @__PURE__ */React.createElement(Steps.Title, {
263
+ css: getWizardStepTitleSx({
264
+ status,
265
+ variant
266
+ })
267
+ }, step.title), step.description && /* @__PURE__ */React.createElement(Flex, {
268
+ sx: WizardStepDescriptionFlexSx
269
+ }, /* @__PURE__ */React.createElement(Steps.Description, {
270
+ css: getWizardStepDescriptionSx({
271
+ status,
272
+ variant
273
+ })
274
+ }, step.description)))), index < steps.length - 1 && /* @__PURE__ */React.createElement(Steps.Separator, {
275
+ css: getWizardStepSeparatorSx({
276
+ isCompleted: index < currentStep,
277
+ variant
278
+ })
279
+ }));
100
280
  }))));
101
281
  }, "WizardStepList");
102
282
 
@@ -146,11 +326,13 @@ var getFlexDirection = /* @__PURE__ */__name(layout => {
146
326
  var Wizard = /* @__PURE__ */__name(({
147
327
  steps,
148
328
  layout = "top",
329
+ variant = "spotlight-accent",
149
330
  onComplete,
150
331
  onCancel,
151
332
  onStepChange,
152
333
  initialStep = 0,
153
- allowStepClick = true
334
+ allowStepClick = true,
335
+ labels
154
336
  }) => {
155
337
  const {
156
338
  intl
@@ -160,6 +342,14 @@ var Wizard = /* @__PURE__ */__name(({
160
342
  const totalSteps = steps.length;
161
343
  const isFirstStep = currentStep === 0;
162
344
  const isLastStep = currentStep === totalSteps - 1;
345
+ const buttonLabels = React3.useMemo(() => {
346
+ return {
347
+ previous: labels?.previous ?? intl.formatMessage(messages.previous),
348
+ next: labels?.next ?? intl.formatMessage(messages.next),
349
+ finish: labels?.finish ?? intl.formatMessage(messages.finish),
350
+ cancel: labels?.cancel ?? intl.formatMessage(messages.cancel)
351
+ };
352
+ }, [intl, labels]);
163
353
  const getStepStatus = React3.useCallback(({
164
354
  stepIndex
165
355
  }) => {
@@ -236,19 +426,16 @@ var Wizard = /* @__PURE__ */__name(({
236
426
  return /* @__PURE__ */React3.createElement(WizardContext.Provider, {
237
427
  value: contextValue
238
428
  }, /* @__PURE__ */React3.createElement(Flex2, {
429
+ "data-variant": variant,
239
430
  sx: {
240
431
  flexDirection: getFlexDirection(layout),
241
- width: "100%",
242
- minHeight: "300px",
243
- border: "1px solid",
244
- borderColor: "display.border.muted.default",
245
- borderRadius: "8px",
246
- overflow: "hidden"
432
+ ...getWizardShellSx(variant)
247
433
  }
248
434
  }, /* @__PURE__ */React3.createElement(WizardStepList, {
249
435
  steps,
250
436
  currentStep,
251
437
  layout,
438
+ variant,
252
439
  allowStepClick,
253
440
  getStepStatus,
254
441
  onStepClick: goToStep
@@ -276,8 +463,8 @@ var Wizard = /* @__PURE__ */__name(({
276
463
  }, onCancel && /* @__PURE__ */React3.createElement(Button, {
277
464
  variant: "secondary",
278
465
  onClick: onCancel,
279
- "aria-label": intl.formatMessage(messages.cancel)
280
- }, intl.formatMessage(messages.cancel))), /* @__PURE__ */React3.createElement(Flex2, {
466
+ "aria-label": buttonLabels.cancel
467
+ }, buttonLabels.cancel)), /* @__PURE__ */React3.createElement(Flex2, {
281
468
  sx: {
282
469
  gap: "3"
283
470
  }
@@ -285,11 +472,12 @@ var Wizard = /* @__PURE__ */__name(({
285
472
  variant: "secondary",
286
473
  onClick: goToPrevious,
287
474
  disabled: isFirstStep,
288
- "aria-label": intl.formatMessage(messages.previous)
289
- }, intl.formatMessage(messages.previous)), /* @__PURE__ */React3.createElement(Button, {
475
+ "aria-label": buttonLabels.previous
476
+ }, buttonLabels.previous), /* @__PURE__ */React3.createElement(Button, {
477
+ variant: getWizardPrimaryButtonVariant(variant),
290
478
  onClick: goToNext,
291
- "aria-label": isLastStep ? intl.formatMessage(messages.finish) : intl.formatMessage(messages.next)
292
- }, isLastStep ? intl.formatMessage(messages.finish) : intl.formatMessage(messages.next)))))));
479
+ "aria-label": isLastStep ? buttonLabels.finish : buttonLabels.next
480
+ }, isLastStep ? buttonLabels.finish : buttonLabels.next))))));
293
481
  }, "Wizard");
294
482
  Wizard.displayName = "Wizard";
295
483
  export { Wizard, useWizard };
package/dist/index.d.cts CHANGED
@@ -1,6 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
 
4
+ type WizardVariant = 'spotlight-accent' | 'spotlight-primary' | 'primary' | 'secondary' | 'accent';
5
+
4
6
  /**
5
7
  * Position of the step list relative to the wizard content.
6
8
  */
@@ -43,6 +45,11 @@ interface WizardProps {
43
45
  * Position of the step list. Defaults to 'top'.
44
46
  */
45
47
  layout?: WizardLayout;
48
+ /**
49
+ * Visual variant for the wizard shell, step accents, and primary action.
50
+ * @default 'spotlight-accent'
51
+ */
52
+ variant?: WizardVariant;
46
53
  /**
47
54
  * Called when the wizard completes (user clicks "Finish" on the last step).
48
55
  */
@@ -67,6 +74,19 @@ interface WizardProps {
67
74
  * Defaults to true.
68
75
  */
69
76
  allowStepClick?: boolean;
77
+ /**
78
+ * Optional custom labels for the navigation buttons.
79
+ */
80
+ labels?: Partial<WizardLabels>;
81
+ }
82
+ /**
83
+ * Customizable labels used by the wizard navigation buttons.
84
+ */
85
+ interface WizardLabels {
86
+ previous: string;
87
+ next: string;
88
+ finish: string;
89
+ cancel: string;
70
90
  }
71
91
  /**
72
92
  * Context value exposed by WizardProvider.
@@ -115,8 +135,18 @@ interface WizardContextValue {
115
135
  setStepValidation: (validate: () => boolean | Promise<boolean>) => void;
116
136
  }
117
137
 
138
+ /**
139
+ * Renders a multi-step wizard with step navigation, localized action labels,
140
+ * and support for completion, cancellation, and step changes.
141
+ *
142
+ * @param props - Wizard configuration and step content.
143
+ * @param props.steps - The ordered steps displayed in the wizard.
144
+ * @param props.onComplete - Called when the user finishes the last step.
145
+ * @param props.onCancel - Called when the user cancels the wizard.
146
+ * @param props.onStepChange - Called when the current step changes.
147
+ */
118
148
  declare const Wizard: {
119
- ({ steps, layout, onComplete, onCancel, onStepChange, initialStep, allowStepClick, }: WizardProps): react_jsx_runtime.JSX.Element;
149
+ ({ steps, layout, variant, onComplete, onCancel, onStepChange, initialStep, allowStepClick, labels, }: WizardProps): react_jsx_runtime.JSX.Element;
120
150
  displayName: string;
121
151
  };
122
152
 
@@ -125,4 +155,4 @@ declare const Wizard: {
125
155
  */
126
156
  declare const useWizard: () => WizardContextValue;
127
157
 
128
- export { Wizard, type WizardContextValue, type WizardLayout, type WizardProps, type WizardStep, type WizardStepStatus, useWizard };
158
+ export { Wizard, type WizardContextValue, type WizardLabels, type WizardLayout, type WizardProps, type WizardStep, type WizardStepStatus, type WizardVariant, useWizard };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  import * as React from 'react';
2
2
  import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
 
4
+ type WizardVariant = 'spotlight-accent' | 'spotlight-primary' | 'primary' | 'secondary' | 'accent';
5
+
4
6
  /**
5
7
  * Position of the step list relative to the wizard content.
6
8
  */
@@ -43,6 +45,11 @@ interface WizardProps {
43
45
  * Position of the step list. Defaults to 'top'.
44
46
  */
45
47
  layout?: WizardLayout;
48
+ /**
49
+ * Visual variant for the wizard shell, step accents, and primary action.
50
+ * @default 'spotlight-accent'
51
+ */
52
+ variant?: WizardVariant;
46
53
  /**
47
54
  * Called when the wizard completes (user clicks "Finish" on the last step).
48
55
  */
@@ -67,6 +74,19 @@ interface WizardProps {
67
74
  * Defaults to true.
68
75
  */
69
76
  allowStepClick?: boolean;
77
+ /**
78
+ * Optional custom labels for the navigation buttons.
79
+ */
80
+ labels?: Partial<WizardLabels>;
81
+ }
82
+ /**
83
+ * Customizable labels used by the wizard navigation buttons.
84
+ */
85
+ interface WizardLabels {
86
+ previous: string;
87
+ next: string;
88
+ finish: string;
89
+ cancel: string;
70
90
  }
71
91
  /**
72
92
  * Context value exposed by WizardProvider.
@@ -115,8 +135,18 @@ interface WizardContextValue {
115
135
  setStepValidation: (validate: () => boolean | Promise<boolean>) => void;
116
136
  }
117
137
 
138
+ /**
139
+ * Renders a multi-step wizard with step navigation, localized action labels,
140
+ * and support for completion, cancellation, and step changes.
141
+ *
142
+ * @param props - Wizard configuration and step content.
143
+ * @param props.steps - The ordered steps displayed in the wizard.
144
+ * @param props.onComplete - Called when the user finishes the last step.
145
+ * @param props.onCancel - Called when the user cancels the wizard.
146
+ * @param props.onStepChange - Called when the current step changes.
147
+ */
118
148
  declare const Wizard: {
119
- ({ steps, layout, onComplete, onCancel, onStepChange, initialStep, allowStepClick, }: WizardProps): react_jsx_runtime.JSX.Element;
149
+ ({ steps, layout, variant, onComplete, onCancel, onStepChange, initialStep, allowStepClick, labels, }: WizardProps): react_jsx_runtime.JSX.Element;
120
150
  displayName: string;
121
151
  };
122
152
 
@@ -125,4 +155,4 @@ declare const Wizard: {
125
155
  */
126
156
  declare const useWizard: () => WizardContextValue;
127
157
 
128
- export { Wizard, type WizardContextValue, type WizardLayout, type WizardProps, type WizardStep, type WizardStepStatus, useWizard };
158
+ export { Wizard, type WizardContextValue, type WizardLabels, type WizardLayout, type WizardProps, type WizardStep, type WizardStepStatus, type WizardVariant, useWizard };
package/dist/index.js CHANGED
@@ -50,9 +50,173 @@ module.exports = __toCommonJS(index_exports);
50
50
 
51
51
  // src/Wizard.tsx
52
52
  var import_react_i18n = require("@ttoss/react-i18n");
53
- var import_ui2 = require("@ttoss/ui");
53
+ var import_ui3 = require("@ttoss/ui");
54
54
  var React3 = __toESM(require("react"), 1);
55
55
 
56
+ // src/Wizard.styles.ts
57
+ var import_ui = require("@ttoss/ui");
58
+ var gradientFlow = (0, import_ui.keyframes)({
59
+ "0%": {
60
+ backgroundPosition: "0% 50%"
61
+ },
62
+ "50%": {
63
+ backgroundPosition: "100% 50%"
64
+ },
65
+ "100%": {
66
+ backgroundPosition: "0% 50%"
67
+ }
68
+ });
69
+ var getAccentGradientBackground = /* @__PURE__ */__name(t => {
70
+ const theme = t;
71
+ const start = theme.colors?.action?.background?.accent?.default || theme.colors?.input?.background?.accent?.default;
72
+ if (!start) return void 0;
73
+ const middle = theme.colors?.action?.background?.accent?.active || theme.colors?.input?.background?.accent?.active || start;
74
+ return `linear-gradient(270deg, ${start}, ${middle}, ${start})`;
75
+ }, "getAccentGradientBackground");
76
+ var getPrimaryGradientBackground = /* @__PURE__ */__name(t => {
77
+ const theme = t;
78
+ const start = theme.colors?.action?.background?.primary?.default;
79
+ if (!start) return void 0;
80
+ const middle = theme.colors?.action?.background?.secondary?.default || start;
81
+ return `linear-gradient(270deg, ${start}, ${middle}, ${start})`;
82
+ }, "getPrimaryGradientBackground");
83
+ var getVariantStyles = /* @__PURE__ */__name((variantType = "spotlight-accent") => {
84
+ const variants = {
85
+ "spotlight-accent": {
86
+ accentColor: "action.background.accent.default",
87
+ accentTextColor: "action.text.accent.default",
88
+ borderColor: "display.border.muted.default",
89
+ primaryButtonVariant: "accent",
90
+ gradientBackground: getAccentGradientBackground
91
+ },
92
+ "spotlight-primary": {
93
+ accentColor: "action.background.primary.default",
94
+ accentTextColor: "display.text.accent.default",
95
+ borderColor: "display.border.muted.default",
96
+ primaryButtonVariant: "primary",
97
+ gradientBackground: getPrimaryGradientBackground
98
+ },
99
+ primary: {
100
+ accentColor: "action.background.primary.default",
101
+ accentTextColor: "action.text.primary.default",
102
+ borderColor: "display.border.muted.default",
103
+ primaryButtonVariant: "primary"
104
+ },
105
+ secondary: {
106
+ accentColor: "action.background.secondary.default",
107
+ accentTextColor: "action.text.primary.default",
108
+ borderColor: "display.border.muted.default",
109
+ primaryButtonVariant: "secondary"
110
+ },
111
+ accent: {
112
+ accentColor: "action.background.accent.default",
113
+ accentTextColor: "action.text.accent.default",
114
+ borderColor: "display.border.muted.default",
115
+ primaryButtonVariant: "accent"
116
+ }
117
+ };
118
+ return variants[variantType] ?? variants["spotlight-accent"];
119
+ }, "getVariantStyles");
120
+ var getWizardShellSx = /* @__PURE__ */__name((variant = "spotlight-accent") => {
121
+ const variantStyles = getVariantStyles(variant);
122
+ return {
123
+ width: "100%",
124
+ minHeight: "300px",
125
+ border: "1px solid",
126
+ borderColor: variantStyles.borderColor,
127
+ borderRadius: "8px",
128
+ overflow: "hidden"
129
+ };
130
+ }, "getWizardShellSx");
131
+ var getWizardStepListSx = /* @__PURE__ */__name(({
132
+ layout,
133
+ variant = "spotlight-accent"
134
+ }) => {
135
+ const isHorizontal = layout === "top" || layout === "bottom";
136
+ const isSpotlight = variant.startsWith("spotlight-");
137
+ const variantStyles = getVariantStyles(variant);
138
+ return {
139
+ position: "relative",
140
+ padding: "6",
141
+ backgroundColor: variantStyles.accentColor,
142
+ ...(isSpotlight ? {
143
+ background: variantStyles.gradientBackground,
144
+ backgroundSize: "400% 400%",
145
+ animation: `${gradientFlow} 6s ease infinite`
146
+ } : {}),
147
+ ...(isHorizontal ? {
148
+ width: "100%"
149
+ } : {
150
+ minWidth: "200px"
151
+ })
152
+ };
153
+ }, "getWizardStepListSx");
154
+ var getWizardStepIndicatorSx = /* @__PURE__ */__name(({
155
+ status,
156
+ variant = "spotlight-accent",
157
+ isClickable
158
+ }) => {
159
+ const variantStyles = getVariantStyles(variant);
160
+ const isCompleted = status === "completed";
161
+ const isUpcoming = status === "upcoming";
162
+ return {
163
+ borderColor: variantStyles.accentTextColor,
164
+ backgroundColor: isCompleted ? variantStyles.accentTextColor : "transparent",
165
+ color: isCompleted ? variantStyles.accentColor : variantStyles.accentTextColor,
166
+ opacity: isUpcoming ? 0.4 : 1,
167
+ transition: "all 0.2s ease",
168
+ ...(isClickable ? {
169
+ _hover: {
170
+ opacity: 1
171
+ }
172
+ } : {})
173
+ };
174
+ }, "getWizardStepIndicatorSx");
175
+ var getWizardStepSeparatorSx = /* @__PURE__ */__name(({
176
+ isCompleted,
177
+ variant = "spotlight-accent"
178
+ }) => {
179
+ const variantStyles = getVariantStyles(variant);
180
+ return {
181
+ backgroundColor: variantStyles.accentTextColor,
182
+ opacity: isCompleted ? 1 : 0.4
183
+ };
184
+ }, "getWizardStepSeparatorSx");
185
+ var getWizardStepTitleSx = /* @__PURE__ */__name(({
186
+ status,
187
+ variant = "spotlight-accent"
188
+ }) => {
189
+ const variantStyles = getVariantStyles(variant);
190
+ return {
191
+ color: variantStyles.accentTextColor,
192
+ textAlign: "center",
193
+ fontWeight: status === "active" ? "bold" : "normal",
194
+ opacity: status === "upcoming" ? 0.4 : 1
195
+ };
196
+ }, "getWizardStepTitleSx");
197
+ var getWizardStepDescriptionSx = /* @__PURE__ */__name(({
198
+ status,
199
+ variant = "spotlight-accent"
200
+ }) => {
201
+ const variantStyles = getVariantStyles(variant);
202
+ return {
203
+ color: variantStyles.accentTextColor,
204
+ textAlign: "center",
205
+ opacity: status === "upcoming" ? 0.4 : 1
206
+ };
207
+ }, "getWizardStepDescriptionSx");
208
+ var WizardStepDescriptionFlexSx = {
209
+ flexDirection: "row",
210
+ alignItems: "center",
211
+ justifyContent: "center"
212
+ };
213
+ var WizardStepTextWrapperSx = {
214
+ textAlign: "center"
215
+ };
216
+ var getWizardPrimaryButtonVariant = /* @__PURE__ */__name((variant = "spotlight-accent") => {
217
+ return getVariantStyles(variant).primaryButtonVariant;
218
+ }, "getWizardPrimaryButtonVariant");
219
+
56
220
  // src/WizardContext.ts
57
221
  var React2 = __toESM(require("react"), 1);
58
222
  var WizardContext = React2.createContext(null);
@@ -66,35 +230,26 @@ var useWizard = /* @__PURE__ */__name(() => {
66
230
 
67
231
  // src/WizardStepList.tsx
68
232
  var import_react = require("@chakra-ui/react");
69
- var import_ui = require("@ttoss/ui");
233
+ var import_ui2 = require("@ttoss/ui");
70
234
  var WizardStepList = /* @__PURE__ */__name(({
71
235
  steps,
72
236
  currentStep,
73
237
  layout,
238
+ variant,
74
239
  allowStepClick,
75
240
  getStepStatus,
76
241
  onStepClick
77
242
  }) => {
78
243
  const isHorizontal = layout === "top" || layout === "bottom";
79
244
  const orientation = isHorizontal ? "horizontal" : "vertical";
80
- return /* @__PURE__ */React.createElement(import_ui.Flex, {
245
+ return /* @__PURE__ */React.createElement(import_ui2.Flex, {
81
246
  role: "navigation",
82
247
  "aria-label": "Wizard steps",
83
- sx: {
84
- padding: "6",
85
- backgroundColor: "navigation.background.muted.default",
86
- ...(isHorizontal ? {
87
- width: "100%",
88
- borderBottom: layout === "top" ? "1px solid" : void 0,
89
- borderTop: layout === "bottom" ? "1px solid" : void 0,
90
- borderColor: "display.border.muted.default"
91
- } : {
92
- minWidth: "200px",
93
- borderRight: layout === "left" ? "1px solid" : void 0,
94
- borderLeft: layout === "right" ? "1px solid" : void 0,
95
- borderColor: "display.border.muted.default"
96
- })
97
- }
248
+ "data-variant": variant,
249
+ sx: getWizardStepListSx({
250
+ layout,
251
+ variant
252
+ })
98
253
  }, /* @__PURE__ */React.createElement(import_react.Steps.Root, {
99
254
  step: currentStep,
100
255
  count: steps.length,
@@ -107,13 +262,13 @@ var WizardStepList = /* @__PURE__ */__name(({
107
262
  return /* @__PURE__ */React.createElement(import_react.Steps.Item, {
108
263
  key: index,
109
264
  index
110
- }, /* @__PURE__ */React.createElement(import_ui.Flex, {
265
+ }, /* @__PURE__ */React.createElement(import_ui2.Flex, {
111
266
  sx: {
112
267
  flexDirection: isHorizontal ? "column" : "row",
113
268
  alignItems: "center",
114
269
  gap: "2"
115
270
  }
116
- }, /* @__PURE__ */React.createElement(import_ui.Box, {
271
+ }, /* @__PURE__ */React.createElement(import_ui2.Box, {
117
272
  role: "button",
118
273
  tabIndex: isClickable ? 0 : -1,
119
274
  onClick: /* @__PURE__ */__name(() => {
@@ -135,10 +290,35 @@ var WizardStepList = /* @__PURE__ */__name(({
135
290
  sx: {
136
291
  cursor: isClickable ? "pointer" : "default"
137
292
  }
138
- }, /* @__PURE__ */React.createElement(import_react.Steps.Indicator, null, /* @__PURE__ */React.createElement(import_react.Steps.Status, {
293
+ }, /* @__PURE__ */React.createElement(import_react.Steps.Indicator, {
294
+ css: getWizardStepIndicatorSx({
295
+ status,
296
+ variant,
297
+ isClickable
298
+ })
299
+ }, /* @__PURE__ */React.createElement(import_react.Steps.Status, {
139
300
  complete: "\u2713",
140
301
  incomplete: /* @__PURE__ */React.createElement(import_react.Steps.Number, null)
141
- }))), (step.title || step.description) && /* @__PURE__ */React.createElement(import_ui.Box, null, step.title && /* @__PURE__ */React.createElement(import_react.Steps.Title, null, step.title), step.description && /* @__PURE__ */React.createElement(import_react.Steps.Description, null, step.description))), index < steps.length - 1 && /* @__PURE__ */React.createElement(import_react.Steps.Separator, null));
302
+ }))), (step.title || step.description) && /* @__PURE__ */React.createElement(import_ui2.Box, {
303
+ sx: WizardStepTextWrapperSx
304
+ }, step.title && /* @__PURE__ */React.createElement(import_react.Steps.Title, {
305
+ css: getWizardStepTitleSx({
306
+ status,
307
+ variant
308
+ })
309
+ }, step.title), step.description && /* @__PURE__ */React.createElement(import_ui2.Flex, {
310
+ sx: WizardStepDescriptionFlexSx
311
+ }, /* @__PURE__ */React.createElement(import_react.Steps.Description, {
312
+ css: getWizardStepDescriptionSx({
313
+ status,
314
+ variant
315
+ })
316
+ }, step.description)))), index < steps.length - 1 && /* @__PURE__ */React.createElement(import_react.Steps.Separator, {
317
+ css: getWizardStepSeparatorSx({
318
+ isCompleted: index < currentStep,
319
+ variant
320
+ })
321
+ }));
142
322
  }))));
143
323
  }, "WizardStepList");
144
324
 
@@ -176,11 +356,13 @@ var getFlexDirection = /* @__PURE__ */__name(layout => {
176
356
  var Wizard = /* @__PURE__ */__name(({
177
357
  steps,
178
358
  layout = "top",
359
+ variant = "spotlight-accent",
179
360
  onComplete,
180
361
  onCancel,
181
362
  onStepChange,
182
363
  initialStep = 0,
183
- allowStepClick = true
364
+ allowStepClick = true,
365
+ labels
184
366
  }) => {
185
367
  const {
186
368
  intl
@@ -190,6 +372,14 @@ var Wizard = /* @__PURE__ */__name(({
190
372
  const totalSteps = steps.length;
191
373
  const isFirstStep = currentStep === 0;
192
374
  const isLastStep = currentStep === totalSteps - 1;
375
+ const buttonLabels = React3.useMemo(() => {
376
+ return {
377
+ previous: labels?.previous ?? intl.formatMessage(messages.previous),
378
+ next: labels?.next ?? intl.formatMessage(messages.next),
379
+ finish: labels?.finish ?? intl.formatMessage(messages.finish),
380
+ cancel: labels?.cancel ?? intl.formatMessage(messages.cancel)
381
+ };
382
+ }, [intl, labels]);
193
383
  const getStepStatus = React3.useCallback(({
194
384
  stepIndex
195
385
  }) => {
@@ -265,61 +455,59 @@ var Wizard = /* @__PURE__ */__name(({
265
455
  }, [currentStep, totalSteps, goToNext, goToPrevious, goToStep, isFirstStep, isLastStep, getStepStatus, setStepValidation]);
266
456
  return /* @__PURE__ */React3.createElement(WizardContext.Provider, {
267
457
  value: contextValue
268
- }, /* @__PURE__ */React3.createElement(import_ui2.Flex, {
458
+ }, /* @__PURE__ */React3.createElement(import_ui3.Flex, {
459
+ "data-variant": variant,
269
460
  sx: {
270
461
  flexDirection: getFlexDirection(layout),
271
- width: "100%",
272
- minHeight: "300px",
273
- border: "1px solid",
274
- borderColor: "display.border.muted.default",
275
- borderRadius: "8px",
276
- overflow: "hidden"
462
+ ...getWizardShellSx(variant)
277
463
  }
278
464
  }, /* @__PURE__ */React3.createElement(WizardStepList, {
279
465
  steps,
280
466
  currentStep,
281
467
  layout,
468
+ variant,
282
469
  allowStepClick,
283
470
  getStepStatus,
284
471
  onStepClick: goToStep
285
- }), /* @__PURE__ */React3.createElement(import_ui2.Flex, {
472
+ }), /* @__PURE__ */React3.createElement(import_ui3.Flex, {
286
473
  sx: {
287
474
  flexDirection: "column",
288
475
  flex: 1,
289
476
  padding: "6"
290
477
  }
291
- }, /* @__PURE__ */React3.createElement(import_ui2.Box, {
478
+ }, /* @__PURE__ */React3.createElement(import_ui3.Box, {
292
479
  sx: {
293
480
  flex: 1,
294
481
  marginBottom: "4"
295
482
  }
296
- }, steps[currentStep].content), /* @__PURE__ */React3.createElement(import_ui2.Flex, {
483
+ }, steps[currentStep].content), /* @__PURE__ */React3.createElement(import_ui3.Flex, {
297
484
  sx: {
298
485
  justifyContent: "space-between",
299
486
  alignItems: "center",
300
487
  gap: "3"
301
488
  }
302
- }, /* @__PURE__ */React3.createElement(import_ui2.Flex, {
489
+ }, /* @__PURE__ */React3.createElement(import_ui3.Flex, {
303
490
  sx: {
304
491
  gap: "3"
305
492
  }
306
- }, onCancel && /* @__PURE__ */React3.createElement(import_ui2.Button, {
493
+ }, onCancel && /* @__PURE__ */React3.createElement(import_ui3.Button, {
307
494
  variant: "secondary",
308
495
  onClick: onCancel,
309
- "aria-label": intl.formatMessage(messages.cancel)
310
- }, intl.formatMessage(messages.cancel))), /* @__PURE__ */React3.createElement(import_ui2.Flex, {
496
+ "aria-label": buttonLabels.cancel
497
+ }, buttonLabels.cancel)), /* @__PURE__ */React3.createElement(import_ui3.Flex, {
311
498
  sx: {
312
499
  gap: "3"
313
500
  }
314
- }, /* @__PURE__ */React3.createElement(import_ui2.Button, {
501
+ }, /* @__PURE__ */React3.createElement(import_ui3.Button, {
315
502
  variant: "secondary",
316
503
  onClick: goToPrevious,
317
504
  disabled: isFirstStep,
318
- "aria-label": intl.formatMessage(messages.previous)
319
- }, intl.formatMessage(messages.previous)), /* @__PURE__ */React3.createElement(import_ui2.Button, {
505
+ "aria-label": buttonLabels.previous
506
+ }, buttonLabels.previous), /* @__PURE__ */React3.createElement(import_ui3.Button, {
507
+ variant: getWizardPrimaryButtonVariant(variant),
320
508
  onClick: goToNext,
321
- "aria-label": isLastStep ? intl.formatMessage(messages.finish) : intl.formatMessage(messages.next)
322
- }, isLastStep ? intl.formatMessage(messages.finish) : intl.formatMessage(messages.next)))))));
509
+ "aria-label": isLastStep ? buttonLabels.finish : buttonLabels.next
510
+ }, isLastStep ? buttonLabels.finish : buttonLabels.next))))));
323
511
  }, "Wizard");
324
512
  Wizard.displayName = "Wizard";
325
513
  // Annotate the CommonJS export names for ESM import in node:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/react-wizard",
3
- "version": "0.3.17",
3
+ "version": "0.4.0",
4
4
  "description": "A React wizard component for guiding users through multi-step flows with configurable step list layouts.",
5
5
  "license": "MIT",
6
6
  "author": "ttoss",
@@ -28,7 +28,7 @@
28
28
  "react": ">=16.8.0",
29
29
  "react-icons": "^5",
30
30
  "@ttoss/react-i18n": "^2.2.8",
31
- "@ttoss/ui": "^6.9.12"
31
+ "@ttoss/ui": "^6.9.13"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/jest": "^30.0.0",
@@ -37,11 +37,11 @@
37
37
  "react": "^19.2.4",
38
38
  "tsup": "^8.5.1",
39
39
  "@ttoss/config": "^1.37.8",
40
- "@ttoss/forms": "^0.43.15",
41
40
  "@ttoss/i18n-cli": "^0.8.8",
42
41
  "@ttoss/react-i18n": "^2.2.8",
43
- "@ttoss/test-utils": "^4.2.8",
44
- "@ttoss/ui": "^6.9.12"
42
+ "@ttoss/forms": "^0.43.16",
43
+ "@ttoss/ui": "^6.9.13",
44
+ "@ttoss/test-utils": "^4.2.8"
45
45
  },
46
46
  "keywords": [
47
47
  "React",