@caffeinebounce/ui 0.62.2

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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/dist/FinancialStatementTable-BNUrdTU4.d.cts +249 -0
  4. package/dist/FinancialStatementTable-BNUrdTU4.d.ts +249 -0
  5. package/dist/NewsletterSignup-BPreFi5W.d.cts +37 -0
  6. package/dist/NewsletterSignup-BPreFi5W.d.ts +37 -0
  7. package/dist/TestimonialsSection-DtPu2OeR.d.ts +736 -0
  8. package/dist/TestimonialsSection-z-yotRfv.d.cts +736 -0
  9. package/dist/UnifiedTableControls-CG299y9h.d.ts +1233 -0
  10. package/dist/UnifiedTableControls-CIjRpNhy.d.cts +1233 -0
  11. package/dist/blog.d.cts +99 -0
  12. package/dist/blog.d.ts +99 -0
  13. package/dist/blog.js +292 -0
  14. package/dist/blog.mjs +279 -0
  15. package/dist/button-BHnoRUkF.d.cts +34 -0
  16. package/dist/button-BHnoRUkF.d.ts +34 -0
  17. package/dist/charts.d.cts +80 -0
  18. package/dist/charts.d.ts +80 -0
  19. package/dist/charts.js +19 -0
  20. package/dist/charts.mjs +2 -0
  21. package/dist/chunk-33JR5SYE.js +44 -0
  22. package/dist/chunk-3NDB4YPC.js +247 -0
  23. package/dist/chunk-5RW4PYZ6.js +1504 -0
  24. package/dist/chunk-5THF4YP6.mjs +155 -0
  25. package/dist/chunk-6BUBNZPG.mjs +164 -0
  26. package/dist/chunk-6DVWMJ3H.mjs +7029 -0
  27. package/dist/chunk-6TGV2DNP.js +120 -0
  28. package/dist/chunk-72JGQ7IJ.mjs +1498 -0
  29. package/dist/chunk-7DHKQODW.mjs +2932 -0
  30. package/dist/chunk-7IKHZKAC.js +160 -0
  31. package/dist/chunk-ADIDI7AJ.js +11 -0
  32. package/dist/chunk-BFWX5GJZ.mjs +940 -0
  33. package/dist/chunk-BMFQG6RA.mjs +5537 -0
  34. package/dist/chunk-C4UT5V3P.js +65 -0
  35. package/dist/chunk-CC4KUIKC.js +2004 -0
  36. package/dist/chunk-D3QXPL47.mjs +1814 -0
  37. package/dist/chunk-DQWHYBV2.js +36 -0
  38. package/dist/chunk-E42B4GSB.js +993 -0
  39. package/dist/chunk-ESZ7CBA2.js +1007 -0
  40. package/dist/chunk-EYJJQVV4.js +111 -0
  41. package/dist/chunk-FRRS2YZH.mjs +129 -0
  42. package/dist/chunk-G5TQWWQA.mjs +37 -0
  43. package/dist/chunk-GAIQJCAZ.js +5612 -0
  44. package/dist/chunk-GMBGWOCR.mjs +48 -0
  45. package/dist/chunk-GUSTCU2W.mjs +105 -0
  46. package/dist/chunk-HBLKVQIQ.mjs +23 -0
  47. package/dist/chunk-HMAMMC72.js +26 -0
  48. package/dist/chunk-IMKLN273.mjs +9 -0
  49. package/dist/chunk-J6OLBSZR.js +250 -0
  50. package/dist/chunk-JAE45W2T.js +28 -0
  51. package/dist/chunk-JORVSG52.js +606 -0
  52. package/dist/chunk-KB7UXIQZ.mjs +984 -0
  53. package/dist/chunk-KGGQ5NZV.js +186 -0
  54. package/dist/chunk-KHCC5UKW.mjs +22 -0
  55. package/dist/chunk-KRRIRS6A.mjs +1945 -0
  56. package/dist/chunk-LQCVRWVF.js +48 -0
  57. package/dist/chunk-MHZXUOGN.mjs +168 -0
  58. package/dist/chunk-MPZFPU4X.js +349 -0
  59. package/dist/chunk-MVYRNJA6.js +74 -0
  60. package/dist/chunk-N6AFNFZR.mjs +565 -0
  61. package/dist/chunk-OFQLWSUR.mjs +214 -0
  62. package/dist/chunk-OLAAXLXY.mjs +219 -0
  63. package/dist/chunk-OZZWDIOY.js +1859 -0
  64. package/dist/chunk-PZRI43EZ.js +111 -0
  65. package/dist/chunk-Q256HRYD.js +176 -0
  66. package/dist/chunk-Q52ZEL62.mjs +223 -0
  67. package/dist/chunk-R26Y7LGJ.js +142 -0
  68. package/dist/chunk-RBUYW6QQ.js +39 -0
  69. package/dist/chunk-RVEFPVZF.mjs +43 -0
  70. package/dist/chunk-SORWLKOK.js +96 -0
  71. package/dist/chunk-STEP6C4C.mjs +33 -0
  72. package/dist/chunk-T5R6HUDG.mjs +22 -0
  73. package/dist/chunk-T6ZBA6VJ.js +7109 -0
  74. package/dist/chunk-UM7WMXIU.js +2995 -0
  75. package/dist/chunk-VBD4Q5LL.mjs +117 -0
  76. package/dist/chunk-WOITB4JL.js +195 -0
  77. package/dist/chunk-YKZEKJMZ.mjs +71 -0
  78. package/dist/chunk-YL7RZRHM.mjs +103 -0
  79. package/dist/chunk-YSLD2HLP.mjs +346 -0
  80. package/dist/chunk-ZFLZA7UP.mjs +140 -0
  81. package/dist/chunk-ZKUIUE7W.mjs +26 -0
  82. package/dist/chunk-ZOA7B32D.js +248 -0
  83. package/dist/data-table.d.cts +46 -0
  84. package/dist/data-table.d.ts +46 -0
  85. package/dist/data-table.js +270 -0
  86. package/dist/data-table.mjs +13 -0
  87. package/dist/editor.d.cts +89 -0
  88. package/dist/editor.d.ts +89 -0
  89. package/dist/editor.js +10 -0
  90. package/dist/editor.mjs +1 -0
  91. package/dist/forms.d.cts +142 -0
  92. package/dist/forms.d.ts +142 -0
  93. package/dist/forms.js +24 -0
  94. package/dist/forms.mjs +11 -0
  95. package/dist/hooks-8ORd7T1A.d.cts +751 -0
  96. package/dist/hooks-B2jU1GVT.d.ts +751 -0
  97. package/dist/hooks.d.cts +6 -0
  98. package/dist/hooks.d.ts +6 -0
  99. package/dist/hooks.js +99 -0
  100. package/dist/hooks.mjs +10 -0
  101. package/dist/index.d.cts +3141 -0
  102. package/dist/index.d.ts +3141 -0
  103. package/dist/index.js +7332 -0
  104. package/dist/index.mjs +5876 -0
  105. package/dist/layouts-DPfDDF53.d.cts +1001 -0
  106. package/dist/layouts-DPfDDF53.d.ts +1001 -0
  107. package/dist/layouts.d.cts +4 -0
  108. package/dist/layouts.d.ts +4 -0
  109. package/dist/layouts.js +100 -0
  110. package/dist/layouts.mjs +11 -0
  111. package/dist/marketing-3d.d.cts +51 -0
  112. package/dist/marketing-3d.d.ts +51 -0
  113. package/dist/marketing-3d.js +553 -0
  114. package/dist/marketing-3d.mjs +526 -0
  115. package/dist/marketing.d.cts +583 -0
  116. package/dist/marketing.d.ts +583 -0
  117. package/dist/marketing.js +299 -0
  118. package/dist/marketing.mjs +10 -0
  119. package/dist/media.d.cts +29 -0
  120. package/dist/media.d.ts +29 -0
  121. package/dist/media.js +189 -0
  122. package/dist/media.mjs +182 -0
  123. package/dist/navigation.d.cts +591 -0
  124. package/dist/navigation.d.ts +591 -0
  125. package/dist/navigation.js +108 -0
  126. package/dist/navigation.mjs +15 -0
  127. package/dist/portal.d.cts +58 -0
  128. package/dist/portal.d.ts +58 -0
  129. package/dist/portal.js +403 -0
  130. package/dist/portal.mjs +395 -0
  131. package/dist/primitives.d.cts +508 -0
  132. package/dist/primitives.d.ts +508 -0
  133. package/dist/primitives.js +295 -0
  134. package/dist/primitives.mjs +14 -0
  135. package/dist/settings.d.cts +216 -0
  136. package/dist/settings.d.ts +216 -0
  137. package/dist/settings.js +34 -0
  138. package/dist/settings.mjs +9 -0
  139. package/dist/shared-Dqn36QHZ.d.cts +4 -0
  140. package/dist/shared-Dqn36QHZ.d.ts +4 -0
  141. package/dist/styles.css +1213 -0
  142. package/package.json +189 -0
  143. package/styles.css +1 -0
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ var chunkADIDI7AJ_js = require('./chunk-ADIDI7AJ.js');
4
+ var SeparatorPrimitive = require('@radix-ui/react-separator');
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
20
+ }
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
24
+
25
+ var SeparatorPrimitive__namespace = /*#__PURE__*/_interopNamespace(SeparatorPrimitive);
26
+
27
+ function Separator({
28
+ className,
29
+ orientation = "horizontal",
30
+ decorative = true,
31
+ ...props
32
+ }) {
33
+ return /* @__PURE__ */ jsxRuntime.jsx(
34
+ SeparatorPrimitive__namespace.Root,
35
+ {
36
+ "data-slot": "separator",
37
+ decorative,
38
+ orientation,
39
+ className: chunkADIDI7AJ_js.cn(
40
+ "bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
41
+ className
42
+ ),
43
+ ...props
44
+ }
45
+ );
46
+ }
47
+
48
+ exports.Separator = Separator;
@@ -0,0 +1,168 @@
1
+ import { RefreshCcw, AlertTriangle, AlertCircle, Database, LoaderCircle } from 'lucide-react';
2
+
3
+ // src/utils/avatar-gradient.ts
4
+ var GRADIENT_PAIRS = [
5
+ // Vibrant contrasts
6
+ { from: "#f97316", to: "#ec4899" },
7
+ // Orange → Pink
8
+ { from: "#ef4444", to: "#a855f7" },
9
+ // Red → Purple
10
+ { from: "#f59e0b", to: "#ef4444" },
11
+ // Amber → Red
12
+ { from: "#ec4899", to: "#8b5cf6" },
13
+ // Pink → Violet
14
+ { from: "#f43f5e", to: "#fb923c" },
15
+ // Rose → Orange
16
+ // Cool gradients
17
+ { from: "#3b82f6", to: "#a855f7" },
18
+ // Blue → Purple
19
+ { from: "#6366f1", to: "#ec4899" },
20
+ // Indigo → Pink
21
+ { from: "#8b5cf6", to: "#06b6d4" },
22
+ // Violet → Cyan
23
+ { from: "#a855f7", to: "#3b82f6" },
24
+ // Purple → Blue
25
+ { from: "#06b6d4", to: "#10b981" },
26
+ // Cyan → Emerald
27
+ // Bold combos
28
+ { from: "#10b981", to: "#3b82f6" },
29
+ // Emerald → Blue
30
+ { from: "#14b8a6", to: "#8b5cf6" },
31
+ // Teal → Violet
32
+ { from: "#22c55e", to: "#06b6d4" },
33
+ // Green → Cyan
34
+ { from: "#0ea5e9", to: "#f43f5e" },
35
+ // Sky → Rose
36
+ { from: "#eab308", to: "#22c55e" }
37
+ // Yellow → Green
38
+ ];
39
+ function hashString(str) {
40
+ let hash = 0;
41
+ for (let i = 0; i < str.length; i++) {
42
+ const char = str.charCodeAt(i);
43
+ hash = (hash << 5) - hash + char;
44
+ hash = hash & hash;
45
+ }
46
+ return Math.abs(hash);
47
+ }
48
+ function getAvatarGradient(userId) {
49
+ const index = hashString(userId) % GRADIENT_PAIRS.length;
50
+ const gradient = GRADIENT_PAIRS[index];
51
+ return {
52
+ from: gradient.from,
53
+ to: gradient.to,
54
+ style: {
55
+ background: `linear-gradient(135deg, ${gradient.from} 0%, ${gradient.to} 100%)`
56
+ },
57
+ className: "text-white"
58
+ };
59
+ }
60
+ function getGradientIndex(userId) {
61
+ return hashString(userId) % GRADIENT_PAIRS.length;
62
+ }
63
+ function getGradientPairs() {
64
+ return GRADIENT_PAIRS;
65
+ }
66
+ var DATA_STATE_COPY = {
67
+ loading: {
68
+ title: "Loading data",
69
+ description: "Please wait while we prepare your finance data."
70
+ },
71
+ empty: {
72
+ title: "No data yet",
73
+ description: "There\u2019s no data for this selection yet."
74
+ },
75
+ stale: {
76
+ title: "Showing older data",
77
+ description: "This view may be out of date. Refresh to see the latest values."
78
+ },
79
+ partial: {
80
+ title: "Some data is missing",
81
+ description: "We loaded what we could, but part of this view is unavailable."
82
+ },
83
+ error: {
84
+ title: "Something went wrong",
85
+ description: "We couldn\u2019t load this data right now. Please try again."
86
+ },
87
+ unauthorized: {
88
+ title: "Access needed",
89
+ description: "You don\u2019t currently have permission to view this data."
90
+ },
91
+ misconfigured: {
92
+ title: "Setup required",
93
+ description: "This view needs additional setup before data can be shown."
94
+ }
95
+ };
96
+ function resolveDataState({
97
+ error,
98
+ data,
99
+ metadata,
100
+ hasData
101
+ }) {
102
+ const normalizedError = error;
103
+ const isUnauthorized = metadata?.isUnauthorized || normalizedError?.status === 401 || normalizedError?.status === 403 || normalizedError?.code === "unauthorized";
104
+ const isMisconfigured = metadata?.isMisconfigured || normalizedError?.status === 501 || normalizedError?.code === "misconfigured";
105
+ const computedHasData = hasData ? hasData(data) : metadata?.hasData ?? (Array.isArray(data) ? data.length > 0 : data != null && (typeof data !== "object" || Object.keys(data).length > 0));
106
+ if (metadata?.isLoading || metadata?.isFetching) {
107
+ return {
108
+ state: "loading",
109
+ retryable: false,
110
+ copy: DATA_STATE_COPY.loading
111
+ };
112
+ }
113
+ if (isUnauthorized) {
114
+ return {
115
+ state: "unauthorized",
116
+ retryable: false,
117
+ copy: DATA_STATE_COPY.unauthorized
118
+ };
119
+ }
120
+ if (isMisconfigured) {
121
+ return {
122
+ state: "misconfigured",
123
+ retryable: false,
124
+ copy: DATA_STATE_COPY.misconfigured
125
+ };
126
+ }
127
+ if (error) {
128
+ return { state: "error", retryable: true, copy: DATA_STATE_COPY.error };
129
+ }
130
+ if (metadata?.isPartial) {
131
+ return { state: "partial", retryable: true, copy: DATA_STATE_COPY.partial };
132
+ }
133
+ if (metadata?.isStale) {
134
+ return { state: "stale", retryable: true, copy: DATA_STATE_COPY.stale };
135
+ }
136
+ if (metadata?.isEmpty || !computedHasData) {
137
+ return { state: "empty", retryable: false, copy: DATA_STATE_COPY.empty };
138
+ }
139
+ return { state: null, retryable: false };
140
+ }
141
+ function getDataStateIcon(state) {
142
+ switch (state) {
143
+ case "loading":
144
+ return LoaderCircle;
145
+ case "empty":
146
+ return Database;
147
+ case "error":
148
+ case "unauthorized":
149
+ case "misconfigured":
150
+ return AlertCircle;
151
+ case "partial":
152
+ return AlertTriangle;
153
+ default:
154
+ return RefreshCcw;
155
+ }
156
+ }
157
+ function getDataStateIconClassName(state) {
158
+ switch (state) {
159
+ case "loading":
160
+ return "animate-spin";
161
+ case "empty":
162
+ return "animate-pulse";
163
+ default:
164
+ return "";
165
+ }
166
+ }
167
+
168
+ export { DATA_STATE_COPY, getAvatarGradient, getDataStateIcon, getDataStateIconClassName, getGradientIndex, getGradientPairs, resolveDataState };
@@ -0,0 +1,349 @@
1
+ 'use strict';
2
+
3
+ var chunkESZ7CBA2_js = require('./chunk-ESZ7CBA2.js');
4
+ var chunkSORWLKOK_js = require('./chunk-SORWLKOK.js');
5
+ var chunkADIDI7AJ_js = require('./chunk-ADIDI7AJ.js');
6
+ var client = require('@caffeinebounce/logger/client');
7
+ var lucideReact = require('lucide-react');
8
+ var react = require('react');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+
11
+ function FormWizard({
12
+ steps,
13
+ currentStep,
14
+ onStepChange,
15
+ getStepStatus,
16
+ getStepTooltip,
17
+ enableKeyboardNavigation = true,
18
+ scopeToDialog = true,
19
+ onCancel,
20
+ onSubmit,
21
+ onReset,
22
+ autoFocusSelector,
23
+ persistKey,
24
+ formData,
25
+ onDataRestored,
26
+ children,
27
+ className
28
+ }) {
29
+ const totalSteps = steps.length;
30
+ const isFirstStep = currentStep === 0;
31
+ const isLastStep = currentStep === totalSteps - 1;
32
+ const { logError } = client.useErrorLoggerSafe();
33
+ const [storedValue, setStoredValue, , isLoaded] = chunkESZ7CBA2_js.useLocalStorage(
34
+ persistKey,
35
+ null
36
+ );
37
+ const debouncedData = chunkESZ7CBA2_js.useDebounce(formData, 500);
38
+ const [hasRestored, setHasRestored] = react.useState(false);
39
+ const isRestoring = react.useRef(false);
40
+ const formDataRef = react.useRef(formData);
41
+ const restoredDataRef = react.useRef(null);
42
+ react.useEffect(() => {
43
+ formDataRef.current = formData;
44
+ }, [formData]);
45
+ const hasRestoredDataPropagated = react.useCallback(() => {
46
+ if (!restoredDataRef.current) return true;
47
+ const restored = restoredDataRef.current;
48
+ const current = debouncedData;
49
+ for (const key of Object.keys(restored)) {
50
+ const restoredVal = restored[key];
51
+ const currentVal = current?.[key];
52
+ if (!restoredVal || restoredVal === "") continue;
53
+ if (Array.isArray(restoredVal) && restoredVal.length === 0) continue;
54
+ const isObjectLike = typeof restoredVal === "object" && restoredVal !== null;
55
+ const valuesMatch = isObjectLike ? JSON.stringify(currentVal) === JSON.stringify(restoredVal) : currentVal === restoredVal;
56
+ if (!valuesMatch) {
57
+ return false;
58
+ }
59
+ }
60
+ restoredDataRef.current = null;
61
+ return true;
62
+ }, [debouncedData]);
63
+ react.useEffect(() => {
64
+ if (hasRestored && persistKey && debouncedData) {
65
+ if (isRestoring.current) {
66
+ return;
67
+ }
68
+ if (restoredDataRef.current && !hasRestoredDataPropagated()) {
69
+ return;
70
+ }
71
+ setStoredValue(debouncedData);
72
+ }
73
+ }, [
74
+ hasRestored,
75
+ persistKey,
76
+ debouncedData,
77
+ setStoredValue,
78
+ hasRestoredDataPropagated
79
+ ]);
80
+ react.useEffect(() => {
81
+ return () => {
82
+ if (hasRestored && persistKey && formDataRef.current) {
83
+ if (isRestoring.current) {
84
+ return;
85
+ }
86
+ if (restoredDataRef.current) {
87
+ return;
88
+ }
89
+ try {
90
+ window.localStorage.setItem(
91
+ persistKey,
92
+ JSON.stringify(formDataRef.current)
93
+ );
94
+ } catch (e) {
95
+ logError(e, {
96
+ component: "FormWizard",
97
+ action: "saveOnUnmount",
98
+ metadata: { persistKey }
99
+ });
100
+ }
101
+ }
102
+ };
103
+ }, [hasRestored, persistKey, logError]);
104
+ react.useEffect(() => {
105
+ if (!isLoaded) {
106
+ return;
107
+ }
108
+ if (persistKey && storedValue && !hasRestored && onDataRestored) {
109
+ restoredDataRef.current = storedValue;
110
+ onDataRestored(storedValue);
111
+ isRestoring.current = true;
112
+ setTimeout(() => {
113
+ isRestoring.current = false;
114
+ }, 600);
115
+ setHasRestored(true);
116
+ } else if (persistKey && !storedValue && !hasRestored) {
117
+ setHasRestored(true);
118
+ }
119
+ }, [isLoaded, persistKey, storedValue, hasRestored, onDataRestored]);
120
+ react.useEffect(() => {
121
+ if (!autoFocusSelector) return;
122
+ const timeoutId = setTimeout(() => {
123
+ const element = document.querySelector(autoFocusSelector);
124
+ element?.focus();
125
+ }, 0);
126
+ return () => clearTimeout(timeoutId);
127
+ }, [autoFocusSelector]);
128
+ const stepStatuses = react.useMemo(() => {
129
+ return steps.map((_, index) => getStepStatus(index));
130
+ }, [steps, getStepStatus]);
131
+ const handleStepClick = react.useCallback(
132
+ (stepIndex) => {
133
+ onStepChange(stepIndex);
134
+ },
135
+ [onStepChange]
136
+ );
137
+ const handleNext = react.useCallback(() => {
138
+ if (!isLastStep) {
139
+ onStepChange(currentStep + 1);
140
+ }
141
+ }, [currentStep, isLastStep, onStepChange]);
142
+ const handleBack = react.useCallback(() => {
143
+ if (!isFirstStep) {
144
+ onStepChange(currentStep - 1);
145
+ }
146
+ }, [currentStep, isFirstStep, onStepChange]);
147
+ react.useEffect(() => {
148
+ if (!enableKeyboardNavigation) return;
149
+ const handleKeyDown = (e) => {
150
+ if (scopeToDialog) {
151
+ const target = e.target;
152
+ const isInDialog = target.closest('[role="dialog"]');
153
+ if (!isInDialog) return;
154
+ }
155
+ if (e.key === "Escape" && onCancel) {
156
+ e.preventDefault();
157
+ e.stopPropagation();
158
+ onCancel();
159
+ return;
160
+ }
161
+ if (e.key === "Enter" && (e.metaKey || e.ctrlKey) && onSubmit) {
162
+ e.preventDefault();
163
+ e.stopPropagation();
164
+ onSubmit();
165
+ return;
166
+ }
167
+ if ((e.key === "r" || e.key === "\xAE" || e.code === "KeyR") && e.altKey && !e.shiftKey && !e.metaKey && !e.ctrlKey && onReset) {
168
+ e.preventDefault();
169
+ e.stopPropagation();
170
+ if (persistKey) {
171
+ try {
172
+ window.localStorage.removeItem(persistKey);
173
+ setStoredValue(null);
174
+ } catch (err) {
175
+ logError(err, {
176
+ component: "FormWizard",
177
+ action: "clearStorageOnReset",
178
+ metadata: { persistKey }
179
+ });
180
+ }
181
+ }
182
+ onReset();
183
+ return;
184
+ }
185
+ if (!e.altKey) return;
186
+ if (e.key === "ArrowLeft" && !isFirstStep) {
187
+ e.preventDefault();
188
+ e.stopPropagation();
189
+ handleBack();
190
+ } else if (e.key === "ArrowRight" && !isLastStep) {
191
+ e.preventDefault();
192
+ e.stopPropagation();
193
+ handleNext();
194
+ }
195
+ };
196
+ window.addEventListener("keydown", handleKeyDown, true);
197
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
198
+ }, [
199
+ enableKeyboardNavigation,
200
+ scopeToDialog,
201
+ isFirstStep,
202
+ isLastStep,
203
+ handleBack,
204
+ handleNext,
205
+ onCancel,
206
+ onSubmit,
207
+ onReset,
208
+ persistKey,
209
+ setStoredValue,
210
+ logError
211
+ ]);
212
+ const getStatusStyles = react.useCallback(
213
+ (stepIndex) => {
214
+ const status = stepStatuses[stepIndex];
215
+ const isCurrent = stepIndex === currentStep;
216
+ const step = steps[stepIndex];
217
+ const Icon = step.icon;
218
+ const tooltip = getStepTooltip?.(stepIndex, status) ?? null;
219
+ switch (status) {
220
+ case "error":
221
+ return {
222
+ border: "border-destructive bg-destructive",
223
+ text: "text-destructive",
224
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-5 h-5 text-white" }),
225
+ tooltip: tooltip || "This section has errors"
226
+ };
227
+ case "complete":
228
+ return {
229
+ border: "border-foreground bg-foreground text-background",
230
+ text: "text-foreground",
231
+ icon: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "w-5 h-5" }),
232
+ tooltip: null
233
+ };
234
+ case "incomplete":
235
+ return {
236
+ border: "border-yellow-500 bg-yellow-500 text-white",
237
+ text: "text-yellow-600 dark:text-yellow-500",
238
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-5 h-5" }),
239
+ tooltip: tooltip || "This section is incomplete"
240
+ };
241
+ case "in-progress":
242
+ return {
243
+ border: "border-primary bg-primary text-primary-foreground",
244
+ text: "text-primary",
245
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-5 h-5" }),
246
+ tooltip: null
247
+ };
248
+ default:
249
+ return {
250
+ border: isCurrent ? "border-muted-foreground bg-muted-foreground text-background dark:border-muted dark:bg-muted dark:text-foreground" : "border-transparent bg-background",
251
+ text: isCurrent ? "text-foreground" : "text-muted-foreground",
252
+ icon: /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-5 h-5" }),
253
+ tooltip: null
254
+ };
255
+ }
256
+ },
257
+ [stepStatuses, currentStep, steps, getStepTooltip]
258
+ );
259
+ const progressPercentage = react.useMemo(() => {
260
+ if (totalSteps <= 1) return 0;
261
+ return currentStep / (totalSteps - 1) * 100;
262
+ }, [currentStep, totalSteps]);
263
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: chunkADIDI7AJ_js.cn("space-y-8", className), children: [
264
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex items-center justify-between", children: [
265
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "absolute top-5 left-5 right-5 h-[2px]", children: [
266
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-border/60 rounded-full" }),
267
+ /* @__PURE__ */ jsxRuntime.jsx(
268
+ "div",
269
+ {
270
+ className: "absolute inset-y-0 left-0 bg-foreground rounded-full transition-all duration-500 ease-out",
271
+ style: { width: `${progressPercentage}%` }
272
+ }
273
+ )
274
+ ] }),
275
+ steps.map((step, index) => {
276
+ const styles = getStatusStyles(index);
277
+ const stepButton = /* @__PURE__ */ jsxRuntime.jsxs(
278
+ "button",
279
+ {
280
+ type: "button",
281
+ onClick: () => handleStepClick(index),
282
+ "aria-label": `Step ${index + 1}: ${step.label}`,
283
+ "aria-current": index === currentStep ? "step" : void 0,
284
+ className: chunkADIDI7AJ_js.cn(
285
+ "relative z-10 flex flex-col items-center gap-2 transition-colors cursor-pointer",
286
+ styles.text
287
+ ),
288
+ children: [
289
+ /* @__PURE__ */ jsxRuntime.jsx(
290
+ "div",
291
+ {
292
+ className: chunkADIDI7AJ_js.cn(
293
+ "w-10 h-10 rounded-full flex items-center justify-center border-2 transition-colors",
294
+ styles.border
295
+ ),
296
+ children: styles.icon
297
+ }
298
+ ),
299
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium hidden sm:block", children: step.label })
300
+ ]
301
+ },
302
+ step.id
303
+ );
304
+ if (styles.tooltip) {
305
+ return /* @__PURE__ */ jsxRuntime.jsxs(chunkSORWLKOK_js.Tooltip, { children: [
306
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipTrigger, { asChild: true, children: stepButton }),
307
+ /* @__PURE__ */ jsxRuntime.jsx(chunkSORWLKOK_js.TooltipContent, { className: "whitespace-pre-line", children: styles.tooltip })
308
+ ] }, step.id);
309
+ }
310
+ return stepButton;
311
+ })
312
+ ] }) }),
313
+ children
314
+ ] }) });
315
+ }
316
+ function useFormWizardNavigation(currentStep, totalSteps, onStepChange) {
317
+ const isFirstStep = currentStep === 0;
318
+ const isLastStep = currentStep === totalSteps - 1;
319
+ const goNext = react.useCallback(() => {
320
+ if (!isLastStep) {
321
+ onStepChange(currentStep + 1);
322
+ }
323
+ }, [currentStep, isLastStep, onStepChange]);
324
+ const goBack = react.useCallback(() => {
325
+ if (!isFirstStep) {
326
+ onStepChange(currentStep - 1);
327
+ }
328
+ }, [currentStep, isFirstStep, onStepChange]);
329
+ const goToStep = react.useCallback(
330
+ (index) => {
331
+ if (index >= 0 && index < totalSteps) {
332
+ onStepChange(index);
333
+ }
334
+ },
335
+ [totalSteps, onStepChange]
336
+ );
337
+ return {
338
+ goNext,
339
+ goBack,
340
+ goToStep,
341
+ isFirstStep,
342
+ isLastStep,
343
+ currentStep,
344
+ totalSteps
345
+ };
346
+ }
347
+
348
+ exports.FormWizard = FormWizard;
349
+ exports.useFormWizardNavigation = useFormWizardNavigation;
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ var chunkADIDI7AJ_js = require('./chunk-ADIDI7AJ.js');
4
+ var TabsPrimitive = require('@radix-ui/react-tabs');
5
+ var React = require('react');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
27
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
28
+
29
+ var Tabs = TabsPrimitive__namespace.Root;
30
+ var TabsList = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
31
+ TabsPrimitive__namespace.List,
32
+ {
33
+ ref,
34
+ className: chunkADIDI7AJ_js.cn("inline-flex h-auto items-center gap-0.5", className),
35
+ ...props
36
+ }
37
+ ));
38
+ TabsList.displayName = TabsPrimitive__namespace.List.displayName;
39
+ var TabsTrigger = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
40
+ TabsPrimitive__namespace.Trigger,
41
+ {
42
+ ref,
43
+ className: chunkADIDI7AJ_js.cn(
44
+ "relative inline-flex items-center justify-center whitespace-nowrap px-2 py-1 text-sm transition-colors rounded-box",
45
+ "ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
46
+ "disabled:pointer-events-none disabled:opacity-50",
47
+ "text-muted-foreground data-[state=inactive]:hover:text-foreground data-[state=inactive]:hover:bg-accent/50",
48
+ "data-[state=active]:text-foreground data-[state=active]:font-medium",
49
+ // Active indicator line
50
+ "after:absolute after:bottom-0 after:left-2 after:right-2 after:h-0.5 after:rounded-full",
51
+ "after:bg-transparent data-[state=active]:after:bg-foreground",
52
+ className
53
+ ),
54
+ ...props
55
+ }
56
+ ));
57
+ TabsTrigger.displayName = TabsPrimitive__namespace.Trigger.displayName;
58
+ var TabsContent = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
59
+ TabsPrimitive__namespace.Content,
60
+ {
61
+ ref,
62
+ className: chunkADIDI7AJ_js.cn(
63
+ "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
64
+ className
65
+ ),
66
+ ...props
67
+ }
68
+ ));
69
+ TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
70
+
71
+ exports.Tabs = Tabs;
72
+ exports.TabsContent = TabsContent;
73
+ exports.TabsList = TabsList;
74
+ exports.TabsTrigger = TabsTrigger;