@pxlabz/tracey-react 0.0.1

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 (135) hide show
  1. package/README.md +83 -0
  2. package/dist/LauncherTrigger-5pNAvA05.js +1056 -0
  3. package/dist/LauncherTrigger-5pNAvA05.js.map +1 -0
  4. package/dist/LauncherTrigger-DjXDXHTm.cjs +1055 -0
  5. package/dist/LauncherTrigger-DjXDXHTm.cjs.map +1 -0
  6. package/dist/__tests__/api-client.test.d.ts +2 -0
  7. package/dist/__tests__/api-client.test.d.ts.map +1 -0
  8. package/dist/__tests__/events.test.d.ts +2 -0
  9. package/dist/__tests__/events.test.d.ts.map +1 -0
  10. package/dist/__tests__/survey-logic.test.d.ts +2 -0
  11. package/dist/__tests__/survey-logic.test.d.ts.map +1 -0
  12. package/dist/components/announcements/AnnouncementBell.d.ts +9 -0
  13. package/dist/components/announcements/AnnouncementBell.d.ts.map +1 -0
  14. package/dist/components/announcements/AnnouncementList.d.ts +7 -0
  15. package/dist/components/announcements/AnnouncementList.d.ts.map +1 -0
  16. package/dist/components/announcements/AnnouncementModal.d.ts +9 -0
  17. package/dist/components/announcements/AnnouncementModal.d.ts.map +1 -0
  18. package/dist/components/announcements/headless/AnnouncementClose.d.ts +9 -0
  19. package/dist/components/announcements/headless/AnnouncementClose.d.ts.map +1 -0
  20. package/dist/components/announcements/headless/AnnouncementContent.d.ts +7 -0
  21. package/dist/components/announcements/headless/AnnouncementContent.d.ts.map +1 -0
  22. package/dist/components/announcements/headless/AnnouncementNavigation.d.ts +15 -0
  23. package/dist/components/announcements/headless/AnnouncementNavigation.d.ts.map +1 -0
  24. package/dist/components/announcements/headless/AnnouncementPortal.d.ts +7 -0
  25. package/dist/components/announcements/headless/AnnouncementPortal.d.ts.map +1 -0
  26. package/dist/components/announcements/headless/AnnouncementRoot.d.ts +24 -0
  27. package/dist/components/announcements/headless/AnnouncementRoot.d.ts.map +1 -0
  28. package/dist/components/announcements/headless/AnnouncementSlidePrimitive.d.ts +14 -0
  29. package/dist/components/announcements/headless/AnnouncementSlidePrimitive.d.ts.map +1 -0
  30. package/dist/components/announcements/headless/AnnouncementTrigger.d.ts +9 -0
  31. package/dist/components/announcements/headless/AnnouncementTrigger.d.ts.map +1 -0
  32. package/dist/components/announcements/headless/index.d.ts +8 -0
  33. package/dist/components/announcements/headless/index.d.ts.map +1 -0
  34. package/dist/components/announcements/index.d.ts +4 -0
  35. package/dist/components/announcements/index.d.ts.map +1 -0
  36. package/dist/components/feedback/FeedbackForm.d.ts +8 -0
  37. package/dist/components/feedback/FeedbackForm.d.ts.map +1 -0
  38. package/dist/components/feedback/FeedbackWidget.d.ts +9 -0
  39. package/dist/components/feedback/FeedbackWidget.d.ts.map +1 -0
  40. package/dist/components/feedback/headless/FeedbackClose.d.ts +9 -0
  41. package/dist/components/feedback/headless/FeedbackClose.d.ts.map +1 -0
  42. package/dist/components/feedback/headless/FeedbackContent.d.ts +6 -0
  43. package/dist/components/feedback/headless/FeedbackContent.d.ts.map +1 -0
  44. package/dist/components/feedback/headless/FeedbackFormPrimitive.d.ts +28 -0
  45. package/dist/components/feedback/headless/FeedbackFormPrimitive.d.ts.map +1 -0
  46. package/dist/components/feedback/headless/FeedbackPortal.d.ts +7 -0
  47. package/dist/components/feedback/headless/FeedbackPortal.d.ts.map +1 -0
  48. package/dist/components/feedback/headless/FeedbackRoot.d.ts +16 -0
  49. package/dist/components/feedback/headless/FeedbackRoot.d.ts.map +1 -0
  50. package/dist/components/feedback/headless/FeedbackTrigger.d.ts +9 -0
  51. package/dist/components/feedback/headless/FeedbackTrigger.d.ts.map +1 -0
  52. package/dist/components/feedback/headless/index.d.ts +7 -0
  53. package/dist/components/feedback/headless/index.d.ts.map +1 -0
  54. package/dist/components/feedback/index.d.ts +4 -0
  55. package/dist/components/feedback/index.d.ts.map +1 -0
  56. package/dist/components/index.d.ts +5 -0
  57. package/dist/components/index.d.ts.map +1 -0
  58. package/dist/components/launcher/TraceyLauncher.d.ts +8 -0
  59. package/dist/components/launcher/TraceyLauncher.d.ts.map +1 -0
  60. package/dist/components/launcher/headless/LauncherBadge.d.ts +8 -0
  61. package/dist/components/launcher/headless/LauncherBadge.d.ts.map +1 -0
  62. package/dist/components/launcher/headless/LauncherMenu.d.ts +6 -0
  63. package/dist/components/launcher/headless/LauncherMenu.d.ts.map +1 -0
  64. package/dist/components/launcher/headless/LauncherMenuItem.d.ts +9 -0
  65. package/dist/components/launcher/headless/LauncherMenuItem.d.ts.map +1 -0
  66. package/dist/components/launcher/headless/LauncherPanel.d.ts +6 -0
  67. package/dist/components/launcher/headless/LauncherPanel.d.ts.map +1 -0
  68. package/dist/components/launcher/headless/LauncherPortal.d.ts +7 -0
  69. package/dist/components/launcher/headless/LauncherPortal.d.ts.map +1 -0
  70. package/dist/components/launcher/headless/LauncherRoot.d.ts +21 -0
  71. package/dist/components/launcher/headless/LauncherRoot.d.ts.map +1 -0
  72. package/dist/components/launcher/headless/LauncherTab.d.ts +8 -0
  73. package/dist/components/launcher/headless/LauncherTab.d.ts.map +1 -0
  74. package/dist/components/launcher/headless/LauncherTabContent.d.ts +8 -0
  75. package/dist/components/launcher/headless/LauncherTabContent.d.ts.map +1 -0
  76. package/dist/components/launcher/headless/LauncherTrigger.d.ts +10 -0
  77. package/dist/components/launcher/headless/LauncherTrigger.d.ts.map +1 -0
  78. package/dist/components/launcher/headless/index.d.ts +10 -0
  79. package/dist/components/launcher/headless/index.d.ts.map +1 -0
  80. package/dist/components/launcher/index.d.ts +3 -0
  81. package/dist/components/launcher/index.d.ts.map +1 -0
  82. package/dist/components/surveys/SurveyWidget.d.ts +10 -0
  83. package/dist/components/surveys/SurveyWidget.d.ts.map +1 -0
  84. package/dist/components/surveys/index.d.ts +2 -0
  85. package/dist/components/surveys/index.d.ts.map +1 -0
  86. package/dist/core/api-client.d.ts +33 -0
  87. package/dist/core/api-client.d.ts.map +1 -0
  88. package/dist/core/events.d.ts +11 -0
  89. package/dist/core/events.d.ts.map +1 -0
  90. package/dist/core/index.d.ts +4 -0
  91. package/dist/core/index.d.ts.map +1 -0
  92. package/dist/core/screenshot.d.ts +12 -0
  93. package/dist/core/screenshot.d.ts.map +1 -0
  94. package/dist/core/survey-logic.d.ts +7 -0
  95. package/dist/core/survey-logic.d.ts.map +1 -0
  96. package/dist/headless.cjs +100 -0
  97. package/dist/headless.cjs.map +1 -0
  98. package/dist/headless.d.ts +11 -0
  99. package/dist/headless.d.ts.map +1 -0
  100. package/dist/headless.js +101 -0
  101. package/dist/headless.js.map +1 -0
  102. package/dist/hooks/index.d.ts +7 -0
  103. package/dist/hooks/index.d.ts.map +1 -0
  104. package/dist/hooks/useAnnouncements.d.ts +14 -0
  105. package/dist/hooks/useAnnouncements.d.ts.map +1 -0
  106. package/dist/hooks/useFeedback.d.ts +10 -0
  107. package/dist/hooks/useFeedback.d.ts.map +1 -0
  108. package/dist/hooks/useMyFeedback.d.ts +16 -0
  109. package/dist/hooks/useMyFeedback.d.ts.map +1 -0
  110. package/dist/hooks/useSurvey.d.ts +22 -0
  111. package/dist/hooks/useSurvey.d.ts.map +1 -0
  112. package/dist/hooks/useTracey.d.ts +3 -0
  113. package/dist/hooks/useTracey.d.ts.map +1 -0
  114. package/dist/hooks/useTraceyEvents.d.ts +14 -0
  115. package/dist/hooks/useTraceyEvents.d.ts.map +1 -0
  116. package/dist/index.cjs +4913 -0
  117. package/dist/index.cjs.map +1 -0
  118. package/dist/index.d.ts +19 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +4892 -0
  121. package/dist/index.js.map +1 -0
  122. package/dist/lib/utils.d.ts +3 -0
  123. package/dist/lib/utils.d.ts.map +1 -0
  124. package/dist/provider/MockTraceyProvider.d.ts +14 -0
  125. package/dist/provider/MockTraceyProvider.d.ts.map +1 -0
  126. package/dist/provider/TraceyProvider.d.ts +11 -0
  127. package/dist/provider/TraceyProvider.d.ts.map +1 -0
  128. package/dist/provider/context.d.ts +19 -0
  129. package/dist/provider/context.d.ts.map +1 -0
  130. package/dist/provider/index.d.ts +4 -0
  131. package/dist/provider/index.d.ts.map +1 -0
  132. package/dist/styles.css +800 -0
  133. package/dist/types.d.ts +188 -0
  134. package/dist/types.d.ts.map +1 -0
  135. package/package.json +94 -0
package/dist/index.js ADDED
@@ -0,0 +1,4892 @@
1
+ import { u as useTracey, F as FeedbackFormPrimitive, a as FeedbackClose, b as FeedbackRoot, c as FeedbackTrigger, d as FeedbackPortal, e as FeedbackContent, f as useAnnouncements, A as AnnouncementRoot, g as AnnouncementPortal, h as AnnouncementContent, i as AnnouncementNavigation, j as AnnouncementClose, L as LauncherRoot, k as LauncherTrigger, l as LauncherBadge, m as LauncherPortal, n as LauncherPanel, o as LauncherTab, p as LauncherTabContent } from "./LauncherTrigger-5pNAvA05.js";
2
+ import { M, T, q, r } from "./LauncherTrigger-5pNAvA05.js";
3
+ import { useState, useRef, useCallback, useEffect, useMemo } from "react";
4
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
+ const DEFAULT_LIMIT = 20;
6
+ function useMyFeedback() {
7
+ const { client, isIdentified } = useTracey();
8
+ const [feedback, setFeedback] = useState([]);
9
+ const [isLoading, setIsLoading] = useState(false);
10
+ const [error, setError] = useState(null);
11
+ const [pagination, setPagination] = useState(null);
12
+ const isFetching = useRef(false);
13
+ const fetchFeedback = useCallback(
14
+ async (offset = 0, append = false) => {
15
+ if (isFetching.current) return;
16
+ isFetching.current = true;
17
+ setIsLoading(true);
18
+ setError(null);
19
+ try {
20
+ const result = await client.getMyFeedback({
21
+ limit: DEFAULT_LIMIT,
22
+ offset
23
+ });
24
+ if (append) {
25
+ setFeedback((prev) => [...prev, ...result.data]);
26
+ } else {
27
+ setFeedback(result.data);
28
+ }
29
+ setPagination(result.pagination);
30
+ } catch (err) {
31
+ const fetchError = err instanceof Error ? err : new Error("Failed to fetch feedback");
32
+ setError(fetchError);
33
+ } finally {
34
+ setIsLoading(false);
35
+ isFetching.current = false;
36
+ }
37
+ },
38
+ [client]
39
+ );
40
+ useEffect(() => {
41
+ if (isIdentified) {
42
+ fetchFeedback();
43
+ }
44
+ }, [isIdentified, fetchFeedback]);
45
+ const refetch = useCallback(async () => {
46
+ await fetchFeedback(0, false);
47
+ }, [fetchFeedback]);
48
+ const loadMore = useCallback(async () => {
49
+ if (!(pagination == null ? void 0 : pagination.hasMore)) return;
50
+ await fetchFeedback(pagination.offset + pagination.limit, true);
51
+ }, [fetchFeedback, pagination]);
52
+ return {
53
+ feedback,
54
+ isLoading,
55
+ error,
56
+ pagination,
57
+ refetch,
58
+ loadMore
59
+ };
60
+ }
61
+ function useSurvey() {
62
+ const { client, events } = useTracey();
63
+ const [activeSurvey, setActiveSurvey] = useState(null);
64
+ const [isLoading, setIsLoading] = useState(false);
65
+ const [isSubmitting, setIsSubmitting] = useState(false);
66
+ const [error, setError] = useState(null);
67
+ const loadActiveSurvey = useCallback(
68
+ async (context) => {
69
+ setIsLoading(true);
70
+ setError(null);
71
+ try {
72
+ const survey = await client.getActiveSurvey(context);
73
+ setActiveSurvey(survey);
74
+ if (survey) {
75
+ events.emit("survey:shown", { survey });
76
+ }
77
+ return survey;
78
+ } catch (err) {
79
+ const resolved = err instanceof Error ? err : new Error("Failed to load active survey");
80
+ setError(resolved);
81
+ events.emit("survey:error", { error: resolved });
82
+ return null;
83
+ } finally {
84
+ setIsLoading(false);
85
+ }
86
+ },
87
+ [client, events]
88
+ );
89
+ const submitSurveyResponse = useCallback(
90
+ async (surveyId, payload) => {
91
+ setIsSubmitting(true);
92
+ setError(null);
93
+ try {
94
+ const response = await client.submitSurveyResponse(surveyId, payload);
95
+ events.emit("survey:submitted", { surveyId, response });
96
+ return response;
97
+ } catch (err) {
98
+ const resolved = err instanceof Error ? err : new Error("Failed to submit survey response");
99
+ setError(resolved);
100
+ events.emit("survey:error", { error: resolved, surveyId });
101
+ return null;
102
+ } finally {
103
+ setIsSubmitting(false);
104
+ }
105
+ },
106
+ [client, events]
107
+ );
108
+ const dismissSurvey = useCallback(
109
+ (surveyId) => {
110
+ events.emit("survey:dismissed", { surveyId });
111
+ setActiveSurvey((current) => (current == null ? void 0 : current.id) === surveyId ? null : current);
112
+ },
113
+ [events]
114
+ );
115
+ const reset = useCallback(() => {
116
+ setActiveSurvey(null);
117
+ setError(null);
118
+ }, []);
119
+ return {
120
+ loadActiveSurvey,
121
+ submitSurveyResponse,
122
+ activeSurvey,
123
+ isLoading,
124
+ isSubmitting,
125
+ error,
126
+ dismissSurvey,
127
+ reset
128
+ };
129
+ }
130
+ async function captureScreenshot() {
131
+ if (typeof window === "undefined" || typeof document === "undefined") {
132
+ return null;
133
+ }
134
+ try {
135
+ const stream = await navigator.mediaDevices.getDisplayMedia({
136
+ video: { displaySurface: "browser" }
137
+ });
138
+ const video = document.createElement("video");
139
+ video.srcObject = stream;
140
+ await video.play();
141
+ await new Promise((resolve) => {
142
+ if (video.readyState >= 1) {
143
+ resolve();
144
+ } else {
145
+ video.addEventListener("loadedmetadata", () => resolve(), {
146
+ once: true
147
+ });
148
+ }
149
+ });
150
+ const canvas = document.createElement("canvas");
151
+ canvas.width = video.videoWidth;
152
+ canvas.height = video.videoHeight;
153
+ const ctx = canvas.getContext("2d");
154
+ if (ctx) {
155
+ ctx.drawImage(video, 0, 0);
156
+ }
157
+ stream.getTracks().forEach((track) => track.stop());
158
+ return canvas.toDataURL("image/png");
159
+ } catch {
160
+ }
161
+ try {
162
+ const html2canvas = await import("html2canvas").then((m) => m.default);
163
+ const canvas = await html2canvas(document.body, {
164
+ useCORS: true,
165
+ allowTaint: false,
166
+ logging: false
167
+ });
168
+ return canvas.toDataURL("image/png");
169
+ } catch {
170
+ console.warn(
171
+ "Screenshot capture failed. Install html2canvas for DOM-based screenshots."
172
+ );
173
+ return null;
174
+ }
175
+ }
176
+ const feedbackTypes$1 = [
177
+ { value: "general", label: "General" },
178
+ { value: "bug", label: "Bug Report" },
179
+ { value: "feature_request", label: "Feature Request" }
180
+ ];
181
+ function FeedbackForm({
182
+ theme,
183
+ onSuccess,
184
+ showScreenshot = true
185
+ }) {
186
+ const primaryColor = (theme == null ? void 0 : theme.primaryColor) ?? "#6366f1";
187
+ const inputStyles = {
188
+ width: "100%",
189
+ padding: "10px 12px",
190
+ border: "1px solid #e5e7eb",
191
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 6,
192
+ fontSize: 14,
193
+ fontFamily: (theme == null ? void 0 : theme.fontFamily) ?? "inherit",
194
+ boxSizing: "border-box"
195
+ };
196
+ const labelStyles = {
197
+ display: "block",
198
+ marginBottom: 6,
199
+ fontSize: 14,
200
+ fontWeight: 500,
201
+ color: (theme == null ? void 0 : theme.textColor) ?? "#374151"
202
+ };
203
+ return /* @__PURE__ */ jsx(FeedbackFormPrimitive, { onSuccess, children: ({
204
+ title,
205
+ setTitle,
206
+ description,
207
+ setDescription,
208
+ type,
209
+ setType,
210
+ screenshot,
211
+ setScreenshot,
212
+ isSubmitting,
213
+ error,
214
+ handleSubmit
215
+ }) => /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
216
+ /* @__PURE__ */ jsxs(
217
+ "div",
218
+ {
219
+ style: {
220
+ display: "flex",
221
+ justifyContent: "space-between",
222
+ alignItems: "center",
223
+ marginBottom: 20
224
+ },
225
+ children: [
226
+ /* @__PURE__ */ jsx(
227
+ "h3",
228
+ {
229
+ style: {
230
+ margin: 0,
231
+ fontSize: 18,
232
+ fontWeight: 600,
233
+ color: (theme == null ? void 0 : theme.textColor) ?? "#111827"
234
+ },
235
+ children: "Send Feedback"
236
+ }
237
+ ),
238
+ /* @__PURE__ */ jsx(FeedbackClose, { children: /* @__PURE__ */ jsx(
239
+ "button",
240
+ {
241
+ type: "button",
242
+ style: {
243
+ background: "none",
244
+ border: "none",
245
+ cursor: "pointer",
246
+ padding: 4,
247
+ color: "#9ca3af"
248
+ },
249
+ children: "✕"
250
+ }
251
+ ) })
252
+ ]
253
+ }
254
+ ),
255
+ error && /* @__PURE__ */ jsx(
256
+ "div",
257
+ {
258
+ style: {
259
+ padding: "10px 12px",
260
+ backgroundColor: "#fef2f2",
261
+ border: "1px solid #fecaca",
262
+ borderRadius: 6,
263
+ marginBottom: 16,
264
+ color: "#dc2626",
265
+ fontSize: 14
266
+ },
267
+ children: error.message
268
+ }
269
+ ),
270
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
271
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Type" }),
272
+ /* @__PURE__ */ jsx(
273
+ "select",
274
+ {
275
+ value: type,
276
+ onChange: (e) => setType(e.target.value),
277
+ style: inputStyles,
278
+ children: feedbackTypes$1.map((ft) => /* @__PURE__ */ jsx("option", { value: ft.value, children: ft.label }, ft.value))
279
+ }
280
+ )
281
+ ] }),
282
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
283
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Title *" }),
284
+ /* @__PURE__ */ jsx(
285
+ "input",
286
+ {
287
+ type: "text",
288
+ value: title,
289
+ onChange: (e) => setTitle(e.target.value),
290
+ placeholder: "Brief summary...",
291
+ required: true,
292
+ style: inputStyles
293
+ }
294
+ )
295
+ ] }),
296
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
297
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Description" }),
298
+ /* @__PURE__ */ jsx(
299
+ "textarea",
300
+ {
301
+ value: description,
302
+ onChange: (e) => setDescription(e.target.value),
303
+ placeholder: "Tell us more...",
304
+ rows: 4,
305
+ style: { ...inputStyles, resize: "vertical" }
306
+ }
307
+ )
308
+ ] }),
309
+ showScreenshot && /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
310
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Screenshot" }),
311
+ screenshot ? /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
312
+ /* @__PURE__ */ jsx(
313
+ "img",
314
+ {
315
+ src: screenshot,
316
+ alt: "Screenshot",
317
+ style: {
318
+ width: "100%",
319
+ borderRadius: 6,
320
+ border: "1px solid #e5e7eb"
321
+ }
322
+ }
323
+ ),
324
+ /* @__PURE__ */ jsx(
325
+ "button",
326
+ {
327
+ type: "button",
328
+ onClick: () => setScreenshot(null),
329
+ style: {
330
+ position: "absolute",
331
+ top: 8,
332
+ right: 8,
333
+ background: "rgba(0,0,0,0.5)",
334
+ color: "#fff",
335
+ border: "none",
336
+ borderRadius: 4,
337
+ padding: "4px 8px",
338
+ cursor: "pointer",
339
+ fontSize: 12
340
+ },
341
+ children: "Remove"
342
+ }
343
+ )
344
+ ] }) : /* @__PURE__ */ jsx(
345
+ "button",
346
+ {
347
+ type: "button",
348
+ onClick: async () => {
349
+ const img = await captureScreenshot();
350
+ if (img) setScreenshot(img);
351
+ },
352
+ style: {
353
+ ...inputStyles,
354
+ backgroundColor: "#f9fafb",
355
+ cursor: "pointer",
356
+ textAlign: "center",
357
+ color: "#6b7280"
358
+ },
359
+ children: "📷 Capture Screenshot"
360
+ }
361
+ )
362
+ ] }),
363
+ /* @__PURE__ */ jsx(
364
+ "button",
365
+ {
366
+ type: "submit",
367
+ disabled: isSubmitting || !title.trim(),
368
+ style: {
369
+ width: "100%",
370
+ padding: "12px 16px",
371
+ backgroundColor: isSubmitting ? "#9ca3af" : primaryColor,
372
+ color: "#fff",
373
+ border: "none",
374
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 6,
375
+ fontSize: 14,
376
+ fontWeight: 500,
377
+ cursor: isSubmitting ? "not-allowed" : "pointer"
378
+ },
379
+ children: isSubmitting ? "Sending..." : "Send Feedback"
380
+ }
381
+ )
382
+ ] }) });
383
+ }
384
+ function getPositionStyles$2(position) {
385
+ if (typeof position === "object" && "x" in position) {
386
+ return {
387
+ position: "fixed",
388
+ left: position.x,
389
+ top: position.y
390
+ };
391
+ }
392
+ const base = { position: "fixed" };
393
+ switch (position) {
394
+ case "top-left":
395
+ return { ...base, top: 16, left: 16 };
396
+ case "top-right":
397
+ return { ...base, top: 16, right: 16 };
398
+ case "bottom-left":
399
+ return { ...base, bottom: 16, left: 16 };
400
+ case "bottom-right":
401
+ default:
402
+ return { ...base, bottom: 16, right: 16 };
403
+ }
404
+ }
405
+ function FeedbackWidget({
406
+ position = "bottom-right",
407
+ theme,
408
+ triggerLabel = "Feedback",
409
+ className
410
+ }) {
411
+ const positionStyles = getPositionStyles$2(position);
412
+ const primaryColor = (theme == null ? void 0 : theme.primaryColor) ?? "#6366f1";
413
+ return /* @__PURE__ */ jsx(FeedbackRoot, { children: /* @__PURE__ */ jsxs("div", { style: positionStyles, className, children: [
414
+ /* @__PURE__ */ jsx(FeedbackTrigger, { children: /* @__PURE__ */ jsx(
415
+ "button",
416
+ {
417
+ type: "button",
418
+ className: "tracey-feedback-trigger",
419
+ style: {
420
+ backgroundColor: primaryColor,
421
+ color: "#fff",
422
+ border: "none",
423
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 8,
424
+ padding: "10px 16px",
425
+ fontSize: 14,
426
+ fontWeight: 500,
427
+ cursor: "pointer",
428
+ fontFamily: (theme == null ? void 0 : theme.fontFamily) ?? "inherit",
429
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)"
430
+ },
431
+ children: triggerLabel
432
+ }
433
+ ) }),
434
+ /* @__PURE__ */ jsx(FeedbackPortal, { children: /* @__PURE__ */ jsx(
435
+ FeedbackContent,
436
+ {
437
+ style: {
438
+ position: "fixed",
439
+ inset: 0,
440
+ display: "flex",
441
+ alignItems: "center",
442
+ justifyContent: "center",
443
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
444
+ zIndex: 9999
445
+ },
446
+ children: /* @__PURE__ */ jsx(
447
+ "div",
448
+ {
449
+ style: {
450
+ backgroundColor: (theme == null ? void 0 : theme.backgroundColor) ?? "#fff",
451
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 12,
452
+ padding: 24,
453
+ width: "100%",
454
+ maxWidth: 400,
455
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.15)"
456
+ },
457
+ children: /* @__PURE__ */ jsx(FeedbackForm, { theme })
458
+ }
459
+ )
460
+ }
461
+ ) })
462
+ ] }) });
463
+ }
464
+ function AnnouncementModal({
465
+ theme,
466
+ behavior = "queue",
467
+ slideMode = "carousel",
468
+ onDismiss
469
+ }) {
470
+ const { unread } = useAnnouncements();
471
+ const currentAnnouncement = behavior === "latest" ? [...unread].sort(
472
+ (a, b) => new Date(b.publishAt ?? 0).getTime() - new Date(a.publishAt ?? 0).getTime()
473
+ )[0] : unread[0];
474
+ if (!currentAnnouncement) {
475
+ return null;
476
+ }
477
+ return /* @__PURE__ */ jsx(
478
+ AnnouncementRoot,
479
+ {
480
+ announcement: currentAnnouncement,
481
+ defaultOpen: true,
482
+ onOpenChange: (open) => {
483
+ if (!open && currentAnnouncement) {
484
+ onDismiss == null ? void 0 : onDismiss(currentAnnouncement);
485
+ }
486
+ },
487
+ children: /* @__PURE__ */ jsx(AnnouncementPortal, { children: /* @__PURE__ */ jsx(
488
+ AnnouncementContent,
489
+ {
490
+ style: {
491
+ position: "fixed",
492
+ inset: 0,
493
+ display: "flex",
494
+ alignItems: "center",
495
+ justifyContent: "center",
496
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
497
+ zIndex: 9999
498
+ },
499
+ children: /* @__PURE__ */ jsx(
500
+ "div",
501
+ {
502
+ style: {
503
+ backgroundColor: (theme == null ? void 0 : theme.backgroundColor) ?? "#fff",
504
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 12,
505
+ padding: 0,
506
+ width: "100%",
507
+ maxWidth: 480,
508
+ maxHeight: "80vh",
509
+ overflow: "hidden",
510
+ boxShadow: "0 4px 20px rgba(0, 0, 0, 0.15)"
511
+ },
512
+ children: /* @__PURE__ */ jsx(
513
+ AnnouncementSlideContent,
514
+ {
515
+ announcement: currentAnnouncement,
516
+ theme,
517
+ slideMode
518
+ }
519
+ )
520
+ }
521
+ )
522
+ }
523
+ ) })
524
+ }
525
+ );
526
+ }
527
+ function AnnouncementSlideContent({
528
+ announcement,
529
+ theme,
530
+ slideMode
531
+ }) {
532
+ const primaryColor = (theme == null ? void 0 : theme.primaryColor) ?? "#6366f1";
533
+ const { markCtaClicked } = useAnnouncements();
534
+ return /* @__PURE__ */ jsx(AnnouncementNavigation, { children: ({
535
+ currentSlide,
536
+ totalSlides,
537
+ canGoNext,
538
+ canGoPrev,
539
+ nextSlide,
540
+ prevSlide,
541
+ goToSlide
542
+ }) => {
543
+ const slide = announcement.slides[currentSlide];
544
+ if (!slide) return null;
545
+ return /* @__PURE__ */ jsxs("div", { style: { position: "relative" }, children: [
546
+ /* @__PURE__ */ jsx(
547
+ "div",
548
+ {
549
+ style: { position: "absolute", top: 12, right: 12, zIndex: 1 },
550
+ children: /* @__PURE__ */ jsx(AnnouncementClose, { children: /* @__PURE__ */ jsx(
551
+ "button",
552
+ {
553
+ type: "button",
554
+ style: {
555
+ background: "rgba(0,0,0,0.3)",
556
+ border: "none",
557
+ borderRadius: "50%",
558
+ width: 32,
559
+ height: 32,
560
+ cursor: "pointer",
561
+ color: "#fff",
562
+ fontSize: 16
563
+ },
564
+ children: "✕"
565
+ }
566
+ ) })
567
+ }
568
+ ),
569
+ slide.imageUrl && /* @__PURE__ */ jsx(
570
+ "div",
571
+ {
572
+ style: {
573
+ width: "100%",
574
+ height: 200,
575
+ backgroundImage: `url(${slide.imageUrl})`,
576
+ backgroundSize: "cover",
577
+ backgroundPosition: "center"
578
+ }
579
+ }
580
+ ),
581
+ /* @__PURE__ */ jsxs("div", { style: { padding: 24 }, children: [
582
+ slide.title && /* @__PURE__ */ jsx(
583
+ "h3",
584
+ {
585
+ style: {
586
+ margin: "0 0 12px",
587
+ fontSize: 20,
588
+ fontWeight: 600,
589
+ color: (theme == null ? void 0 : theme.textColor) ?? "#111827"
590
+ },
591
+ children: slide.title
592
+ }
593
+ ),
594
+ slide.body && /* @__PURE__ */ jsx(
595
+ "p",
596
+ {
597
+ style: {
598
+ margin: "0 0 20px",
599
+ fontSize: 14,
600
+ lineHeight: 1.6,
601
+ color: "#6b7280"
602
+ },
603
+ children: slide.body
604
+ }
605
+ ),
606
+ slide.ctaText && slide.ctaUrl && /* @__PURE__ */ jsx(
607
+ "a",
608
+ {
609
+ href: slide.ctaUrl,
610
+ target: "_blank",
611
+ rel: "noopener noreferrer",
612
+ onClick: () => markCtaClicked(announcement.id, currentSlide),
613
+ style: {
614
+ display: "inline-block",
615
+ padding: "10px 20px",
616
+ backgroundColor: primaryColor,
617
+ color: "#fff",
618
+ textDecoration: "none",
619
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 6,
620
+ fontSize: 14,
621
+ fontWeight: 500
622
+ },
623
+ children: slide.ctaText
624
+ }
625
+ ),
626
+ totalSlides > 1 && /* @__PURE__ */ jsx(
627
+ "div",
628
+ {
629
+ style: {
630
+ display: "flex",
631
+ justifyContent: "space-between",
632
+ alignItems: "center",
633
+ marginTop: 20
634
+ },
635
+ children: slideMode === "carousel" ? /* @__PURE__ */ jsxs(Fragment, { children: [
636
+ /* @__PURE__ */ jsx(
637
+ "button",
638
+ {
639
+ type: "button",
640
+ onClick: prevSlide,
641
+ disabled: !canGoPrev,
642
+ style: {
643
+ padding: "8px 16px",
644
+ border: "1px solid #e5e7eb",
645
+ borderRadius: 6,
646
+ background: "none",
647
+ cursor: canGoPrev ? "pointer" : "not-allowed",
648
+ opacity: canGoPrev ? 1 : 0.5
649
+ },
650
+ children: "← Previous"
651
+ }
652
+ ),
653
+ /* @__PURE__ */ jsxs("span", { style: { color: "#9ca3af", fontSize: 14 }, children: [
654
+ currentSlide + 1,
655
+ " / ",
656
+ totalSlides
657
+ ] }),
658
+ /* @__PURE__ */ jsx(
659
+ "button",
660
+ {
661
+ type: "button",
662
+ onClick: nextSlide,
663
+ disabled: !canGoNext,
664
+ style: {
665
+ padding: "8px 16px",
666
+ border: "1px solid #e5e7eb",
667
+ borderRadius: 6,
668
+ background: "none",
669
+ cursor: canGoNext ? "pointer" : "not-allowed",
670
+ opacity: canGoNext ? 1 : 0.5
671
+ },
672
+ children: "Next →"
673
+ }
674
+ )
675
+ ] }) : /* @__PURE__ */ jsx(
676
+ "div",
677
+ {
678
+ style: {
679
+ display: "flex",
680
+ gap: 8,
681
+ justifyContent: "center",
682
+ width: "100%"
683
+ },
684
+ children: Array.from({ length: totalSlides }).map((_, i) => /* @__PURE__ */ jsx(
685
+ "button",
686
+ {
687
+ type: "button",
688
+ onClick: () => goToSlide(i),
689
+ style: {
690
+ width: 10,
691
+ height: 10,
692
+ borderRadius: "50%",
693
+ border: "none",
694
+ backgroundColor: i === currentSlide ? primaryColor : "#e5e7eb",
695
+ cursor: "pointer"
696
+ }
697
+ },
698
+ i
699
+ ))
700
+ }
701
+ )
702
+ }
703
+ )
704
+ ] })
705
+ ] });
706
+ } });
707
+ }
708
+ function getPositionStyles$1(position) {
709
+ if (typeof position === "object" && "x" in position) {
710
+ return {
711
+ position: "fixed",
712
+ left: position.x,
713
+ top: position.y
714
+ };
715
+ }
716
+ const base = { position: "fixed" };
717
+ switch (position) {
718
+ case "top-left":
719
+ return { ...base, top: 16, left: 16 };
720
+ case "top-right":
721
+ return { ...base, top: 16, right: 16 };
722
+ case "bottom-left":
723
+ return { ...base, bottom: 16, left: 16 };
724
+ case "bottom-right":
725
+ default:
726
+ return { ...base, bottom: 16, right: 16 };
727
+ }
728
+ }
729
+ const BOUNCE_KEYFRAMES = `
730
+ @keyframes tracey-badge-bounce {
731
+ 0% { transform: scale(1); }
732
+ 30% { transform: scale(1.3); }
733
+ 50% { transform: scale(0.9); }
734
+ 70% { transform: scale(1.1); }
735
+ 100% { transform: scale(1); }
736
+ }
737
+ `;
738
+ function AnnouncementBell({
739
+ position = "top-right",
740
+ theme,
741
+ showCount = true,
742
+ onClick: _onClick = "modal"
743
+ }) {
744
+ const { unreadCount } = useAnnouncements();
745
+ const [showModal, setShowModal] = useState(false);
746
+ const [animating, setAnimating] = useState(false);
747
+ const prevCountRef = useRef(unreadCount);
748
+ const positionStyles = getPositionStyles$1(position);
749
+ const primaryColor = (theme == null ? void 0 : theme.primaryColor) ?? "#6366f1";
750
+ useEffect(() => {
751
+ if (unreadCount > prevCountRef.current && unreadCount > 0) {
752
+ setAnimating(true);
753
+ const timeout = setTimeout(() => setAnimating(false), 600);
754
+ return () => clearTimeout(timeout);
755
+ }
756
+ prevCountRef.current = unreadCount;
757
+ }, [unreadCount]);
758
+ useEffect(() => {
759
+ prevCountRef.current = unreadCount;
760
+ }, [unreadCount]);
761
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
762
+ /* @__PURE__ */ jsx("style", { children: BOUNCE_KEYFRAMES }),
763
+ /* @__PURE__ */ jsx("div", { style: positionStyles, children: /* @__PURE__ */ jsxs(
764
+ "button",
765
+ {
766
+ type: "button",
767
+ onClick: () => setShowModal(true),
768
+ style: {
769
+ position: "relative",
770
+ width: 44,
771
+ height: 44,
772
+ borderRadius: "50%",
773
+ backgroundColor: (theme == null ? void 0 : theme.backgroundColor) ?? "#fff",
774
+ border: "none",
775
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
776
+ cursor: "pointer",
777
+ display: "flex",
778
+ alignItems: "center",
779
+ justifyContent: "center"
780
+ },
781
+ "aria-label": `Announcements${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
782
+ children: [
783
+ /* @__PURE__ */ jsxs(
784
+ "svg",
785
+ {
786
+ width: "20",
787
+ height: "20",
788
+ viewBox: "0 0 24 24",
789
+ fill: "none",
790
+ stroke: (theme == null ? void 0 : theme.textColor) ?? "#374151",
791
+ strokeWidth: "2",
792
+ strokeLinecap: "round",
793
+ strokeLinejoin: "round",
794
+ children: [
795
+ /* @__PURE__ */ jsx("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }),
796
+ /* @__PURE__ */ jsx("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" })
797
+ ]
798
+ }
799
+ ),
800
+ showCount && unreadCount > 0 && /* @__PURE__ */ jsx(
801
+ "span",
802
+ {
803
+ "data-testid": "announcement-badge",
804
+ style: {
805
+ position: "absolute",
806
+ top: -4,
807
+ right: -4,
808
+ minWidth: 20,
809
+ height: 20,
810
+ borderRadius: 10,
811
+ backgroundColor: primaryColor,
812
+ color: "#fff",
813
+ fontSize: 11,
814
+ fontWeight: 600,
815
+ display: "flex",
816
+ alignItems: "center",
817
+ justifyContent: "center",
818
+ padding: "0 6px",
819
+ animation: animating ? "tracey-badge-bounce 0.6s ease-in-out" : "none"
820
+ },
821
+ children: unreadCount > 99 ? "99+" : unreadCount
822
+ }
823
+ )
824
+ ]
825
+ }
826
+ ) }),
827
+ showModal && unreadCount > 0 && /* @__PURE__ */ jsx(
828
+ AnnouncementModal,
829
+ {
830
+ theme,
831
+ onDismiss: () => setShowModal(false)
832
+ }
833
+ )
834
+ ] });
835
+ }
836
+ function formatRelativeTime(dateStr) {
837
+ if (!dateStr) return "";
838
+ const now = Date.now();
839
+ const date = new Date(dateStr).getTime();
840
+ const diffMs = now - date;
841
+ const diffMins = Math.floor(diffMs / 6e4);
842
+ if (diffMins < 1) return "Just now";
843
+ if (diffMins < 60) return `${diffMins}m ago`;
844
+ const diffHours = Math.floor(diffMins / 60);
845
+ if (diffHours < 24) return `${diffHours}h ago`;
846
+ const diffDays = Math.floor(diffHours / 24);
847
+ if (diffDays < 30) return `${diffDays}d ago`;
848
+ const diffMonths = Math.floor(diffDays / 30);
849
+ return `${diffMonths}mo ago`;
850
+ }
851
+ function getBodyPreview(announcement) {
852
+ const slide = announcement.slides[0];
853
+ if (!(slide == null ? void 0 : slide.body)) return "";
854
+ return slide.body.length > 120 ? slide.body.slice(0, 120) + "..." : slide.body;
855
+ }
856
+ function AnnouncementList({
857
+ theme,
858
+ maxHeight = 360
859
+ }) {
860
+ const {
861
+ announcements,
862
+ unreadCount,
863
+ isLoading,
864
+ markAllAsRead,
865
+ markAsViewed,
866
+ markCtaClicked
867
+ } = useAnnouncements();
868
+ const primaryColor = (theme == null ? void 0 : theme.primaryColor) ?? "#6366f1";
869
+ const textColor = (theme == null ? void 0 : theme.textColor) ?? "#374151";
870
+ const bgColor = (theme == null ? void 0 : theme.backgroundColor) ?? "#fff";
871
+ if (isLoading) {
872
+ return /* @__PURE__ */ jsx("div", { style: { padding: 20 }, children: [1, 2, 3].map((i) => /* @__PURE__ */ jsx(
873
+ "div",
874
+ {
875
+ style: {
876
+ height: 72,
877
+ backgroundColor: "#f3f4f6",
878
+ borderRadius: 8,
879
+ marginBottom: 8,
880
+ animation: "tracey-skeleton-pulse 1.5s ease-in-out infinite"
881
+ }
882
+ },
883
+ i
884
+ )) });
885
+ }
886
+ if (announcements.length === 0) {
887
+ return /* @__PURE__ */ jsxs(
888
+ "div",
889
+ {
890
+ style: {
891
+ padding: "40px 20px",
892
+ textAlign: "center",
893
+ color: "#9ca3af",
894
+ fontSize: 14
895
+ },
896
+ children: [
897
+ /* @__PURE__ */ jsxs(
898
+ "svg",
899
+ {
900
+ width: "40",
901
+ height: "40",
902
+ viewBox: "0 0 24 24",
903
+ fill: "none",
904
+ stroke: "#d1d5db",
905
+ strokeWidth: "1.5",
906
+ strokeLinecap: "round",
907
+ strokeLinejoin: "round",
908
+ style: { margin: "0 auto 12px" },
909
+ children: [
910
+ /* @__PURE__ */ jsx("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }),
911
+ /* @__PURE__ */ jsx("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" })
912
+ ]
913
+ }
914
+ ),
915
+ /* @__PURE__ */ jsx("p", { style: { margin: 0 }, children: "No announcements yet" })
916
+ ]
917
+ }
918
+ );
919
+ }
920
+ const headerStyle = {
921
+ display: "flex",
922
+ justifyContent: "space-between",
923
+ alignItems: "center",
924
+ padding: "0 16px 12px",
925
+ borderBottom: "1px solid #f3f4f6"
926
+ };
927
+ return /* @__PURE__ */ jsxs("div", { children: [
928
+ unreadCount > 0 && /* @__PURE__ */ jsxs("div", { style: headerStyle, children: [
929
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 12, color: "#9ca3af" }, children: [
930
+ unreadCount,
931
+ " unread"
932
+ ] }),
933
+ /* @__PURE__ */ jsx(
934
+ "button",
935
+ {
936
+ type: "button",
937
+ onClick: markAllAsRead,
938
+ style: {
939
+ background: "none",
940
+ border: "none",
941
+ cursor: "pointer",
942
+ fontSize: 12,
943
+ color: primaryColor,
944
+ fontWeight: 500,
945
+ padding: 0
946
+ },
947
+ children: "Mark all as read"
948
+ }
949
+ )
950
+ ] }),
951
+ /* @__PURE__ */ jsx(
952
+ "div",
953
+ {
954
+ style: {
955
+ maxHeight,
956
+ overflowY: "auto",
957
+ padding: "8px 0"
958
+ },
959
+ children: announcements.map((announcement) => /* @__PURE__ */ jsx(
960
+ AnnouncementCard,
961
+ {
962
+ announcement,
963
+ theme,
964
+ primaryColor,
965
+ textColor,
966
+ bgColor,
967
+ onView: () => markAsViewed(announcement.id),
968
+ onCtaClick: (slideIndex) => markCtaClicked(announcement.id, slideIndex)
969
+ },
970
+ announcement.id
971
+ ))
972
+ }
973
+ )
974
+ ] });
975
+ }
976
+ function AnnouncementCard({
977
+ announcement,
978
+ primaryColor,
979
+ textColor,
980
+ bgColor,
981
+ onView,
982
+ onCtaClick
983
+ }) {
984
+ const isUnread = !announcement.viewed;
985
+ const bodyPreview = getBodyPreview(announcement);
986
+ const firstSlide = announcement.slides[0];
987
+ const hasCta = (firstSlide == null ? void 0 : firstSlide.ctaText) && (firstSlide == null ? void 0 : firstSlide.ctaUrl);
988
+ const timeAgo = formatRelativeTime(announcement.publishAt);
989
+ return /* @__PURE__ */ jsx(
990
+ "div",
991
+ {
992
+ role: "article",
993
+ onClick: () => {
994
+ if (isUnread) onView();
995
+ },
996
+ style: {
997
+ padding: "12px 16px",
998
+ cursor: isUnread ? "pointer" : "default",
999
+ backgroundColor: isUnread ? `${primaryColor}08` : "transparent",
1000
+ borderBottom: "1px solid #f3f4f6",
1001
+ transition: "background-color 0.15s ease"
1002
+ },
1003
+ onMouseEnter: (e) => {
1004
+ e.currentTarget.style.backgroundColor = bgColor === "#fff" ? "#f9fafb" : "rgba(0,0,0,0.03)";
1005
+ },
1006
+ onMouseLeave: (e) => {
1007
+ e.currentTarget.style.backgroundColor = isUnread ? `${primaryColor}08` : "transparent";
1008
+ },
1009
+ children: /* @__PURE__ */ jsxs(
1010
+ "div",
1011
+ {
1012
+ style: {
1013
+ display: "flex",
1014
+ alignItems: "flex-start",
1015
+ gap: 10
1016
+ },
1017
+ children: [
1018
+ isUnread && /* @__PURE__ */ jsx(
1019
+ "span",
1020
+ {
1021
+ "data-testid": "unread-dot",
1022
+ style: {
1023
+ width: 8,
1024
+ height: 8,
1025
+ borderRadius: "50%",
1026
+ backgroundColor: primaryColor,
1027
+ flexShrink: 0,
1028
+ marginTop: 5
1029
+ }
1030
+ }
1031
+ ),
1032
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
1033
+ /* @__PURE__ */ jsxs(
1034
+ "div",
1035
+ {
1036
+ style: {
1037
+ display: "flex",
1038
+ justifyContent: "space-between",
1039
+ alignItems: "baseline",
1040
+ gap: 8
1041
+ },
1042
+ children: [
1043
+ /* @__PURE__ */ jsx(
1044
+ "h4",
1045
+ {
1046
+ style: {
1047
+ margin: 0,
1048
+ fontSize: 14,
1049
+ fontWeight: isUnread ? 600 : 500,
1050
+ color: textColor,
1051
+ overflow: "hidden",
1052
+ textOverflow: "ellipsis",
1053
+ whiteSpace: "nowrap"
1054
+ },
1055
+ children: announcement.title
1056
+ }
1057
+ ),
1058
+ timeAgo && /* @__PURE__ */ jsx(
1059
+ "span",
1060
+ {
1061
+ style: {
1062
+ fontSize: 11,
1063
+ color: "#9ca3af",
1064
+ whiteSpace: "nowrap",
1065
+ flexShrink: 0
1066
+ },
1067
+ children: timeAgo
1068
+ }
1069
+ )
1070
+ ]
1071
+ }
1072
+ ),
1073
+ bodyPreview && /* @__PURE__ */ jsx(
1074
+ "p",
1075
+ {
1076
+ style: {
1077
+ margin: "4px 0 0",
1078
+ fontSize: 13,
1079
+ color: "#6b7280",
1080
+ lineHeight: 1.4,
1081
+ overflow: "hidden",
1082
+ display: "-webkit-box",
1083
+ WebkitLineClamp: 2,
1084
+ WebkitBoxOrient: "vertical"
1085
+ },
1086
+ children: bodyPreview
1087
+ }
1088
+ ),
1089
+ hasCta && /* @__PURE__ */ jsx(
1090
+ "a",
1091
+ {
1092
+ href: firstSlide.ctaUrl,
1093
+ target: "_blank",
1094
+ rel: "noopener noreferrer",
1095
+ onClick: (e) => {
1096
+ e.stopPropagation();
1097
+ onCtaClick(0);
1098
+ },
1099
+ style: {
1100
+ display: "inline-block",
1101
+ marginTop: 8,
1102
+ fontSize: 13,
1103
+ fontWeight: 500,
1104
+ color: primaryColor,
1105
+ textDecoration: "none"
1106
+ },
1107
+ children: firstSlide.ctaText
1108
+ }
1109
+ )
1110
+ ] })
1111
+ ]
1112
+ }
1113
+ )
1114
+ }
1115
+ );
1116
+ }
1117
+ let stylesInjected = false;
1118
+ function injectStyles() {
1119
+ if (stylesInjected || typeof document === "undefined") return;
1120
+ stylesInjected = true;
1121
+ const style = document.createElement("style");
1122
+ style.setAttribute("data-tracey-launcher", "");
1123
+ style.textContent = `
1124
+ @keyframes tracey-panel-enter {
1125
+ from { opacity: 0; transform: translateY(8px) scale(0.96); }
1126
+ to { opacity: 1; transform: translateY(0) scale(1); }
1127
+ }
1128
+ @keyframes tracey-badge-pulse {
1129
+ 0% { transform: scale(0.5); }
1130
+ 70% { transform: scale(1.1); }
1131
+ 100% { transform: scale(1); }
1132
+ }
1133
+ @keyframes tracey-skeleton-pulse {
1134
+ 0%, 100% { opacity: 0.5; }
1135
+ 50% { opacity: 1; }
1136
+ }
1137
+ @keyframes tracey-success-enter {
1138
+ from { opacity: 0; transform: scale(0.9); }
1139
+ to { opacity: 1; transform: scale(1); }
1140
+ }
1141
+ `;
1142
+ document.head.appendChild(style);
1143
+ }
1144
+ function getPositionStyles(position) {
1145
+ if (typeof position === "object" && "x" in position) {
1146
+ return {
1147
+ position: "fixed",
1148
+ left: position.x,
1149
+ top: position.y
1150
+ };
1151
+ }
1152
+ const base = { position: "fixed", zIndex: 9998 };
1153
+ switch (position) {
1154
+ case "top-left":
1155
+ return { ...base, top: 16, left: 16 };
1156
+ case "top-right":
1157
+ return { ...base, top: 16, right: 16 };
1158
+ case "bottom-left":
1159
+ return { ...base, bottom: 16, left: 16 };
1160
+ case "bottom-right":
1161
+ default:
1162
+ return { ...base, bottom: 16, right: 16 };
1163
+ }
1164
+ }
1165
+ function getPanelPosition(position) {
1166
+ if (typeof position === "object" && "x" in position) {
1167
+ return { bottom: "100%", left: 0, marginBottom: 8 };
1168
+ }
1169
+ const isTop = position === "top-left" || position === "top-right";
1170
+ const isLeft = position === "top-left" || position === "bottom-left";
1171
+ return {
1172
+ ...isTop ? { top: "100%", marginTop: 8 } : { bottom: "100%", marginBottom: 8 },
1173
+ ...isLeft ? { left: 0 } : { right: 0 }
1174
+ };
1175
+ }
1176
+ const feedbackTypes = [
1177
+ { value: "general", label: "General" },
1178
+ { value: "bug", label: "Bug Report" },
1179
+ { value: "feature_request", label: "Feature Request" }
1180
+ ];
1181
+ function TraceyLauncher({
1182
+ position = "bottom-right",
1183
+ theme,
1184
+ className
1185
+ }) {
1186
+ useEffect(() => {
1187
+ injectStyles();
1188
+ }, []);
1189
+ const { unreadCount } = useAnnouncements();
1190
+ const positionStyles = getPositionStyles(position);
1191
+ const panelPositionStyles = getPanelPosition(position);
1192
+ const primaryColor = (theme == null ? void 0 : theme.primaryColor) ?? "#6366f1";
1193
+ const borderRadius = (theme == null ? void 0 : theme.borderRadius) ?? 8;
1194
+ const textColor = (theme == null ? void 0 : theme.textColor) ?? "#374151";
1195
+ const bgColor = (theme == null ? void 0 : theme.backgroundColor) ?? "#fff";
1196
+ const fontFamily = (theme == null ? void 0 : theme.fontFamily) ?? "inherit";
1197
+ return /* @__PURE__ */ jsx(LauncherRoot, { defaultActiveItem: "feedback", children: /* @__PURE__ */ jsx("div", { style: positionStyles, className, children: /* @__PURE__ */ jsxs("div", { style: { position: "relative", display: "inline-block" }, children: [
1198
+ /* @__PURE__ */ jsx(LauncherTrigger, { children: /* @__PURE__ */ jsx(
1199
+ "button",
1200
+ {
1201
+ type: "button",
1202
+ "aria-label": `Tracey widget${unreadCount > 0 ? ` (${unreadCount} unread)` : ""}`,
1203
+ style: {
1204
+ width: 52,
1205
+ height: 52,
1206
+ borderRadius: "50%",
1207
+ backgroundColor: primaryColor,
1208
+ border: "none",
1209
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.2)",
1210
+ cursor: "pointer",
1211
+ display: "flex",
1212
+ alignItems: "center",
1213
+ justifyContent: "center",
1214
+ transition: "transform 0.2s ease, box-shadow 0.2s ease"
1215
+ },
1216
+ onMouseEnter: (e) => {
1217
+ e.currentTarget.style.transform = "scale(1.05)";
1218
+ e.currentTarget.style.boxShadow = "0 6px 16px rgba(0, 0, 0, 0.25)";
1219
+ },
1220
+ onMouseLeave: (e) => {
1221
+ e.currentTarget.style.transform = "scale(1)";
1222
+ e.currentTarget.style.boxShadow = "0 4px 12px rgba(0, 0, 0, 0.2)";
1223
+ },
1224
+ children: /* @__PURE__ */ jsxs(
1225
+ "svg",
1226
+ {
1227
+ width: "22",
1228
+ height: "22",
1229
+ viewBox: "0 0 24 24",
1230
+ fill: "none",
1231
+ stroke: "#fff",
1232
+ strokeWidth: "2",
1233
+ strokeLinecap: "round",
1234
+ strokeLinejoin: "round",
1235
+ children: [
1236
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "12", r: "1" }),
1237
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "12", r: "1" }),
1238
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "12", r: "1" }),
1239
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "5", r: "1" }),
1240
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "5", r: "1" }),
1241
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "5", r: "1" }),
1242
+ /* @__PURE__ */ jsx("circle", { cx: "12", cy: "19", r: "1" }),
1243
+ /* @__PURE__ */ jsx("circle", { cx: "19", cy: "19", r: "1" }),
1244
+ /* @__PURE__ */ jsx("circle", { cx: "5", cy: "19", r: "1" })
1245
+ ]
1246
+ }
1247
+ )
1248
+ }
1249
+ ) }),
1250
+ /* @__PURE__ */ jsx(LauncherBadge, { count: unreadCount, children: (count) => /* @__PURE__ */ jsx(
1251
+ "span",
1252
+ {
1253
+ style: {
1254
+ position: "absolute",
1255
+ top: -4,
1256
+ right: -4,
1257
+ minWidth: 20,
1258
+ height: 20,
1259
+ borderRadius: 10,
1260
+ backgroundColor: "#ef4444",
1261
+ color: "#fff",
1262
+ fontSize: 11,
1263
+ fontWeight: 600,
1264
+ display: "flex",
1265
+ alignItems: "center",
1266
+ justifyContent: "center",
1267
+ padding: "0 6px",
1268
+ pointerEvents: "none",
1269
+ animation: "tracey-badge-pulse 0.3s ease-out"
1270
+ },
1271
+ children: count > 99 ? "99+" : count
1272
+ }
1273
+ ) }),
1274
+ /* @__PURE__ */ jsx(LauncherPortal, { children: /* @__PURE__ */ jsx("div", { style: positionStyles, children: /* @__PURE__ */ jsx("div", { style: { position: "relative", display: "inline-block" }, children: /* @__PURE__ */ jsxs(
1275
+ LauncherPanel,
1276
+ {
1277
+ style: {
1278
+ position: "absolute",
1279
+ ...panelPositionStyles,
1280
+ width: 380,
1281
+ backgroundColor: bgColor,
1282
+ borderRadius,
1283
+ boxShadow: "0 12px 40px rgba(0, 0, 0, 0.15), 0 4px 12px rgba(0, 0, 0, 0.1)",
1284
+ overflow: "hidden",
1285
+ animation: "tracey-panel-enter 0.2s ease-out",
1286
+ fontFamily
1287
+ },
1288
+ children: [
1289
+ /* @__PURE__ */ jsxs(
1290
+ "div",
1291
+ {
1292
+ role: "tablist",
1293
+ style: {
1294
+ display: "flex",
1295
+ borderBottom: "1px solid #e5e7eb",
1296
+ backgroundColor: bgColor
1297
+ },
1298
+ children: [
1299
+ /* @__PURE__ */ jsxs(
1300
+ LauncherTab,
1301
+ {
1302
+ value: "feedback",
1303
+ style: {
1304
+ flex: 1,
1305
+ display: "flex",
1306
+ alignItems: "center",
1307
+ justifyContent: "center",
1308
+ gap: 6,
1309
+ padding: "12px 0",
1310
+ border: "none",
1311
+ background: "none",
1312
+ cursor: "pointer",
1313
+ fontSize: 13,
1314
+ fontWeight: 500,
1315
+ fontFamily,
1316
+ color: textColor,
1317
+ borderBottom: "2px solid transparent",
1318
+ transition: "border-color 0.15s ease, color 0.15s ease"
1319
+ },
1320
+ children: [
1321
+ /* @__PURE__ */ jsx(
1322
+ "svg",
1323
+ {
1324
+ width: "16",
1325
+ height: "16",
1326
+ viewBox: "0 0 24 24",
1327
+ fill: "none",
1328
+ stroke: "currentColor",
1329
+ strokeWidth: "2",
1330
+ strokeLinecap: "round",
1331
+ strokeLinejoin: "round",
1332
+ children: /* @__PURE__ */ jsx("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
1333
+ }
1334
+ ),
1335
+ "Feedback"
1336
+ ]
1337
+ }
1338
+ ),
1339
+ /* @__PURE__ */ jsxs(
1340
+ LauncherTab,
1341
+ {
1342
+ value: "announcements",
1343
+ style: {
1344
+ flex: 1,
1345
+ display: "flex",
1346
+ alignItems: "center",
1347
+ justifyContent: "center",
1348
+ gap: 6,
1349
+ padding: "12px 0",
1350
+ border: "none",
1351
+ background: "none",
1352
+ cursor: "pointer",
1353
+ fontSize: 13,
1354
+ fontWeight: 500,
1355
+ fontFamily,
1356
+ color: textColor,
1357
+ borderBottom: "2px solid transparent",
1358
+ transition: "border-color 0.15s ease, color 0.15s ease"
1359
+ },
1360
+ children: [
1361
+ /* @__PURE__ */ jsxs(
1362
+ "svg",
1363
+ {
1364
+ width: "16",
1365
+ height: "16",
1366
+ viewBox: "0 0 24 24",
1367
+ fill: "none",
1368
+ stroke: "currentColor",
1369
+ strokeWidth: "2",
1370
+ strokeLinecap: "round",
1371
+ strokeLinejoin: "round",
1372
+ children: [
1373
+ /* @__PURE__ */ jsx("path", { d: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9" }),
1374
+ /* @__PURE__ */ jsx("path", { d: "M13.73 21a2 2 0 0 1-3.46 0" })
1375
+ ]
1376
+ }
1377
+ ),
1378
+ "What's New",
1379
+ /* @__PURE__ */ jsx(LauncherBadge, { count: unreadCount, children: (count) => /* @__PURE__ */ jsx(
1380
+ "span",
1381
+ {
1382
+ style: {
1383
+ minWidth: 18,
1384
+ height: 18,
1385
+ borderRadius: 9,
1386
+ backgroundColor: "#ef4444",
1387
+ color: "#fff",
1388
+ fontSize: 10,
1389
+ fontWeight: 600,
1390
+ display: "inline-flex",
1391
+ alignItems: "center",
1392
+ justifyContent: "center",
1393
+ padding: "0 5px"
1394
+ },
1395
+ children: count > 99 ? "99+" : count
1396
+ }
1397
+ ) })
1398
+ ]
1399
+ }
1400
+ )
1401
+ ]
1402
+ }
1403
+ ),
1404
+ /* @__PURE__ */ jsx("style", { children: `
1405
+ [role="tab"][data-state="active"] {
1406
+ border-bottom-color: ${primaryColor} !important;
1407
+ color: ${primaryColor} !important;
1408
+ }
1409
+ ` }),
1410
+ /* @__PURE__ */ jsx(LauncherTabContent, { value: "feedback", children: /* @__PURE__ */ jsx("div", { style: { padding: 16 }, children: /* @__PURE__ */ jsx(
1411
+ EmbeddedFeedbackForm,
1412
+ {
1413
+ primaryColor,
1414
+ textColor,
1415
+ fontFamily,
1416
+ borderRadius
1417
+ }
1418
+ ) }) }),
1419
+ /* @__PURE__ */ jsx(LauncherTabContent, { value: "announcements", children: /* @__PURE__ */ jsx(AnnouncementList, { theme, maxHeight: 360 }) })
1420
+ ]
1421
+ }
1422
+ ) }) }) })
1423
+ ] }) }) });
1424
+ }
1425
+ function EmbeddedFeedbackForm({
1426
+ primaryColor,
1427
+ textColor,
1428
+ fontFamily,
1429
+ borderRadius
1430
+ }) {
1431
+ const [showSuccess, setShowSuccess] = useState(false);
1432
+ const handleSuccess = useCallback(() => {
1433
+ setShowSuccess(true);
1434
+ setTimeout(() => setShowSuccess(false), 3e3);
1435
+ }, []);
1436
+ const inputStyles = {
1437
+ width: "100%",
1438
+ padding: "10px 12px",
1439
+ border: "1px solid #e5e7eb",
1440
+ borderRadius: typeof borderRadius === "number" ? borderRadius - 2 : 6,
1441
+ fontSize: 14,
1442
+ fontFamily,
1443
+ boxSizing: "border-box",
1444
+ color: textColor,
1445
+ backgroundColor: "transparent"
1446
+ };
1447
+ const labelStyles = {
1448
+ display: "block",
1449
+ marginBottom: 4,
1450
+ fontSize: 13,
1451
+ fontWeight: 500,
1452
+ color: textColor
1453
+ };
1454
+ if (showSuccess) {
1455
+ return /* @__PURE__ */ jsxs(
1456
+ "div",
1457
+ {
1458
+ style: {
1459
+ padding: "32px 16px",
1460
+ textAlign: "center",
1461
+ animation: "tracey-success-enter 0.2s ease-out"
1462
+ },
1463
+ children: [
1464
+ /* @__PURE__ */ jsx(
1465
+ "div",
1466
+ {
1467
+ style: {
1468
+ width: 48,
1469
+ height: 48,
1470
+ borderRadius: "50%",
1471
+ backgroundColor: "#ecfdf5",
1472
+ display: "flex",
1473
+ alignItems: "center",
1474
+ justifyContent: "center",
1475
+ margin: "0 auto 12px"
1476
+ },
1477
+ children: /* @__PURE__ */ jsx(
1478
+ "svg",
1479
+ {
1480
+ width: "24",
1481
+ height: "24",
1482
+ viewBox: "0 0 24 24",
1483
+ fill: "none",
1484
+ stroke: "#10b981",
1485
+ strokeWidth: "2.5",
1486
+ strokeLinecap: "round",
1487
+ strokeLinejoin: "round",
1488
+ children: /* @__PURE__ */ jsx("polyline", { points: "20 6 9 17 4 12" })
1489
+ }
1490
+ )
1491
+ }
1492
+ ),
1493
+ /* @__PURE__ */ jsx(
1494
+ "p",
1495
+ {
1496
+ style: {
1497
+ margin: 0,
1498
+ fontSize: 15,
1499
+ fontWeight: 600,
1500
+ color: textColor
1501
+ },
1502
+ children: "Thank you!"
1503
+ }
1504
+ ),
1505
+ /* @__PURE__ */ jsx(
1506
+ "p",
1507
+ {
1508
+ style: {
1509
+ margin: "4px 0 0",
1510
+ fontSize: 13,
1511
+ color: "#6b7280"
1512
+ },
1513
+ children: "Your feedback has been submitted."
1514
+ }
1515
+ )
1516
+ ]
1517
+ }
1518
+ );
1519
+ }
1520
+ return /* @__PURE__ */ jsx(FeedbackRoot, { defaultOpen: true, children: /* @__PURE__ */ jsx(FeedbackFormPrimitive, { onSuccess: handleSuccess, closeOnSuccess: false, children: ({
1521
+ title,
1522
+ setTitle,
1523
+ description,
1524
+ setDescription,
1525
+ type,
1526
+ setType,
1527
+ isSubmitting,
1528
+ error,
1529
+ handleSubmit
1530
+ }) => /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, children: [
1531
+ error && /* @__PURE__ */ jsx(
1532
+ "div",
1533
+ {
1534
+ style: {
1535
+ padding: "8px 12px",
1536
+ backgroundColor: "#fef2f2",
1537
+ border: "1px solid #fecaca",
1538
+ borderRadius: 6,
1539
+ marginBottom: 12,
1540
+ color: "#dc2626",
1541
+ fontSize: 13
1542
+ },
1543
+ children: error.message
1544
+ }
1545
+ ),
1546
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 12 }, children: [
1547
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Type" }),
1548
+ /* @__PURE__ */ jsx(
1549
+ "select",
1550
+ {
1551
+ value: type,
1552
+ onChange: (e) => setType(e.target.value),
1553
+ style: inputStyles,
1554
+ children: feedbackTypes.map((ft) => /* @__PURE__ */ jsx("option", { value: ft.value, children: ft.label }, ft.value))
1555
+ }
1556
+ )
1557
+ ] }),
1558
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 12 }, children: [
1559
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Title *" }),
1560
+ /* @__PURE__ */ jsx(
1561
+ "input",
1562
+ {
1563
+ type: "text",
1564
+ value: title,
1565
+ onChange: (e) => setTitle(e.target.value),
1566
+ placeholder: "Brief summary...",
1567
+ required: true,
1568
+ style: inputStyles
1569
+ }
1570
+ )
1571
+ ] }),
1572
+ /* @__PURE__ */ jsxs("div", { style: { marginBottom: 16 }, children: [
1573
+ /* @__PURE__ */ jsx("label", { style: labelStyles, children: "Description" }),
1574
+ /* @__PURE__ */ jsx(
1575
+ "textarea",
1576
+ {
1577
+ value: description,
1578
+ onChange: (e) => setDescription(e.target.value),
1579
+ placeholder: "Tell us more...",
1580
+ rows: 3,
1581
+ style: { ...inputStyles, resize: "vertical" }
1582
+ }
1583
+ )
1584
+ ] }),
1585
+ /* @__PURE__ */ jsx(
1586
+ "button",
1587
+ {
1588
+ type: "submit",
1589
+ disabled: isSubmitting || !title.trim(),
1590
+ style: {
1591
+ width: "100%",
1592
+ padding: "10px 16px",
1593
+ backgroundColor: isSubmitting ? "#9ca3af" : primaryColor,
1594
+ color: "#fff",
1595
+ border: "none",
1596
+ borderRadius: typeof borderRadius === "number" ? borderRadius - 2 : 6,
1597
+ fontSize: 14,
1598
+ fontWeight: 500,
1599
+ cursor: isSubmitting ? "not-allowed" : "pointer",
1600
+ transition: "background-color 0.15s ease"
1601
+ },
1602
+ children: isSubmitting ? "Sending..." : "Send Feedback"
1603
+ }
1604
+ )
1605
+ ] }) }) });
1606
+ }
1607
+ function getAnswerValue(answers, questionKey) {
1608
+ const value = answers[questionKey];
1609
+ if (value === void 0 || value === "") {
1610
+ return void 0;
1611
+ }
1612
+ return value;
1613
+ }
1614
+ function isRuleMatch(rule, answerValue) {
1615
+ if (rule.operator === "answered") return answerValue !== void 0;
1616
+ if (rule.operator === "not_answered") return answerValue === void 0;
1617
+ if (answerValue === void 0) return false;
1618
+ if (rule.operator === "eq") return answerValue === rule.value;
1619
+ if (rule.operator === "neq") return answerValue !== rule.value;
1620
+ if (rule.operator === "gte") {
1621
+ return typeof answerValue === "number" && typeof rule.value === "number" && answerValue >= rule.value;
1622
+ }
1623
+ if (rule.operator === "lte") {
1624
+ return typeof answerValue === "number" && typeof rule.value === "number" && answerValue <= rule.value;
1625
+ }
1626
+ if (rule.operator === "in") {
1627
+ return Array.isArray(rule.value) && rule.value.includes(answerValue);
1628
+ }
1629
+ return false;
1630
+ }
1631
+ function getActiveSurveyQuestionKeys(params) {
1632
+ const questions = [...params.questions].sort((a, b) => a.position - b.position);
1633
+ const questionIndexByKey = new Map(
1634
+ questions.map((question, index2) => [question.questionKey, index2])
1635
+ );
1636
+ const rulesBySource = /* @__PURE__ */ new Map();
1637
+ for (const rule of params.logicRules) {
1638
+ if (!rule.sourceQuestionKey) continue;
1639
+ const existing = rulesBySource.get(rule.sourceQuestionKey) ?? [];
1640
+ existing.push(rule);
1641
+ rulesBySource.set(rule.sourceQuestionKey, existing);
1642
+ }
1643
+ for (const rules of rulesBySource.values()) {
1644
+ rules.sort((a, b) => a.priority - b.priority);
1645
+ }
1646
+ const active = /* @__PURE__ */ new Set();
1647
+ let index = 0;
1648
+ let guard = 0;
1649
+ while (index >= 0 && index < questions.length && guard < questions.length + 10) {
1650
+ const current = questions[index];
1651
+ if (!current) break;
1652
+ active.add(current.questionKey);
1653
+ const answerValue = getAnswerValue(params.answers, current.questionKey);
1654
+ const rules = rulesBySource.get(current.questionKey) ?? [];
1655
+ const matchedRule = rules.find((rule) => isRuleMatch(rule, answerValue));
1656
+ if (matchedRule) {
1657
+ if (matchedRule.action === "end_survey") {
1658
+ break;
1659
+ }
1660
+ if (matchedRule.nextQuestionKey) {
1661
+ const nextIndex = questionIndexByKey.get(matchedRule.nextQuestionKey);
1662
+ if (nextIndex !== void 0 && nextIndex > index) {
1663
+ index = nextIndex;
1664
+ guard++;
1665
+ continue;
1666
+ }
1667
+ }
1668
+ }
1669
+ index++;
1670
+ guard++;
1671
+ }
1672
+ return active;
1673
+ }
1674
+ function SurveyWidget({
1675
+ anonymousSessionId,
1676
+ url,
1677
+ theme,
1678
+ autoLoad = true,
1679
+ title = "Quick Survey"
1680
+ }) {
1681
+ const {
1682
+ activeSurvey,
1683
+ loadActiveSurvey,
1684
+ submitSurveyResponse,
1685
+ dismissSurvey,
1686
+ isLoading,
1687
+ isSubmitting,
1688
+ error
1689
+ } = useSurvey();
1690
+ const [answers, setAnswers] = useState({});
1691
+ const [submitted, setSubmitted] = useState(false);
1692
+ useEffect(() => {
1693
+ if (!autoLoad) return;
1694
+ void loadActiveSurvey({ anonymousSessionId, url });
1695
+ }, [autoLoad, anonymousSessionId, loadActiveSurvey, url]);
1696
+ const sortedQuestions = useMemo(() => {
1697
+ if (!activeSurvey) return [];
1698
+ return [...activeSurvey.questions].sort((a, b) => a.position - b.position);
1699
+ }, [activeSurvey]);
1700
+ const activeQuestionKeys = useMemo(() => {
1701
+ if (!activeSurvey) return /* @__PURE__ */ new Set();
1702
+ return getActiveSurveyQuestionKeys({
1703
+ questions: sortedQuestions,
1704
+ logicRules: activeSurvey.logicRules,
1705
+ answers
1706
+ });
1707
+ }, [activeSurvey, answers, sortedQuestions]);
1708
+ const visibleQuestions = useMemo(
1709
+ () => sortedQuestions.filter(
1710
+ (question) => activeQuestionKeys.has(question.questionKey)
1711
+ ),
1712
+ [activeQuestionKeys, sortedQuestions]
1713
+ );
1714
+ if (isLoading) {
1715
+ return /* @__PURE__ */ jsx("div", { className: "tracey-survey-widget", children: "Loading survey..." });
1716
+ }
1717
+ if (submitted) {
1718
+ return /* @__PURE__ */ jsx("div", { className: "tracey-survey-widget", children: "Thanks for your feedback." });
1719
+ }
1720
+ if (!activeSurvey) {
1721
+ return null;
1722
+ }
1723
+ async function handleSubmit(event) {
1724
+ event.preventDefault();
1725
+ const survey = activeSurvey;
1726
+ if (!survey) return;
1727
+ const payload = [];
1728
+ for (const question of visibleQuestions) {
1729
+ const value = answers[question.questionKey];
1730
+ if (value === void 0 || value === "") {
1731
+ if (question.required) {
1732
+ return;
1733
+ }
1734
+ continue;
1735
+ }
1736
+ if (question.type === "nps" || question.type === "rating") {
1737
+ payload.push({
1738
+ questionKey: question.questionKey,
1739
+ type: question.type,
1740
+ valueNumber: Number(value)
1741
+ });
1742
+ continue;
1743
+ }
1744
+ payload.push({
1745
+ questionKey: question.questionKey,
1746
+ type: question.type,
1747
+ valueText: String(value)
1748
+ });
1749
+ }
1750
+ const result = await submitSurveyResponse(survey.id, {
1751
+ anonymousSessionId,
1752
+ answers: payload
1753
+ });
1754
+ if (result == null ? void 0 : result.success) {
1755
+ setSubmitted(true);
1756
+ }
1757
+ }
1758
+ return /* @__PURE__ */ jsxs(
1759
+ "div",
1760
+ {
1761
+ className: "tracey-survey-widget",
1762
+ style: {
1763
+ border: "1px solid #e5e7eb",
1764
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 10,
1765
+ padding: 16,
1766
+ backgroundColor: (theme == null ? void 0 : theme.backgroundColor) ?? "#fff",
1767
+ fontFamily: (theme == null ? void 0 : theme.fontFamily) ?? "inherit",
1768
+ maxWidth: 420
1769
+ },
1770
+ children: [
1771
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", justifyContent: "space-between", gap: 8 }, children: [
1772
+ /* @__PURE__ */ jsxs("div", { children: [
1773
+ /* @__PURE__ */ jsx("p", { style: { margin: 0, fontWeight: 600 }, children: title }),
1774
+ /* @__PURE__ */ jsx("p", { style: { margin: "4px 0 0", color: "#6b7280", fontSize: 13 }, children: activeSurvey.name })
1775
+ ] }),
1776
+ /* @__PURE__ */ jsx(
1777
+ "button",
1778
+ {
1779
+ type: "button",
1780
+ onClick: () => dismissSurvey(activeSurvey.id),
1781
+ style: { border: "none", background: "transparent", cursor: "pointer" },
1782
+ children: "×"
1783
+ }
1784
+ )
1785
+ ] }),
1786
+ /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, style: { marginTop: 12, display: "grid", gap: 12 }, children: [
1787
+ visibleQuestions.map((question) => /* @__PURE__ */ jsxs("label", { style: { display: "grid", gap: 6 }, children: [
1788
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 14, fontWeight: 500 }, children: question.title }),
1789
+ question.type === "nps" || question.type === "rating" ? /* @__PURE__ */ jsx(
1790
+ "input",
1791
+ {
1792
+ type: "number",
1793
+ min: question.type === "nps" ? 0 : Number(question.config.min ?? 1),
1794
+ max: question.type === "nps" ? 10 : Number(question.config.max ?? 5),
1795
+ required: question.required,
1796
+ value: answers[question.questionKey] ?? "",
1797
+ onChange: (event) => setAnswers((prev) => ({
1798
+ ...prev,
1799
+ [question.questionKey]: Number(event.target.value)
1800
+ }))
1801
+ }
1802
+ ) : question.type === "single_choice" ? /* @__PURE__ */ jsxs(
1803
+ "select",
1804
+ {
1805
+ required: question.required,
1806
+ value: String(answers[question.questionKey] ?? ""),
1807
+ onChange: (event) => setAnswers((prev) => ({
1808
+ ...prev,
1809
+ [question.questionKey]: event.target.value
1810
+ })),
1811
+ children: [
1812
+ /* @__PURE__ */ jsx("option", { value: "", children: "Select an option" }),
1813
+ Array.isArray(question.config.options) && question.config.options.map((option) => /* @__PURE__ */ jsx("option", { value: String(option), children: String(option) }, String(option)))
1814
+ ]
1815
+ }
1816
+ ) : /* @__PURE__ */ jsx(
1817
+ "textarea",
1818
+ {
1819
+ required: question.required,
1820
+ value: String(answers[question.questionKey] ?? ""),
1821
+ onChange: (event) => setAnswers((prev) => ({
1822
+ ...prev,
1823
+ [question.questionKey]: event.target.value
1824
+ })),
1825
+ placeholder: typeof question.config.placeholder === "string" ? question.config.placeholder : "Your answer"
1826
+ }
1827
+ )
1828
+ ] }, question.questionKey)),
1829
+ error && /* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#dc2626", fontSize: 13 }, children: error.message }),
1830
+ /* @__PURE__ */ jsx(
1831
+ "button",
1832
+ {
1833
+ type: "submit",
1834
+ disabled: isSubmitting,
1835
+ style: {
1836
+ backgroundColor: (theme == null ? void 0 : theme.primaryColor) ?? "#2563eb",
1837
+ color: "#fff",
1838
+ border: "none",
1839
+ borderRadius: (theme == null ? void 0 : theme.borderRadius) ?? 8,
1840
+ padding: "10px 14px",
1841
+ cursor: "pointer"
1842
+ },
1843
+ children: isSubmitting ? "Submitting..." : "Submit"
1844
+ }
1845
+ )
1846
+ ] })
1847
+ ]
1848
+ }
1849
+ );
1850
+ }
1851
+ function r2(e) {
1852
+ var t, f, n = "";
1853
+ if ("string" == typeof e || "number" == typeof e) n += e;
1854
+ else if ("object" == typeof e) if (Array.isArray(e)) {
1855
+ var o = e.length;
1856
+ for (t = 0; t < o; t++) e[t] && (f = r2(e[t])) && (n && (n += " "), n += f);
1857
+ } else for (f in e) e[f] && (n && (n += " "), n += f);
1858
+ return n;
1859
+ }
1860
+ function clsx() {
1861
+ for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r2(e)) && (n && (n += " "), n += t);
1862
+ return n;
1863
+ }
1864
+ const concatArrays = (array1, array2) => {
1865
+ const combinedArray = new Array(array1.length + array2.length);
1866
+ for (let i = 0; i < array1.length; i++) {
1867
+ combinedArray[i] = array1[i];
1868
+ }
1869
+ for (let i = 0; i < array2.length; i++) {
1870
+ combinedArray[array1.length + i] = array2[i];
1871
+ }
1872
+ return combinedArray;
1873
+ };
1874
+ const createClassValidatorObject = (classGroupId, validator) => ({
1875
+ classGroupId,
1876
+ validator
1877
+ });
1878
+ const createClassPartObject = (nextPart = /* @__PURE__ */ new Map(), validators = null, classGroupId) => ({
1879
+ nextPart,
1880
+ validators,
1881
+ classGroupId
1882
+ });
1883
+ const CLASS_PART_SEPARATOR = "-";
1884
+ const EMPTY_CONFLICTS = [];
1885
+ const ARBITRARY_PROPERTY_PREFIX = "arbitrary..";
1886
+ const createClassGroupUtils = (config) => {
1887
+ const classMap = createClassMap(config);
1888
+ const {
1889
+ conflictingClassGroups,
1890
+ conflictingClassGroupModifiers
1891
+ } = config;
1892
+ const getClassGroupId = (className) => {
1893
+ if (className.startsWith("[") && className.endsWith("]")) {
1894
+ return getGroupIdForArbitraryProperty(className);
1895
+ }
1896
+ const classParts = className.split(CLASS_PART_SEPARATOR);
1897
+ const startIndex = classParts[0] === "" && classParts.length > 1 ? 1 : 0;
1898
+ return getGroupRecursive(classParts, startIndex, classMap);
1899
+ };
1900
+ const getConflictingClassGroupIds = (classGroupId, hasPostfixModifier) => {
1901
+ if (hasPostfixModifier) {
1902
+ const modifierConflicts = conflictingClassGroupModifiers[classGroupId];
1903
+ const baseConflicts = conflictingClassGroups[classGroupId];
1904
+ if (modifierConflicts) {
1905
+ if (baseConflicts) {
1906
+ return concatArrays(baseConflicts, modifierConflicts);
1907
+ }
1908
+ return modifierConflicts;
1909
+ }
1910
+ return baseConflicts || EMPTY_CONFLICTS;
1911
+ }
1912
+ return conflictingClassGroups[classGroupId] || EMPTY_CONFLICTS;
1913
+ };
1914
+ return {
1915
+ getClassGroupId,
1916
+ getConflictingClassGroupIds
1917
+ };
1918
+ };
1919
+ const getGroupRecursive = (classParts, startIndex, classPartObject) => {
1920
+ const classPathsLength = classParts.length - startIndex;
1921
+ if (classPathsLength === 0) {
1922
+ return classPartObject.classGroupId;
1923
+ }
1924
+ const currentClassPart = classParts[startIndex];
1925
+ const nextClassPartObject = classPartObject.nextPart.get(currentClassPart);
1926
+ if (nextClassPartObject) {
1927
+ const result = getGroupRecursive(classParts, startIndex + 1, nextClassPartObject);
1928
+ if (result) return result;
1929
+ }
1930
+ const validators = classPartObject.validators;
1931
+ if (validators === null) {
1932
+ return void 0;
1933
+ }
1934
+ const classRest = startIndex === 0 ? classParts.join(CLASS_PART_SEPARATOR) : classParts.slice(startIndex).join(CLASS_PART_SEPARATOR);
1935
+ const validatorsLength = validators.length;
1936
+ for (let i = 0; i < validatorsLength; i++) {
1937
+ const validatorObj = validators[i];
1938
+ if (validatorObj.validator(classRest)) {
1939
+ return validatorObj.classGroupId;
1940
+ }
1941
+ }
1942
+ return void 0;
1943
+ };
1944
+ const getGroupIdForArbitraryProperty = (className) => className.slice(1, -1).indexOf(":") === -1 ? void 0 : (() => {
1945
+ const content = className.slice(1, -1);
1946
+ const colonIndex = content.indexOf(":");
1947
+ const property = content.slice(0, colonIndex);
1948
+ return property ? ARBITRARY_PROPERTY_PREFIX + property : void 0;
1949
+ })();
1950
+ const createClassMap = (config) => {
1951
+ const {
1952
+ theme,
1953
+ classGroups
1954
+ } = config;
1955
+ return processClassGroups(classGroups, theme);
1956
+ };
1957
+ const processClassGroups = (classGroups, theme) => {
1958
+ const classMap = createClassPartObject();
1959
+ for (const classGroupId in classGroups) {
1960
+ const group = classGroups[classGroupId];
1961
+ processClassesRecursively(group, classMap, classGroupId, theme);
1962
+ }
1963
+ return classMap;
1964
+ };
1965
+ const processClassesRecursively = (classGroup, classPartObject, classGroupId, theme) => {
1966
+ const len = classGroup.length;
1967
+ for (let i = 0; i < len; i++) {
1968
+ const classDefinition = classGroup[i];
1969
+ processClassDefinition(classDefinition, classPartObject, classGroupId, theme);
1970
+ }
1971
+ };
1972
+ const processClassDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
1973
+ if (typeof classDefinition === "string") {
1974
+ processStringDefinition(classDefinition, classPartObject, classGroupId);
1975
+ return;
1976
+ }
1977
+ if (typeof classDefinition === "function") {
1978
+ processFunctionDefinition(classDefinition, classPartObject, classGroupId, theme);
1979
+ return;
1980
+ }
1981
+ processObjectDefinition(classDefinition, classPartObject, classGroupId, theme);
1982
+ };
1983
+ const processStringDefinition = (classDefinition, classPartObject, classGroupId) => {
1984
+ const classPartObjectToEdit = classDefinition === "" ? classPartObject : getPart(classPartObject, classDefinition);
1985
+ classPartObjectToEdit.classGroupId = classGroupId;
1986
+ };
1987
+ const processFunctionDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
1988
+ if (isThemeGetter(classDefinition)) {
1989
+ processClassesRecursively(classDefinition(theme), classPartObject, classGroupId, theme);
1990
+ return;
1991
+ }
1992
+ if (classPartObject.validators === null) {
1993
+ classPartObject.validators = [];
1994
+ }
1995
+ classPartObject.validators.push(createClassValidatorObject(classGroupId, classDefinition));
1996
+ };
1997
+ const processObjectDefinition = (classDefinition, classPartObject, classGroupId, theme) => {
1998
+ const entries = Object.entries(classDefinition);
1999
+ const len = entries.length;
2000
+ for (let i = 0; i < len; i++) {
2001
+ const [key, value] = entries[i];
2002
+ processClassesRecursively(value, getPart(classPartObject, key), classGroupId, theme);
2003
+ }
2004
+ };
2005
+ const getPart = (classPartObject, path) => {
2006
+ let current = classPartObject;
2007
+ const parts = path.split(CLASS_PART_SEPARATOR);
2008
+ const len = parts.length;
2009
+ for (let i = 0; i < len; i++) {
2010
+ const part = parts[i];
2011
+ let next = current.nextPart.get(part);
2012
+ if (!next) {
2013
+ next = createClassPartObject();
2014
+ current.nextPart.set(part, next);
2015
+ }
2016
+ current = next;
2017
+ }
2018
+ return current;
2019
+ };
2020
+ const isThemeGetter = (func) => "isThemeGetter" in func && func.isThemeGetter === true;
2021
+ const createLruCache = (maxCacheSize) => {
2022
+ if (maxCacheSize < 1) {
2023
+ return {
2024
+ get: () => void 0,
2025
+ set: () => {
2026
+ }
2027
+ };
2028
+ }
2029
+ let cacheSize = 0;
2030
+ let cache = /* @__PURE__ */ Object.create(null);
2031
+ let previousCache = /* @__PURE__ */ Object.create(null);
2032
+ const update = (key, value) => {
2033
+ cache[key] = value;
2034
+ cacheSize++;
2035
+ if (cacheSize > maxCacheSize) {
2036
+ cacheSize = 0;
2037
+ previousCache = cache;
2038
+ cache = /* @__PURE__ */ Object.create(null);
2039
+ }
2040
+ };
2041
+ return {
2042
+ get(key) {
2043
+ let value = cache[key];
2044
+ if (value !== void 0) {
2045
+ return value;
2046
+ }
2047
+ if ((value = previousCache[key]) !== void 0) {
2048
+ update(key, value);
2049
+ return value;
2050
+ }
2051
+ },
2052
+ set(key, value) {
2053
+ if (key in cache) {
2054
+ cache[key] = value;
2055
+ } else {
2056
+ update(key, value);
2057
+ }
2058
+ }
2059
+ };
2060
+ };
2061
+ const IMPORTANT_MODIFIER = "!";
2062
+ const MODIFIER_SEPARATOR = ":";
2063
+ const EMPTY_MODIFIERS = [];
2064
+ const createResultObject = (modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition, isExternal) => ({
2065
+ modifiers,
2066
+ hasImportantModifier,
2067
+ baseClassName,
2068
+ maybePostfixModifierPosition,
2069
+ isExternal
2070
+ });
2071
+ const createParseClassName = (config) => {
2072
+ const {
2073
+ prefix,
2074
+ experimentalParseClassName
2075
+ } = config;
2076
+ let parseClassName = (className) => {
2077
+ const modifiers = [];
2078
+ let bracketDepth = 0;
2079
+ let parenDepth = 0;
2080
+ let modifierStart = 0;
2081
+ let postfixModifierPosition;
2082
+ const len = className.length;
2083
+ for (let index = 0; index < len; index++) {
2084
+ const currentCharacter = className[index];
2085
+ if (bracketDepth === 0 && parenDepth === 0) {
2086
+ if (currentCharacter === MODIFIER_SEPARATOR) {
2087
+ modifiers.push(className.slice(modifierStart, index));
2088
+ modifierStart = index + 1;
2089
+ continue;
2090
+ }
2091
+ if (currentCharacter === "/") {
2092
+ postfixModifierPosition = index;
2093
+ continue;
2094
+ }
2095
+ }
2096
+ if (currentCharacter === "[") bracketDepth++;
2097
+ else if (currentCharacter === "]") bracketDepth--;
2098
+ else if (currentCharacter === "(") parenDepth++;
2099
+ else if (currentCharacter === ")") parenDepth--;
2100
+ }
2101
+ const baseClassNameWithImportantModifier = modifiers.length === 0 ? className : className.slice(modifierStart);
2102
+ let baseClassName = baseClassNameWithImportantModifier;
2103
+ let hasImportantModifier = false;
2104
+ if (baseClassNameWithImportantModifier.endsWith(IMPORTANT_MODIFIER)) {
2105
+ baseClassName = baseClassNameWithImportantModifier.slice(0, -1);
2106
+ hasImportantModifier = true;
2107
+ } else if (
2108
+ /**
2109
+ * In Tailwind CSS v3 the important modifier was at the start of the base class name. This is still supported for legacy reasons.
2110
+ * @see https://github.com/dcastil/tailwind-merge/issues/513#issuecomment-2614029864
2111
+ */
2112
+ baseClassNameWithImportantModifier.startsWith(IMPORTANT_MODIFIER)
2113
+ ) {
2114
+ baseClassName = baseClassNameWithImportantModifier.slice(1);
2115
+ hasImportantModifier = true;
2116
+ }
2117
+ const maybePostfixModifierPosition = postfixModifierPosition && postfixModifierPosition > modifierStart ? postfixModifierPosition - modifierStart : void 0;
2118
+ return createResultObject(modifiers, hasImportantModifier, baseClassName, maybePostfixModifierPosition);
2119
+ };
2120
+ if (prefix) {
2121
+ const fullPrefix = prefix + MODIFIER_SEPARATOR;
2122
+ const parseClassNameOriginal = parseClassName;
2123
+ parseClassName = (className) => className.startsWith(fullPrefix) ? parseClassNameOriginal(className.slice(fullPrefix.length)) : createResultObject(EMPTY_MODIFIERS, false, className, void 0, true);
2124
+ }
2125
+ if (experimentalParseClassName) {
2126
+ const parseClassNameOriginal = parseClassName;
2127
+ parseClassName = (className) => experimentalParseClassName({
2128
+ className,
2129
+ parseClassName: parseClassNameOriginal
2130
+ });
2131
+ }
2132
+ return parseClassName;
2133
+ };
2134
+ const createSortModifiers = (config) => {
2135
+ const modifierWeights = /* @__PURE__ */ new Map();
2136
+ config.orderSensitiveModifiers.forEach((mod, index) => {
2137
+ modifierWeights.set(mod, 1e6 + index);
2138
+ });
2139
+ return (modifiers) => {
2140
+ const result = [];
2141
+ let currentSegment = [];
2142
+ for (let i = 0; i < modifiers.length; i++) {
2143
+ const modifier = modifiers[i];
2144
+ const isArbitrary = modifier[0] === "[";
2145
+ const isOrderSensitive = modifierWeights.has(modifier);
2146
+ if (isArbitrary || isOrderSensitive) {
2147
+ if (currentSegment.length > 0) {
2148
+ currentSegment.sort();
2149
+ result.push(...currentSegment);
2150
+ currentSegment = [];
2151
+ }
2152
+ result.push(modifier);
2153
+ } else {
2154
+ currentSegment.push(modifier);
2155
+ }
2156
+ }
2157
+ if (currentSegment.length > 0) {
2158
+ currentSegment.sort();
2159
+ result.push(...currentSegment);
2160
+ }
2161
+ return result;
2162
+ };
2163
+ };
2164
+ const createConfigUtils = (config) => ({
2165
+ cache: createLruCache(config.cacheSize),
2166
+ parseClassName: createParseClassName(config),
2167
+ sortModifiers: createSortModifiers(config),
2168
+ ...createClassGroupUtils(config)
2169
+ });
2170
+ const SPLIT_CLASSES_REGEX = /\s+/;
2171
+ const mergeClassList = (classList, configUtils) => {
2172
+ const {
2173
+ parseClassName,
2174
+ getClassGroupId,
2175
+ getConflictingClassGroupIds,
2176
+ sortModifiers
2177
+ } = configUtils;
2178
+ const classGroupsInConflict = [];
2179
+ const classNames = classList.trim().split(SPLIT_CLASSES_REGEX);
2180
+ let result = "";
2181
+ for (let index = classNames.length - 1; index >= 0; index -= 1) {
2182
+ const originalClassName = classNames[index];
2183
+ const {
2184
+ isExternal,
2185
+ modifiers,
2186
+ hasImportantModifier,
2187
+ baseClassName,
2188
+ maybePostfixModifierPosition
2189
+ } = parseClassName(originalClassName);
2190
+ if (isExternal) {
2191
+ result = originalClassName + (result.length > 0 ? " " + result : result);
2192
+ continue;
2193
+ }
2194
+ let hasPostfixModifier = !!maybePostfixModifierPosition;
2195
+ let classGroupId = getClassGroupId(hasPostfixModifier ? baseClassName.substring(0, maybePostfixModifierPosition) : baseClassName);
2196
+ if (!classGroupId) {
2197
+ if (!hasPostfixModifier) {
2198
+ result = originalClassName + (result.length > 0 ? " " + result : result);
2199
+ continue;
2200
+ }
2201
+ classGroupId = getClassGroupId(baseClassName);
2202
+ if (!classGroupId) {
2203
+ result = originalClassName + (result.length > 0 ? " " + result : result);
2204
+ continue;
2205
+ }
2206
+ hasPostfixModifier = false;
2207
+ }
2208
+ const variantModifier = modifiers.length === 0 ? "" : modifiers.length === 1 ? modifiers[0] : sortModifiers(modifiers).join(":");
2209
+ const modifierId = hasImportantModifier ? variantModifier + IMPORTANT_MODIFIER : variantModifier;
2210
+ const classId = modifierId + classGroupId;
2211
+ if (classGroupsInConflict.indexOf(classId) > -1) {
2212
+ continue;
2213
+ }
2214
+ classGroupsInConflict.push(classId);
2215
+ const conflictGroups = getConflictingClassGroupIds(classGroupId, hasPostfixModifier);
2216
+ for (let i = 0; i < conflictGroups.length; ++i) {
2217
+ const group = conflictGroups[i];
2218
+ classGroupsInConflict.push(modifierId + group);
2219
+ }
2220
+ result = originalClassName + (result.length > 0 ? " " + result : result);
2221
+ }
2222
+ return result;
2223
+ };
2224
+ const twJoin = (...classLists) => {
2225
+ let index = 0;
2226
+ let argument;
2227
+ let resolvedValue;
2228
+ let string = "";
2229
+ while (index < classLists.length) {
2230
+ if (argument = classLists[index++]) {
2231
+ if (resolvedValue = toValue(argument)) {
2232
+ string && (string += " ");
2233
+ string += resolvedValue;
2234
+ }
2235
+ }
2236
+ }
2237
+ return string;
2238
+ };
2239
+ const toValue = (mix) => {
2240
+ if (typeof mix === "string") {
2241
+ return mix;
2242
+ }
2243
+ let resolvedValue;
2244
+ let string = "";
2245
+ for (let k = 0; k < mix.length; k++) {
2246
+ if (mix[k]) {
2247
+ if (resolvedValue = toValue(mix[k])) {
2248
+ string && (string += " ");
2249
+ string += resolvedValue;
2250
+ }
2251
+ }
2252
+ }
2253
+ return string;
2254
+ };
2255
+ const createTailwindMerge = (createConfigFirst, ...createConfigRest) => {
2256
+ let configUtils;
2257
+ let cacheGet;
2258
+ let cacheSet;
2259
+ let functionToCall;
2260
+ const initTailwindMerge = (classList) => {
2261
+ const config = createConfigRest.reduce((previousConfig, createConfigCurrent) => createConfigCurrent(previousConfig), createConfigFirst());
2262
+ configUtils = createConfigUtils(config);
2263
+ cacheGet = configUtils.cache.get;
2264
+ cacheSet = configUtils.cache.set;
2265
+ functionToCall = tailwindMerge;
2266
+ return tailwindMerge(classList);
2267
+ };
2268
+ const tailwindMerge = (classList) => {
2269
+ const cachedResult = cacheGet(classList);
2270
+ if (cachedResult) {
2271
+ return cachedResult;
2272
+ }
2273
+ const result = mergeClassList(classList, configUtils);
2274
+ cacheSet(classList, result);
2275
+ return result;
2276
+ };
2277
+ functionToCall = initTailwindMerge;
2278
+ return (...args) => functionToCall(twJoin(...args));
2279
+ };
2280
+ const fallbackThemeArr = [];
2281
+ const fromTheme = (key) => {
2282
+ const themeGetter = (theme) => theme[key] || fallbackThemeArr;
2283
+ themeGetter.isThemeGetter = true;
2284
+ return themeGetter;
2285
+ };
2286
+ const arbitraryValueRegex = /^\[(?:(\w[\w-]*):)?(.+)\]$/i;
2287
+ const arbitraryVariableRegex = /^\((?:(\w[\w-]*):)?(.+)\)$/i;
2288
+ const fractionRegex = /^\d+\/\d+$/;
2289
+ const tshirtUnitRegex = /^(\d+(\.\d+)?)?(xs|sm|md|lg|xl)$/;
2290
+ const lengthUnitRegex = /\d+(%|px|r?em|[sdl]?v([hwib]|min|max)|pt|pc|in|cm|mm|cap|ch|ex|r?lh|cq(w|h|i|b|min|max))|\b(calc|min|max|clamp)\(.+\)|^0$/;
2291
+ const colorFunctionRegex = /^(rgba?|hsla?|hwb|(ok)?(lab|lch)|color-mix)\(.+\)$/;
2292
+ const shadowRegex = /^(inset_)?-?((\d+)?\.?(\d+)[a-z]+|0)_-?((\d+)?\.?(\d+)[a-z]+|0)/;
2293
+ const imageRegex = /^(url|image|image-set|cross-fade|element|(repeating-)?(linear|radial|conic)-gradient)\(.+\)$/;
2294
+ const isFraction = (value) => fractionRegex.test(value);
2295
+ const isNumber = (value) => !!value && !Number.isNaN(Number(value));
2296
+ const isInteger = (value) => !!value && Number.isInteger(Number(value));
2297
+ const isPercent = (value) => value.endsWith("%") && isNumber(value.slice(0, -1));
2298
+ const isTshirtSize = (value) => tshirtUnitRegex.test(value);
2299
+ const isAny = () => true;
2300
+ const isLengthOnly = (value) => (
2301
+ // `colorFunctionRegex` check is necessary because color functions can have percentages in them which which would be incorrectly classified as lengths.
2302
+ // For example, `hsl(0 0% 0%)` would be classified as a length without this check.
2303
+ // I could also use lookbehind assertion in `lengthUnitRegex` but that isn't supported widely enough.
2304
+ lengthUnitRegex.test(value) && !colorFunctionRegex.test(value)
2305
+ );
2306
+ const isNever = () => false;
2307
+ const isShadow = (value) => shadowRegex.test(value);
2308
+ const isImage = (value) => imageRegex.test(value);
2309
+ const isAnyNonArbitrary = (value) => !isArbitraryValue(value) && !isArbitraryVariable(value);
2310
+ const isArbitrarySize = (value) => getIsArbitraryValue(value, isLabelSize, isNever);
2311
+ const isArbitraryValue = (value) => arbitraryValueRegex.test(value);
2312
+ const isArbitraryLength = (value) => getIsArbitraryValue(value, isLabelLength, isLengthOnly);
2313
+ const isArbitraryNumber = (value) => getIsArbitraryValue(value, isLabelNumber, isNumber);
2314
+ const isArbitraryPosition = (value) => getIsArbitraryValue(value, isLabelPosition, isNever);
2315
+ const isArbitraryImage = (value) => getIsArbitraryValue(value, isLabelImage, isImage);
2316
+ const isArbitraryShadow = (value) => getIsArbitraryValue(value, isLabelShadow, isShadow);
2317
+ const isArbitraryVariable = (value) => arbitraryVariableRegex.test(value);
2318
+ const isArbitraryVariableLength = (value) => getIsArbitraryVariable(value, isLabelLength);
2319
+ const isArbitraryVariableFamilyName = (value) => getIsArbitraryVariable(value, isLabelFamilyName);
2320
+ const isArbitraryVariablePosition = (value) => getIsArbitraryVariable(value, isLabelPosition);
2321
+ const isArbitraryVariableSize = (value) => getIsArbitraryVariable(value, isLabelSize);
2322
+ const isArbitraryVariableImage = (value) => getIsArbitraryVariable(value, isLabelImage);
2323
+ const isArbitraryVariableShadow = (value) => getIsArbitraryVariable(value, isLabelShadow, true);
2324
+ const getIsArbitraryValue = (value, testLabel, testValue) => {
2325
+ const result = arbitraryValueRegex.exec(value);
2326
+ if (result) {
2327
+ if (result[1]) {
2328
+ return testLabel(result[1]);
2329
+ }
2330
+ return testValue(result[2]);
2331
+ }
2332
+ return false;
2333
+ };
2334
+ const getIsArbitraryVariable = (value, testLabel, shouldMatchNoLabel = false) => {
2335
+ const result = arbitraryVariableRegex.exec(value);
2336
+ if (result) {
2337
+ if (result[1]) {
2338
+ return testLabel(result[1]);
2339
+ }
2340
+ return shouldMatchNoLabel;
2341
+ }
2342
+ return false;
2343
+ };
2344
+ const isLabelPosition = (label) => label === "position" || label === "percentage";
2345
+ const isLabelImage = (label) => label === "image" || label === "url";
2346
+ const isLabelSize = (label) => label === "length" || label === "size" || label === "bg-size";
2347
+ const isLabelLength = (label) => label === "length";
2348
+ const isLabelNumber = (label) => label === "number";
2349
+ const isLabelFamilyName = (label) => label === "family-name";
2350
+ const isLabelShadow = (label) => label === "shadow";
2351
+ const getDefaultConfig = () => {
2352
+ const themeColor = fromTheme("color");
2353
+ const themeFont = fromTheme("font");
2354
+ const themeText = fromTheme("text");
2355
+ const themeFontWeight = fromTheme("font-weight");
2356
+ const themeTracking = fromTheme("tracking");
2357
+ const themeLeading = fromTheme("leading");
2358
+ const themeBreakpoint = fromTheme("breakpoint");
2359
+ const themeContainer = fromTheme("container");
2360
+ const themeSpacing = fromTheme("spacing");
2361
+ const themeRadius = fromTheme("radius");
2362
+ const themeShadow = fromTheme("shadow");
2363
+ const themeInsetShadow = fromTheme("inset-shadow");
2364
+ const themeTextShadow = fromTheme("text-shadow");
2365
+ const themeDropShadow = fromTheme("drop-shadow");
2366
+ const themeBlur = fromTheme("blur");
2367
+ const themePerspective = fromTheme("perspective");
2368
+ const themeAspect = fromTheme("aspect");
2369
+ const themeEase = fromTheme("ease");
2370
+ const themeAnimate = fromTheme("animate");
2371
+ const scaleBreak = () => ["auto", "avoid", "all", "avoid-page", "page", "left", "right", "column"];
2372
+ const scalePosition = () => [
2373
+ "center",
2374
+ "top",
2375
+ "bottom",
2376
+ "left",
2377
+ "right",
2378
+ "top-left",
2379
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
2380
+ "left-top",
2381
+ "top-right",
2382
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
2383
+ "right-top",
2384
+ "bottom-right",
2385
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
2386
+ "right-bottom",
2387
+ "bottom-left",
2388
+ // Deprecated since Tailwind CSS v4.1.0, see https://github.com/tailwindlabs/tailwindcss/pull/17378
2389
+ "left-bottom"
2390
+ ];
2391
+ const scalePositionWithArbitrary = () => [...scalePosition(), isArbitraryVariable, isArbitraryValue];
2392
+ const scaleOverflow = () => ["auto", "hidden", "clip", "visible", "scroll"];
2393
+ const scaleOverscroll = () => ["auto", "contain", "none"];
2394
+ const scaleUnambiguousSpacing = () => [isArbitraryVariable, isArbitraryValue, themeSpacing];
2395
+ const scaleInset = () => [isFraction, "full", "auto", ...scaleUnambiguousSpacing()];
2396
+ const scaleGridTemplateColsRows = () => [isInteger, "none", "subgrid", isArbitraryVariable, isArbitraryValue];
2397
+ const scaleGridColRowStartAndEnd = () => ["auto", {
2398
+ span: ["full", isInteger, isArbitraryVariable, isArbitraryValue]
2399
+ }, isInteger, isArbitraryVariable, isArbitraryValue];
2400
+ const scaleGridColRowStartOrEnd = () => [isInteger, "auto", isArbitraryVariable, isArbitraryValue];
2401
+ const scaleGridAutoColsRows = () => ["auto", "min", "max", "fr", isArbitraryVariable, isArbitraryValue];
2402
+ const scaleAlignPrimaryAxis = () => ["start", "end", "center", "between", "around", "evenly", "stretch", "baseline", "center-safe", "end-safe"];
2403
+ const scaleAlignSecondaryAxis = () => ["start", "end", "center", "stretch", "center-safe", "end-safe"];
2404
+ const scaleMargin = () => ["auto", ...scaleUnambiguousSpacing()];
2405
+ const scaleSizing = () => [isFraction, "auto", "full", "dvw", "dvh", "lvw", "lvh", "svw", "svh", "min", "max", "fit", ...scaleUnambiguousSpacing()];
2406
+ const scaleColor = () => [themeColor, isArbitraryVariable, isArbitraryValue];
2407
+ const scaleBgPosition = () => [...scalePosition(), isArbitraryVariablePosition, isArbitraryPosition, {
2408
+ position: [isArbitraryVariable, isArbitraryValue]
2409
+ }];
2410
+ const scaleBgRepeat = () => ["no-repeat", {
2411
+ repeat: ["", "x", "y", "space", "round"]
2412
+ }];
2413
+ const scaleBgSize = () => ["auto", "cover", "contain", isArbitraryVariableSize, isArbitrarySize, {
2414
+ size: [isArbitraryVariable, isArbitraryValue]
2415
+ }];
2416
+ const scaleGradientStopPosition = () => [isPercent, isArbitraryVariableLength, isArbitraryLength];
2417
+ const scaleRadius = () => [
2418
+ // Deprecated since Tailwind CSS v4.0.0
2419
+ "",
2420
+ "none",
2421
+ "full",
2422
+ themeRadius,
2423
+ isArbitraryVariable,
2424
+ isArbitraryValue
2425
+ ];
2426
+ const scaleBorderWidth = () => ["", isNumber, isArbitraryVariableLength, isArbitraryLength];
2427
+ const scaleLineStyle = () => ["solid", "dashed", "dotted", "double"];
2428
+ const scaleBlendMode = () => ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "hue", "saturation", "color", "luminosity"];
2429
+ const scaleMaskImagePosition = () => [isNumber, isPercent, isArbitraryVariablePosition, isArbitraryPosition];
2430
+ const scaleBlur = () => [
2431
+ // Deprecated since Tailwind CSS v4.0.0
2432
+ "",
2433
+ "none",
2434
+ themeBlur,
2435
+ isArbitraryVariable,
2436
+ isArbitraryValue
2437
+ ];
2438
+ const scaleRotate = () => ["none", isNumber, isArbitraryVariable, isArbitraryValue];
2439
+ const scaleScale = () => ["none", isNumber, isArbitraryVariable, isArbitraryValue];
2440
+ const scaleSkew = () => [isNumber, isArbitraryVariable, isArbitraryValue];
2441
+ const scaleTranslate = () => [isFraction, "full", ...scaleUnambiguousSpacing()];
2442
+ return {
2443
+ cacheSize: 500,
2444
+ theme: {
2445
+ animate: ["spin", "ping", "pulse", "bounce"],
2446
+ aspect: ["video"],
2447
+ blur: [isTshirtSize],
2448
+ breakpoint: [isTshirtSize],
2449
+ color: [isAny],
2450
+ container: [isTshirtSize],
2451
+ "drop-shadow": [isTshirtSize],
2452
+ ease: ["in", "out", "in-out"],
2453
+ font: [isAnyNonArbitrary],
2454
+ "font-weight": ["thin", "extralight", "light", "normal", "medium", "semibold", "bold", "extrabold", "black"],
2455
+ "inset-shadow": [isTshirtSize],
2456
+ leading: ["none", "tight", "snug", "normal", "relaxed", "loose"],
2457
+ perspective: ["dramatic", "near", "normal", "midrange", "distant", "none"],
2458
+ radius: [isTshirtSize],
2459
+ shadow: [isTshirtSize],
2460
+ spacing: ["px", isNumber],
2461
+ text: [isTshirtSize],
2462
+ "text-shadow": [isTshirtSize],
2463
+ tracking: ["tighter", "tight", "normal", "wide", "wider", "widest"]
2464
+ },
2465
+ classGroups: {
2466
+ // --------------
2467
+ // --- Layout ---
2468
+ // --------------
2469
+ /**
2470
+ * Aspect Ratio
2471
+ * @see https://tailwindcss.com/docs/aspect-ratio
2472
+ */
2473
+ aspect: [{
2474
+ aspect: ["auto", "square", isFraction, isArbitraryValue, isArbitraryVariable, themeAspect]
2475
+ }],
2476
+ /**
2477
+ * Container
2478
+ * @see https://tailwindcss.com/docs/container
2479
+ * @deprecated since Tailwind CSS v4.0.0
2480
+ */
2481
+ container: ["container"],
2482
+ /**
2483
+ * Columns
2484
+ * @see https://tailwindcss.com/docs/columns
2485
+ */
2486
+ columns: [{
2487
+ columns: [isNumber, isArbitraryValue, isArbitraryVariable, themeContainer]
2488
+ }],
2489
+ /**
2490
+ * Break After
2491
+ * @see https://tailwindcss.com/docs/break-after
2492
+ */
2493
+ "break-after": [{
2494
+ "break-after": scaleBreak()
2495
+ }],
2496
+ /**
2497
+ * Break Before
2498
+ * @see https://tailwindcss.com/docs/break-before
2499
+ */
2500
+ "break-before": [{
2501
+ "break-before": scaleBreak()
2502
+ }],
2503
+ /**
2504
+ * Break Inside
2505
+ * @see https://tailwindcss.com/docs/break-inside
2506
+ */
2507
+ "break-inside": [{
2508
+ "break-inside": ["auto", "avoid", "avoid-page", "avoid-column"]
2509
+ }],
2510
+ /**
2511
+ * Box Decoration Break
2512
+ * @see https://tailwindcss.com/docs/box-decoration-break
2513
+ */
2514
+ "box-decoration": [{
2515
+ "box-decoration": ["slice", "clone"]
2516
+ }],
2517
+ /**
2518
+ * Box Sizing
2519
+ * @see https://tailwindcss.com/docs/box-sizing
2520
+ */
2521
+ box: [{
2522
+ box: ["border", "content"]
2523
+ }],
2524
+ /**
2525
+ * Display
2526
+ * @see https://tailwindcss.com/docs/display
2527
+ */
2528
+ display: ["block", "inline-block", "inline", "flex", "inline-flex", "table", "inline-table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group", "table-row-group", "table-row", "flow-root", "grid", "inline-grid", "contents", "list-item", "hidden"],
2529
+ /**
2530
+ * Screen Reader Only
2531
+ * @see https://tailwindcss.com/docs/display#screen-reader-only
2532
+ */
2533
+ sr: ["sr-only", "not-sr-only"],
2534
+ /**
2535
+ * Floats
2536
+ * @see https://tailwindcss.com/docs/float
2537
+ */
2538
+ float: [{
2539
+ float: ["right", "left", "none", "start", "end"]
2540
+ }],
2541
+ /**
2542
+ * Clear
2543
+ * @see https://tailwindcss.com/docs/clear
2544
+ */
2545
+ clear: [{
2546
+ clear: ["left", "right", "both", "none", "start", "end"]
2547
+ }],
2548
+ /**
2549
+ * Isolation
2550
+ * @see https://tailwindcss.com/docs/isolation
2551
+ */
2552
+ isolation: ["isolate", "isolation-auto"],
2553
+ /**
2554
+ * Object Fit
2555
+ * @see https://tailwindcss.com/docs/object-fit
2556
+ */
2557
+ "object-fit": [{
2558
+ object: ["contain", "cover", "fill", "none", "scale-down"]
2559
+ }],
2560
+ /**
2561
+ * Object Position
2562
+ * @see https://tailwindcss.com/docs/object-position
2563
+ */
2564
+ "object-position": [{
2565
+ object: scalePositionWithArbitrary()
2566
+ }],
2567
+ /**
2568
+ * Overflow
2569
+ * @see https://tailwindcss.com/docs/overflow
2570
+ */
2571
+ overflow: [{
2572
+ overflow: scaleOverflow()
2573
+ }],
2574
+ /**
2575
+ * Overflow X
2576
+ * @see https://tailwindcss.com/docs/overflow
2577
+ */
2578
+ "overflow-x": [{
2579
+ "overflow-x": scaleOverflow()
2580
+ }],
2581
+ /**
2582
+ * Overflow Y
2583
+ * @see https://tailwindcss.com/docs/overflow
2584
+ */
2585
+ "overflow-y": [{
2586
+ "overflow-y": scaleOverflow()
2587
+ }],
2588
+ /**
2589
+ * Overscroll Behavior
2590
+ * @see https://tailwindcss.com/docs/overscroll-behavior
2591
+ */
2592
+ overscroll: [{
2593
+ overscroll: scaleOverscroll()
2594
+ }],
2595
+ /**
2596
+ * Overscroll Behavior X
2597
+ * @see https://tailwindcss.com/docs/overscroll-behavior
2598
+ */
2599
+ "overscroll-x": [{
2600
+ "overscroll-x": scaleOverscroll()
2601
+ }],
2602
+ /**
2603
+ * Overscroll Behavior Y
2604
+ * @see https://tailwindcss.com/docs/overscroll-behavior
2605
+ */
2606
+ "overscroll-y": [{
2607
+ "overscroll-y": scaleOverscroll()
2608
+ }],
2609
+ /**
2610
+ * Position
2611
+ * @see https://tailwindcss.com/docs/position
2612
+ */
2613
+ position: ["static", "fixed", "absolute", "relative", "sticky"],
2614
+ /**
2615
+ * Top / Right / Bottom / Left
2616
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2617
+ */
2618
+ inset: [{
2619
+ inset: scaleInset()
2620
+ }],
2621
+ /**
2622
+ * Right / Left
2623
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2624
+ */
2625
+ "inset-x": [{
2626
+ "inset-x": scaleInset()
2627
+ }],
2628
+ /**
2629
+ * Top / Bottom
2630
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2631
+ */
2632
+ "inset-y": [{
2633
+ "inset-y": scaleInset()
2634
+ }],
2635
+ /**
2636
+ * Start
2637
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2638
+ */
2639
+ start: [{
2640
+ start: scaleInset()
2641
+ }],
2642
+ /**
2643
+ * End
2644
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2645
+ */
2646
+ end: [{
2647
+ end: scaleInset()
2648
+ }],
2649
+ /**
2650
+ * Top
2651
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2652
+ */
2653
+ top: [{
2654
+ top: scaleInset()
2655
+ }],
2656
+ /**
2657
+ * Right
2658
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2659
+ */
2660
+ right: [{
2661
+ right: scaleInset()
2662
+ }],
2663
+ /**
2664
+ * Bottom
2665
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2666
+ */
2667
+ bottom: [{
2668
+ bottom: scaleInset()
2669
+ }],
2670
+ /**
2671
+ * Left
2672
+ * @see https://tailwindcss.com/docs/top-right-bottom-left
2673
+ */
2674
+ left: [{
2675
+ left: scaleInset()
2676
+ }],
2677
+ /**
2678
+ * Visibility
2679
+ * @see https://tailwindcss.com/docs/visibility
2680
+ */
2681
+ visibility: ["visible", "invisible", "collapse"],
2682
+ /**
2683
+ * Z-Index
2684
+ * @see https://tailwindcss.com/docs/z-index
2685
+ */
2686
+ z: [{
2687
+ z: [isInteger, "auto", isArbitraryVariable, isArbitraryValue]
2688
+ }],
2689
+ // ------------------------
2690
+ // --- Flexbox and Grid ---
2691
+ // ------------------------
2692
+ /**
2693
+ * Flex Basis
2694
+ * @see https://tailwindcss.com/docs/flex-basis
2695
+ */
2696
+ basis: [{
2697
+ basis: [isFraction, "full", "auto", themeContainer, ...scaleUnambiguousSpacing()]
2698
+ }],
2699
+ /**
2700
+ * Flex Direction
2701
+ * @see https://tailwindcss.com/docs/flex-direction
2702
+ */
2703
+ "flex-direction": [{
2704
+ flex: ["row", "row-reverse", "col", "col-reverse"]
2705
+ }],
2706
+ /**
2707
+ * Flex Wrap
2708
+ * @see https://tailwindcss.com/docs/flex-wrap
2709
+ */
2710
+ "flex-wrap": [{
2711
+ flex: ["nowrap", "wrap", "wrap-reverse"]
2712
+ }],
2713
+ /**
2714
+ * Flex
2715
+ * @see https://tailwindcss.com/docs/flex
2716
+ */
2717
+ flex: [{
2718
+ flex: [isNumber, isFraction, "auto", "initial", "none", isArbitraryValue]
2719
+ }],
2720
+ /**
2721
+ * Flex Grow
2722
+ * @see https://tailwindcss.com/docs/flex-grow
2723
+ */
2724
+ grow: [{
2725
+ grow: ["", isNumber, isArbitraryVariable, isArbitraryValue]
2726
+ }],
2727
+ /**
2728
+ * Flex Shrink
2729
+ * @see https://tailwindcss.com/docs/flex-shrink
2730
+ */
2731
+ shrink: [{
2732
+ shrink: ["", isNumber, isArbitraryVariable, isArbitraryValue]
2733
+ }],
2734
+ /**
2735
+ * Order
2736
+ * @see https://tailwindcss.com/docs/order
2737
+ */
2738
+ order: [{
2739
+ order: [isInteger, "first", "last", "none", isArbitraryVariable, isArbitraryValue]
2740
+ }],
2741
+ /**
2742
+ * Grid Template Columns
2743
+ * @see https://tailwindcss.com/docs/grid-template-columns
2744
+ */
2745
+ "grid-cols": [{
2746
+ "grid-cols": scaleGridTemplateColsRows()
2747
+ }],
2748
+ /**
2749
+ * Grid Column Start / End
2750
+ * @see https://tailwindcss.com/docs/grid-column
2751
+ */
2752
+ "col-start-end": [{
2753
+ col: scaleGridColRowStartAndEnd()
2754
+ }],
2755
+ /**
2756
+ * Grid Column Start
2757
+ * @see https://tailwindcss.com/docs/grid-column
2758
+ */
2759
+ "col-start": [{
2760
+ "col-start": scaleGridColRowStartOrEnd()
2761
+ }],
2762
+ /**
2763
+ * Grid Column End
2764
+ * @see https://tailwindcss.com/docs/grid-column
2765
+ */
2766
+ "col-end": [{
2767
+ "col-end": scaleGridColRowStartOrEnd()
2768
+ }],
2769
+ /**
2770
+ * Grid Template Rows
2771
+ * @see https://tailwindcss.com/docs/grid-template-rows
2772
+ */
2773
+ "grid-rows": [{
2774
+ "grid-rows": scaleGridTemplateColsRows()
2775
+ }],
2776
+ /**
2777
+ * Grid Row Start / End
2778
+ * @see https://tailwindcss.com/docs/grid-row
2779
+ */
2780
+ "row-start-end": [{
2781
+ row: scaleGridColRowStartAndEnd()
2782
+ }],
2783
+ /**
2784
+ * Grid Row Start
2785
+ * @see https://tailwindcss.com/docs/grid-row
2786
+ */
2787
+ "row-start": [{
2788
+ "row-start": scaleGridColRowStartOrEnd()
2789
+ }],
2790
+ /**
2791
+ * Grid Row End
2792
+ * @see https://tailwindcss.com/docs/grid-row
2793
+ */
2794
+ "row-end": [{
2795
+ "row-end": scaleGridColRowStartOrEnd()
2796
+ }],
2797
+ /**
2798
+ * Grid Auto Flow
2799
+ * @see https://tailwindcss.com/docs/grid-auto-flow
2800
+ */
2801
+ "grid-flow": [{
2802
+ "grid-flow": ["row", "col", "dense", "row-dense", "col-dense"]
2803
+ }],
2804
+ /**
2805
+ * Grid Auto Columns
2806
+ * @see https://tailwindcss.com/docs/grid-auto-columns
2807
+ */
2808
+ "auto-cols": [{
2809
+ "auto-cols": scaleGridAutoColsRows()
2810
+ }],
2811
+ /**
2812
+ * Grid Auto Rows
2813
+ * @see https://tailwindcss.com/docs/grid-auto-rows
2814
+ */
2815
+ "auto-rows": [{
2816
+ "auto-rows": scaleGridAutoColsRows()
2817
+ }],
2818
+ /**
2819
+ * Gap
2820
+ * @see https://tailwindcss.com/docs/gap
2821
+ */
2822
+ gap: [{
2823
+ gap: scaleUnambiguousSpacing()
2824
+ }],
2825
+ /**
2826
+ * Gap X
2827
+ * @see https://tailwindcss.com/docs/gap
2828
+ */
2829
+ "gap-x": [{
2830
+ "gap-x": scaleUnambiguousSpacing()
2831
+ }],
2832
+ /**
2833
+ * Gap Y
2834
+ * @see https://tailwindcss.com/docs/gap
2835
+ */
2836
+ "gap-y": [{
2837
+ "gap-y": scaleUnambiguousSpacing()
2838
+ }],
2839
+ /**
2840
+ * Justify Content
2841
+ * @see https://tailwindcss.com/docs/justify-content
2842
+ */
2843
+ "justify-content": [{
2844
+ justify: [...scaleAlignPrimaryAxis(), "normal"]
2845
+ }],
2846
+ /**
2847
+ * Justify Items
2848
+ * @see https://tailwindcss.com/docs/justify-items
2849
+ */
2850
+ "justify-items": [{
2851
+ "justify-items": [...scaleAlignSecondaryAxis(), "normal"]
2852
+ }],
2853
+ /**
2854
+ * Justify Self
2855
+ * @see https://tailwindcss.com/docs/justify-self
2856
+ */
2857
+ "justify-self": [{
2858
+ "justify-self": ["auto", ...scaleAlignSecondaryAxis()]
2859
+ }],
2860
+ /**
2861
+ * Align Content
2862
+ * @see https://tailwindcss.com/docs/align-content
2863
+ */
2864
+ "align-content": [{
2865
+ content: ["normal", ...scaleAlignPrimaryAxis()]
2866
+ }],
2867
+ /**
2868
+ * Align Items
2869
+ * @see https://tailwindcss.com/docs/align-items
2870
+ */
2871
+ "align-items": [{
2872
+ items: [...scaleAlignSecondaryAxis(), {
2873
+ baseline: ["", "last"]
2874
+ }]
2875
+ }],
2876
+ /**
2877
+ * Align Self
2878
+ * @see https://tailwindcss.com/docs/align-self
2879
+ */
2880
+ "align-self": [{
2881
+ self: ["auto", ...scaleAlignSecondaryAxis(), {
2882
+ baseline: ["", "last"]
2883
+ }]
2884
+ }],
2885
+ /**
2886
+ * Place Content
2887
+ * @see https://tailwindcss.com/docs/place-content
2888
+ */
2889
+ "place-content": [{
2890
+ "place-content": scaleAlignPrimaryAxis()
2891
+ }],
2892
+ /**
2893
+ * Place Items
2894
+ * @see https://tailwindcss.com/docs/place-items
2895
+ */
2896
+ "place-items": [{
2897
+ "place-items": [...scaleAlignSecondaryAxis(), "baseline"]
2898
+ }],
2899
+ /**
2900
+ * Place Self
2901
+ * @see https://tailwindcss.com/docs/place-self
2902
+ */
2903
+ "place-self": [{
2904
+ "place-self": ["auto", ...scaleAlignSecondaryAxis()]
2905
+ }],
2906
+ // Spacing
2907
+ /**
2908
+ * Padding
2909
+ * @see https://tailwindcss.com/docs/padding
2910
+ */
2911
+ p: [{
2912
+ p: scaleUnambiguousSpacing()
2913
+ }],
2914
+ /**
2915
+ * Padding X
2916
+ * @see https://tailwindcss.com/docs/padding
2917
+ */
2918
+ px: [{
2919
+ px: scaleUnambiguousSpacing()
2920
+ }],
2921
+ /**
2922
+ * Padding Y
2923
+ * @see https://tailwindcss.com/docs/padding
2924
+ */
2925
+ py: [{
2926
+ py: scaleUnambiguousSpacing()
2927
+ }],
2928
+ /**
2929
+ * Padding Start
2930
+ * @see https://tailwindcss.com/docs/padding
2931
+ */
2932
+ ps: [{
2933
+ ps: scaleUnambiguousSpacing()
2934
+ }],
2935
+ /**
2936
+ * Padding End
2937
+ * @see https://tailwindcss.com/docs/padding
2938
+ */
2939
+ pe: [{
2940
+ pe: scaleUnambiguousSpacing()
2941
+ }],
2942
+ /**
2943
+ * Padding Top
2944
+ * @see https://tailwindcss.com/docs/padding
2945
+ */
2946
+ pt: [{
2947
+ pt: scaleUnambiguousSpacing()
2948
+ }],
2949
+ /**
2950
+ * Padding Right
2951
+ * @see https://tailwindcss.com/docs/padding
2952
+ */
2953
+ pr: [{
2954
+ pr: scaleUnambiguousSpacing()
2955
+ }],
2956
+ /**
2957
+ * Padding Bottom
2958
+ * @see https://tailwindcss.com/docs/padding
2959
+ */
2960
+ pb: [{
2961
+ pb: scaleUnambiguousSpacing()
2962
+ }],
2963
+ /**
2964
+ * Padding Left
2965
+ * @see https://tailwindcss.com/docs/padding
2966
+ */
2967
+ pl: [{
2968
+ pl: scaleUnambiguousSpacing()
2969
+ }],
2970
+ /**
2971
+ * Margin
2972
+ * @see https://tailwindcss.com/docs/margin
2973
+ */
2974
+ m: [{
2975
+ m: scaleMargin()
2976
+ }],
2977
+ /**
2978
+ * Margin X
2979
+ * @see https://tailwindcss.com/docs/margin
2980
+ */
2981
+ mx: [{
2982
+ mx: scaleMargin()
2983
+ }],
2984
+ /**
2985
+ * Margin Y
2986
+ * @see https://tailwindcss.com/docs/margin
2987
+ */
2988
+ my: [{
2989
+ my: scaleMargin()
2990
+ }],
2991
+ /**
2992
+ * Margin Start
2993
+ * @see https://tailwindcss.com/docs/margin
2994
+ */
2995
+ ms: [{
2996
+ ms: scaleMargin()
2997
+ }],
2998
+ /**
2999
+ * Margin End
3000
+ * @see https://tailwindcss.com/docs/margin
3001
+ */
3002
+ me: [{
3003
+ me: scaleMargin()
3004
+ }],
3005
+ /**
3006
+ * Margin Top
3007
+ * @see https://tailwindcss.com/docs/margin
3008
+ */
3009
+ mt: [{
3010
+ mt: scaleMargin()
3011
+ }],
3012
+ /**
3013
+ * Margin Right
3014
+ * @see https://tailwindcss.com/docs/margin
3015
+ */
3016
+ mr: [{
3017
+ mr: scaleMargin()
3018
+ }],
3019
+ /**
3020
+ * Margin Bottom
3021
+ * @see https://tailwindcss.com/docs/margin
3022
+ */
3023
+ mb: [{
3024
+ mb: scaleMargin()
3025
+ }],
3026
+ /**
3027
+ * Margin Left
3028
+ * @see https://tailwindcss.com/docs/margin
3029
+ */
3030
+ ml: [{
3031
+ ml: scaleMargin()
3032
+ }],
3033
+ /**
3034
+ * Space Between X
3035
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
3036
+ */
3037
+ "space-x": [{
3038
+ "space-x": scaleUnambiguousSpacing()
3039
+ }],
3040
+ /**
3041
+ * Space Between X Reverse
3042
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
3043
+ */
3044
+ "space-x-reverse": ["space-x-reverse"],
3045
+ /**
3046
+ * Space Between Y
3047
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
3048
+ */
3049
+ "space-y": [{
3050
+ "space-y": scaleUnambiguousSpacing()
3051
+ }],
3052
+ /**
3053
+ * Space Between Y Reverse
3054
+ * @see https://tailwindcss.com/docs/margin#adding-space-between-children
3055
+ */
3056
+ "space-y-reverse": ["space-y-reverse"],
3057
+ // --------------
3058
+ // --- Sizing ---
3059
+ // --------------
3060
+ /**
3061
+ * Size
3062
+ * @see https://tailwindcss.com/docs/width#setting-both-width-and-height
3063
+ */
3064
+ size: [{
3065
+ size: scaleSizing()
3066
+ }],
3067
+ /**
3068
+ * Width
3069
+ * @see https://tailwindcss.com/docs/width
3070
+ */
3071
+ w: [{
3072
+ w: [themeContainer, "screen", ...scaleSizing()]
3073
+ }],
3074
+ /**
3075
+ * Min-Width
3076
+ * @see https://tailwindcss.com/docs/min-width
3077
+ */
3078
+ "min-w": [{
3079
+ "min-w": [
3080
+ themeContainer,
3081
+ "screen",
3082
+ /** Deprecated. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
3083
+ "none",
3084
+ ...scaleSizing()
3085
+ ]
3086
+ }],
3087
+ /**
3088
+ * Max-Width
3089
+ * @see https://tailwindcss.com/docs/max-width
3090
+ */
3091
+ "max-w": [{
3092
+ "max-w": [
3093
+ themeContainer,
3094
+ "screen",
3095
+ "none",
3096
+ /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
3097
+ "prose",
3098
+ /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
3099
+ {
3100
+ screen: [themeBreakpoint]
3101
+ },
3102
+ ...scaleSizing()
3103
+ ]
3104
+ }],
3105
+ /**
3106
+ * Height
3107
+ * @see https://tailwindcss.com/docs/height
3108
+ */
3109
+ h: [{
3110
+ h: ["screen", "lh", ...scaleSizing()]
3111
+ }],
3112
+ /**
3113
+ * Min-Height
3114
+ * @see https://tailwindcss.com/docs/min-height
3115
+ */
3116
+ "min-h": [{
3117
+ "min-h": ["screen", "lh", "none", ...scaleSizing()]
3118
+ }],
3119
+ /**
3120
+ * Max-Height
3121
+ * @see https://tailwindcss.com/docs/max-height
3122
+ */
3123
+ "max-h": [{
3124
+ "max-h": ["screen", "lh", ...scaleSizing()]
3125
+ }],
3126
+ // ------------------
3127
+ // --- Typography ---
3128
+ // ------------------
3129
+ /**
3130
+ * Font Size
3131
+ * @see https://tailwindcss.com/docs/font-size
3132
+ */
3133
+ "font-size": [{
3134
+ text: ["base", themeText, isArbitraryVariableLength, isArbitraryLength]
3135
+ }],
3136
+ /**
3137
+ * Font Smoothing
3138
+ * @see https://tailwindcss.com/docs/font-smoothing
3139
+ */
3140
+ "font-smoothing": ["antialiased", "subpixel-antialiased"],
3141
+ /**
3142
+ * Font Style
3143
+ * @see https://tailwindcss.com/docs/font-style
3144
+ */
3145
+ "font-style": ["italic", "not-italic"],
3146
+ /**
3147
+ * Font Weight
3148
+ * @see https://tailwindcss.com/docs/font-weight
3149
+ */
3150
+ "font-weight": [{
3151
+ font: [themeFontWeight, isArbitraryVariable, isArbitraryNumber]
3152
+ }],
3153
+ /**
3154
+ * Font Stretch
3155
+ * @see https://tailwindcss.com/docs/font-stretch
3156
+ */
3157
+ "font-stretch": [{
3158
+ "font-stretch": ["ultra-condensed", "extra-condensed", "condensed", "semi-condensed", "normal", "semi-expanded", "expanded", "extra-expanded", "ultra-expanded", isPercent, isArbitraryValue]
3159
+ }],
3160
+ /**
3161
+ * Font Family
3162
+ * @see https://tailwindcss.com/docs/font-family
3163
+ */
3164
+ "font-family": [{
3165
+ font: [isArbitraryVariableFamilyName, isArbitraryValue, themeFont]
3166
+ }],
3167
+ /**
3168
+ * Font Variant Numeric
3169
+ * @see https://tailwindcss.com/docs/font-variant-numeric
3170
+ */
3171
+ "fvn-normal": ["normal-nums"],
3172
+ /**
3173
+ * Font Variant Numeric
3174
+ * @see https://tailwindcss.com/docs/font-variant-numeric
3175
+ */
3176
+ "fvn-ordinal": ["ordinal"],
3177
+ /**
3178
+ * Font Variant Numeric
3179
+ * @see https://tailwindcss.com/docs/font-variant-numeric
3180
+ */
3181
+ "fvn-slashed-zero": ["slashed-zero"],
3182
+ /**
3183
+ * Font Variant Numeric
3184
+ * @see https://tailwindcss.com/docs/font-variant-numeric
3185
+ */
3186
+ "fvn-figure": ["lining-nums", "oldstyle-nums"],
3187
+ /**
3188
+ * Font Variant Numeric
3189
+ * @see https://tailwindcss.com/docs/font-variant-numeric
3190
+ */
3191
+ "fvn-spacing": ["proportional-nums", "tabular-nums"],
3192
+ /**
3193
+ * Font Variant Numeric
3194
+ * @see https://tailwindcss.com/docs/font-variant-numeric
3195
+ */
3196
+ "fvn-fraction": ["diagonal-fractions", "stacked-fractions"],
3197
+ /**
3198
+ * Letter Spacing
3199
+ * @see https://tailwindcss.com/docs/letter-spacing
3200
+ */
3201
+ tracking: [{
3202
+ tracking: [themeTracking, isArbitraryVariable, isArbitraryValue]
3203
+ }],
3204
+ /**
3205
+ * Line Clamp
3206
+ * @see https://tailwindcss.com/docs/line-clamp
3207
+ */
3208
+ "line-clamp": [{
3209
+ "line-clamp": [isNumber, "none", isArbitraryVariable, isArbitraryNumber]
3210
+ }],
3211
+ /**
3212
+ * Line Height
3213
+ * @see https://tailwindcss.com/docs/line-height
3214
+ */
3215
+ leading: [{
3216
+ leading: [
3217
+ /** Deprecated since Tailwind CSS v4.0.0. @see https://github.com/tailwindlabs/tailwindcss.com/issues/2027#issuecomment-2620152757 */
3218
+ themeLeading,
3219
+ ...scaleUnambiguousSpacing()
3220
+ ]
3221
+ }],
3222
+ /**
3223
+ * List Style Image
3224
+ * @see https://tailwindcss.com/docs/list-style-image
3225
+ */
3226
+ "list-image": [{
3227
+ "list-image": ["none", isArbitraryVariable, isArbitraryValue]
3228
+ }],
3229
+ /**
3230
+ * List Style Position
3231
+ * @see https://tailwindcss.com/docs/list-style-position
3232
+ */
3233
+ "list-style-position": [{
3234
+ list: ["inside", "outside"]
3235
+ }],
3236
+ /**
3237
+ * List Style Type
3238
+ * @see https://tailwindcss.com/docs/list-style-type
3239
+ */
3240
+ "list-style-type": [{
3241
+ list: ["disc", "decimal", "none", isArbitraryVariable, isArbitraryValue]
3242
+ }],
3243
+ /**
3244
+ * Text Alignment
3245
+ * @see https://tailwindcss.com/docs/text-align
3246
+ */
3247
+ "text-alignment": [{
3248
+ text: ["left", "center", "right", "justify", "start", "end"]
3249
+ }],
3250
+ /**
3251
+ * Placeholder Color
3252
+ * @deprecated since Tailwind CSS v3.0.0
3253
+ * @see https://v3.tailwindcss.com/docs/placeholder-color
3254
+ */
3255
+ "placeholder-color": [{
3256
+ placeholder: scaleColor()
3257
+ }],
3258
+ /**
3259
+ * Text Color
3260
+ * @see https://tailwindcss.com/docs/text-color
3261
+ */
3262
+ "text-color": [{
3263
+ text: scaleColor()
3264
+ }],
3265
+ /**
3266
+ * Text Decoration
3267
+ * @see https://tailwindcss.com/docs/text-decoration
3268
+ */
3269
+ "text-decoration": ["underline", "overline", "line-through", "no-underline"],
3270
+ /**
3271
+ * Text Decoration Style
3272
+ * @see https://tailwindcss.com/docs/text-decoration-style
3273
+ */
3274
+ "text-decoration-style": [{
3275
+ decoration: [...scaleLineStyle(), "wavy"]
3276
+ }],
3277
+ /**
3278
+ * Text Decoration Thickness
3279
+ * @see https://tailwindcss.com/docs/text-decoration-thickness
3280
+ */
3281
+ "text-decoration-thickness": [{
3282
+ decoration: [isNumber, "from-font", "auto", isArbitraryVariable, isArbitraryLength]
3283
+ }],
3284
+ /**
3285
+ * Text Decoration Color
3286
+ * @see https://tailwindcss.com/docs/text-decoration-color
3287
+ */
3288
+ "text-decoration-color": [{
3289
+ decoration: scaleColor()
3290
+ }],
3291
+ /**
3292
+ * Text Underline Offset
3293
+ * @see https://tailwindcss.com/docs/text-underline-offset
3294
+ */
3295
+ "underline-offset": [{
3296
+ "underline-offset": [isNumber, "auto", isArbitraryVariable, isArbitraryValue]
3297
+ }],
3298
+ /**
3299
+ * Text Transform
3300
+ * @see https://tailwindcss.com/docs/text-transform
3301
+ */
3302
+ "text-transform": ["uppercase", "lowercase", "capitalize", "normal-case"],
3303
+ /**
3304
+ * Text Overflow
3305
+ * @see https://tailwindcss.com/docs/text-overflow
3306
+ */
3307
+ "text-overflow": ["truncate", "text-ellipsis", "text-clip"],
3308
+ /**
3309
+ * Text Wrap
3310
+ * @see https://tailwindcss.com/docs/text-wrap
3311
+ */
3312
+ "text-wrap": [{
3313
+ text: ["wrap", "nowrap", "balance", "pretty"]
3314
+ }],
3315
+ /**
3316
+ * Text Indent
3317
+ * @see https://tailwindcss.com/docs/text-indent
3318
+ */
3319
+ indent: [{
3320
+ indent: scaleUnambiguousSpacing()
3321
+ }],
3322
+ /**
3323
+ * Vertical Alignment
3324
+ * @see https://tailwindcss.com/docs/vertical-align
3325
+ */
3326
+ "vertical-align": [{
3327
+ align: ["baseline", "top", "middle", "bottom", "text-top", "text-bottom", "sub", "super", isArbitraryVariable, isArbitraryValue]
3328
+ }],
3329
+ /**
3330
+ * Whitespace
3331
+ * @see https://tailwindcss.com/docs/whitespace
3332
+ */
3333
+ whitespace: [{
3334
+ whitespace: ["normal", "nowrap", "pre", "pre-line", "pre-wrap", "break-spaces"]
3335
+ }],
3336
+ /**
3337
+ * Word Break
3338
+ * @see https://tailwindcss.com/docs/word-break
3339
+ */
3340
+ break: [{
3341
+ break: ["normal", "words", "all", "keep"]
3342
+ }],
3343
+ /**
3344
+ * Overflow Wrap
3345
+ * @see https://tailwindcss.com/docs/overflow-wrap
3346
+ */
3347
+ wrap: [{
3348
+ wrap: ["break-word", "anywhere", "normal"]
3349
+ }],
3350
+ /**
3351
+ * Hyphens
3352
+ * @see https://tailwindcss.com/docs/hyphens
3353
+ */
3354
+ hyphens: [{
3355
+ hyphens: ["none", "manual", "auto"]
3356
+ }],
3357
+ /**
3358
+ * Content
3359
+ * @see https://tailwindcss.com/docs/content
3360
+ */
3361
+ content: [{
3362
+ content: ["none", isArbitraryVariable, isArbitraryValue]
3363
+ }],
3364
+ // -------------------
3365
+ // --- Backgrounds ---
3366
+ // -------------------
3367
+ /**
3368
+ * Background Attachment
3369
+ * @see https://tailwindcss.com/docs/background-attachment
3370
+ */
3371
+ "bg-attachment": [{
3372
+ bg: ["fixed", "local", "scroll"]
3373
+ }],
3374
+ /**
3375
+ * Background Clip
3376
+ * @see https://tailwindcss.com/docs/background-clip
3377
+ */
3378
+ "bg-clip": [{
3379
+ "bg-clip": ["border", "padding", "content", "text"]
3380
+ }],
3381
+ /**
3382
+ * Background Origin
3383
+ * @see https://tailwindcss.com/docs/background-origin
3384
+ */
3385
+ "bg-origin": [{
3386
+ "bg-origin": ["border", "padding", "content"]
3387
+ }],
3388
+ /**
3389
+ * Background Position
3390
+ * @see https://tailwindcss.com/docs/background-position
3391
+ */
3392
+ "bg-position": [{
3393
+ bg: scaleBgPosition()
3394
+ }],
3395
+ /**
3396
+ * Background Repeat
3397
+ * @see https://tailwindcss.com/docs/background-repeat
3398
+ */
3399
+ "bg-repeat": [{
3400
+ bg: scaleBgRepeat()
3401
+ }],
3402
+ /**
3403
+ * Background Size
3404
+ * @see https://tailwindcss.com/docs/background-size
3405
+ */
3406
+ "bg-size": [{
3407
+ bg: scaleBgSize()
3408
+ }],
3409
+ /**
3410
+ * Background Image
3411
+ * @see https://tailwindcss.com/docs/background-image
3412
+ */
3413
+ "bg-image": [{
3414
+ bg: ["none", {
3415
+ linear: [{
3416
+ to: ["t", "tr", "r", "br", "b", "bl", "l", "tl"]
3417
+ }, isInteger, isArbitraryVariable, isArbitraryValue],
3418
+ radial: ["", isArbitraryVariable, isArbitraryValue],
3419
+ conic: [isInteger, isArbitraryVariable, isArbitraryValue]
3420
+ }, isArbitraryVariableImage, isArbitraryImage]
3421
+ }],
3422
+ /**
3423
+ * Background Color
3424
+ * @see https://tailwindcss.com/docs/background-color
3425
+ */
3426
+ "bg-color": [{
3427
+ bg: scaleColor()
3428
+ }],
3429
+ /**
3430
+ * Gradient Color Stops From Position
3431
+ * @see https://tailwindcss.com/docs/gradient-color-stops
3432
+ */
3433
+ "gradient-from-pos": [{
3434
+ from: scaleGradientStopPosition()
3435
+ }],
3436
+ /**
3437
+ * Gradient Color Stops Via Position
3438
+ * @see https://tailwindcss.com/docs/gradient-color-stops
3439
+ */
3440
+ "gradient-via-pos": [{
3441
+ via: scaleGradientStopPosition()
3442
+ }],
3443
+ /**
3444
+ * Gradient Color Stops To Position
3445
+ * @see https://tailwindcss.com/docs/gradient-color-stops
3446
+ */
3447
+ "gradient-to-pos": [{
3448
+ to: scaleGradientStopPosition()
3449
+ }],
3450
+ /**
3451
+ * Gradient Color Stops From
3452
+ * @see https://tailwindcss.com/docs/gradient-color-stops
3453
+ */
3454
+ "gradient-from": [{
3455
+ from: scaleColor()
3456
+ }],
3457
+ /**
3458
+ * Gradient Color Stops Via
3459
+ * @see https://tailwindcss.com/docs/gradient-color-stops
3460
+ */
3461
+ "gradient-via": [{
3462
+ via: scaleColor()
3463
+ }],
3464
+ /**
3465
+ * Gradient Color Stops To
3466
+ * @see https://tailwindcss.com/docs/gradient-color-stops
3467
+ */
3468
+ "gradient-to": [{
3469
+ to: scaleColor()
3470
+ }],
3471
+ // ---------------
3472
+ // --- Borders ---
3473
+ // ---------------
3474
+ /**
3475
+ * Border Radius
3476
+ * @see https://tailwindcss.com/docs/border-radius
3477
+ */
3478
+ rounded: [{
3479
+ rounded: scaleRadius()
3480
+ }],
3481
+ /**
3482
+ * Border Radius Start
3483
+ * @see https://tailwindcss.com/docs/border-radius
3484
+ */
3485
+ "rounded-s": [{
3486
+ "rounded-s": scaleRadius()
3487
+ }],
3488
+ /**
3489
+ * Border Radius End
3490
+ * @see https://tailwindcss.com/docs/border-radius
3491
+ */
3492
+ "rounded-e": [{
3493
+ "rounded-e": scaleRadius()
3494
+ }],
3495
+ /**
3496
+ * Border Radius Top
3497
+ * @see https://tailwindcss.com/docs/border-radius
3498
+ */
3499
+ "rounded-t": [{
3500
+ "rounded-t": scaleRadius()
3501
+ }],
3502
+ /**
3503
+ * Border Radius Right
3504
+ * @see https://tailwindcss.com/docs/border-radius
3505
+ */
3506
+ "rounded-r": [{
3507
+ "rounded-r": scaleRadius()
3508
+ }],
3509
+ /**
3510
+ * Border Radius Bottom
3511
+ * @see https://tailwindcss.com/docs/border-radius
3512
+ */
3513
+ "rounded-b": [{
3514
+ "rounded-b": scaleRadius()
3515
+ }],
3516
+ /**
3517
+ * Border Radius Left
3518
+ * @see https://tailwindcss.com/docs/border-radius
3519
+ */
3520
+ "rounded-l": [{
3521
+ "rounded-l": scaleRadius()
3522
+ }],
3523
+ /**
3524
+ * Border Radius Start Start
3525
+ * @see https://tailwindcss.com/docs/border-radius
3526
+ */
3527
+ "rounded-ss": [{
3528
+ "rounded-ss": scaleRadius()
3529
+ }],
3530
+ /**
3531
+ * Border Radius Start End
3532
+ * @see https://tailwindcss.com/docs/border-radius
3533
+ */
3534
+ "rounded-se": [{
3535
+ "rounded-se": scaleRadius()
3536
+ }],
3537
+ /**
3538
+ * Border Radius End End
3539
+ * @see https://tailwindcss.com/docs/border-radius
3540
+ */
3541
+ "rounded-ee": [{
3542
+ "rounded-ee": scaleRadius()
3543
+ }],
3544
+ /**
3545
+ * Border Radius End Start
3546
+ * @see https://tailwindcss.com/docs/border-radius
3547
+ */
3548
+ "rounded-es": [{
3549
+ "rounded-es": scaleRadius()
3550
+ }],
3551
+ /**
3552
+ * Border Radius Top Left
3553
+ * @see https://tailwindcss.com/docs/border-radius
3554
+ */
3555
+ "rounded-tl": [{
3556
+ "rounded-tl": scaleRadius()
3557
+ }],
3558
+ /**
3559
+ * Border Radius Top Right
3560
+ * @see https://tailwindcss.com/docs/border-radius
3561
+ */
3562
+ "rounded-tr": [{
3563
+ "rounded-tr": scaleRadius()
3564
+ }],
3565
+ /**
3566
+ * Border Radius Bottom Right
3567
+ * @see https://tailwindcss.com/docs/border-radius
3568
+ */
3569
+ "rounded-br": [{
3570
+ "rounded-br": scaleRadius()
3571
+ }],
3572
+ /**
3573
+ * Border Radius Bottom Left
3574
+ * @see https://tailwindcss.com/docs/border-radius
3575
+ */
3576
+ "rounded-bl": [{
3577
+ "rounded-bl": scaleRadius()
3578
+ }],
3579
+ /**
3580
+ * Border Width
3581
+ * @see https://tailwindcss.com/docs/border-width
3582
+ */
3583
+ "border-w": [{
3584
+ border: scaleBorderWidth()
3585
+ }],
3586
+ /**
3587
+ * Border Width X
3588
+ * @see https://tailwindcss.com/docs/border-width
3589
+ */
3590
+ "border-w-x": [{
3591
+ "border-x": scaleBorderWidth()
3592
+ }],
3593
+ /**
3594
+ * Border Width Y
3595
+ * @see https://tailwindcss.com/docs/border-width
3596
+ */
3597
+ "border-w-y": [{
3598
+ "border-y": scaleBorderWidth()
3599
+ }],
3600
+ /**
3601
+ * Border Width Start
3602
+ * @see https://tailwindcss.com/docs/border-width
3603
+ */
3604
+ "border-w-s": [{
3605
+ "border-s": scaleBorderWidth()
3606
+ }],
3607
+ /**
3608
+ * Border Width End
3609
+ * @see https://tailwindcss.com/docs/border-width
3610
+ */
3611
+ "border-w-e": [{
3612
+ "border-e": scaleBorderWidth()
3613
+ }],
3614
+ /**
3615
+ * Border Width Top
3616
+ * @see https://tailwindcss.com/docs/border-width
3617
+ */
3618
+ "border-w-t": [{
3619
+ "border-t": scaleBorderWidth()
3620
+ }],
3621
+ /**
3622
+ * Border Width Right
3623
+ * @see https://tailwindcss.com/docs/border-width
3624
+ */
3625
+ "border-w-r": [{
3626
+ "border-r": scaleBorderWidth()
3627
+ }],
3628
+ /**
3629
+ * Border Width Bottom
3630
+ * @see https://tailwindcss.com/docs/border-width
3631
+ */
3632
+ "border-w-b": [{
3633
+ "border-b": scaleBorderWidth()
3634
+ }],
3635
+ /**
3636
+ * Border Width Left
3637
+ * @see https://tailwindcss.com/docs/border-width
3638
+ */
3639
+ "border-w-l": [{
3640
+ "border-l": scaleBorderWidth()
3641
+ }],
3642
+ /**
3643
+ * Divide Width X
3644
+ * @see https://tailwindcss.com/docs/border-width#between-children
3645
+ */
3646
+ "divide-x": [{
3647
+ "divide-x": scaleBorderWidth()
3648
+ }],
3649
+ /**
3650
+ * Divide Width X Reverse
3651
+ * @see https://tailwindcss.com/docs/border-width#between-children
3652
+ */
3653
+ "divide-x-reverse": ["divide-x-reverse"],
3654
+ /**
3655
+ * Divide Width Y
3656
+ * @see https://tailwindcss.com/docs/border-width#between-children
3657
+ */
3658
+ "divide-y": [{
3659
+ "divide-y": scaleBorderWidth()
3660
+ }],
3661
+ /**
3662
+ * Divide Width Y Reverse
3663
+ * @see https://tailwindcss.com/docs/border-width#between-children
3664
+ */
3665
+ "divide-y-reverse": ["divide-y-reverse"],
3666
+ /**
3667
+ * Border Style
3668
+ * @see https://tailwindcss.com/docs/border-style
3669
+ */
3670
+ "border-style": [{
3671
+ border: [...scaleLineStyle(), "hidden", "none"]
3672
+ }],
3673
+ /**
3674
+ * Divide Style
3675
+ * @see https://tailwindcss.com/docs/border-style#setting-the-divider-style
3676
+ */
3677
+ "divide-style": [{
3678
+ divide: [...scaleLineStyle(), "hidden", "none"]
3679
+ }],
3680
+ /**
3681
+ * Border Color
3682
+ * @see https://tailwindcss.com/docs/border-color
3683
+ */
3684
+ "border-color": [{
3685
+ border: scaleColor()
3686
+ }],
3687
+ /**
3688
+ * Border Color X
3689
+ * @see https://tailwindcss.com/docs/border-color
3690
+ */
3691
+ "border-color-x": [{
3692
+ "border-x": scaleColor()
3693
+ }],
3694
+ /**
3695
+ * Border Color Y
3696
+ * @see https://tailwindcss.com/docs/border-color
3697
+ */
3698
+ "border-color-y": [{
3699
+ "border-y": scaleColor()
3700
+ }],
3701
+ /**
3702
+ * Border Color S
3703
+ * @see https://tailwindcss.com/docs/border-color
3704
+ */
3705
+ "border-color-s": [{
3706
+ "border-s": scaleColor()
3707
+ }],
3708
+ /**
3709
+ * Border Color E
3710
+ * @see https://tailwindcss.com/docs/border-color
3711
+ */
3712
+ "border-color-e": [{
3713
+ "border-e": scaleColor()
3714
+ }],
3715
+ /**
3716
+ * Border Color Top
3717
+ * @see https://tailwindcss.com/docs/border-color
3718
+ */
3719
+ "border-color-t": [{
3720
+ "border-t": scaleColor()
3721
+ }],
3722
+ /**
3723
+ * Border Color Right
3724
+ * @see https://tailwindcss.com/docs/border-color
3725
+ */
3726
+ "border-color-r": [{
3727
+ "border-r": scaleColor()
3728
+ }],
3729
+ /**
3730
+ * Border Color Bottom
3731
+ * @see https://tailwindcss.com/docs/border-color
3732
+ */
3733
+ "border-color-b": [{
3734
+ "border-b": scaleColor()
3735
+ }],
3736
+ /**
3737
+ * Border Color Left
3738
+ * @see https://tailwindcss.com/docs/border-color
3739
+ */
3740
+ "border-color-l": [{
3741
+ "border-l": scaleColor()
3742
+ }],
3743
+ /**
3744
+ * Divide Color
3745
+ * @see https://tailwindcss.com/docs/divide-color
3746
+ */
3747
+ "divide-color": [{
3748
+ divide: scaleColor()
3749
+ }],
3750
+ /**
3751
+ * Outline Style
3752
+ * @see https://tailwindcss.com/docs/outline-style
3753
+ */
3754
+ "outline-style": [{
3755
+ outline: [...scaleLineStyle(), "none", "hidden"]
3756
+ }],
3757
+ /**
3758
+ * Outline Offset
3759
+ * @see https://tailwindcss.com/docs/outline-offset
3760
+ */
3761
+ "outline-offset": [{
3762
+ "outline-offset": [isNumber, isArbitraryVariable, isArbitraryValue]
3763
+ }],
3764
+ /**
3765
+ * Outline Width
3766
+ * @see https://tailwindcss.com/docs/outline-width
3767
+ */
3768
+ "outline-w": [{
3769
+ outline: ["", isNumber, isArbitraryVariableLength, isArbitraryLength]
3770
+ }],
3771
+ /**
3772
+ * Outline Color
3773
+ * @see https://tailwindcss.com/docs/outline-color
3774
+ */
3775
+ "outline-color": [{
3776
+ outline: scaleColor()
3777
+ }],
3778
+ // ---------------
3779
+ // --- Effects ---
3780
+ // ---------------
3781
+ /**
3782
+ * Box Shadow
3783
+ * @see https://tailwindcss.com/docs/box-shadow
3784
+ */
3785
+ shadow: [{
3786
+ shadow: [
3787
+ // Deprecated since Tailwind CSS v4.0.0
3788
+ "",
3789
+ "none",
3790
+ themeShadow,
3791
+ isArbitraryVariableShadow,
3792
+ isArbitraryShadow
3793
+ ]
3794
+ }],
3795
+ /**
3796
+ * Box Shadow Color
3797
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-shadow-color
3798
+ */
3799
+ "shadow-color": [{
3800
+ shadow: scaleColor()
3801
+ }],
3802
+ /**
3803
+ * Inset Box Shadow
3804
+ * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-shadow
3805
+ */
3806
+ "inset-shadow": [{
3807
+ "inset-shadow": ["none", themeInsetShadow, isArbitraryVariableShadow, isArbitraryShadow]
3808
+ }],
3809
+ /**
3810
+ * Inset Box Shadow Color
3811
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-shadow-color
3812
+ */
3813
+ "inset-shadow-color": [{
3814
+ "inset-shadow": scaleColor()
3815
+ }],
3816
+ /**
3817
+ * Ring Width
3818
+ * @see https://tailwindcss.com/docs/box-shadow#adding-a-ring
3819
+ */
3820
+ "ring-w": [{
3821
+ ring: scaleBorderWidth()
3822
+ }],
3823
+ /**
3824
+ * Ring Width Inset
3825
+ * @see https://v3.tailwindcss.com/docs/ring-width#inset-rings
3826
+ * @deprecated since Tailwind CSS v4.0.0
3827
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158
3828
+ */
3829
+ "ring-w-inset": ["ring-inset"],
3830
+ /**
3831
+ * Ring Color
3832
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-ring-color
3833
+ */
3834
+ "ring-color": [{
3835
+ ring: scaleColor()
3836
+ }],
3837
+ /**
3838
+ * Ring Offset Width
3839
+ * @see https://v3.tailwindcss.com/docs/ring-offset-width
3840
+ * @deprecated since Tailwind CSS v4.0.0
3841
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158
3842
+ */
3843
+ "ring-offset-w": [{
3844
+ "ring-offset": [isNumber, isArbitraryLength]
3845
+ }],
3846
+ /**
3847
+ * Ring Offset Color
3848
+ * @see https://v3.tailwindcss.com/docs/ring-offset-color
3849
+ * @deprecated since Tailwind CSS v4.0.0
3850
+ * @see https://github.com/tailwindlabs/tailwindcss/blob/v4.0.0/packages/tailwindcss/src/utilities.ts#L4158
3851
+ */
3852
+ "ring-offset-color": [{
3853
+ "ring-offset": scaleColor()
3854
+ }],
3855
+ /**
3856
+ * Inset Ring Width
3857
+ * @see https://tailwindcss.com/docs/box-shadow#adding-an-inset-ring
3858
+ */
3859
+ "inset-ring-w": [{
3860
+ "inset-ring": scaleBorderWidth()
3861
+ }],
3862
+ /**
3863
+ * Inset Ring Color
3864
+ * @see https://tailwindcss.com/docs/box-shadow#setting-the-inset-ring-color
3865
+ */
3866
+ "inset-ring-color": [{
3867
+ "inset-ring": scaleColor()
3868
+ }],
3869
+ /**
3870
+ * Text Shadow
3871
+ * @see https://tailwindcss.com/docs/text-shadow
3872
+ */
3873
+ "text-shadow": [{
3874
+ "text-shadow": ["none", themeTextShadow, isArbitraryVariableShadow, isArbitraryShadow]
3875
+ }],
3876
+ /**
3877
+ * Text Shadow Color
3878
+ * @see https://tailwindcss.com/docs/text-shadow#setting-the-shadow-color
3879
+ */
3880
+ "text-shadow-color": [{
3881
+ "text-shadow": scaleColor()
3882
+ }],
3883
+ /**
3884
+ * Opacity
3885
+ * @see https://tailwindcss.com/docs/opacity
3886
+ */
3887
+ opacity: [{
3888
+ opacity: [isNumber, isArbitraryVariable, isArbitraryValue]
3889
+ }],
3890
+ /**
3891
+ * Mix Blend Mode
3892
+ * @see https://tailwindcss.com/docs/mix-blend-mode
3893
+ */
3894
+ "mix-blend": [{
3895
+ "mix-blend": [...scaleBlendMode(), "plus-darker", "plus-lighter"]
3896
+ }],
3897
+ /**
3898
+ * Background Blend Mode
3899
+ * @see https://tailwindcss.com/docs/background-blend-mode
3900
+ */
3901
+ "bg-blend": [{
3902
+ "bg-blend": scaleBlendMode()
3903
+ }],
3904
+ /**
3905
+ * Mask Clip
3906
+ * @see https://tailwindcss.com/docs/mask-clip
3907
+ */
3908
+ "mask-clip": [{
3909
+ "mask-clip": ["border", "padding", "content", "fill", "stroke", "view"]
3910
+ }, "mask-no-clip"],
3911
+ /**
3912
+ * Mask Composite
3913
+ * @see https://tailwindcss.com/docs/mask-composite
3914
+ */
3915
+ "mask-composite": [{
3916
+ mask: ["add", "subtract", "intersect", "exclude"]
3917
+ }],
3918
+ /**
3919
+ * Mask Image
3920
+ * @see https://tailwindcss.com/docs/mask-image
3921
+ */
3922
+ "mask-image-linear-pos": [{
3923
+ "mask-linear": [isNumber]
3924
+ }],
3925
+ "mask-image-linear-from-pos": [{
3926
+ "mask-linear-from": scaleMaskImagePosition()
3927
+ }],
3928
+ "mask-image-linear-to-pos": [{
3929
+ "mask-linear-to": scaleMaskImagePosition()
3930
+ }],
3931
+ "mask-image-linear-from-color": [{
3932
+ "mask-linear-from": scaleColor()
3933
+ }],
3934
+ "mask-image-linear-to-color": [{
3935
+ "mask-linear-to": scaleColor()
3936
+ }],
3937
+ "mask-image-t-from-pos": [{
3938
+ "mask-t-from": scaleMaskImagePosition()
3939
+ }],
3940
+ "mask-image-t-to-pos": [{
3941
+ "mask-t-to": scaleMaskImagePosition()
3942
+ }],
3943
+ "mask-image-t-from-color": [{
3944
+ "mask-t-from": scaleColor()
3945
+ }],
3946
+ "mask-image-t-to-color": [{
3947
+ "mask-t-to": scaleColor()
3948
+ }],
3949
+ "mask-image-r-from-pos": [{
3950
+ "mask-r-from": scaleMaskImagePosition()
3951
+ }],
3952
+ "mask-image-r-to-pos": [{
3953
+ "mask-r-to": scaleMaskImagePosition()
3954
+ }],
3955
+ "mask-image-r-from-color": [{
3956
+ "mask-r-from": scaleColor()
3957
+ }],
3958
+ "mask-image-r-to-color": [{
3959
+ "mask-r-to": scaleColor()
3960
+ }],
3961
+ "mask-image-b-from-pos": [{
3962
+ "mask-b-from": scaleMaskImagePosition()
3963
+ }],
3964
+ "mask-image-b-to-pos": [{
3965
+ "mask-b-to": scaleMaskImagePosition()
3966
+ }],
3967
+ "mask-image-b-from-color": [{
3968
+ "mask-b-from": scaleColor()
3969
+ }],
3970
+ "mask-image-b-to-color": [{
3971
+ "mask-b-to": scaleColor()
3972
+ }],
3973
+ "mask-image-l-from-pos": [{
3974
+ "mask-l-from": scaleMaskImagePosition()
3975
+ }],
3976
+ "mask-image-l-to-pos": [{
3977
+ "mask-l-to": scaleMaskImagePosition()
3978
+ }],
3979
+ "mask-image-l-from-color": [{
3980
+ "mask-l-from": scaleColor()
3981
+ }],
3982
+ "mask-image-l-to-color": [{
3983
+ "mask-l-to": scaleColor()
3984
+ }],
3985
+ "mask-image-x-from-pos": [{
3986
+ "mask-x-from": scaleMaskImagePosition()
3987
+ }],
3988
+ "mask-image-x-to-pos": [{
3989
+ "mask-x-to": scaleMaskImagePosition()
3990
+ }],
3991
+ "mask-image-x-from-color": [{
3992
+ "mask-x-from": scaleColor()
3993
+ }],
3994
+ "mask-image-x-to-color": [{
3995
+ "mask-x-to": scaleColor()
3996
+ }],
3997
+ "mask-image-y-from-pos": [{
3998
+ "mask-y-from": scaleMaskImagePosition()
3999
+ }],
4000
+ "mask-image-y-to-pos": [{
4001
+ "mask-y-to": scaleMaskImagePosition()
4002
+ }],
4003
+ "mask-image-y-from-color": [{
4004
+ "mask-y-from": scaleColor()
4005
+ }],
4006
+ "mask-image-y-to-color": [{
4007
+ "mask-y-to": scaleColor()
4008
+ }],
4009
+ "mask-image-radial": [{
4010
+ "mask-radial": [isArbitraryVariable, isArbitraryValue]
4011
+ }],
4012
+ "mask-image-radial-from-pos": [{
4013
+ "mask-radial-from": scaleMaskImagePosition()
4014
+ }],
4015
+ "mask-image-radial-to-pos": [{
4016
+ "mask-radial-to": scaleMaskImagePosition()
4017
+ }],
4018
+ "mask-image-radial-from-color": [{
4019
+ "mask-radial-from": scaleColor()
4020
+ }],
4021
+ "mask-image-radial-to-color": [{
4022
+ "mask-radial-to": scaleColor()
4023
+ }],
4024
+ "mask-image-radial-shape": [{
4025
+ "mask-radial": ["circle", "ellipse"]
4026
+ }],
4027
+ "mask-image-radial-size": [{
4028
+ "mask-radial": [{
4029
+ closest: ["side", "corner"],
4030
+ farthest: ["side", "corner"]
4031
+ }]
4032
+ }],
4033
+ "mask-image-radial-pos": [{
4034
+ "mask-radial-at": scalePosition()
4035
+ }],
4036
+ "mask-image-conic-pos": [{
4037
+ "mask-conic": [isNumber]
4038
+ }],
4039
+ "mask-image-conic-from-pos": [{
4040
+ "mask-conic-from": scaleMaskImagePosition()
4041
+ }],
4042
+ "mask-image-conic-to-pos": [{
4043
+ "mask-conic-to": scaleMaskImagePosition()
4044
+ }],
4045
+ "mask-image-conic-from-color": [{
4046
+ "mask-conic-from": scaleColor()
4047
+ }],
4048
+ "mask-image-conic-to-color": [{
4049
+ "mask-conic-to": scaleColor()
4050
+ }],
4051
+ /**
4052
+ * Mask Mode
4053
+ * @see https://tailwindcss.com/docs/mask-mode
4054
+ */
4055
+ "mask-mode": [{
4056
+ mask: ["alpha", "luminance", "match"]
4057
+ }],
4058
+ /**
4059
+ * Mask Origin
4060
+ * @see https://tailwindcss.com/docs/mask-origin
4061
+ */
4062
+ "mask-origin": [{
4063
+ "mask-origin": ["border", "padding", "content", "fill", "stroke", "view"]
4064
+ }],
4065
+ /**
4066
+ * Mask Position
4067
+ * @see https://tailwindcss.com/docs/mask-position
4068
+ */
4069
+ "mask-position": [{
4070
+ mask: scaleBgPosition()
4071
+ }],
4072
+ /**
4073
+ * Mask Repeat
4074
+ * @see https://tailwindcss.com/docs/mask-repeat
4075
+ */
4076
+ "mask-repeat": [{
4077
+ mask: scaleBgRepeat()
4078
+ }],
4079
+ /**
4080
+ * Mask Size
4081
+ * @see https://tailwindcss.com/docs/mask-size
4082
+ */
4083
+ "mask-size": [{
4084
+ mask: scaleBgSize()
4085
+ }],
4086
+ /**
4087
+ * Mask Type
4088
+ * @see https://tailwindcss.com/docs/mask-type
4089
+ */
4090
+ "mask-type": [{
4091
+ "mask-type": ["alpha", "luminance"]
4092
+ }],
4093
+ /**
4094
+ * Mask Image
4095
+ * @see https://tailwindcss.com/docs/mask-image
4096
+ */
4097
+ "mask-image": [{
4098
+ mask: ["none", isArbitraryVariable, isArbitraryValue]
4099
+ }],
4100
+ // ---------------
4101
+ // --- Filters ---
4102
+ // ---------------
4103
+ /**
4104
+ * Filter
4105
+ * @see https://tailwindcss.com/docs/filter
4106
+ */
4107
+ filter: [{
4108
+ filter: [
4109
+ // Deprecated since Tailwind CSS v3.0.0
4110
+ "",
4111
+ "none",
4112
+ isArbitraryVariable,
4113
+ isArbitraryValue
4114
+ ]
4115
+ }],
4116
+ /**
4117
+ * Blur
4118
+ * @see https://tailwindcss.com/docs/blur
4119
+ */
4120
+ blur: [{
4121
+ blur: scaleBlur()
4122
+ }],
4123
+ /**
4124
+ * Brightness
4125
+ * @see https://tailwindcss.com/docs/brightness
4126
+ */
4127
+ brightness: [{
4128
+ brightness: [isNumber, isArbitraryVariable, isArbitraryValue]
4129
+ }],
4130
+ /**
4131
+ * Contrast
4132
+ * @see https://tailwindcss.com/docs/contrast
4133
+ */
4134
+ contrast: [{
4135
+ contrast: [isNumber, isArbitraryVariable, isArbitraryValue]
4136
+ }],
4137
+ /**
4138
+ * Drop Shadow
4139
+ * @see https://tailwindcss.com/docs/drop-shadow
4140
+ */
4141
+ "drop-shadow": [{
4142
+ "drop-shadow": [
4143
+ // Deprecated since Tailwind CSS v4.0.0
4144
+ "",
4145
+ "none",
4146
+ themeDropShadow,
4147
+ isArbitraryVariableShadow,
4148
+ isArbitraryShadow
4149
+ ]
4150
+ }],
4151
+ /**
4152
+ * Drop Shadow Color
4153
+ * @see https://tailwindcss.com/docs/filter-drop-shadow#setting-the-shadow-color
4154
+ */
4155
+ "drop-shadow-color": [{
4156
+ "drop-shadow": scaleColor()
4157
+ }],
4158
+ /**
4159
+ * Grayscale
4160
+ * @see https://tailwindcss.com/docs/grayscale
4161
+ */
4162
+ grayscale: [{
4163
+ grayscale: ["", isNumber, isArbitraryVariable, isArbitraryValue]
4164
+ }],
4165
+ /**
4166
+ * Hue Rotate
4167
+ * @see https://tailwindcss.com/docs/hue-rotate
4168
+ */
4169
+ "hue-rotate": [{
4170
+ "hue-rotate": [isNumber, isArbitraryVariable, isArbitraryValue]
4171
+ }],
4172
+ /**
4173
+ * Invert
4174
+ * @see https://tailwindcss.com/docs/invert
4175
+ */
4176
+ invert: [{
4177
+ invert: ["", isNumber, isArbitraryVariable, isArbitraryValue]
4178
+ }],
4179
+ /**
4180
+ * Saturate
4181
+ * @see https://tailwindcss.com/docs/saturate
4182
+ */
4183
+ saturate: [{
4184
+ saturate: [isNumber, isArbitraryVariable, isArbitraryValue]
4185
+ }],
4186
+ /**
4187
+ * Sepia
4188
+ * @see https://tailwindcss.com/docs/sepia
4189
+ */
4190
+ sepia: [{
4191
+ sepia: ["", isNumber, isArbitraryVariable, isArbitraryValue]
4192
+ }],
4193
+ /**
4194
+ * Backdrop Filter
4195
+ * @see https://tailwindcss.com/docs/backdrop-filter
4196
+ */
4197
+ "backdrop-filter": [{
4198
+ "backdrop-filter": [
4199
+ // Deprecated since Tailwind CSS v3.0.0
4200
+ "",
4201
+ "none",
4202
+ isArbitraryVariable,
4203
+ isArbitraryValue
4204
+ ]
4205
+ }],
4206
+ /**
4207
+ * Backdrop Blur
4208
+ * @see https://tailwindcss.com/docs/backdrop-blur
4209
+ */
4210
+ "backdrop-blur": [{
4211
+ "backdrop-blur": scaleBlur()
4212
+ }],
4213
+ /**
4214
+ * Backdrop Brightness
4215
+ * @see https://tailwindcss.com/docs/backdrop-brightness
4216
+ */
4217
+ "backdrop-brightness": [{
4218
+ "backdrop-brightness": [isNumber, isArbitraryVariable, isArbitraryValue]
4219
+ }],
4220
+ /**
4221
+ * Backdrop Contrast
4222
+ * @see https://tailwindcss.com/docs/backdrop-contrast
4223
+ */
4224
+ "backdrop-contrast": [{
4225
+ "backdrop-contrast": [isNumber, isArbitraryVariable, isArbitraryValue]
4226
+ }],
4227
+ /**
4228
+ * Backdrop Grayscale
4229
+ * @see https://tailwindcss.com/docs/backdrop-grayscale
4230
+ */
4231
+ "backdrop-grayscale": [{
4232
+ "backdrop-grayscale": ["", isNumber, isArbitraryVariable, isArbitraryValue]
4233
+ }],
4234
+ /**
4235
+ * Backdrop Hue Rotate
4236
+ * @see https://tailwindcss.com/docs/backdrop-hue-rotate
4237
+ */
4238
+ "backdrop-hue-rotate": [{
4239
+ "backdrop-hue-rotate": [isNumber, isArbitraryVariable, isArbitraryValue]
4240
+ }],
4241
+ /**
4242
+ * Backdrop Invert
4243
+ * @see https://tailwindcss.com/docs/backdrop-invert
4244
+ */
4245
+ "backdrop-invert": [{
4246
+ "backdrop-invert": ["", isNumber, isArbitraryVariable, isArbitraryValue]
4247
+ }],
4248
+ /**
4249
+ * Backdrop Opacity
4250
+ * @see https://tailwindcss.com/docs/backdrop-opacity
4251
+ */
4252
+ "backdrop-opacity": [{
4253
+ "backdrop-opacity": [isNumber, isArbitraryVariable, isArbitraryValue]
4254
+ }],
4255
+ /**
4256
+ * Backdrop Saturate
4257
+ * @see https://tailwindcss.com/docs/backdrop-saturate
4258
+ */
4259
+ "backdrop-saturate": [{
4260
+ "backdrop-saturate": [isNumber, isArbitraryVariable, isArbitraryValue]
4261
+ }],
4262
+ /**
4263
+ * Backdrop Sepia
4264
+ * @see https://tailwindcss.com/docs/backdrop-sepia
4265
+ */
4266
+ "backdrop-sepia": [{
4267
+ "backdrop-sepia": ["", isNumber, isArbitraryVariable, isArbitraryValue]
4268
+ }],
4269
+ // --------------
4270
+ // --- Tables ---
4271
+ // --------------
4272
+ /**
4273
+ * Border Collapse
4274
+ * @see https://tailwindcss.com/docs/border-collapse
4275
+ */
4276
+ "border-collapse": [{
4277
+ border: ["collapse", "separate"]
4278
+ }],
4279
+ /**
4280
+ * Border Spacing
4281
+ * @see https://tailwindcss.com/docs/border-spacing
4282
+ */
4283
+ "border-spacing": [{
4284
+ "border-spacing": scaleUnambiguousSpacing()
4285
+ }],
4286
+ /**
4287
+ * Border Spacing X
4288
+ * @see https://tailwindcss.com/docs/border-spacing
4289
+ */
4290
+ "border-spacing-x": [{
4291
+ "border-spacing-x": scaleUnambiguousSpacing()
4292
+ }],
4293
+ /**
4294
+ * Border Spacing Y
4295
+ * @see https://tailwindcss.com/docs/border-spacing
4296
+ */
4297
+ "border-spacing-y": [{
4298
+ "border-spacing-y": scaleUnambiguousSpacing()
4299
+ }],
4300
+ /**
4301
+ * Table Layout
4302
+ * @see https://tailwindcss.com/docs/table-layout
4303
+ */
4304
+ "table-layout": [{
4305
+ table: ["auto", "fixed"]
4306
+ }],
4307
+ /**
4308
+ * Caption Side
4309
+ * @see https://tailwindcss.com/docs/caption-side
4310
+ */
4311
+ caption: [{
4312
+ caption: ["top", "bottom"]
4313
+ }],
4314
+ // ---------------------------------
4315
+ // --- Transitions and Animation ---
4316
+ // ---------------------------------
4317
+ /**
4318
+ * Transition Property
4319
+ * @see https://tailwindcss.com/docs/transition-property
4320
+ */
4321
+ transition: [{
4322
+ transition: ["", "all", "colors", "opacity", "shadow", "transform", "none", isArbitraryVariable, isArbitraryValue]
4323
+ }],
4324
+ /**
4325
+ * Transition Behavior
4326
+ * @see https://tailwindcss.com/docs/transition-behavior
4327
+ */
4328
+ "transition-behavior": [{
4329
+ transition: ["normal", "discrete"]
4330
+ }],
4331
+ /**
4332
+ * Transition Duration
4333
+ * @see https://tailwindcss.com/docs/transition-duration
4334
+ */
4335
+ duration: [{
4336
+ duration: [isNumber, "initial", isArbitraryVariable, isArbitraryValue]
4337
+ }],
4338
+ /**
4339
+ * Transition Timing Function
4340
+ * @see https://tailwindcss.com/docs/transition-timing-function
4341
+ */
4342
+ ease: [{
4343
+ ease: ["linear", "initial", themeEase, isArbitraryVariable, isArbitraryValue]
4344
+ }],
4345
+ /**
4346
+ * Transition Delay
4347
+ * @see https://tailwindcss.com/docs/transition-delay
4348
+ */
4349
+ delay: [{
4350
+ delay: [isNumber, isArbitraryVariable, isArbitraryValue]
4351
+ }],
4352
+ /**
4353
+ * Animation
4354
+ * @see https://tailwindcss.com/docs/animation
4355
+ */
4356
+ animate: [{
4357
+ animate: ["none", themeAnimate, isArbitraryVariable, isArbitraryValue]
4358
+ }],
4359
+ // ------------------
4360
+ // --- Transforms ---
4361
+ // ------------------
4362
+ /**
4363
+ * Backface Visibility
4364
+ * @see https://tailwindcss.com/docs/backface-visibility
4365
+ */
4366
+ backface: [{
4367
+ backface: ["hidden", "visible"]
4368
+ }],
4369
+ /**
4370
+ * Perspective
4371
+ * @see https://tailwindcss.com/docs/perspective
4372
+ */
4373
+ perspective: [{
4374
+ perspective: [themePerspective, isArbitraryVariable, isArbitraryValue]
4375
+ }],
4376
+ /**
4377
+ * Perspective Origin
4378
+ * @see https://tailwindcss.com/docs/perspective-origin
4379
+ */
4380
+ "perspective-origin": [{
4381
+ "perspective-origin": scalePositionWithArbitrary()
4382
+ }],
4383
+ /**
4384
+ * Rotate
4385
+ * @see https://tailwindcss.com/docs/rotate
4386
+ */
4387
+ rotate: [{
4388
+ rotate: scaleRotate()
4389
+ }],
4390
+ /**
4391
+ * Rotate X
4392
+ * @see https://tailwindcss.com/docs/rotate
4393
+ */
4394
+ "rotate-x": [{
4395
+ "rotate-x": scaleRotate()
4396
+ }],
4397
+ /**
4398
+ * Rotate Y
4399
+ * @see https://tailwindcss.com/docs/rotate
4400
+ */
4401
+ "rotate-y": [{
4402
+ "rotate-y": scaleRotate()
4403
+ }],
4404
+ /**
4405
+ * Rotate Z
4406
+ * @see https://tailwindcss.com/docs/rotate
4407
+ */
4408
+ "rotate-z": [{
4409
+ "rotate-z": scaleRotate()
4410
+ }],
4411
+ /**
4412
+ * Scale
4413
+ * @see https://tailwindcss.com/docs/scale
4414
+ */
4415
+ scale: [{
4416
+ scale: scaleScale()
4417
+ }],
4418
+ /**
4419
+ * Scale X
4420
+ * @see https://tailwindcss.com/docs/scale
4421
+ */
4422
+ "scale-x": [{
4423
+ "scale-x": scaleScale()
4424
+ }],
4425
+ /**
4426
+ * Scale Y
4427
+ * @see https://tailwindcss.com/docs/scale
4428
+ */
4429
+ "scale-y": [{
4430
+ "scale-y": scaleScale()
4431
+ }],
4432
+ /**
4433
+ * Scale Z
4434
+ * @see https://tailwindcss.com/docs/scale
4435
+ */
4436
+ "scale-z": [{
4437
+ "scale-z": scaleScale()
4438
+ }],
4439
+ /**
4440
+ * Scale 3D
4441
+ * @see https://tailwindcss.com/docs/scale
4442
+ */
4443
+ "scale-3d": ["scale-3d"],
4444
+ /**
4445
+ * Skew
4446
+ * @see https://tailwindcss.com/docs/skew
4447
+ */
4448
+ skew: [{
4449
+ skew: scaleSkew()
4450
+ }],
4451
+ /**
4452
+ * Skew X
4453
+ * @see https://tailwindcss.com/docs/skew
4454
+ */
4455
+ "skew-x": [{
4456
+ "skew-x": scaleSkew()
4457
+ }],
4458
+ /**
4459
+ * Skew Y
4460
+ * @see https://tailwindcss.com/docs/skew
4461
+ */
4462
+ "skew-y": [{
4463
+ "skew-y": scaleSkew()
4464
+ }],
4465
+ /**
4466
+ * Transform
4467
+ * @see https://tailwindcss.com/docs/transform
4468
+ */
4469
+ transform: [{
4470
+ transform: [isArbitraryVariable, isArbitraryValue, "", "none", "gpu", "cpu"]
4471
+ }],
4472
+ /**
4473
+ * Transform Origin
4474
+ * @see https://tailwindcss.com/docs/transform-origin
4475
+ */
4476
+ "transform-origin": [{
4477
+ origin: scalePositionWithArbitrary()
4478
+ }],
4479
+ /**
4480
+ * Transform Style
4481
+ * @see https://tailwindcss.com/docs/transform-style
4482
+ */
4483
+ "transform-style": [{
4484
+ transform: ["3d", "flat"]
4485
+ }],
4486
+ /**
4487
+ * Translate
4488
+ * @see https://tailwindcss.com/docs/translate
4489
+ */
4490
+ translate: [{
4491
+ translate: scaleTranslate()
4492
+ }],
4493
+ /**
4494
+ * Translate X
4495
+ * @see https://tailwindcss.com/docs/translate
4496
+ */
4497
+ "translate-x": [{
4498
+ "translate-x": scaleTranslate()
4499
+ }],
4500
+ /**
4501
+ * Translate Y
4502
+ * @see https://tailwindcss.com/docs/translate
4503
+ */
4504
+ "translate-y": [{
4505
+ "translate-y": scaleTranslate()
4506
+ }],
4507
+ /**
4508
+ * Translate Z
4509
+ * @see https://tailwindcss.com/docs/translate
4510
+ */
4511
+ "translate-z": [{
4512
+ "translate-z": scaleTranslate()
4513
+ }],
4514
+ /**
4515
+ * Translate None
4516
+ * @see https://tailwindcss.com/docs/translate
4517
+ */
4518
+ "translate-none": ["translate-none"],
4519
+ // ---------------------
4520
+ // --- Interactivity ---
4521
+ // ---------------------
4522
+ /**
4523
+ * Accent Color
4524
+ * @see https://tailwindcss.com/docs/accent-color
4525
+ */
4526
+ accent: [{
4527
+ accent: scaleColor()
4528
+ }],
4529
+ /**
4530
+ * Appearance
4531
+ * @see https://tailwindcss.com/docs/appearance
4532
+ */
4533
+ appearance: [{
4534
+ appearance: ["none", "auto"]
4535
+ }],
4536
+ /**
4537
+ * Caret Color
4538
+ * @see https://tailwindcss.com/docs/just-in-time-mode#caret-color-utilities
4539
+ */
4540
+ "caret-color": [{
4541
+ caret: scaleColor()
4542
+ }],
4543
+ /**
4544
+ * Color Scheme
4545
+ * @see https://tailwindcss.com/docs/color-scheme
4546
+ */
4547
+ "color-scheme": [{
4548
+ scheme: ["normal", "dark", "light", "light-dark", "only-dark", "only-light"]
4549
+ }],
4550
+ /**
4551
+ * Cursor
4552
+ * @see https://tailwindcss.com/docs/cursor
4553
+ */
4554
+ cursor: [{
4555
+ cursor: ["auto", "default", "pointer", "wait", "text", "move", "help", "not-allowed", "none", "context-menu", "progress", "cell", "crosshair", "vertical-text", "alias", "copy", "no-drop", "grab", "grabbing", "all-scroll", "col-resize", "row-resize", "n-resize", "e-resize", "s-resize", "w-resize", "ne-resize", "nw-resize", "se-resize", "sw-resize", "ew-resize", "ns-resize", "nesw-resize", "nwse-resize", "zoom-in", "zoom-out", isArbitraryVariable, isArbitraryValue]
4556
+ }],
4557
+ /**
4558
+ * Field Sizing
4559
+ * @see https://tailwindcss.com/docs/field-sizing
4560
+ */
4561
+ "field-sizing": [{
4562
+ "field-sizing": ["fixed", "content"]
4563
+ }],
4564
+ /**
4565
+ * Pointer Events
4566
+ * @see https://tailwindcss.com/docs/pointer-events
4567
+ */
4568
+ "pointer-events": [{
4569
+ "pointer-events": ["auto", "none"]
4570
+ }],
4571
+ /**
4572
+ * Resize
4573
+ * @see https://tailwindcss.com/docs/resize
4574
+ */
4575
+ resize: [{
4576
+ resize: ["none", "", "y", "x"]
4577
+ }],
4578
+ /**
4579
+ * Scroll Behavior
4580
+ * @see https://tailwindcss.com/docs/scroll-behavior
4581
+ */
4582
+ "scroll-behavior": [{
4583
+ scroll: ["auto", "smooth"]
4584
+ }],
4585
+ /**
4586
+ * Scroll Margin
4587
+ * @see https://tailwindcss.com/docs/scroll-margin
4588
+ */
4589
+ "scroll-m": [{
4590
+ "scroll-m": scaleUnambiguousSpacing()
4591
+ }],
4592
+ /**
4593
+ * Scroll Margin X
4594
+ * @see https://tailwindcss.com/docs/scroll-margin
4595
+ */
4596
+ "scroll-mx": [{
4597
+ "scroll-mx": scaleUnambiguousSpacing()
4598
+ }],
4599
+ /**
4600
+ * Scroll Margin Y
4601
+ * @see https://tailwindcss.com/docs/scroll-margin
4602
+ */
4603
+ "scroll-my": [{
4604
+ "scroll-my": scaleUnambiguousSpacing()
4605
+ }],
4606
+ /**
4607
+ * Scroll Margin Start
4608
+ * @see https://tailwindcss.com/docs/scroll-margin
4609
+ */
4610
+ "scroll-ms": [{
4611
+ "scroll-ms": scaleUnambiguousSpacing()
4612
+ }],
4613
+ /**
4614
+ * Scroll Margin End
4615
+ * @see https://tailwindcss.com/docs/scroll-margin
4616
+ */
4617
+ "scroll-me": [{
4618
+ "scroll-me": scaleUnambiguousSpacing()
4619
+ }],
4620
+ /**
4621
+ * Scroll Margin Top
4622
+ * @see https://tailwindcss.com/docs/scroll-margin
4623
+ */
4624
+ "scroll-mt": [{
4625
+ "scroll-mt": scaleUnambiguousSpacing()
4626
+ }],
4627
+ /**
4628
+ * Scroll Margin Right
4629
+ * @see https://tailwindcss.com/docs/scroll-margin
4630
+ */
4631
+ "scroll-mr": [{
4632
+ "scroll-mr": scaleUnambiguousSpacing()
4633
+ }],
4634
+ /**
4635
+ * Scroll Margin Bottom
4636
+ * @see https://tailwindcss.com/docs/scroll-margin
4637
+ */
4638
+ "scroll-mb": [{
4639
+ "scroll-mb": scaleUnambiguousSpacing()
4640
+ }],
4641
+ /**
4642
+ * Scroll Margin Left
4643
+ * @see https://tailwindcss.com/docs/scroll-margin
4644
+ */
4645
+ "scroll-ml": [{
4646
+ "scroll-ml": scaleUnambiguousSpacing()
4647
+ }],
4648
+ /**
4649
+ * Scroll Padding
4650
+ * @see https://tailwindcss.com/docs/scroll-padding
4651
+ */
4652
+ "scroll-p": [{
4653
+ "scroll-p": scaleUnambiguousSpacing()
4654
+ }],
4655
+ /**
4656
+ * Scroll Padding X
4657
+ * @see https://tailwindcss.com/docs/scroll-padding
4658
+ */
4659
+ "scroll-px": [{
4660
+ "scroll-px": scaleUnambiguousSpacing()
4661
+ }],
4662
+ /**
4663
+ * Scroll Padding Y
4664
+ * @see https://tailwindcss.com/docs/scroll-padding
4665
+ */
4666
+ "scroll-py": [{
4667
+ "scroll-py": scaleUnambiguousSpacing()
4668
+ }],
4669
+ /**
4670
+ * Scroll Padding Start
4671
+ * @see https://tailwindcss.com/docs/scroll-padding
4672
+ */
4673
+ "scroll-ps": [{
4674
+ "scroll-ps": scaleUnambiguousSpacing()
4675
+ }],
4676
+ /**
4677
+ * Scroll Padding End
4678
+ * @see https://tailwindcss.com/docs/scroll-padding
4679
+ */
4680
+ "scroll-pe": [{
4681
+ "scroll-pe": scaleUnambiguousSpacing()
4682
+ }],
4683
+ /**
4684
+ * Scroll Padding Top
4685
+ * @see https://tailwindcss.com/docs/scroll-padding
4686
+ */
4687
+ "scroll-pt": [{
4688
+ "scroll-pt": scaleUnambiguousSpacing()
4689
+ }],
4690
+ /**
4691
+ * Scroll Padding Right
4692
+ * @see https://tailwindcss.com/docs/scroll-padding
4693
+ */
4694
+ "scroll-pr": [{
4695
+ "scroll-pr": scaleUnambiguousSpacing()
4696
+ }],
4697
+ /**
4698
+ * Scroll Padding Bottom
4699
+ * @see https://tailwindcss.com/docs/scroll-padding
4700
+ */
4701
+ "scroll-pb": [{
4702
+ "scroll-pb": scaleUnambiguousSpacing()
4703
+ }],
4704
+ /**
4705
+ * Scroll Padding Left
4706
+ * @see https://tailwindcss.com/docs/scroll-padding
4707
+ */
4708
+ "scroll-pl": [{
4709
+ "scroll-pl": scaleUnambiguousSpacing()
4710
+ }],
4711
+ /**
4712
+ * Scroll Snap Align
4713
+ * @see https://tailwindcss.com/docs/scroll-snap-align
4714
+ */
4715
+ "snap-align": [{
4716
+ snap: ["start", "end", "center", "align-none"]
4717
+ }],
4718
+ /**
4719
+ * Scroll Snap Stop
4720
+ * @see https://tailwindcss.com/docs/scroll-snap-stop
4721
+ */
4722
+ "snap-stop": [{
4723
+ snap: ["normal", "always"]
4724
+ }],
4725
+ /**
4726
+ * Scroll Snap Type
4727
+ * @see https://tailwindcss.com/docs/scroll-snap-type
4728
+ */
4729
+ "snap-type": [{
4730
+ snap: ["none", "x", "y", "both"]
4731
+ }],
4732
+ /**
4733
+ * Scroll Snap Type Strictness
4734
+ * @see https://tailwindcss.com/docs/scroll-snap-type
4735
+ */
4736
+ "snap-strictness": [{
4737
+ snap: ["mandatory", "proximity"]
4738
+ }],
4739
+ /**
4740
+ * Touch Action
4741
+ * @see https://tailwindcss.com/docs/touch-action
4742
+ */
4743
+ touch: [{
4744
+ touch: ["auto", "none", "manipulation"]
4745
+ }],
4746
+ /**
4747
+ * Touch Action X
4748
+ * @see https://tailwindcss.com/docs/touch-action
4749
+ */
4750
+ "touch-x": [{
4751
+ "touch-pan": ["x", "left", "right"]
4752
+ }],
4753
+ /**
4754
+ * Touch Action Y
4755
+ * @see https://tailwindcss.com/docs/touch-action
4756
+ */
4757
+ "touch-y": [{
4758
+ "touch-pan": ["y", "up", "down"]
4759
+ }],
4760
+ /**
4761
+ * Touch Action Pinch Zoom
4762
+ * @see https://tailwindcss.com/docs/touch-action
4763
+ */
4764
+ "touch-pz": ["touch-pinch-zoom"],
4765
+ /**
4766
+ * User Select
4767
+ * @see https://tailwindcss.com/docs/user-select
4768
+ */
4769
+ select: [{
4770
+ select: ["none", "text", "all", "auto"]
4771
+ }],
4772
+ /**
4773
+ * Will Change
4774
+ * @see https://tailwindcss.com/docs/will-change
4775
+ */
4776
+ "will-change": [{
4777
+ "will-change": ["auto", "scroll", "contents", "transform", isArbitraryVariable, isArbitraryValue]
4778
+ }],
4779
+ // -----------
4780
+ // --- SVG ---
4781
+ // -----------
4782
+ /**
4783
+ * Fill
4784
+ * @see https://tailwindcss.com/docs/fill
4785
+ */
4786
+ fill: [{
4787
+ fill: ["none", ...scaleColor()]
4788
+ }],
4789
+ /**
4790
+ * Stroke Width
4791
+ * @see https://tailwindcss.com/docs/stroke-width
4792
+ */
4793
+ "stroke-w": [{
4794
+ stroke: [isNumber, isArbitraryVariableLength, isArbitraryLength, isArbitraryNumber]
4795
+ }],
4796
+ /**
4797
+ * Stroke
4798
+ * @see https://tailwindcss.com/docs/stroke
4799
+ */
4800
+ stroke: [{
4801
+ stroke: ["none", ...scaleColor()]
4802
+ }],
4803
+ // ---------------------
4804
+ // --- Accessibility ---
4805
+ // ---------------------
4806
+ /**
4807
+ * Forced Color Adjust
4808
+ * @see https://tailwindcss.com/docs/forced-color-adjust
4809
+ */
4810
+ "forced-color-adjust": [{
4811
+ "forced-color-adjust": ["auto", "none"]
4812
+ }]
4813
+ },
4814
+ conflictingClassGroups: {
4815
+ overflow: ["overflow-x", "overflow-y"],
4816
+ overscroll: ["overscroll-x", "overscroll-y"],
4817
+ inset: ["inset-x", "inset-y", "start", "end", "top", "right", "bottom", "left"],
4818
+ "inset-x": ["right", "left"],
4819
+ "inset-y": ["top", "bottom"],
4820
+ flex: ["basis", "grow", "shrink"],
4821
+ gap: ["gap-x", "gap-y"],
4822
+ p: ["px", "py", "ps", "pe", "pt", "pr", "pb", "pl"],
4823
+ px: ["pr", "pl"],
4824
+ py: ["pt", "pb"],
4825
+ m: ["mx", "my", "ms", "me", "mt", "mr", "mb", "ml"],
4826
+ mx: ["mr", "ml"],
4827
+ my: ["mt", "mb"],
4828
+ size: ["w", "h"],
4829
+ "font-size": ["leading"],
4830
+ "fvn-normal": ["fvn-ordinal", "fvn-slashed-zero", "fvn-figure", "fvn-spacing", "fvn-fraction"],
4831
+ "fvn-ordinal": ["fvn-normal"],
4832
+ "fvn-slashed-zero": ["fvn-normal"],
4833
+ "fvn-figure": ["fvn-normal"],
4834
+ "fvn-spacing": ["fvn-normal"],
4835
+ "fvn-fraction": ["fvn-normal"],
4836
+ "line-clamp": ["display", "overflow"],
4837
+ rounded: ["rounded-s", "rounded-e", "rounded-t", "rounded-r", "rounded-b", "rounded-l", "rounded-ss", "rounded-se", "rounded-ee", "rounded-es", "rounded-tl", "rounded-tr", "rounded-br", "rounded-bl"],
4838
+ "rounded-s": ["rounded-ss", "rounded-es"],
4839
+ "rounded-e": ["rounded-se", "rounded-ee"],
4840
+ "rounded-t": ["rounded-tl", "rounded-tr"],
4841
+ "rounded-r": ["rounded-tr", "rounded-br"],
4842
+ "rounded-b": ["rounded-br", "rounded-bl"],
4843
+ "rounded-l": ["rounded-tl", "rounded-bl"],
4844
+ "border-spacing": ["border-spacing-x", "border-spacing-y"],
4845
+ "border-w": ["border-w-x", "border-w-y", "border-w-s", "border-w-e", "border-w-t", "border-w-r", "border-w-b", "border-w-l"],
4846
+ "border-w-x": ["border-w-r", "border-w-l"],
4847
+ "border-w-y": ["border-w-t", "border-w-b"],
4848
+ "border-color": ["border-color-x", "border-color-y", "border-color-s", "border-color-e", "border-color-t", "border-color-r", "border-color-b", "border-color-l"],
4849
+ "border-color-x": ["border-color-r", "border-color-l"],
4850
+ "border-color-y": ["border-color-t", "border-color-b"],
4851
+ translate: ["translate-x", "translate-y", "translate-none"],
4852
+ "translate-none": ["translate", "translate-x", "translate-y", "translate-z"],
4853
+ "scroll-m": ["scroll-mx", "scroll-my", "scroll-ms", "scroll-me", "scroll-mt", "scroll-mr", "scroll-mb", "scroll-ml"],
4854
+ "scroll-mx": ["scroll-mr", "scroll-ml"],
4855
+ "scroll-my": ["scroll-mt", "scroll-mb"],
4856
+ "scroll-p": ["scroll-px", "scroll-py", "scroll-ps", "scroll-pe", "scroll-pt", "scroll-pr", "scroll-pb", "scroll-pl"],
4857
+ "scroll-px": ["scroll-pr", "scroll-pl"],
4858
+ "scroll-py": ["scroll-pt", "scroll-pb"],
4859
+ touch: ["touch-x", "touch-y", "touch-pz"],
4860
+ "touch-x": ["touch"],
4861
+ "touch-y": ["touch"],
4862
+ "touch-pz": ["touch"]
4863
+ },
4864
+ conflictingClassGroupModifiers: {
4865
+ "font-size": ["leading"]
4866
+ },
4867
+ orderSensitiveModifiers: ["*", "**", "after", "backdrop", "before", "details-content", "file", "first-letter", "first-line", "marker", "placeholder", "selection"]
4868
+ };
4869
+ };
4870
+ const twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
4871
+ function cn(...inputs) {
4872
+ return twMerge(clsx(inputs));
4873
+ }
4874
+ export {
4875
+ AnnouncementBell,
4876
+ AnnouncementList,
4877
+ AnnouncementModal,
4878
+ FeedbackForm,
4879
+ FeedbackWidget,
4880
+ M as MockTraceyProvider,
4881
+ SurveyWidget,
4882
+ TraceyLauncher,
4883
+ T as TraceyProvider,
4884
+ cn,
4885
+ useAnnouncements,
4886
+ q as useFeedback,
4887
+ useMyFeedback,
4888
+ useSurvey,
4889
+ useTracey,
4890
+ r as useTraceyEvents
4891
+ };
4892
+ //# sourceMappingURL=index.js.map