motionwind-core 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/dist/adapter.cjs +31 -0
- package/dist/adapter.cjs.map +1 -0
- package/dist/adapter.d.cts +14 -0
- package/dist/adapter.d.ts +14 -0
- package/dist/adapter.js +3 -0
- package/dist/adapter.js.map +1 -0
- package/dist/chunk-A7EAMXLY.js +1098 -0
- package/dist/chunk-A7EAMXLY.js.map +1 -0
- package/dist/chunk-IJZCYKTO.js +352 -0
- package/dist/chunk-IJZCYKTO.js.map +1 -0
- package/dist/chunk-P6FC2RDE.js +25 -0
- package/dist/chunk-P6FC2RDE.js.map +1 -0
- package/dist/chunk-ULRTFOGX.js +28 -0
- package/dist/chunk-ULRTFOGX.js.map +1 -0
- package/dist/chunk-Z5I36REG.js +411 -0
- package/dist/chunk-Z5I36REG.js.map +1 -0
- package/dist/config.cjs +30 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +3 -0
- package/dist/config.js.map +1 -0
- package/dist/index.cjs +1970 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +60 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.cjs +1690 -0
- package/dist/parser.cjs.map +1 -0
- package/dist/parser.d.cts +21 -0
- package/dist/parser.d.ts +21 -0
- package/dist/parser.js +6 -0
- package/dist/parser.js.map +1 -0
- package/dist/recipes.cjs +359 -0
- package/dist/recipes.cjs.map +1 -0
- package/dist/recipes.d.cts +19 -0
- package/dist/recipes.d.ts +19 -0
- package/dist/recipes.js +4 -0
- package/dist/recipes.js.map +1 -0
- package/dist/registry.cjs +421 -0
- package/dist/registry.cjs.map +1 -0
- package/dist/registry.d.cts +1 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.js +3 -0
- package/dist/registry.js.map +1 -0
- package/dist/types-BYtWWSgh.d.cts +185 -0
- package/dist/types-BYtWWSgh.d.ts +185 -0
- package/llms.txt +77 -0
- package/package.json +96 -0
package/dist/parser.cjs
ADDED
|
@@ -0,0 +1,1690 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/registry.ts
|
|
4
|
+
var ALL = ["react", "vue", "vanilla", "react-native"];
|
|
5
|
+
var WEB = ["react", "vue", "vanilla"];
|
|
6
|
+
var gesture = (id, motionKey, description) => ({
|
|
7
|
+
id: `gesture.${id}`,
|
|
8
|
+
category: "gesture",
|
|
9
|
+
label: `animate-${id}:`,
|
|
10
|
+
snippet: `animate-${id}:`,
|
|
11
|
+
description,
|
|
12
|
+
motionKey,
|
|
13
|
+
platforms: ALL
|
|
14
|
+
});
|
|
15
|
+
var GESTURE_DEFINITIONS = [
|
|
16
|
+
gesture("hover", "whileHover", "Animate while an element is hovered."),
|
|
17
|
+
gesture("tap", "whileTap", "Animate while an element is pressed."),
|
|
18
|
+
gesture("focus", "whileFocus", "Animate while an element has focus."),
|
|
19
|
+
gesture("inview", "whileInView", "Animate while an element is in view."),
|
|
20
|
+
gesture("drag", "whileDrag", "Animate while an element is dragged."),
|
|
21
|
+
gesture("initial", "initial", "Set the state before an animation begins."),
|
|
22
|
+
gesture("enter", "animate", "Animate to a state when an element enters."),
|
|
23
|
+
gesture("exit", "exit", "Animate to a state when an element exits.")
|
|
24
|
+
];
|
|
25
|
+
var property = (label, snippet, motionKey, description, platforms = ALL) => ({
|
|
26
|
+
id: `property.${label.replace(/[^a-z0-9]+/gi, "-").replace(/^-|-$/g, "")}`,
|
|
27
|
+
category: "property",
|
|
28
|
+
label,
|
|
29
|
+
snippet,
|
|
30
|
+
motionKey,
|
|
31
|
+
description,
|
|
32
|
+
platforms
|
|
33
|
+
});
|
|
34
|
+
[
|
|
35
|
+
property(
|
|
36
|
+
"scale-",
|
|
37
|
+
"scale-${1:110}",
|
|
38
|
+
"scale",
|
|
39
|
+
"Scale (100 is the resting value)."
|
|
40
|
+
),
|
|
41
|
+
property("scale-x-", "scale-x-${1:110}", "scaleX", "Scale on the x axis."),
|
|
42
|
+
property("scale-y-", "scale-y-${1:110}", "scaleY", "Scale on the y axis."),
|
|
43
|
+
property(
|
|
44
|
+
"scale-z-",
|
|
45
|
+
"scale-z-${1:110}",
|
|
46
|
+
"scaleZ",
|
|
47
|
+
"Scale on the z axis.",
|
|
48
|
+
WEB
|
|
49
|
+
),
|
|
50
|
+
property("rotate-", "rotate-${1:45}", "rotate", "Rotate in degrees."),
|
|
51
|
+
property(
|
|
52
|
+
"rotate-x-",
|
|
53
|
+
"rotate-x-${1:45}",
|
|
54
|
+
"rotateX",
|
|
55
|
+
"Rotate around the x axis."
|
|
56
|
+
),
|
|
57
|
+
property(
|
|
58
|
+
"rotate-y-",
|
|
59
|
+
"rotate-y-${1:45}",
|
|
60
|
+
"rotateY",
|
|
61
|
+
"Rotate around the y axis."
|
|
62
|
+
),
|
|
63
|
+
property("x-", "x-${1:20}", "x", "Translate on the x axis."),
|
|
64
|
+
property("y-", "y-${1:20}", "y", "Translate on the y axis."),
|
|
65
|
+
property("z-", "z-${1:20}", "z", "Translate on the z axis.", WEB),
|
|
66
|
+
// z-{0,10,20,30,40,50,auto} maps to zIndex (Tailwind-standard values)
|
|
67
|
+
{
|
|
68
|
+
id: "property.z-zIndex",
|
|
69
|
+
category: "property",
|
|
70
|
+
label: "z-",
|
|
71
|
+
snippet: "z-${1|0,10,20,30,40,50,auto|}",
|
|
72
|
+
motionKey: "zIndex",
|
|
73
|
+
description: "Animate z-index (Tailwind values: 0, 10, 20, 30, 40, 50, auto). Non-standard values translate on the z axis instead.",
|
|
74
|
+
platforms: WEB
|
|
75
|
+
},
|
|
76
|
+
property("skew-x-", "skew-x-${1:12}", "skewX", "Skew on the x axis."),
|
|
77
|
+
property("skew-y-", "skew-y-${1:12}", "skewY", "Skew on the y axis."),
|
|
78
|
+
property(
|
|
79
|
+
"origin-x-",
|
|
80
|
+
"origin-x-${1:50}",
|
|
81
|
+
"originX",
|
|
82
|
+
"Set the x transform origin.",
|
|
83
|
+
WEB
|
|
84
|
+
),
|
|
85
|
+
property(
|
|
86
|
+
"origin-y-",
|
|
87
|
+
"origin-y-${1:50}",
|
|
88
|
+
"originY",
|
|
89
|
+
"Set the y transform origin.",
|
|
90
|
+
WEB
|
|
91
|
+
),
|
|
92
|
+
property(
|
|
93
|
+
"perspective-",
|
|
94
|
+
"perspective-${1:800}",
|
|
95
|
+
"perspective",
|
|
96
|
+
"Set 3D perspective.",
|
|
97
|
+
WEB
|
|
98
|
+
),
|
|
99
|
+
property("opacity-", "opacity-${1:0}", "opacity", "Animate opacity (0\u2013100)."),
|
|
100
|
+
property("blur-", "blur-${1:10}", "filter", "Animate CSS blur.", WEB),
|
|
101
|
+
property(
|
|
102
|
+
"brightness-",
|
|
103
|
+
"brightness-${1:120}",
|
|
104
|
+
"filter",
|
|
105
|
+
"Animate CSS brightness.",
|
|
106
|
+
WEB
|
|
107
|
+
),
|
|
108
|
+
property(
|
|
109
|
+
"contrast-",
|
|
110
|
+
"contrast-${1:120}",
|
|
111
|
+
"filter",
|
|
112
|
+
"Animate CSS contrast.",
|
|
113
|
+
WEB
|
|
114
|
+
),
|
|
115
|
+
property(
|
|
116
|
+
"saturate-",
|
|
117
|
+
"saturate-${1:120}",
|
|
118
|
+
"filter",
|
|
119
|
+
"Animate CSS saturation.",
|
|
120
|
+
WEB
|
|
121
|
+
),
|
|
122
|
+
property(
|
|
123
|
+
"grayscale-",
|
|
124
|
+
"grayscale-${1:100}",
|
|
125
|
+
"filter",
|
|
126
|
+
"Animate CSS grayscale.",
|
|
127
|
+
WEB
|
|
128
|
+
),
|
|
129
|
+
property(
|
|
130
|
+
"backdrop-blur-",
|
|
131
|
+
"backdrop-blur-${1:10}",
|
|
132
|
+
"backdropFilter",
|
|
133
|
+
"Animate backdrop blur.",
|
|
134
|
+
WEB
|
|
135
|
+
),
|
|
136
|
+
property("w-", "w-${1:100}", "width", "Animate width."),
|
|
137
|
+
property("h-", "h-${1:100}", "height", "Animate height."),
|
|
138
|
+
property(
|
|
139
|
+
"rounded-",
|
|
140
|
+
"rounded-${1:12}",
|
|
141
|
+
"borderRadius",
|
|
142
|
+
"Animate border radius."
|
|
143
|
+
),
|
|
144
|
+
property(
|
|
145
|
+
"rounded-tl-",
|
|
146
|
+
"rounded-tl-${1:12}",
|
|
147
|
+
"borderTopLeftRadius",
|
|
148
|
+
"Animate top-left border radius."
|
|
149
|
+
),
|
|
150
|
+
property(
|
|
151
|
+
"rounded-tr-",
|
|
152
|
+
"rounded-tr-${1:12}",
|
|
153
|
+
"borderTopRightRadius",
|
|
154
|
+
"Animate top-right border radius."
|
|
155
|
+
),
|
|
156
|
+
property(
|
|
157
|
+
"rounded-bl-",
|
|
158
|
+
"rounded-bl-${1:12}",
|
|
159
|
+
"borderBottomLeftRadius",
|
|
160
|
+
"Animate bottom-left border radius."
|
|
161
|
+
),
|
|
162
|
+
property(
|
|
163
|
+
"rounded-br-",
|
|
164
|
+
"rounded-br-${1:12}",
|
|
165
|
+
"borderBottomRightRadius",
|
|
166
|
+
"Animate bottom-right border radius."
|
|
167
|
+
),
|
|
168
|
+
property("top-", "top-${1:0}", "top", "Animate top position."),
|
|
169
|
+
property("left-", "left-${1:0}", "left", "Animate left position."),
|
|
170
|
+
property("right-", "right-${1:0}", "right", "Animate right position."),
|
|
171
|
+
property("bottom-", "bottom-${1:0}", "bottom", "Animate bottom position."),
|
|
172
|
+
property("p-", "p-${1:16}", "padding", "Animate padding."),
|
|
173
|
+
property("m-", "m-${1:16}", "margin", "Animate margin."),
|
|
174
|
+
property("gap-", "gap-${1:8}", "gap", "Animate gap."),
|
|
175
|
+
property("text-size-", "text-size-${1:16}", "fontSize", "Animate font size."),
|
|
176
|
+
property(
|
|
177
|
+
"tracking-",
|
|
178
|
+
"tracking-${1:1}",
|
|
179
|
+
"letterSpacing",
|
|
180
|
+
"Animate letter spacing."
|
|
181
|
+
),
|
|
182
|
+
property("leading-", "leading-${1:24}", "lineHeight", "Animate line height."),
|
|
183
|
+
property(
|
|
184
|
+
"border-w-",
|
|
185
|
+
"border-w-${1:2}",
|
|
186
|
+
"borderWidth",
|
|
187
|
+
"Animate border width."
|
|
188
|
+
),
|
|
189
|
+
property(
|
|
190
|
+
"bg-#",
|
|
191
|
+
"bg-#${1:c8ff2e}",
|
|
192
|
+
"backgroundColor",
|
|
193
|
+
"Animate background color."
|
|
194
|
+
),
|
|
195
|
+
property("text-#", "text-#${1:ffffff}", "color", "Animate text color."),
|
|
196
|
+
property(
|
|
197
|
+
"border-#",
|
|
198
|
+
"border-#${1:c8ff2e}",
|
|
199
|
+
"borderColor",
|
|
200
|
+
"Animate border color."
|
|
201
|
+
),
|
|
202
|
+
property(
|
|
203
|
+
"path-length-",
|
|
204
|
+
"path-length-${1:1}",
|
|
205
|
+
"pathLength",
|
|
206
|
+
"Animate SVG path length.",
|
|
207
|
+
WEB
|
|
208
|
+
),
|
|
209
|
+
property(
|
|
210
|
+
"text-shadow-[",
|
|
211
|
+
"text-shadow-[${1:value}]",
|
|
212
|
+
"textShadow",
|
|
213
|
+
"Animate text shadow (arbitrary value; underscores become spaces).",
|
|
214
|
+
WEB
|
|
215
|
+
),
|
|
216
|
+
property(
|
|
217
|
+
"[=]",
|
|
218
|
+
"[${1:property}=${2:value}]",
|
|
219
|
+
"arbitrary",
|
|
220
|
+
"Animate an allow-listed arbitrary value.",
|
|
221
|
+
WEB
|
|
222
|
+
)
|
|
223
|
+
];
|
|
224
|
+
var GESTURE_MAP = Object.fromEntries(
|
|
225
|
+
GESTURE_DEFINITIONS.map((definition) => [
|
|
226
|
+
definition.label.slice("animate-".length, -1),
|
|
227
|
+
definition.motionKey
|
|
228
|
+
])
|
|
229
|
+
);
|
|
230
|
+
var GESTURE_KEYS = new Set(Object.keys(GESTURE_MAP));
|
|
231
|
+
var EASING_MAP = {
|
|
232
|
+
"ease-in": "easeIn",
|
|
233
|
+
"ease-out": "easeOut",
|
|
234
|
+
"ease-in-out": "easeInOut",
|
|
235
|
+
"ease-linear": "linear",
|
|
236
|
+
"ease-circ-in": "circIn",
|
|
237
|
+
"ease-circ-out": "circOut",
|
|
238
|
+
"ease-circ-in-out": "circInOut",
|
|
239
|
+
"ease-back-in": "backIn",
|
|
240
|
+
"ease-back-out": "backOut",
|
|
241
|
+
"ease-back-in-out": "backInOut",
|
|
242
|
+
"ease-anticipate": "anticipate"
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// src/config.ts
|
|
246
|
+
function definePreset(preset) {
|
|
247
|
+
return preset;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// src/recipes.ts
|
|
251
|
+
var COMMUNITY_METADATA = {
|
|
252
|
+
maintainer: "motionwind/core",
|
|
253
|
+
version: "1.0.0",
|
|
254
|
+
compatibleCore: ">=2.0.0 <3",
|
|
255
|
+
bundleImpact: "Preset only; no runtime code added."
|
|
256
|
+
};
|
|
257
|
+
var source = (id) => `https://github.com/piyushzingade/motionwind/tree/main/registry/recipes/${id}.json`;
|
|
258
|
+
var MOTIONWIND_RECIPES = [
|
|
259
|
+
{
|
|
260
|
+
id: "button-press",
|
|
261
|
+
name: "Button press",
|
|
262
|
+
description: "A compact spring response for primary actions.",
|
|
263
|
+
category: "interaction",
|
|
264
|
+
classes: "animate-hover:scale-105 animate-tap:scale-95 animate-spring animate-stiffness-420 animate-damping-24",
|
|
265
|
+
accessibility: "Preserves keyboard focus and does not communicate state through motion alone.",
|
|
266
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
267
|
+
...COMMUNITY_METADATA,
|
|
268
|
+
source: source("button-press")
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: "dialog-enter",
|
|
272
|
+
name: "Dialog entrance",
|
|
273
|
+
description: "Fade and lift a dialog into place without excessive travel.",
|
|
274
|
+
category: "entrance",
|
|
275
|
+
classes: "animate-initial:opacity-0 animate-initial:y-12 animate-enter:opacity-100 animate-enter:y-0 animate-duration-240 animate-ease-out",
|
|
276
|
+
accessibility: "Pair with a focus trap and disable transform movement for reduced-motion users.",
|
|
277
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
278
|
+
...COMMUNITY_METADATA,
|
|
279
|
+
source: source("dialog-enter")
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
id: "list-stagger",
|
|
283
|
+
name: "List stagger",
|
|
284
|
+
description: "A restrained stagger for newly revealed collections.",
|
|
285
|
+
category: "entrance",
|
|
286
|
+
classes: "animate-stagger-55 animate-delay-children-40 animate-when-before",
|
|
287
|
+
accessibility: "Keep the list readable before and after animation; avoid repeated autoplay.",
|
|
288
|
+
adapters: ["react", "vue"],
|
|
289
|
+
...COMMUNITY_METADATA,
|
|
290
|
+
source: source("list-stagger")
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
id: "page-reveal",
|
|
294
|
+
name: "Page reveal",
|
|
295
|
+
description: "A single-run opacity and vertical reveal for page sections.",
|
|
296
|
+
category: "scroll",
|
|
297
|
+
classes: "animate-initial:opacity-0 animate-initial:y-24 animate-inview:opacity-100 animate-inview:y-0 animate-once animate-duration-480 animate-ease-out",
|
|
298
|
+
accessibility: "Content remains in document order and visible when reduced motion is requested.",
|
|
299
|
+
adapters: ["react", "vue", "vanilla"],
|
|
300
|
+
...COMMUNITY_METADATA,
|
|
301
|
+
source: source("page-reveal")
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
id: "loading-orbit",
|
|
305
|
+
name: "Loading orbit",
|
|
306
|
+
description: "A continuous linear rotation for non-blocking progress indicators.",
|
|
307
|
+
category: "loading",
|
|
308
|
+
classes: "animate-enter:rotate-360 animate-repeat-infinite animate-duration-900 animate-ease-linear",
|
|
309
|
+
accessibility: "Add an accessible status label and stop the loop when loading completes.",
|
|
310
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
311
|
+
...COMMUNITY_METADATA,
|
|
312
|
+
source: source("loading-orbit")
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
id: "menu-pop",
|
|
316
|
+
name: "Menu pop",
|
|
317
|
+
description: "A fast scale-and-fade entrance for contextual menus.",
|
|
318
|
+
category: "entrance",
|
|
319
|
+
classes: "animate-initial:opacity-0 animate-initial:scale-95 animate-enter:opacity-100 animate-enter:scale-100 animate-duration-160 animate-ease-out",
|
|
320
|
+
accessibility: "Move focus into the menu, return it on close, and preserve arrow-key navigation.",
|
|
321
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
322
|
+
...COMMUNITY_METADATA,
|
|
323
|
+
source: source("menu-pop")
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
id: "accordion-reveal",
|
|
327
|
+
name: "Accordion reveal",
|
|
328
|
+
description: "A layout-aware reveal for expandable disclosure content.",
|
|
329
|
+
category: "layout",
|
|
330
|
+
classes: "animate-layout-size animate-initial:opacity-0 animate-enter:opacity-100 animate-duration-220 animate-ease-out",
|
|
331
|
+
accessibility: "Use a native button with aria-expanded and keep content reachable without animation.",
|
|
332
|
+
adapters: ["react", "vue"],
|
|
333
|
+
...COMMUNITY_METADATA,
|
|
334
|
+
source: source("accordion-reveal")
|
|
335
|
+
},
|
|
336
|
+
{
|
|
337
|
+
id: "tab-indicator",
|
|
338
|
+
name: "Tab indicator",
|
|
339
|
+
description: "A shared-layout spring for an active tab indicator.",
|
|
340
|
+
category: "layout",
|
|
341
|
+
classes: "animate-layout-id-active-tab animate-spring animate-stiffness-440 animate-damping-34",
|
|
342
|
+
accessibility: "Pair with tablist semantics, roving focus, and an independent selected-state cue.",
|
|
343
|
+
adapters: ["react", "vue"],
|
|
344
|
+
...COMMUNITY_METADATA,
|
|
345
|
+
source: source("tab-indicator")
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
id: "toast-enter",
|
|
349
|
+
name: "Toast entrance",
|
|
350
|
+
description: "A short horizontal slide for non-blocking notifications.",
|
|
351
|
+
category: "entrance",
|
|
352
|
+
classes: "animate-initial:opacity-0 animate-initial:x-24 animate-enter:opacity-100 animate-enter:x-0 animate-duration-240 animate-ease-out",
|
|
353
|
+
accessibility: "Use an appropriate live region and provide enough time to read or dismiss the toast.",
|
|
354
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
355
|
+
...COMMUNITY_METADATA,
|
|
356
|
+
source: source("toast-enter")
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
id: "sortable-item",
|
|
360
|
+
name: "Sortable item",
|
|
361
|
+
description: "Layout animation and vertical drag feedback for reorderable lists.",
|
|
362
|
+
category: "interaction",
|
|
363
|
+
classes: "animate-layout-position animate-drag-y animate-drag-snap animate-drag:scale-103 animate-spring animate-stiffness-360 animate-damping-28",
|
|
364
|
+
accessibility: "Provide keyboard reordering controls and announce the new item position.",
|
|
365
|
+
adapters: ["react", "vue"],
|
|
366
|
+
...COMMUNITY_METADATA,
|
|
367
|
+
source: source("sortable-item")
|
|
368
|
+
},
|
|
369
|
+
{
|
|
370
|
+
id: "svg-line-loader",
|
|
371
|
+
name: "SVG line loader",
|
|
372
|
+
description: "Draw and repeat an SVG path for compact progress feedback.",
|
|
373
|
+
category: "loading",
|
|
374
|
+
classes: "animate-initial:path-length-0 animate-enter:path-length-1 animate-duration-900 animate-ease-in-out animate-repeat-infinite animate-repeat-reverse",
|
|
375
|
+
accessibility: "Give the SVG a status label and stop repeating when the operation completes.",
|
|
376
|
+
adapters: ["react", "vue", "vanilla"],
|
|
377
|
+
...COMMUNITY_METADATA,
|
|
378
|
+
source: source("svg-line-loader")
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
id: "scroll-progress",
|
|
382
|
+
name: "Scroll progress",
|
|
383
|
+
description: "Map page scroll progress to a horizontal scale indicator.",
|
|
384
|
+
category: "scroll",
|
|
385
|
+
classes: "animate-scroll:scaleX-[0,1] animate-scroll-container",
|
|
386
|
+
accessibility: "Treat the indicator as supplemental; expose document progress in text when it matters.",
|
|
387
|
+
adapters: ["react", "vanilla"],
|
|
388
|
+
...COMMUNITY_METADATA,
|
|
389
|
+
source: source("scroll-progress")
|
|
390
|
+
},
|
|
391
|
+
{
|
|
392
|
+
id: "flip-card",
|
|
393
|
+
name: "Flip card",
|
|
394
|
+
description: "A 3-D card that rotates 180 degrees around the Y axis on hover.",
|
|
395
|
+
category: "interaction",
|
|
396
|
+
classes: "animate-hover:rotate-y-180 animate-duration-480 animate-ease-in-out",
|
|
397
|
+
accessibility: "Pair with a separate back face and keep both sides keyboard-accessible.",
|
|
398
|
+
adapters: ["react", "vue", "vanilla"],
|
|
399
|
+
...COMMUNITY_METADATA,
|
|
400
|
+
source: source("flip-card")
|
|
401
|
+
},
|
|
402
|
+
{
|
|
403
|
+
id: "marquee",
|
|
404
|
+
name: "Marquee",
|
|
405
|
+
description: "A continuously looping horizontal scroll for text or image strips.",
|
|
406
|
+
category: "entrance",
|
|
407
|
+
classes: "animate-initial:x-100pct animate-enter:-x-100pct animate-repeat-infinite animate-ease-linear animate-duration-4000",
|
|
408
|
+
accessibility: "Pause the marquee on focus or hover; do not convey critical information through motion alone.",
|
|
409
|
+
adapters: ["react", "vue", "vanilla"],
|
|
410
|
+
...COMMUNITY_METADATA,
|
|
411
|
+
source: source("marquee")
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
id: "magnetic-button",
|
|
415
|
+
name: "Magnetic button",
|
|
416
|
+
description: "A subtle spring scale that draws attention on hover without moving the element.",
|
|
417
|
+
category: "interaction",
|
|
418
|
+
classes: "animate-hover:scale-103 animate-spring animate-stiffness-280 animate-damping-22",
|
|
419
|
+
accessibility: "Do not use scale change as the only indicator of an interactive element.",
|
|
420
|
+
adapters: ["react", "vue", "vanilla"],
|
|
421
|
+
...COMMUNITY_METADATA,
|
|
422
|
+
source: source("magnetic-button")
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
id: "drawer",
|
|
426
|
+
name: "Drawer",
|
|
427
|
+
description: "A side panel that slides in from the edge and returns on exit.",
|
|
428
|
+
category: "entrance",
|
|
429
|
+
classes: "animate-initial:x-100pct animate-enter:x-0 animate-exit:x-100pct animate-duration-320 animate-ease-out",
|
|
430
|
+
accessibility: "Trap focus inside the drawer, return focus on close, and support Escape to dismiss.",
|
|
431
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
432
|
+
...COMMUNITY_METADATA,
|
|
433
|
+
source: source("drawer")
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
id: "tooltip-pop",
|
|
437
|
+
name: "Tooltip pop",
|
|
438
|
+
description: "A small scale-and-fade entrance for contextual tooltips.",
|
|
439
|
+
category: "entrance",
|
|
440
|
+
classes: "animate-initial:opacity-0 animate-initial:scale-75 animate-enter:opacity-100 animate-enter:scale-100 animate-duration-160 animate-ease-back-out",
|
|
441
|
+
accessibility: "Use role='tooltip', aria-describedby, and ensure the tooltip is dismissible without a mouse.",
|
|
442
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
443
|
+
...COMMUNITY_METADATA,
|
|
444
|
+
source: source("tooltip-pop")
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
id: "skeleton-pulse",
|
|
448
|
+
name: "Skeleton pulse",
|
|
449
|
+
description: "A pulsing opacity loop for placeholder content while data loads.",
|
|
450
|
+
category: "loading",
|
|
451
|
+
classes: "animate-initial:opacity-100 animate-enter:opacity-40 animate-repeat-infinite animate-repeat-reverse animate-duration-800 animate-ease-in-out",
|
|
452
|
+
accessibility: "Announce loading state with aria-busy; remove skeleton when content arrives.",
|
|
453
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
454
|
+
...COMMUNITY_METADATA,
|
|
455
|
+
source: source("skeleton-pulse")
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
id: "shimmer-load",
|
|
459
|
+
name: "Shimmer load",
|
|
460
|
+
description: "A left-to-right gradient shimmer applied to a loading overlay.",
|
|
461
|
+
category: "loading",
|
|
462
|
+
classes: "animate-initial:-x-100pct animate-enter:x-100pct animate-repeat-infinite animate-duration-1200 animate-ease-in-out",
|
|
463
|
+
accessibility: "Place the shimmer on a decorative overlay; expose loading status through accessible text.",
|
|
464
|
+
adapters: ["react", "vue", "vanilla"],
|
|
465
|
+
...COMMUNITY_METADATA,
|
|
466
|
+
source: source("shimmer-load")
|
|
467
|
+
},
|
|
468
|
+
{
|
|
469
|
+
id: "card-hover",
|
|
470
|
+
name: "Card hover",
|
|
471
|
+
description: "A spring lift and upward nudge for interactive cards on hover.",
|
|
472
|
+
category: "interaction",
|
|
473
|
+
classes: "animate-hover:scale-103 animate-hover:y--4 animate-spring animate-stiffness-380 animate-damping-26",
|
|
474
|
+
accessibility: "Ensure focus styles are visible and the hover state is not the only interactive cue.",
|
|
475
|
+
adapters: ["react", "vue", "vanilla"],
|
|
476
|
+
...COMMUNITY_METADATA,
|
|
477
|
+
source: source("card-hover")
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
id: "number-counter",
|
|
481
|
+
name: "Number counter",
|
|
482
|
+
description: "A fade and rise entrance for statistic values triggered when they scroll into view.",
|
|
483
|
+
category: "scroll",
|
|
484
|
+
classes: "animate-initial:opacity-0 animate-initial:y-12 animate-inview:opacity-100 animate-inview:y-0 animate-once animate-duration-400 animate-ease-out",
|
|
485
|
+
accessibility: "Present the final value in document order and avoid conveying meaning through counting motion.",
|
|
486
|
+
adapters: ["react", "vue", "vanilla"],
|
|
487
|
+
...COMMUNITY_METADATA,
|
|
488
|
+
source: source("number-counter")
|
|
489
|
+
},
|
|
490
|
+
{
|
|
491
|
+
id: "progress-bar",
|
|
492
|
+
name: "Progress bar",
|
|
493
|
+
description: "An animated width fill for a progress bar triggered on scroll into view.",
|
|
494
|
+
category: "scroll",
|
|
495
|
+
classes: "animate-initial:w-0 animate-inview:w-100pct animate-once animate-duration-800 animate-ease-out",
|
|
496
|
+
accessibility: "Use a native progress element or role='progressbar' with aria-valuenow to expose state.",
|
|
497
|
+
adapters: ["react", "vue", "vanilla"],
|
|
498
|
+
...COMMUNITY_METADATA,
|
|
499
|
+
source: source("progress-bar")
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
id: "ripple",
|
|
503
|
+
name: "Ripple",
|
|
504
|
+
description: "A radial scale-and-fade burst that emanates from a tap point.",
|
|
505
|
+
category: "interaction",
|
|
506
|
+
classes: "animate-initial:scale-0 animate-initial:opacity-100 animate-enter:scale-400 animate-enter:opacity-0 animate-duration-500 animate-ease-out",
|
|
507
|
+
accessibility: "Use the ripple as a purely decorative effect and do not rely on it to communicate state.",
|
|
508
|
+
adapters: ["react", "vue", "vanilla"],
|
|
509
|
+
...COMMUNITY_METADATA,
|
|
510
|
+
source: source("ripple")
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
id: "blob-morph",
|
|
514
|
+
name: "Blob morph",
|
|
515
|
+
description: "An organic border-radius keyframe loop for fluid decorative shapes.",
|
|
516
|
+
category: "loading",
|
|
517
|
+
classes: "animate-enter:rounded-[0,30,60,30,0] animate-repeat-infinite animate-duration-3000 animate-ease-in-out animate-repeat-reverse",
|
|
518
|
+
accessibility: "Use only for decorative elements; apply aria-hidden to prevent interference with screen readers.",
|
|
519
|
+
adapters: ["react", "vue", "vanilla"],
|
|
520
|
+
...COMMUNITY_METADATA,
|
|
521
|
+
source: source("blob-morph")
|
|
522
|
+
},
|
|
523
|
+
{
|
|
524
|
+
id: "ticker",
|
|
525
|
+
name: "Ticker",
|
|
526
|
+
description: "A stock- or news-style ticker where items enter from the right and exit to the left.",
|
|
527
|
+
category: "entrance",
|
|
528
|
+
classes: "animate-initial:x-100pct animate-enter:x-0 animate-exit:-x-100pct animate-duration-500 animate-ease-out animate-stagger-150",
|
|
529
|
+
accessibility: "Provide a way to pause the ticker and make all content available in a static list.",
|
|
530
|
+
adapters: ["react", "vue", "vanilla"],
|
|
531
|
+
...COMMUNITY_METADATA,
|
|
532
|
+
source: source("ticker")
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
id: "popover-reveal",
|
|
536
|
+
name: "Popover reveal",
|
|
537
|
+
description: "A short downward fade-in for anchored popovers and dropdowns.",
|
|
538
|
+
category: "entrance",
|
|
539
|
+
classes: "animate-initial:opacity-0 animate-initial:y--8 animate-enter:opacity-100 animate-enter:y-0 animate-duration-180 animate-ease-out",
|
|
540
|
+
accessibility: "Move focus into the popover on open and return it to the trigger on close.",
|
|
541
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
542
|
+
...COMMUNITY_METADATA,
|
|
543
|
+
source: source("popover-reveal")
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
id: "stepper",
|
|
547
|
+
name: "Stepper",
|
|
548
|
+
description: "Sequential staggered entrances for step-indicator items.",
|
|
549
|
+
category: "entrance",
|
|
550
|
+
classes: "animate-initial:opacity-0 animate-initial:scale-80 animate-enter:opacity-100 animate-enter:scale-100 animate-stagger-80 animate-delay-children-100 animate-duration-200 animate-ease-back-out",
|
|
551
|
+
accessibility: "Announce the current step and total steps; keep step content readable without animation.",
|
|
552
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
553
|
+
...COMMUNITY_METADATA,
|
|
554
|
+
source: source("stepper")
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
id: "notification-stack",
|
|
558
|
+
name: "Notification stack",
|
|
559
|
+
description: "Staggered upward entrances for stacked notification cards.",
|
|
560
|
+
category: "entrance",
|
|
561
|
+
classes: "animate-initial:opacity-0 animate-initial:y--20 animate-enter:opacity-100 animate-enter:y-0 animate-stagger-80 animate-duration-260 animate-ease-back-out",
|
|
562
|
+
accessibility: "Use a live region with aria-live='polite' and provide enough time to read each notification.",
|
|
563
|
+
adapters: ["react", "vue", "vanilla", "react-native"],
|
|
564
|
+
...COMMUNITY_METADATA,
|
|
565
|
+
source: source("notification-stack")
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
id: "drag-reorder",
|
|
569
|
+
name: "Drag reorder",
|
|
570
|
+
description: "Vertical drag with layout animation for reorderable list items.",
|
|
571
|
+
category: "interaction",
|
|
572
|
+
classes: "animate-drag-y animate-layout-position animate-drag:scale-102 animate-spring animate-stiffness-320 animate-damping-30",
|
|
573
|
+
accessibility: "Provide keyboard controls for reordering and announce the new position after a drop.",
|
|
574
|
+
adapters: ["react", "vue"],
|
|
575
|
+
...COMMUNITY_METADATA,
|
|
576
|
+
source: source("drag-reorder")
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
id: "parallax-scroll",
|
|
580
|
+
name: "Parallax scroll",
|
|
581
|
+
description: "Map scroll progress to a Y translation so a layer moves at a different speed.",
|
|
582
|
+
category: "scroll",
|
|
583
|
+
classes: "animate-scroll:y-[-50,50] animate-scroll-container",
|
|
584
|
+
accessibility: "Respect prefers-reduced-motion; parallax depth cues must not convey meaning exclusively.",
|
|
585
|
+
adapters: ["react", "vanilla"],
|
|
586
|
+
...COMMUNITY_METADATA,
|
|
587
|
+
source: source("parallax-scroll")
|
|
588
|
+
}
|
|
589
|
+
];
|
|
590
|
+
var BUILT_IN_PRESETS = Object.fromEntries(
|
|
591
|
+
MOTIONWIND_RECIPES.map((recipe) => [recipe.id, definePreset(recipe.classes)])
|
|
592
|
+
);
|
|
593
|
+
|
|
594
|
+
// src/parser.ts
|
|
595
|
+
var CACHE_MAX = 1e3;
|
|
596
|
+
var cache = /* @__PURE__ */ new Map();
|
|
597
|
+
function presetClasses(value) {
|
|
598
|
+
return (typeof value === "string" ? value.split(/\s+/) : [...value]).filter(
|
|
599
|
+
Boolean
|
|
600
|
+
);
|
|
601
|
+
}
|
|
602
|
+
function availablePresets(config2) {
|
|
603
|
+
const pluginPresets = Object.assign(
|
|
604
|
+
{},
|
|
605
|
+
...(config2?.plugins ?? []).map((plugin) => plugin.presets ?? {})
|
|
606
|
+
);
|
|
607
|
+
return { ...BUILT_IN_PRESETS, ...pluginPresets, ...config2?.presets ?? {} };
|
|
608
|
+
}
|
|
609
|
+
function expandConfiguredTokens(className, config2, diagnostics) {
|
|
610
|
+
const presets = availablePresets(config2);
|
|
611
|
+
const output = [];
|
|
612
|
+
const expand = (token, stack) => {
|
|
613
|
+
if (!token.startsWith("animate-preset-")) {
|
|
614
|
+
const durationName = token.startsWith("animate-duration-") ? token.slice("animate-duration-".length) : "";
|
|
615
|
+
const duration = durationName ? config2?.tokens?.durations?.[durationName] : void 0;
|
|
616
|
+
if (duration !== void 0) {
|
|
617
|
+
output.push(`animate-duration-${duration}`);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
const easingName = token.startsWith("animate-ease-") ? token.slice("animate-ease-".length) : "";
|
|
621
|
+
const easing = easingName ? config2?.tokens?.easings?.[easingName] : void 0;
|
|
622
|
+
if (Array.isArray(easing)) {
|
|
623
|
+
output.push(`animate-ease-[${easing.join(",")}]`);
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
const springName = token.startsWith("animate-spring-") ? token.slice("animate-spring-".length) : "";
|
|
627
|
+
const spring = springName ? config2?.tokens?.springs?.[springName] : void 0;
|
|
628
|
+
if (spring) {
|
|
629
|
+
output.push("animate-spring");
|
|
630
|
+
if (spring.stiffness !== void 0)
|
|
631
|
+
output.push(`animate-stiffness-${spring.stiffness}`);
|
|
632
|
+
if (spring.damping !== void 0)
|
|
633
|
+
output.push(`animate-damping-${spring.damping}`);
|
|
634
|
+
if (spring.bounce !== void 0)
|
|
635
|
+
output.push(`animate-bounce-${spring.bounce}`);
|
|
636
|
+
if (spring.mass !== void 0)
|
|
637
|
+
output.push(`animate-mass-${spring.mass}`);
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
output.push(token);
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
643
|
+
const name = token.slice("animate-preset-".length);
|
|
644
|
+
const preset = presets[name];
|
|
645
|
+
if (!preset) {
|
|
646
|
+
diagnostics.push({
|
|
647
|
+
code: "unknown-preset",
|
|
648
|
+
message: `Unknown motionwind preset "${name}".`,
|
|
649
|
+
severity: config2?.strict ? "error" : "warning",
|
|
650
|
+
token
|
|
651
|
+
});
|
|
652
|
+
output.push(token);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
if (stack.includes(name) || stack.length >= 8) {
|
|
656
|
+
diagnostics.push({
|
|
657
|
+
code: "circular-preset",
|
|
658
|
+
message: `Circular motionwind preset expansion: ${[...stack, name].join(" \u2192 ")}.`,
|
|
659
|
+
severity: "error",
|
|
660
|
+
token
|
|
661
|
+
});
|
|
662
|
+
return;
|
|
663
|
+
}
|
|
664
|
+
for (const expanded of presetClasses(preset))
|
|
665
|
+
expand(expanded, [...stack, name]);
|
|
666
|
+
};
|
|
667
|
+
for (const token of className.split(/\s+/).filter(Boolean)) expand(token, []);
|
|
668
|
+
return output;
|
|
669
|
+
}
|
|
670
|
+
function mergePatch(patch, gestures, transition, viewport, dragConfig, layoutConfig, scroll, variants, variantState) {
|
|
671
|
+
for (const [key, values] of Object.entries(patch.gestures ?? {})) {
|
|
672
|
+
gestures[key] = {
|
|
673
|
+
...gestures[key] ?? {},
|
|
674
|
+
...values ?? {}
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
Object.assign(transition, patch.transition);
|
|
678
|
+
Object.assign(viewport, patch.viewport);
|
|
679
|
+
Object.assign(dragConfig, patch.dragConfig);
|
|
680
|
+
Object.assign(layoutConfig, patch.layoutConfig);
|
|
681
|
+
if (patch.scroll) {
|
|
682
|
+
Object.assign(scroll, patch.scroll);
|
|
683
|
+
if (patch.scroll.values)
|
|
684
|
+
scroll.values = { ...scroll.values, ...patch.scroll.values };
|
|
685
|
+
}
|
|
686
|
+
for (const [name, values] of Object.entries(patch.variants ?? {})) {
|
|
687
|
+
variants[name] = { ...variants[name] ?? {}, ...values };
|
|
688
|
+
}
|
|
689
|
+
Object.assign(variantState, patch.variantState);
|
|
690
|
+
}
|
|
691
|
+
var TAILWIND_ANIMATE_CLASSES = /* @__PURE__ */ new Set([
|
|
692
|
+
"animate-spin",
|
|
693
|
+
"animate-ping",
|
|
694
|
+
"animate-pulse",
|
|
695
|
+
"animate-bounce",
|
|
696
|
+
"animate-none"
|
|
697
|
+
]);
|
|
698
|
+
function cacheSet(key, value) {
|
|
699
|
+
if (cache.size >= CACHE_MAX) {
|
|
700
|
+
const firstKey = cache.keys().next().value;
|
|
701
|
+
if (firstKey !== void 0) cache.delete(firstKey);
|
|
702
|
+
}
|
|
703
|
+
cache.set(key, value);
|
|
704
|
+
}
|
|
705
|
+
var UNIT_MAP = {
|
|
706
|
+
pct: "%",
|
|
707
|
+
px: "px",
|
|
708
|
+
vh: "vh",
|
|
709
|
+
vw: "vw",
|
|
710
|
+
rem: "rem",
|
|
711
|
+
em: "em",
|
|
712
|
+
dvh: "dvh",
|
|
713
|
+
svh: "svh",
|
|
714
|
+
lvh: "lvh"
|
|
715
|
+
};
|
|
716
|
+
function parseNumericWithUnit(str, sign) {
|
|
717
|
+
if (str === "auto") return "auto";
|
|
718
|
+
for (const [suffix, unit] of Object.entries(UNIT_MAP)) {
|
|
719
|
+
if (str.endsWith(suffix)) {
|
|
720
|
+
const numPart = str.slice(0, -suffix.length);
|
|
721
|
+
const n2 = Number(numPart);
|
|
722
|
+
if (isNaN(n2)) return null;
|
|
723
|
+
return `${n2 * sign}${unit}`;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
const n = Number(str);
|
|
727
|
+
if (isNaN(n)) return null;
|
|
728
|
+
return n * sign;
|
|
729
|
+
}
|
|
730
|
+
var ARBITRARY_VALUE_ALLOWLIST = /* @__PURE__ */ new Set([
|
|
731
|
+
"x",
|
|
732
|
+
"y",
|
|
733
|
+
"z",
|
|
734
|
+
"scale",
|
|
735
|
+
"scaleX",
|
|
736
|
+
"scaleY",
|
|
737
|
+
"scaleZ",
|
|
738
|
+
"rotate",
|
|
739
|
+
"rotateX",
|
|
740
|
+
"rotateY",
|
|
741
|
+
"rotateZ",
|
|
742
|
+
"skew",
|
|
743
|
+
"skewX",
|
|
744
|
+
"skewY",
|
|
745
|
+
"originX",
|
|
746
|
+
"originY",
|
|
747
|
+
"originZ",
|
|
748
|
+
"perspective",
|
|
749
|
+
"opacity",
|
|
750
|
+
"filter",
|
|
751
|
+
"backdropFilter",
|
|
752
|
+
"clipPath",
|
|
753
|
+
"width",
|
|
754
|
+
"height",
|
|
755
|
+
"top",
|
|
756
|
+
"left",
|
|
757
|
+
"right",
|
|
758
|
+
"bottom",
|
|
759
|
+
"padding",
|
|
760
|
+
"margin",
|
|
761
|
+
"gap",
|
|
762
|
+
"borderRadius",
|
|
763
|
+
"borderTopLeftRadius",
|
|
764
|
+
"borderTopRightRadius",
|
|
765
|
+
"borderBottomLeftRadius",
|
|
766
|
+
"borderBottomRightRadius",
|
|
767
|
+
"borderWidth",
|
|
768
|
+
"fontSize",
|
|
769
|
+
"letterSpacing",
|
|
770
|
+
"lineHeight",
|
|
771
|
+
"backgroundColor",
|
|
772
|
+
"color",
|
|
773
|
+
"borderColor",
|
|
774
|
+
"boxShadow",
|
|
775
|
+
"textShadow",
|
|
776
|
+
"zIndex",
|
|
777
|
+
"pathLength",
|
|
778
|
+
"pathOffset",
|
|
779
|
+
"pathSpacing"
|
|
780
|
+
]);
|
|
781
|
+
function parsePropertyValue(raw) {
|
|
782
|
+
if (raw.startsWith("[") && raw.endsWith("]")) {
|
|
783
|
+
const inner = raw.slice(1, -1);
|
|
784
|
+
const eqIdx = inner.indexOf("=");
|
|
785
|
+
if (eqIdx === -1) return null;
|
|
786
|
+
const key = inner.slice(0, eqIdx);
|
|
787
|
+
if (!ARBITRARY_VALUE_ALLOWLIST.has(key)) return null;
|
|
788
|
+
const val = inner.slice(eqIdx + 1);
|
|
789
|
+
const num = Number(val);
|
|
790
|
+
return { key, value: isNaN(num) ? val : num };
|
|
791
|
+
}
|
|
792
|
+
let negative = false;
|
|
793
|
+
let str = raw;
|
|
794
|
+
if (str.startsWith("-")) {
|
|
795
|
+
negative = true;
|
|
796
|
+
str = str.slice(1);
|
|
797
|
+
}
|
|
798
|
+
const sign = negative ? -1 : 1;
|
|
799
|
+
const keyframeMatch = str.match(/^(\w+(?:-\w+)?)-\[([^\]]+)\]$/);
|
|
800
|
+
if (keyframeMatch) {
|
|
801
|
+
const propName = keyframeMatch[1];
|
|
802
|
+
const valuesStr = keyframeMatch[2];
|
|
803
|
+
const propKey = normalizePropertyName(propName);
|
|
804
|
+
if (propKey) {
|
|
805
|
+
const rawValues = valuesStr.split(",").reduce((acc, v) => {
|
|
806
|
+
const t = v.trim();
|
|
807
|
+
if (t) acc.push(t);
|
|
808
|
+
return acc;
|
|
809
|
+
}, []);
|
|
810
|
+
if (rawValues.length > 0) {
|
|
811
|
+
const scaleProps = /* @__PURE__ */ new Set([
|
|
812
|
+
"scale",
|
|
813
|
+
"scaleX",
|
|
814
|
+
"scaleY",
|
|
815
|
+
"scaleZ",
|
|
816
|
+
"opacity",
|
|
817
|
+
"brightness",
|
|
818
|
+
"contrast",
|
|
819
|
+
"saturate"
|
|
820
|
+
]);
|
|
821
|
+
const parsed = [];
|
|
822
|
+
let valid = true;
|
|
823
|
+
for (const rv of rawValues) {
|
|
824
|
+
const unitVal = parseNumericWithUnit(rv, 1);
|
|
825
|
+
if (unitVal === null) {
|
|
826
|
+
valid = false;
|
|
827
|
+
break;
|
|
828
|
+
}
|
|
829
|
+
if (typeof unitVal === "number" && scaleProps.has(propKey)) {
|
|
830
|
+
parsed.push(unitVal / 100);
|
|
831
|
+
} else {
|
|
832
|
+
parsed.push(unitVal);
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
if (valid) {
|
|
836
|
+
return { key: propKey, value: parsed };
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
if (str.startsWith("scale-z-")) {
|
|
842
|
+
const n = Number(str.slice(8));
|
|
843
|
+
if (!isNaN(n)) return { key: "scaleZ", value: n / 100 * sign };
|
|
844
|
+
}
|
|
845
|
+
if (str.startsWith("scale-x-")) {
|
|
846
|
+
const n = Number(str.slice(8));
|
|
847
|
+
if (!isNaN(n)) return { key: "scaleX", value: n / 100 * sign };
|
|
848
|
+
}
|
|
849
|
+
if (str.startsWith("scale-y-")) {
|
|
850
|
+
const n = Number(str.slice(8));
|
|
851
|
+
if (!isNaN(n)) return { key: "scaleY", value: n / 100 * sign };
|
|
852
|
+
}
|
|
853
|
+
if (str.startsWith("scale-")) {
|
|
854
|
+
const n = Number(str.slice(6));
|
|
855
|
+
if (!isNaN(n)) return { key: "scale", value: n / 100 * sign };
|
|
856
|
+
}
|
|
857
|
+
if (str.startsWith("rotate-x-")) {
|
|
858
|
+
const n = Number(str.slice(9));
|
|
859
|
+
if (!isNaN(n)) return { key: "rotateX", value: n * sign };
|
|
860
|
+
}
|
|
861
|
+
if (str.startsWith("rotate-y-")) {
|
|
862
|
+
const n = Number(str.slice(9));
|
|
863
|
+
if (!isNaN(n)) return { key: "rotateY", value: n * sign };
|
|
864
|
+
}
|
|
865
|
+
if (str.startsWith("rotate-")) {
|
|
866
|
+
const n = Number(str.slice(7));
|
|
867
|
+
if (!isNaN(n)) return { key: "rotate", value: n * sign };
|
|
868
|
+
}
|
|
869
|
+
if (str.startsWith("skew-x-")) {
|
|
870
|
+
const n = Number(str.slice(7));
|
|
871
|
+
if (!isNaN(n)) return { key: "skewX", value: n * sign };
|
|
872
|
+
}
|
|
873
|
+
if (str.startsWith("skew-y-")) {
|
|
874
|
+
const n = Number(str.slice(7));
|
|
875
|
+
if (!isNaN(n)) return { key: "skewY", value: n * sign };
|
|
876
|
+
}
|
|
877
|
+
if (str.startsWith("skew-")) {
|
|
878
|
+
const n = Number(str.slice(5));
|
|
879
|
+
if (!isNaN(n)) return { key: "skew", value: n * sign };
|
|
880
|
+
}
|
|
881
|
+
if (str.startsWith("origin-x-")) {
|
|
882
|
+
const n = Number(str.slice(9));
|
|
883
|
+
if (!isNaN(n)) return { key: "originX", value: n / 100 * sign };
|
|
884
|
+
}
|
|
885
|
+
if (str.startsWith("origin-y-")) {
|
|
886
|
+
const n = Number(str.slice(9));
|
|
887
|
+
if (!isNaN(n)) return { key: "originY", value: n / 100 * sign };
|
|
888
|
+
}
|
|
889
|
+
if (str.startsWith("origin-z-")) {
|
|
890
|
+
const n = Number(str.slice(9));
|
|
891
|
+
if (!isNaN(n)) return { key: "originZ", value: n * sign };
|
|
892
|
+
}
|
|
893
|
+
if (str.startsWith("perspective-")) {
|
|
894
|
+
const n = Number(str.slice(12));
|
|
895
|
+
if (!isNaN(n)) return { key: "perspective", value: n * sign };
|
|
896
|
+
}
|
|
897
|
+
if (str.startsWith("x-")) {
|
|
898
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
899
|
+
if (val !== null) return { key: "x", value: val };
|
|
900
|
+
}
|
|
901
|
+
if (str.startsWith("y-")) {
|
|
902
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
903
|
+
if (val !== null) return { key: "y", value: val };
|
|
904
|
+
}
|
|
905
|
+
if (str.startsWith("z-")) {
|
|
906
|
+
const suffix = str.slice(2);
|
|
907
|
+
if (suffix === "auto") return { key: "zIndex", value: "auto" };
|
|
908
|
+
const zn = Number(suffix);
|
|
909
|
+
if (!isNaN(zn) && [0, 10, 20, 30, 40, 50].includes(zn))
|
|
910
|
+
return { key: "zIndex", value: zn };
|
|
911
|
+
}
|
|
912
|
+
if (str.startsWith("z-")) {
|
|
913
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
914
|
+
if (val !== null) return { key: "z", value: val };
|
|
915
|
+
}
|
|
916
|
+
if (str.startsWith("opacity-")) {
|
|
917
|
+
const n = Number(str.slice(8));
|
|
918
|
+
if (!isNaN(n)) return { key: "opacity", value: n / 100 * sign };
|
|
919
|
+
}
|
|
920
|
+
if (str.startsWith("blur-")) {
|
|
921
|
+
const n = Number(str.slice(5));
|
|
922
|
+
if (!isNaN(n))
|
|
923
|
+
return { key: "filter", value: `blur(${Math.max(0, n * sign)}px)` };
|
|
924
|
+
}
|
|
925
|
+
if (str.startsWith("brightness-")) {
|
|
926
|
+
const n = Number(str.slice(11));
|
|
927
|
+
if (!isNaN(n))
|
|
928
|
+
return {
|
|
929
|
+
key: "filter",
|
|
930
|
+
value: `brightness(${Math.max(0, n / 100 * sign)})`
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
if (str.startsWith("contrast-")) {
|
|
934
|
+
const n = Number(str.slice(9));
|
|
935
|
+
if (!isNaN(n))
|
|
936
|
+
return {
|
|
937
|
+
key: "filter",
|
|
938
|
+
value: `contrast(${Math.max(0, n / 100 * sign)})`
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
if (str.startsWith("saturate-")) {
|
|
942
|
+
const n = Number(str.slice(9));
|
|
943
|
+
if (!isNaN(n))
|
|
944
|
+
return {
|
|
945
|
+
key: "filter",
|
|
946
|
+
value: `saturate(${Math.max(0, n / 100 * sign)})`
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
if (str.startsWith("grayscale-")) {
|
|
950
|
+
const n = Number(str.slice(10));
|
|
951
|
+
if (!isNaN(n))
|
|
952
|
+
return {
|
|
953
|
+
key: "filter",
|
|
954
|
+
value: `grayscale(${Math.max(0, n / 100 * sign)})`
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
if (str.startsWith("sepia-")) {
|
|
958
|
+
const n = Number(str.slice(6));
|
|
959
|
+
if (!isNaN(n))
|
|
960
|
+
return {
|
|
961
|
+
key: "filter",
|
|
962
|
+
value: `sepia(${Math.max(0, n / 100 * sign)})`
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
if (str.startsWith("invert-")) {
|
|
966
|
+
const n = Number(str.slice(7));
|
|
967
|
+
if (!isNaN(n))
|
|
968
|
+
return {
|
|
969
|
+
key: "filter",
|
|
970
|
+
value: `invert(${Math.max(0, n / 100 * sign)})`
|
|
971
|
+
};
|
|
972
|
+
}
|
|
973
|
+
if (str.startsWith("hue-rotate-")) {
|
|
974
|
+
const n = Number(str.slice(11));
|
|
975
|
+
if (!isNaN(n))
|
|
976
|
+
return { key: "filter", value: `hue-rotate(${n * sign}deg)` };
|
|
977
|
+
}
|
|
978
|
+
if (str.startsWith("drop-shadow-")) {
|
|
979
|
+
const val = str.slice(12);
|
|
980
|
+
if (val.startsWith("[") && val.endsWith("]")) {
|
|
981
|
+
return {
|
|
982
|
+
key: "filter",
|
|
983
|
+
value: `drop-shadow(${val.slice(1, -1).replace(/_/g, " ")})`
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
if (str.startsWith("backdrop-blur-")) {
|
|
988
|
+
const n = Number(str.slice(14));
|
|
989
|
+
if (!isNaN(n))
|
|
990
|
+
return {
|
|
991
|
+
key: "backdropFilter",
|
|
992
|
+
value: `blur(${Math.max(0, n * sign)}px)`
|
|
993
|
+
};
|
|
994
|
+
}
|
|
995
|
+
if (str.startsWith("clip-")) {
|
|
996
|
+
const val = str.slice(5);
|
|
997
|
+
if (val.startsWith("[") && val.endsWith("]")) {
|
|
998
|
+
return { key: "clipPath", value: val.slice(1, -1) };
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
if (str.startsWith("rounded-tl-")) {
|
|
1002
|
+
const n = Number(str.slice(11));
|
|
1003
|
+
if (!isNaN(n)) return { key: "borderTopLeftRadius", value: n * sign };
|
|
1004
|
+
}
|
|
1005
|
+
if (str.startsWith("rounded-tr-")) {
|
|
1006
|
+
const n = Number(str.slice(11));
|
|
1007
|
+
if (!isNaN(n)) return { key: "borderTopRightRadius", value: n * sign };
|
|
1008
|
+
}
|
|
1009
|
+
if (str.startsWith("rounded-bl-")) {
|
|
1010
|
+
const n = Number(str.slice(11));
|
|
1011
|
+
if (!isNaN(n)) return { key: "borderBottomLeftRadius", value: n * sign };
|
|
1012
|
+
}
|
|
1013
|
+
if (str.startsWith("rounded-br-")) {
|
|
1014
|
+
const n = Number(str.slice(11));
|
|
1015
|
+
if (!isNaN(n)) return { key: "borderBottomRightRadius", value: n * sign };
|
|
1016
|
+
}
|
|
1017
|
+
if (str.startsWith("rounded-")) {
|
|
1018
|
+
const n = Number(str.slice(8));
|
|
1019
|
+
if (!isNaN(n)) return { key: "borderRadius", value: n * sign };
|
|
1020
|
+
}
|
|
1021
|
+
if (str.startsWith("w-")) {
|
|
1022
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
1023
|
+
if (val !== null) return { key: "width", value: val };
|
|
1024
|
+
}
|
|
1025
|
+
if (str.startsWith("h-")) {
|
|
1026
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
1027
|
+
if (val !== null) return { key: "height", value: val };
|
|
1028
|
+
}
|
|
1029
|
+
if (str.startsWith("top-")) {
|
|
1030
|
+
const val = parseNumericWithUnit(str.slice(4), sign);
|
|
1031
|
+
if (val !== null) return { key: "top", value: val };
|
|
1032
|
+
}
|
|
1033
|
+
if (str.startsWith("left-")) {
|
|
1034
|
+
const val = parseNumericWithUnit(str.slice(5), sign);
|
|
1035
|
+
if (val !== null) return { key: "left", value: val };
|
|
1036
|
+
}
|
|
1037
|
+
if (str.startsWith("right-")) {
|
|
1038
|
+
const val = parseNumericWithUnit(str.slice(6), sign);
|
|
1039
|
+
if (val !== null) return { key: "right", value: val };
|
|
1040
|
+
}
|
|
1041
|
+
if (str.startsWith("bottom-")) {
|
|
1042
|
+
const val = parseNumericWithUnit(str.slice(7), sign);
|
|
1043
|
+
if (val !== null) return { key: "bottom", value: val };
|
|
1044
|
+
}
|
|
1045
|
+
if (str.startsWith("p-")) {
|
|
1046
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
1047
|
+
if (val !== null) return { key: "padding", value: val };
|
|
1048
|
+
}
|
|
1049
|
+
if (str.startsWith("m-")) {
|
|
1050
|
+
const val = parseNumericWithUnit(str.slice(2), sign);
|
|
1051
|
+
if (val !== null) return { key: "margin", value: val };
|
|
1052
|
+
}
|
|
1053
|
+
if (str.startsWith("gap-")) {
|
|
1054
|
+
const val = parseNumericWithUnit(str.slice(4), sign);
|
|
1055
|
+
if (val !== null) return { key: "gap", value: val };
|
|
1056
|
+
}
|
|
1057
|
+
if (str.startsWith("text-size-")) {
|
|
1058
|
+
const val = parseNumericWithUnit(str.slice(10), sign);
|
|
1059
|
+
if (val !== null) return { key: "fontSize", value: val };
|
|
1060
|
+
}
|
|
1061
|
+
if (str.startsWith("tracking-")) {
|
|
1062
|
+
const val = parseNumericWithUnit(str.slice(9), sign);
|
|
1063
|
+
if (val !== null) return { key: "letterSpacing", value: val };
|
|
1064
|
+
}
|
|
1065
|
+
if (str.startsWith("leading-")) {
|
|
1066
|
+
const val = parseNumericWithUnit(str.slice(8), sign);
|
|
1067
|
+
if (val !== null) return { key: "lineHeight", value: val };
|
|
1068
|
+
}
|
|
1069
|
+
if (str.startsWith("border-w-")) {
|
|
1070
|
+
const n = Number(str.slice(9));
|
|
1071
|
+
if (!isNaN(n)) return { key: "borderWidth", value: n * sign };
|
|
1072
|
+
}
|
|
1073
|
+
if (str.startsWith("path-length-")) {
|
|
1074
|
+
const n = Number(str.slice(12));
|
|
1075
|
+
if (!isNaN(n)) return { key: "pathLength", value: n * sign };
|
|
1076
|
+
}
|
|
1077
|
+
if (str.startsWith("path-offset-")) {
|
|
1078
|
+
const n = Number(str.slice(12));
|
|
1079
|
+
if (!isNaN(n)) return { key: "pathOffset", value: n * sign };
|
|
1080
|
+
}
|
|
1081
|
+
if (str.startsWith("path-spacing-")) {
|
|
1082
|
+
const n = Number(str.slice(13));
|
|
1083
|
+
if (!isNaN(n)) return { key: "pathSpacing", value: n * sign };
|
|
1084
|
+
}
|
|
1085
|
+
if (str.startsWith("bg-")) {
|
|
1086
|
+
const color = str.slice(3);
|
|
1087
|
+
if (isValidColor(color)) {
|
|
1088
|
+
return { key: "backgroundColor", value: color };
|
|
1089
|
+
}
|
|
1090
|
+
return null;
|
|
1091
|
+
}
|
|
1092
|
+
if (str.startsWith("text-shadow-")) {
|
|
1093
|
+
const val = str.slice(12);
|
|
1094
|
+
if (val.startsWith("[") && val.endsWith("]")) {
|
|
1095
|
+
return {
|
|
1096
|
+
key: "textShadow",
|
|
1097
|
+
value: val.slice(1, -1).replace(/_/g, " ")
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
if (str.startsWith("text-")) {
|
|
1102
|
+
const color = str.slice(5);
|
|
1103
|
+
if (isValidColor(color)) {
|
|
1104
|
+
return { key: "color", value: color };
|
|
1105
|
+
}
|
|
1106
|
+
return null;
|
|
1107
|
+
}
|
|
1108
|
+
if (str.startsWith("border-")) {
|
|
1109
|
+
const color = str.slice(7);
|
|
1110
|
+
if (isValidColor(color)) {
|
|
1111
|
+
return { key: "borderColor", value: color };
|
|
1112
|
+
}
|
|
1113
|
+
return null;
|
|
1114
|
+
}
|
|
1115
|
+
if (str.startsWith("shadow-")) {
|
|
1116
|
+
const val = str.slice(7);
|
|
1117
|
+
if (val.startsWith("[") && val.endsWith("]")) {
|
|
1118
|
+
return { key: "boxShadow", value: val.slice(1, -1) };
|
|
1119
|
+
}
|
|
1120
|
+
return null;
|
|
1121
|
+
}
|
|
1122
|
+
return null;
|
|
1123
|
+
}
|
|
1124
|
+
var HEX_COLOR_RE = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
|
|
1125
|
+
var FUNC_COLOR_RE = /^(?:rgb|rgba|hsl|hsla)\(.+\)$/;
|
|
1126
|
+
function isValidColor(color) {
|
|
1127
|
+
return HEX_COLOR_RE.test(color) || FUNC_COLOR_RE.test(color);
|
|
1128
|
+
}
|
|
1129
|
+
function normalizePropertyName(name) {
|
|
1130
|
+
const map = {
|
|
1131
|
+
scale: "scale",
|
|
1132
|
+
"scale-x": "scaleX",
|
|
1133
|
+
"scale-y": "scaleY",
|
|
1134
|
+
"scale-z": "scaleZ",
|
|
1135
|
+
rotate: "rotate",
|
|
1136
|
+
"rotate-x": "rotateX",
|
|
1137
|
+
"rotate-y": "rotateY",
|
|
1138
|
+
x: "x",
|
|
1139
|
+
y: "y",
|
|
1140
|
+
z: "z",
|
|
1141
|
+
opacity: "opacity",
|
|
1142
|
+
"skew-x": "skewX",
|
|
1143
|
+
"skew-y": "skewY",
|
|
1144
|
+
skew: "skew",
|
|
1145
|
+
w: "width",
|
|
1146
|
+
h: "height",
|
|
1147
|
+
rounded: "borderRadius",
|
|
1148
|
+
"rounded-tl": "borderTopLeftRadius",
|
|
1149
|
+
"rounded-tr": "borderTopRightRadius",
|
|
1150
|
+
"rounded-bl": "borderBottomLeftRadius",
|
|
1151
|
+
"rounded-br": "borderBottomRightRadius",
|
|
1152
|
+
"origin-x": "originX",
|
|
1153
|
+
"origin-y": "originY",
|
|
1154
|
+
"origin-z": "originZ",
|
|
1155
|
+
perspective: "perspective"
|
|
1156
|
+
};
|
|
1157
|
+
return map[name] ?? null;
|
|
1158
|
+
}
|
|
1159
|
+
function normalizeScrollProp(name) {
|
|
1160
|
+
const n = name.toLowerCase().replace(/-/g, "");
|
|
1161
|
+
const map = {
|
|
1162
|
+
x: "x",
|
|
1163
|
+
y: "y",
|
|
1164
|
+
z: "z",
|
|
1165
|
+
opacity: "opacity",
|
|
1166
|
+
rotate: "rotate",
|
|
1167
|
+
rotatex: "rotateX",
|
|
1168
|
+
rotatey: "rotateY",
|
|
1169
|
+
scale: "scale",
|
|
1170
|
+
scalex: "scaleX",
|
|
1171
|
+
scaley: "scaleY"
|
|
1172
|
+
};
|
|
1173
|
+
return map[n] ?? null;
|
|
1174
|
+
}
|
|
1175
|
+
function parseScrollValue(raw) {
|
|
1176
|
+
const m = raw.match(/^([\w-]+?)-\[([^\]]+)\]$/);
|
|
1177
|
+
if (!m) return null;
|
|
1178
|
+
const key = normalizeScrollProp(m[1]);
|
|
1179
|
+
if (!key) return null;
|
|
1180
|
+
const parts = m[2].split(",").map((v) => Number(v.trim()));
|
|
1181
|
+
if (parts.length < 2 || parts.some((n) => isNaN(n))) return null;
|
|
1182
|
+
return { key, value: parts };
|
|
1183
|
+
}
|
|
1184
|
+
function classifyToken(token, gestures, transition, viewport, dragConfig, layoutConfig, scroll, variants, variantState) {
|
|
1185
|
+
if (!token.startsWith("animate-")) return false;
|
|
1186
|
+
const rest = token.slice(8);
|
|
1187
|
+
const colonIdx = rest.indexOf(":");
|
|
1188
|
+
if (colonIdx !== -1) {
|
|
1189
|
+
const gesturePrefix = rest.slice(0, colonIdx);
|
|
1190
|
+
const propValueStr = rest.slice(colonIdx + 1);
|
|
1191
|
+
if (gesturePrefix === "scroll") {
|
|
1192
|
+
const parsed = parseScrollValue(propValueStr);
|
|
1193
|
+
if (parsed) {
|
|
1194
|
+
scroll.values[parsed.key] = parsed.value;
|
|
1195
|
+
return true;
|
|
1196
|
+
}
|
|
1197
|
+
return false;
|
|
1198
|
+
}
|
|
1199
|
+
if (gesturePrefix.startsWith("variant-")) {
|
|
1200
|
+
const variantName = gesturePrefix.slice(8);
|
|
1201
|
+
const parsed = parsePropertyValue(propValueStr);
|
|
1202
|
+
if (variantName && parsed) {
|
|
1203
|
+
if (!variants[variantName]) variants[variantName] = {};
|
|
1204
|
+
const bucket = variants[variantName];
|
|
1205
|
+
if ((parsed.key === "filter" || parsed.key === "backdropFilter") && typeof parsed.value === "string" && typeof bucket[parsed.key] === "string") {
|
|
1206
|
+
bucket[parsed.key] += ` ${parsed.value}`;
|
|
1207
|
+
} else {
|
|
1208
|
+
bucket[parsed.key] = parsed.value;
|
|
1209
|
+
}
|
|
1210
|
+
return true;
|
|
1211
|
+
}
|
|
1212
|
+
return false;
|
|
1213
|
+
}
|
|
1214
|
+
if (GESTURE_KEYS.has(gesturePrefix)) {
|
|
1215
|
+
const gestureKey = GESTURE_MAP[gesturePrefix];
|
|
1216
|
+
const parsed = parsePropertyValue(propValueStr);
|
|
1217
|
+
if (parsed) {
|
|
1218
|
+
if (!gestures[gestureKey]) gestures[gestureKey] = {};
|
|
1219
|
+
if ((parsed.key === "filter" || parsed.key === "backdropFilter") && typeof parsed.value === "string" && typeof gestures[gestureKey][parsed.key] === "string") {
|
|
1220
|
+
gestures[gestureKey][parsed.key] += ` ${parsed.value}`;
|
|
1221
|
+
} else {
|
|
1222
|
+
if (process.env.NODE_ENV !== "production" && gestures[gestureKey][parsed.key] !== void 0) {
|
|
1223
|
+
console.warn(
|
|
1224
|
+
`[motionwind] Duplicate property "${parsed.key}" in "${gestureKey}" (class "${token}"). The last value will be used.`
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
gestures[gestureKey][parsed.key] = parsed.value;
|
|
1228
|
+
}
|
|
1229
|
+
return true;
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
return false;
|
|
1233
|
+
}
|
|
1234
|
+
if (rest.startsWith("duration-")) {
|
|
1235
|
+
const ms = Number(rest.slice(9));
|
|
1236
|
+
if (!isNaN(ms)) {
|
|
1237
|
+
transition.duration = ms / 1e3;
|
|
1238
|
+
return true;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
if (rest.startsWith("delay-children-")) {
|
|
1242
|
+
const ms = Number(rest.slice(15));
|
|
1243
|
+
if (!isNaN(ms)) {
|
|
1244
|
+
transition.delayChildren = ms / 1e3;
|
|
1245
|
+
return true;
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
if (rest.startsWith("delay-")) {
|
|
1249
|
+
const ms = Number(rest.slice(6));
|
|
1250
|
+
if (!isNaN(ms)) {
|
|
1251
|
+
transition.delay = ms / 1e3;
|
|
1252
|
+
return true;
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
if (rest.startsWith("ease-[") && rest.endsWith("]")) {
|
|
1256
|
+
const inner = rest.slice(6, -1);
|
|
1257
|
+
const values = inner.split(",").map((v) => Number(v.trim()));
|
|
1258
|
+
if (values.length === 4 && values.every((v) => !isNaN(v))) {
|
|
1259
|
+
transition.ease = values;
|
|
1260
|
+
return true;
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
if (rest.startsWith("ease-steps-")) {
|
|
1264
|
+
const n = Number(rest.slice(11));
|
|
1265
|
+
if (!isNaN(n) && n > 0) {
|
|
1266
|
+
transition.ease = `steps(${n})`;
|
|
1267
|
+
return true;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
for (const [suffix, easeValue] of Object.entries(EASING_MAP)) {
|
|
1271
|
+
if (rest === suffix) {
|
|
1272
|
+
transition.ease = easeValue;
|
|
1273
|
+
return true;
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
if (rest === "spring") {
|
|
1277
|
+
transition.type = "spring";
|
|
1278
|
+
return true;
|
|
1279
|
+
}
|
|
1280
|
+
if (rest.startsWith("stiffness-")) {
|
|
1281
|
+
const n = Number(rest.slice(10));
|
|
1282
|
+
if (!isNaN(n)) {
|
|
1283
|
+
transition.stiffness = n;
|
|
1284
|
+
return true;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
if (rest.startsWith("damping-")) {
|
|
1288
|
+
const n = Number(rest.slice(8));
|
|
1289
|
+
if (!isNaN(n)) {
|
|
1290
|
+
transition.damping = n;
|
|
1291
|
+
return true;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
if (rest.startsWith("bounce-")) {
|
|
1295
|
+
const n = Number(rest.slice(7));
|
|
1296
|
+
if (!isNaN(n)) {
|
|
1297
|
+
transition.bounce = n / 100;
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
if (rest.startsWith("mass-")) {
|
|
1302
|
+
const n = Number(rest.slice(5));
|
|
1303
|
+
if (!isNaN(n)) {
|
|
1304
|
+
transition.mass = n / 10;
|
|
1305
|
+
return true;
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
if (rest === "repeat-infinite") {
|
|
1309
|
+
transition.repeat = Infinity;
|
|
1310
|
+
return true;
|
|
1311
|
+
}
|
|
1312
|
+
if (rest === "repeat-reverse") {
|
|
1313
|
+
transition.repeatType = "reverse";
|
|
1314
|
+
return true;
|
|
1315
|
+
}
|
|
1316
|
+
if (rest === "repeat-mirror") {
|
|
1317
|
+
transition.repeatType = "mirror";
|
|
1318
|
+
return true;
|
|
1319
|
+
}
|
|
1320
|
+
if (rest.startsWith("repeat-delay-")) {
|
|
1321
|
+
const ms = Number(rest.slice(13));
|
|
1322
|
+
if (!isNaN(ms)) {
|
|
1323
|
+
transition.repeatDelay = ms / 1e3;
|
|
1324
|
+
return true;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
if (rest.startsWith("repeat-")) {
|
|
1328
|
+
const n = Number(rest.slice(7));
|
|
1329
|
+
if (!isNaN(n)) {
|
|
1330
|
+
transition.repeat = n;
|
|
1331
|
+
return true;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
if (rest === "stagger-reverse") {
|
|
1335
|
+
transition.staggerDirection = -1;
|
|
1336
|
+
return true;
|
|
1337
|
+
}
|
|
1338
|
+
if (rest.startsWith("stagger-")) {
|
|
1339
|
+
const ms = Number(rest.slice(8));
|
|
1340
|
+
if (!isNaN(ms)) {
|
|
1341
|
+
transition.staggerChildren = ms / 1e3;
|
|
1342
|
+
return true;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
if (rest === "when-before") {
|
|
1346
|
+
transition.when = "beforeChildren";
|
|
1347
|
+
return true;
|
|
1348
|
+
}
|
|
1349
|
+
if (rest === "when-after") {
|
|
1350
|
+
transition.when = "afterChildren";
|
|
1351
|
+
return true;
|
|
1352
|
+
}
|
|
1353
|
+
if (rest.startsWith("rest-speed-")) {
|
|
1354
|
+
const n = Number(rest.slice(11));
|
|
1355
|
+
if (!isNaN(n)) {
|
|
1356
|
+
transition.restSpeed = n;
|
|
1357
|
+
return true;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
if (rest.startsWith("rest-delta-")) {
|
|
1361
|
+
const n = Number(rest.slice(11));
|
|
1362
|
+
if (!isNaN(n)) {
|
|
1363
|
+
transition.restDelta = n;
|
|
1364
|
+
return true;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
if (rest.startsWith("times-[") && rest.endsWith("]")) {
|
|
1368
|
+
const inner = rest.slice(7, -1);
|
|
1369
|
+
const values = inner.split(",").map((v) => Number(v.trim()));
|
|
1370
|
+
if (!values.some(isNaN)) {
|
|
1371
|
+
transition.times = values;
|
|
1372
|
+
return true;
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
if (rest === "once") {
|
|
1376
|
+
viewport.once = true;
|
|
1377
|
+
return true;
|
|
1378
|
+
}
|
|
1379
|
+
if (rest === "amount-all") {
|
|
1380
|
+
viewport.amount = "all";
|
|
1381
|
+
return true;
|
|
1382
|
+
}
|
|
1383
|
+
if (rest.startsWith("amount-")) {
|
|
1384
|
+
const n = Number(rest.slice(7));
|
|
1385
|
+
if (!isNaN(n)) {
|
|
1386
|
+
viewport.amount = n / 100;
|
|
1387
|
+
return true;
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
if (rest.startsWith("margin-")) {
|
|
1391
|
+
const n = Number(rest.slice(7));
|
|
1392
|
+
if (!isNaN(n)) {
|
|
1393
|
+
viewport.margin = `${n}px`;
|
|
1394
|
+
return true;
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
if (rest === "scroll-axis-x") {
|
|
1398
|
+
scroll.axis = "x";
|
|
1399
|
+
return true;
|
|
1400
|
+
}
|
|
1401
|
+
if (rest === "scroll-axis-y") {
|
|
1402
|
+
scroll.axis = "y";
|
|
1403
|
+
return true;
|
|
1404
|
+
}
|
|
1405
|
+
if (rest === "scroll-container") {
|
|
1406
|
+
scroll.container = true;
|
|
1407
|
+
return true;
|
|
1408
|
+
}
|
|
1409
|
+
if (rest.startsWith("scroll-offset-[") && rest.endsWith("]")) {
|
|
1410
|
+
const inner = rest.slice(15, -1);
|
|
1411
|
+
const parts = inner.split(",").map((p) => p.trim().replace(/_/g, " "));
|
|
1412
|
+
if (parts.length === 2) {
|
|
1413
|
+
scroll.offset = [parts[0], parts[1]];
|
|
1414
|
+
return true;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
if (rest.startsWith("from-")) {
|
|
1418
|
+
const name = rest.slice(5);
|
|
1419
|
+
if (name && !/\s/.test(name)) {
|
|
1420
|
+
variantState.initial = name;
|
|
1421
|
+
return true;
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
if (rest.startsWith("to-")) {
|
|
1425
|
+
const name = rest.slice(3);
|
|
1426
|
+
if (name && !/\s/.test(name)) {
|
|
1427
|
+
variantState.animate = name;
|
|
1428
|
+
return true;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
if (rest.startsWith("exit-")) {
|
|
1432
|
+
const name = rest.slice(5);
|
|
1433
|
+
if (name && !/\s/.test(name)) {
|
|
1434
|
+
variantState.exit = name;
|
|
1435
|
+
return true;
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
if (rest === "drag-x") {
|
|
1439
|
+
dragConfig.drag = "x";
|
|
1440
|
+
return true;
|
|
1441
|
+
}
|
|
1442
|
+
if (rest === "drag-y") {
|
|
1443
|
+
dragConfig.drag = "y";
|
|
1444
|
+
return true;
|
|
1445
|
+
}
|
|
1446
|
+
if (rest === "drag-both") {
|
|
1447
|
+
dragConfig.drag = true;
|
|
1448
|
+
return true;
|
|
1449
|
+
}
|
|
1450
|
+
if (rest.startsWith("drag-elastic-")) {
|
|
1451
|
+
const n = Number(rest.slice(13));
|
|
1452
|
+
if (!isNaN(n)) {
|
|
1453
|
+
dragConfig.dragElastic = n / 100;
|
|
1454
|
+
return true;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
if (rest === "drag-snap") {
|
|
1458
|
+
dragConfig.dragSnapToOrigin = true;
|
|
1459
|
+
return true;
|
|
1460
|
+
}
|
|
1461
|
+
if (rest === "drag-no-momentum") {
|
|
1462
|
+
dragConfig.dragMomentum = false;
|
|
1463
|
+
return true;
|
|
1464
|
+
}
|
|
1465
|
+
if (rest === "drag-lock") {
|
|
1466
|
+
dragConfig.dragDirectionLock = true;
|
|
1467
|
+
return true;
|
|
1468
|
+
}
|
|
1469
|
+
if (rest.startsWith("drag-constraint-")) {
|
|
1470
|
+
const sub = rest.slice(16);
|
|
1471
|
+
const sides = {
|
|
1472
|
+
"t-": "top",
|
|
1473
|
+
"l-": "left",
|
|
1474
|
+
"r-": "right",
|
|
1475
|
+
"b-": "bottom"
|
|
1476
|
+
};
|
|
1477
|
+
for (const [prefix, side] of Object.entries(sides)) {
|
|
1478
|
+
if (sub.startsWith(prefix)) {
|
|
1479
|
+
const n = Number(sub.slice(2));
|
|
1480
|
+
if (!isNaN(n)) {
|
|
1481
|
+
if (!dragConfig.dragConstraints) dragConfig.dragConstraints = {};
|
|
1482
|
+
dragConfig.dragConstraints[side] = n;
|
|
1483
|
+
return true;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
if (rest === "layout") {
|
|
1489
|
+
layoutConfig.layout = true;
|
|
1490
|
+
return true;
|
|
1491
|
+
}
|
|
1492
|
+
if (rest === "layout-position") {
|
|
1493
|
+
layoutConfig.layout = "position";
|
|
1494
|
+
return true;
|
|
1495
|
+
}
|
|
1496
|
+
if (rest === "layout-size") {
|
|
1497
|
+
layoutConfig.layout = "size";
|
|
1498
|
+
return true;
|
|
1499
|
+
}
|
|
1500
|
+
if (rest === "layout-preserve") {
|
|
1501
|
+
layoutConfig.layout = "preserve-aspect";
|
|
1502
|
+
return true;
|
|
1503
|
+
}
|
|
1504
|
+
if (rest === "layout-scroll") {
|
|
1505
|
+
layoutConfig.layoutScroll = true;
|
|
1506
|
+
return true;
|
|
1507
|
+
}
|
|
1508
|
+
if (rest === "layout-root") {
|
|
1509
|
+
layoutConfig.layoutRoot = true;
|
|
1510
|
+
return true;
|
|
1511
|
+
}
|
|
1512
|
+
if (rest.startsWith("layout-id-")) {
|
|
1513
|
+
const id = rest.slice(10);
|
|
1514
|
+
if (id && !/\s/.test(id)) {
|
|
1515
|
+
layoutConfig.layoutId = id;
|
|
1516
|
+
return true;
|
|
1517
|
+
}
|
|
1518
|
+
return false;
|
|
1519
|
+
}
|
|
1520
|
+
return false;
|
|
1521
|
+
}
|
|
1522
|
+
function parseMotionClasses(className, config2) {
|
|
1523
|
+
const cached = config2 ? void 0 : cache.get(className);
|
|
1524
|
+
if (cached) return cached;
|
|
1525
|
+
const diagnostics = [];
|
|
1526
|
+
const tokens = expandConfiguredTokens(className, config2, diagnostics);
|
|
1527
|
+
const tailwind = [];
|
|
1528
|
+
const gestures = {};
|
|
1529
|
+
const transition = {};
|
|
1530
|
+
const viewport = {};
|
|
1531
|
+
const dragConfig = {};
|
|
1532
|
+
const layoutConfig = {};
|
|
1533
|
+
const scroll = { axis: "y", container: false, values: {} };
|
|
1534
|
+
const variants = {};
|
|
1535
|
+
const variantState = {};
|
|
1536
|
+
let reducedMotionPolicy = void 0;
|
|
1537
|
+
for (const token of tokens) {
|
|
1538
|
+
let innerToken = token;
|
|
1539
|
+
if (token.startsWith("motion-reduce:")) {
|
|
1540
|
+
reducedMotionPolicy = "reduce";
|
|
1541
|
+
innerToken = token.slice("motion-reduce:".length);
|
|
1542
|
+
} else if (token.startsWith("motion-safe:")) {
|
|
1543
|
+
reducedMotionPolicy = "safe";
|
|
1544
|
+
innerToken = token.slice("motion-safe:".length);
|
|
1545
|
+
}
|
|
1546
|
+
if (!innerToken) continue;
|
|
1547
|
+
let consumed = classifyToken(
|
|
1548
|
+
innerToken,
|
|
1549
|
+
gestures,
|
|
1550
|
+
transition,
|
|
1551
|
+
viewport,
|
|
1552
|
+
dragConfig,
|
|
1553
|
+
layoutConfig,
|
|
1554
|
+
scroll,
|
|
1555
|
+
variants,
|
|
1556
|
+
variantState
|
|
1557
|
+
);
|
|
1558
|
+
if (!consumed) {
|
|
1559
|
+
const easingName = innerToken.startsWith("animate-ease-") ? innerToken.slice("animate-ease-".length) : "";
|
|
1560
|
+
const easing = easingName ? config2?.tokens?.easings?.[easingName] : void 0;
|
|
1561
|
+
if (typeof easing === "string") {
|
|
1562
|
+
transition.ease = easing;
|
|
1563
|
+
consumed = true;
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
if (!consumed) {
|
|
1567
|
+
for (const plugin of config2?.plugins ?? []) {
|
|
1568
|
+
const patch = plugin.transformToken?.(innerToken, { config: config2 });
|
|
1569
|
+
if (!patch) continue;
|
|
1570
|
+
mergePatch(
|
|
1571
|
+
patch,
|
|
1572
|
+
gestures,
|
|
1573
|
+
transition,
|
|
1574
|
+
viewport,
|
|
1575
|
+
dragConfig,
|
|
1576
|
+
layoutConfig,
|
|
1577
|
+
scroll,
|
|
1578
|
+
variants,
|
|
1579
|
+
variantState
|
|
1580
|
+
);
|
|
1581
|
+
consumed = true;
|
|
1582
|
+
break;
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
if (!consumed) {
|
|
1586
|
+
if (innerToken.startsWith("animate-") && !TAILWIND_ANIMATE_CLASSES.has(innerToken)) {
|
|
1587
|
+
diagnostics.push({
|
|
1588
|
+
code: "unknown-class",
|
|
1589
|
+
message: `Unrecognized motionwind class "${innerToken}".`,
|
|
1590
|
+
severity: config2?.strict ? "error" : "warning",
|
|
1591
|
+
token: innerToken
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
if (process.env.NODE_ENV !== "production" && innerToken.startsWith("animate-") && !TAILWIND_ANIMATE_CLASSES.has(innerToken)) {
|
|
1595
|
+
console.warn(
|
|
1596
|
+
`[motionwind] Unrecognized class "${innerToken}". It starts with "animate-" but doesn't match any known pattern.`
|
|
1597
|
+
);
|
|
1598
|
+
}
|
|
1599
|
+
tailwind.push(innerToken);
|
|
1600
|
+
}
|
|
1601
|
+
}
|
|
1602
|
+
const hasMotion = Object.keys(gestures).length > 0 || Object.keys(transition).length > 0 || Object.keys(viewport).length > 0 || Object.keys(dragConfig).length > 0 || Object.keys(layoutConfig).length > 0 || Object.keys(scroll.values).length > 0 || Object.keys(variants).length > 0 || Object.keys(variantState).length > 0;
|
|
1603
|
+
const result = {
|
|
1604
|
+
tailwindClasses: tailwind.join(" "),
|
|
1605
|
+
gestures,
|
|
1606
|
+
transition,
|
|
1607
|
+
viewport,
|
|
1608
|
+
dragConfig,
|
|
1609
|
+
layoutConfig,
|
|
1610
|
+
scroll,
|
|
1611
|
+
variants,
|
|
1612
|
+
variantState,
|
|
1613
|
+
hasMotion,
|
|
1614
|
+
...reducedMotionPolicy !== void 0 && { reducedMotionPolicy },
|
|
1615
|
+
diagnostics
|
|
1616
|
+
};
|
|
1617
|
+
for (const plugin of config2?.plugins ?? []) {
|
|
1618
|
+
const pluginDiagnostics = plugin.diagnose?.(className, result, { config: config2 }) ?? [];
|
|
1619
|
+
diagnostics.push(
|
|
1620
|
+
...pluginDiagnostics.map((diagnostic) => ({
|
|
1621
|
+
...diagnostic,
|
|
1622
|
+
plugin: plugin.name
|
|
1623
|
+
}))
|
|
1624
|
+
);
|
|
1625
|
+
}
|
|
1626
|
+
if (!config2) cacheSet(className, result);
|
|
1627
|
+
return result;
|
|
1628
|
+
}
|
|
1629
|
+
function clearParserCache() {
|
|
1630
|
+
cache.clear();
|
|
1631
|
+
}
|
|
1632
|
+
function freshAccumulators() {
|
|
1633
|
+
return {
|
|
1634
|
+
gestures: {},
|
|
1635
|
+
transition: {},
|
|
1636
|
+
viewport: {},
|
|
1637
|
+
dragConfig: {},
|
|
1638
|
+
layoutConfig: {},
|
|
1639
|
+
scroll: { axis: "y", container: false, values: {} },
|
|
1640
|
+
variants: {},
|
|
1641
|
+
variantState: {}
|
|
1642
|
+
};
|
|
1643
|
+
}
|
|
1644
|
+
function classifyMotionToken(token, config2) {
|
|
1645
|
+
if (token.startsWith("motion-reduce:") || token.startsWith("motion-safe:")) {
|
|
1646
|
+
const inner = token.startsWith("motion-reduce:") ? token.slice("motion-reduce:".length) : token.slice("motion-safe:".length);
|
|
1647
|
+
return inner ? classifyMotionToken(inner, config2) : "tailwind";
|
|
1648
|
+
}
|
|
1649
|
+
if (!token.startsWith("animate-")) return "tailwind";
|
|
1650
|
+
if (TAILWIND_ANIMATE_CLASSES.has(token)) return "tailwind";
|
|
1651
|
+
if (config2 || token.startsWith("animate-preset-")) {
|
|
1652
|
+
const parsed = parseMotionClasses(token, config2);
|
|
1653
|
+
if (!parsed.hasMotion) return "unknown";
|
|
1654
|
+
if (Object.keys(parsed.variantState).length || Object.keys(parsed.variants).length)
|
|
1655
|
+
return "variant";
|
|
1656
|
+
if (Object.keys(parsed.gestures).length) return "gesture";
|
|
1657
|
+
if (Object.keys(parsed.viewport).length) return "viewport";
|
|
1658
|
+
if (Object.keys(parsed.scroll.values).length) return "scroll";
|
|
1659
|
+
if (Object.keys(parsed.dragConfig).length) return "drag";
|
|
1660
|
+
if (Object.keys(parsed.layoutConfig).length) return "layout";
|
|
1661
|
+
return "transition";
|
|
1662
|
+
}
|
|
1663
|
+
const a = freshAccumulators();
|
|
1664
|
+
const consumed = classifyToken(
|
|
1665
|
+
token,
|
|
1666
|
+
a.gestures,
|
|
1667
|
+
a.transition,
|
|
1668
|
+
a.viewport,
|
|
1669
|
+
a.dragConfig,
|
|
1670
|
+
a.layoutConfig,
|
|
1671
|
+
a.scroll,
|
|
1672
|
+
a.variants,
|
|
1673
|
+
a.variantState
|
|
1674
|
+
);
|
|
1675
|
+
if (!consumed) return "unknown";
|
|
1676
|
+
if (token.startsWith("animate-scroll")) return "scroll";
|
|
1677
|
+
if (token.startsWith("animate-variant-")) return "variant";
|
|
1678
|
+
if (Object.keys(a.variantState).length) return "variant";
|
|
1679
|
+
if (Object.keys(a.gestures).length) return "gesture";
|
|
1680
|
+
if (Object.keys(a.viewport).length) return "viewport";
|
|
1681
|
+
if (Object.keys(a.dragConfig).length) return "drag";
|
|
1682
|
+
if (Object.keys(a.layoutConfig).length) return "layout";
|
|
1683
|
+
return "transition";
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
exports.classifyMotionToken = classifyMotionToken;
|
|
1687
|
+
exports.clearParserCache = clearParserCache;
|
|
1688
|
+
exports.parseMotionClasses = parseMotionClasses;
|
|
1689
|
+
//# sourceMappingURL=parser.cjs.map
|
|
1690
|
+
//# sourceMappingURL=parser.cjs.map
|