@yewdiel21/motion-kit 0.16.0 → 0.17.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.
Files changed (60) hide show
  1. package/README.md +21 -0
  2. package/dist/auto/index.d.ts +8 -3
  3. package/dist/auto/index.js +13 -3
  4. package/dist/auto/index.js.map +1 -1
  5. package/dist/{chunk-SDQ776LG.js → chunk-7IQTMF7Y.js} +1414 -38
  6. package/dist/chunk-7IQTMF7Y.js.map +1 -0
  7. package/dist/{chunk-NFZIX3IA.js → chunk-BZLMCHUD.js} +2 -2
  8. package/dist/{chunk-RBEKR5UZ.js → chunk-VJFPTLAK.js} +2 -2
  9. package/dist/css/components/drilldown-menu.css +130 -0
  10. package/dist/css/components/signature-pad.css +104 -0
  11. package/dist/css/components/voice-message-bubble.css +50 -0
  12. package/dist/css/components/waveform-player.css +36 -0
  13. package/dist/css/components/wheel-picker.css +17 -0
  14. package/dist/elements/index.d.ts +90 -4
  15. package/dist/elements/index.js +281 -4
  16. package/dist/elements/index.js.map +1 -1
  17. package/dist/{reveal-DRpNO4KP.d.ts → engine-Bn6hC87X.d.ts} +194 -1
  18. package/dist/index.css +305 -0
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +13 -3
  21. package/dist/index.js.map +1 -1
  22. package/dist/react/index.d.ts +45 -7
  23. package/dist/react/index.js +227 -3
  24. package/dist/react/index.js.map +1 -1
  25. package/dist/{reduced-DQwVXQYb.d.ts → reduced-YS6TZjpa.d.ts} +1 -1
  26. package/dist/{store-Da3zSh8Z.d.ts → store-CZ6vdtIE.d.ts} +1 -1
  27. package/package.json +110 -110
  28. package/registry.json +64 -0
  29. package/src/auto/auto-init.ts +308 -293
  30. package/src/components/drilldown-menu/README.md +163 -0
  31. package/src/components/drilldown-menu/drilldown-menu.css +129 -0
  32. package/src/components/drilldown-menu/element.ts +59 -0
  33. package/src/components/drilldown-menu/engine.ts +338 -0
  34. package/src/components/drilldown-menu/react.tsx +76 -0
  35. package/src/components/signature-pad/README.md +97 -0
  36. package/src/components/signature-pad/element.ts +57 -0
  37. package/src/components/signature-pad/engine.ts +437 -0
  38. package/src/components/signature-pad/react.tsx +56 -0
  39. package/src/components/signature-pad/signature-pad.css +103 -0
  40. package/src/components/voice-message-bubble/README.md +31 -0
  41. package/src/components/voice-message-bubble/element.ts +20 -0
  42. package/src/components/voice-message-bubble/engine.ts +68 -0
  43. package/src/components/voice-message-bubble/react.tsx +27 -0
  44. package/src/components/voice-message-bubble/voice-message-bubble.css +12 -0
  45. package/src/components/waveform-player/README.md +30 -0
  46. package/src/components/waveform-player/element.ts +21 -0
  47. package/src/components/waveform-player/engine.ts +261 -0
  48. package/src/components/waveform-player/react.tsx +27 -0
  49. package/src/components/waveform-player/waveform-player.css +35 -0
  50. package/src/components/wheel-picker/README.md +33 -0
  51. package/src/components/wheel-picker/element.ts +18 -0
  52. package/src/components/wheel-picker/engine.ts +210 -0
  53. package/src/components/wheel-picker/react.tsx +32 -0
  54. package/src/components/wheel-picker/wheel-picker.css +16 -0
  55. package/src/elements/index.ts +273 -258
  56. package/src/index.ts +295 -290
  57. package/src/react/index.ts +176 -171
  58. package/dist/chunk-SDQ776LG.js.map +0 -1
  59. /package/dist/{chunk-NFZIX3IA.js.map → chunk-BZLMCHUD.js.map} +0 -0
  60. /package/dist/{chunk-RBEKR5UZ.js.map → chunk-VJFPTLAK.js.map} +0 -0
@@ -1,293 +1,308 @@
1
- import { createQuantity } from '../components/quantity/engine';
2
- import { createPagination } from '../components/pagination/engine';
3
- import { createHoverCard } from '../components/hover-card/engine';
4
- import { createInputOtp } from '../components/input-otp/engine';
5
- import { createJoinedCta } from '../recipes/joined-cta/create-joined-cta';
6
- import { createImageZoom } from '../recipes/image-zoom/create-image-zoom';
7
- import { createFontCycle } from '../recipes/font-cycle/create-font-cycle';
8
- import { createThumbnailNav } from '../recipes/thumbnail-nav/create-thumbnail-nav';
9
- import { createActionButton } from '../recipes/action-button/create-action-button';
10
- import { createFilmHero } from '../recipes/film-hero/create-film-hero';
11
- import { createEditorialReveal } from '../recipes/editorial-reveal/create-editorial-reveal';
12
- import { createStudioDock } from '../components/studio-dock/engine';
13
- import { createCalendar } from '../components/calendar/engine';
14
- import { createSlotPicker } from '../components/slot-picker/engine';
15
- import { createWeightHover } from '../recipes/weight-hover/create-weight-hover';
16
- import { createSticker } from '../recipes/sticker/create-sticker';
17
- import { createScrollDock } from '../recipes/scroll-dock/create-scroll-dock';
18
- import { createLocalClock } from '../recipes/local-clock/create-local-clock';
19
- import { createTrailer } from '../components/trailer/engine';
20
- import { createCreditCard } from '../components/credit-card/engine';
21
- import { createCommandSearch } from '../components/command-search/engine';
22
- import { createHoldConfirm } from '../components/hold-confirm/engine';
23
- import { createImagePreview } from '../components/image-preview/engine';
24
- import { createLikeButton } from '../components/like-button/engine';
25
- import { createNotificationBell } from '../components/notification-bell/engine';
26
- import { createPasswordStrength } from '../components/password-strength/engine';
27
- import { createScratchCard } from '../components/scratch-card/engine';
28
- import { createStarRating } from '../components/star-rating/engine';
29
- import { createSwipeActions } from '../components/swipe-actions/engine';
30
- import { createAttachment } from '../components/attachment/engine';
31
- import { createSkeleton } from '../components/skeleton/engine';
32
- import { createQuestionnaire } from '../components/questionnaire/engine';
33
- import { createCodeBlock } from '../components/code-block/engine';
34
- import { createContextMenu } from '../components/context-menu/engine';
35
- import { createDrawer } from '../components/drawer/engine';
36
- import { createLinkPreview } from '../components/link-preview/engine';
37
- import { createProgress } from '../components/progress/engine';
38
- import { createRangeSlider } from '../components/range-slider/engine';
39
- import { createChart } from '../components/chart/engine';
40
- import { createColorSlider } from '../components/color-slider/engine';
41
- import { createColorArea } from '../components/color-area/engine';
42
- import { createColorField } from '../components/color-field/engine';
43
- import { createColorPicker } from '../components/color-picker/engine';
44
- import { createTimeField } from '../components/time-field/engine';
45
- import { createRangeCalendar } from '../components/range-calendar/engine';
46
- import { createDateRangePicker } from '../components/date-range-picker/engine';
47
- import { createTooltip } from '../components/tooltip/engine';
48
- import { createPopover } from '../components/popover/engine';
49
- import { createLoadingButton } from '../components/loading-button/engine';
50
- import { createBreadcrumb } from '../components/breadcrumb/engine';
51
- import { createEmptyState } from '../components/empty-state/engine';
52
- import { createStatCard } from '../components/stat-card/engine';
53
- import { createChartTooltip } from '../components/chart-tooltip/engine';
54
- import { createMultiSelect } from '../components/multi-select/engine';
55
- import { createTagInput } from '../components/tag-input/engine';
56
- import { createDateTimePicker } from '../components/date-time-picker/engine';
57
- import { createFilterBuilder } from '../components/filter-builder/engine';
58
- import { createTimeline } from '../components/timeline/engine';
59
- import { createActivityFeed } from '../components/activity-feed/engine';
60
- import { createTreeView } from '../components/tree-view/engine';
61
- import { createFileExplorer } from '../components/file-explorer/engine';
62
- import { createJsonViewer } from '../components/json-viewer/engine';
63
- import { createVirtualList } from '../components/virtual-list/engine';
64
- import { createResizablePanel } from '../components/resizable-panel/engine';
65
- import { createSplitView } from '../components/split-view/engine';
66
- import { createDataTable } from '../components/data-table/engine';
67
- import { createEditableTable } from '../components/editable-table/engine';
68
- import { createRichTextEditor } from '../components/rich-text-editor/engine';
69
- import { createSelect } from '../components/select/engine';
70
- import { createAddToCart } from '../components/add-to-cart/engine';
71
- import { createScrollIsland } from '../components/scroll-island/engine';
72
- import { ScrollTrigger } from '../core/gsap';
73
- import { warnOnce, type Instance } from '../core/types';
74
- import { createSpringCards } from '../recipes/spring-cards/create-spring-cards';
75
- import { createCurvedCarousel } from '../recipes/curved-carousel/create-curved-carousel';
76
- import { createPile } from '../recipes/pile/create-pile';
77
- import { createWords } from '../recipes/words/create-words';
78
- import { createFlow } from '../recipes/flow/create-flow';
79
- import { createPop } from '../recipes/pop/create-pop';
80
- import { createFitText } from '../recipes/fit-text/create-fit-text';
81
- import { createStretchFooter } from '../recipes/stretch-footer/create-stretch-footer';
82
- import { createRadialMenu } from '../recipes/radial-menu/create-radial-menu';
83
- import { createTabs } from '../recipes/tabs/create-tabs';
84
- import { createCounter } from '../recipes/counter/create-counter';
85
- import { createDetails } from '../recipes/details/create-details';
86
- import { createReveal } from '../recipes/reveal/create-reveal';
87
- import { createReflow } from '../recipes/reflow/create-reflow';
88
- import { createSlotText } from '../recipes/slot-text/create-slot-text';
89
- import { createSortable } from '../recipes/sortable/create-sortable';
90
- import { createMaskText } from '../recipes/mask-text/create-mask-text';
91
- import { createCascade } from '../recipes/cascade/create-cascade';
92
- import { createTextRoll } from '../recipes/text-roll/create-text-roll';
93
- import { createLetters } from '../recipes/letters/create-letters';
94
- import { createParallax } from '../recipes/parallax/create-parallax';
95
- import { createDepthGrid } from '../recipes/depth-grid/create-depth-grid';
96
- import { createFrameZoom } from '../recipes/frame-zoom/create-frame-zoom';
97
- import { createContrast } from '../recipes/contrast/create-contrast';
98
- import { createMarquee } from '../recipes/marquee/create-marquee';
99
- import { createCardDock } from '../recipes/card-dock/create-card-dock';
100
- import { createSnapStrip } from '../recipes/snap-strip/create-snap-strip';
101
- import { createFillText } from '../recipes/fill-text/create-fill-text';
102
- import { parseOptions } from './parse-options';
103
- import { createTicketMenu } from '../recipes/ticket-menu/create-ticket-menu';
104
- import { createInfiniteReel } from '../recipes/infinite-reel/create-infinite-reel';
105
- import { createRepelBento } from '../recipes/repel-bento/create-repel-bento';
106
- import { createRotator } from '../recipes/rotator/create-rotator';
107
- import { createDragRuler } from '../recipes/drag-ruler/create-drag-ruler';
108
- import { createDockPill } from '../recipes/dock-pill/create-dock-pill';
109
-
110
- type Factory = (el: HTMLElement, options: Record<string, unknown>) => Instance;
111
-
112
- const factories = {
113
- 'joined-cta': createJoinedCta,
114
- 'image-zoom': createImageZoom,
115
- 'font-cycle': createFontCycle,
116
- 'thumbnail-nav': createThumbnailNav,
117
- 'action-button': createActionButton,
118
- 'film-hero': createFilmHero,
119
- 'editorial-reveal': createEditorialReveal,
120
- 'studio-dock': createStudioDock,
121
- 'trailer': createTrailer,
122
- 'quantity': createQuantity,
123
- 'pagination': createPagination,
124
- 'hover-card': createHoverCard,
125
- 'input-otp': createInputOtp,
126
- 'calendar': createCalendar,
127
- 'slot-picker': createSlotPicker,
128
- 'credit-card': createCreditCard,
129
- 'command-search': createCommandSearch,
130
- 'hold-confirm': createHoldConfirm,
131
- 'image-preview': createImagePreview,
132
- 'like-button': createLikeButton,
133
- 'notification-bell': createNotificationBell,
134
- 'password-strength': createPasswordStrength,
135
- 'scratch-card': createScratchCard,
136
- 'star-rating': createStarRating,
137
- 'swipe-actions': createSwipeActions,
138
- 'attachment': createAttachment,
139
- 'skeleton': createSkeleton,
140
- 'questionnaire': createQuestionnaire,
141
- 'code-block': createCodeBlock,
142
- 'context-menu': createContextMenu,
143
- 'drawer': createDrawer,
144
- 'link-preview': createLinkPreview,
145
- 'progress': createProgress,
146
- 'range-slider': createRangeSlider,
147
- 'chart': createChart,
148
- 'color-slider': createColorSlider,
149
- 'color-area': createColorArea,
150
- 'color-field': createColorField,
151
- 'color-picker': createColorPicker,
152
- 'time-field': createTimeField,
153
- 'range-calendar': createRangeCalendar,
154
- 'date-range-picker': createDateRangePicker,
155
- 'tooltip': createTooltip,
156
- 'popover': createPopover,
157
- 'loading-button': createLoadingButton,
158
- 'breadcrumb': createBreadcrumb,
159
- 'empty-state': createEmptyState,
160
- 'stat-card': createStatCard,
161
- 'chart-tooltip': createChartTooltip,
162
- 'multi-select': createMultiSelect,
163
- 'tag-input': createTagInput,
164
- 'date-time-picker': createDateTimePicker,
165
- 'filter-builder': createFilterBuilder,
166
- 'timeline': createTimeline,
167
- 'activity-feed': createActivityFeed,
168
- 'tree-view': createTreeView,
169
- 'file-explorer': createFileExplorer,
170
- 'json-viewer': createJsonViewer,
171
- 'virtual-list': createVirtualList,
172
- 'resizable-panel': createResizablePanel,
173
- 'split-view': createSplitView,
174
- 'data-table': createDataTable,
175
- 'editable-table': createEditableTable,
176
- 'rich-text-editor': createRichTextEditor,
177
- 'select': createSelect,
178
- 'add-to-cart': createAddToCart,
179
- 'scroll-island': createScrollIsland,
180
- 'weight-hover': createWeightHover,
181
- 'sticker': createSticker,
182
- 'scroll-dock': createScrollDock,
183
- 'local-clock': createLocalClock,
184
- 'spring-cards': createSpringCards,
185
- 'curved-carousel': (el, options) =>
186
- createCurvedCarousel(el, {
187
- ...options,
188
- onSelect: (index, slide) => el.dispatchEvent(new CustomEvent('mk:select', { detail: { index, slide }, bubbles: true })),
189
- }),
190
- pile: createPile,
191
- words: createWords,
192
- flow: createFlow,
193
- pop: createPop,
194
- 'fit-text': createFitText,
195
- 'stretch-footer': createStretchFooter,
196
- 'radial-menu': createRadialMenu,
197
- tabs: createTabs,
198
- counter: createCounter,
199
- details: (el) => createDetails(el),
200
- reveal: createReveal,
201
- reflow: createReflow,
202
- 'slot-text': createSlotText,
203
- sortable: createSortable,
204
- 'mask-text': createMaskText,
205
- cascade: createCascade,
206
- 'text-roll': createTextRoll,
207
- letters: createLetters,
208
- parallax: createParallax,
209
- 'depth-grid': createDepthGrid,
210
- 'frame-zoom': createFrameZoom,
211
- contrast: createContrast,
212
- marquee: createMarquee,
213
- 'card-dock': createCardDock,
214
- 'snap-strip': createSnapStrip,
215
- 'fill-text': createFillText,
216
- 'ticket-menu': createTicketMenu,
217
- 'infinite-reel': createInfiniteReel,
218
- 'repel-bento': createRepelBento,
219
- 'rotator': createRotator,
220
- 'drag-ruler': createDragRuler,
221
- 'dock-pill': createDockPill,
222
- } satisfies Record<string, Factory>;
223
-
224
- export type RecipeName = keyof typeof factories;
225
- export const recipeNames = Object.keys(factories) as RecipeName[];
226
-
227
- /** Measured text: wait for web fonts, fit before splitting into words. */
228
- const AFTER_FONTS: RecipeName[] = ['fit-text', 'words', 'slot-text'];
229
-
230
- const instances = new WeakMap<HTMLElement, Map<RecipeName, Instance>>();
231
-
232
- export interface AutoInitOptions {
233
- /** Only start these recipes. */
234
- only?: RecipeName[];
235
- }
236
-
237
- /**
238
- * Start every `[data-mk]` recipe inside `root` (an element may list several:
239
- * `data-mk="fit-text words"`). Options come from `data-mk-*` attributes.
240
- * Returns a function that destroys what this call created. Safe to call again:
241
- * elements that already run a recipe are skipped.
242
- */
243
- export function autoInit(root: ParentNode = document, { only }: AutoInitOptions = {}): () => void {
244
- if (typeof window === 'undefined') return () => {};
245
- const created: Array<[HTMLElement, RecipeName, Instance]> = [];
246
- let cancelled = false;
247
-
248
- const elements = [...root.querySelectorAll<HTMLElement>('[data-mk]')];
249
- if (root instanceof HTMLElement && root.matches('[data-mk]')) elements.unshift(root);
250
-
251
- const start = (el: HTMLElement, name: RecipeName) => {
252
- if (cancelled) return;
253
- const running = instances.get(el) ?? new Map<RecipeName, Instance>();
254
- if (running.has(name)) return;
255
- const instance = (factories[name] as Factory)(el, parseOptions(el));
256
- running.set(name, instance);
257
- instances.set(el, running);
258
- created.push([el, name, instance]);
259
- };
260
-
261
- const now: Array<[HTMLElement, RecipeName]> = [];
262
- const later: Array<[HTMLElement, RecipeName]> = [];
263
- for (const el of elements) {
264
- for (const raw of (el.dataset.mk ?? '').split(/\s+/).filter(Boolean)) {
265
- if (!(raw in factories)) {
266
- warnOnce(`autoInit: unknown recipe "${raw}" (known: ${recipeNames.join(', ')})`);
267
- continue;
268
- }
269
- const name = raw as RecipeName;
270
- if (only && !only.includes(name)) continue;
271
- (AFTER_FONTS.includes(name) ? later : now).push([el, name]);
272
- }
273
- }
274
-
275
- now.forEach(([el, name]) => start(el, name));
276
- if (later.length) {
277
- later.sort((a, b) => AFTER_FONTS.indexOf(a[1]) - AFTER_FONTS.indexOf(b[1]));
278
- const fonts = document.fonts?.ready ?? Promise.resolve();
279
- void Promise.race([fonts, new Promise((resolve) => setTimeout(resolve, 1500))]).then(() => {
280
- later.forEach(([el, name]) => start(el, name));
281
- if (!cancelled) ScrollTrigger.refresh();
282
- });
283
- }
284
-
285
- return () => {
286
- cancelled = true;
287
- for (const [el, name, instance] of created.reverse()) {
288
- instance.destroy();
289
- instances.get(el)?.delete(name);
290
- }
291
- created.length = 0;
292
- };
293
- }
1
+ import { createQuantity } from '../components/quantity/engine';
2
+ import { createPagination } from '../components/pagination/engine';
3
+ import { createHoverCard } from '../components/hover-card/engine';
4
+ import { createInputOtp } from '../components/input-otp/engine';
5
+ import { createJoinedCta } from '../recipes/joined-cta/create-joined-cta';
6
+ import { createImageZoom } from '../recipes/image-zoom/create-image-zoom';
7
+ import { createFontCycle } from '../recipes/font-cycle/create-font-cycle';
8
+ import { createThumbnailNav } from '../recipes/thumbnail-nav/create-thumbnail-nav';
9
+ import { createActionButton } from '../recipes/action-button/create-action-button';
10
+ import { createFilmHero } from '../recipes/film-hero/create-film-hero';
11
+ import { createEditorialReveal } from '../recipes/editorial-reveal/create-editorial-reveal';
12
+ import { createStudioDock } from '../components/studio-dock/engine';
13
+ import { createCalendar } from '../components/calendar/engine';
14
+ import { createSlotPicker } from '../components/slot-picker/engine';
15
+ import { createWeightHover } from '../recipes/weight-hover/create-weight-hover';
16
+ import { createSticker } from '../recipes/sticker/create-sticker';
17
+ import { createScrollDock } from '../recipes/scroll-dock/create-scroll-dock';
18
+ import { createLocalClock } from '../recipes/local-clock/create-local-clock';
19
+ import { createTrailer } from '../components/trailer/engine';
20
+ import { createCreditCard } from '../components/credit-card/engine';
21
+ import { createCommandSearch } from '../components/command-search/engine';
22
+ import { createHoldConfirm } from '../components/hold-confirm/engine';
23
+ import { createImagePreview } from '../components/image-preview/engine';
24
+ import { createLikeButton } from '../components/like-button/engine';
25
+ import { createNotificationBell } from '../components/notification-bell/engine';
26
+ import { createPasswordStrength } from '../components/password-strength/engine';
27
+ import { createScratchCard } from '../components/scratch-card/engine';
28
+ import { createStarRating } from '../components/star-rating/engine';
29
+ import { createSwipeActions } from '../components/swipe-actions/engine';
30
+ import { createAttachment } from '../components/attachment/engine';
31
+ import { createSkeleton } from '../components/skeleton/engine';
32
+ import { createQuestionnaire } from '../components/questionnaire/engine';
33
+ import { createCodeBlock } from '../components/code-block/engine';
34
+ import { createContextMenu } from '../components/context-menu/engine';
35
+ import { createDrawer } from '../components/drawer/engine';
36
+ import { createLinkPreview } from '../components/link-preview/engine';
37
+ import { createProgress } from '../components/progress/engine';
38
+ import { createRangeSlider } from '../components/range-slider/engine';
39
+ import { createChart } from '../components/chart/engine';
40
+ import { createColorSlider } from '../components/color-slider/engine';
41
+ import { createColorArea } from '../components/color-area/engine';
42
+ import { createColorField } from '../components/color-field/engine';
43
+ import { createColorPicker } from '../components/color-picker/engine';
44
+ import { createTimeField } from '../components/time-field/engine';
45
+ import { createRangeCalendar } from '../components/range-calendar/engine';
46
+ import { createDateRangePicker } from '../components/date-range-picker/engine';
47
+ import { createTooltip } from '../components/tooltip/engine';
48
+ import { createPopover } from '../components/popover/engine';
49
+ import { createLoadingButton } from '../components/loading-button/engine';
50
+ import { createBreadcrumb } from '../components/breadcrumb/engine';
51
+ import { createEmptyState } from '../components/empty-state/engine';
52
+ import { createStatCard } from '../components/stat-card/engine';
53
+ import { createChartTooltip } from '../components/chart-tooltip/engine';
54
+ import { createMultiSelect } from '../components/multi-select/engine';
55
+ import { createTagInput } from '../components/tag-input/engine';
56
+ import { createDateTimePicker } from '../components/date-time-picker/engine';
57
+ import { createFilterBuilder } from '../components/filter-builder/engine';
58
+ import { createTimeline } from '../components/timeline/engine';
59
+ import { createActivityFeed } from '../components/activity-feed/engine';
60
+ import { createTreeView } from '../components/tree-view/engine';
61
+ import { createFileExplorer } from '../components/file-explorer/engine';
62
+ import { createJsonViewer } from '../components/json-viewer/engine';
63
+ import { createVirtualList } from '../components/virtual-list/engine';
64
+ import { createResizablePanel } from '../components/resizable-panel/engine';
65
+ import { createSplitView } from '../components/split-view/engine';
66
+ import { createDataTable } from '../components/data-table/engine';
67
+ import { createEditableTable } from '../components/editable-table/engine';
68
+ import { createRichTextEditor } from '../components/rich-text-editor/engine';
69
+ import { createSelect } from '../components/select/engine';
70
+ import { createAddToCart } from '../components/add-to-cart/engine';
71
+ import { createScrollIsland } from '../components/scroll-island/engine';
72
+ import { ScrollTrigger } from '../core/gsap';
73
+ import { warnOnce, type Instance } from '../core/types';
74
+ import { createSpringCards } from '../recipes/spring-cards/create-spring-cards';
75
+ import { createCurvedCarousel } from '../recipes/curved-carousel/create-curved-carousel';
76
+ import { createPile } from '../recipes/pile/create-pile';
77
+ import { createWords } from '../recipes/words/create-words';
78
+ import { createFlow } from '../recipes/flow/create-flow';
79
+ import { createPop } from '../recipes/pop/create-pop';
80
+ import { createFitText } from '../recipes/fit-text/create-fit-text';
81
+ import { createStretchFooter } from '../recipes/stretch-footer/create-stretch-footer';
82
+ import { createRadialMenu } from '../recipes/radial-menu/create-radial-menu';
83
+ import { createTabs } from '../recipes/tabs/create-tabs';
84
+ import { createCounter } from '../recipes/counter/create-counter';
85
+ import { createDetails } from '../recipes/details/create-details';
86
+ import { createReveal } from '../recipes/reveal/create-reveal';
87
+ import { createReflow } from '../recipes/reflow/create-reflow';
88
+ import { createSlotText } from '../recipes/slot-text/create-slot-text';
89
+ import { createSortable } from '../recipes/sortable/create-sortable';
90
+ import { createMaskText } from '../recipes/mask-text/create-mask-text';
91
+ import { createCascade } from '../recipes/cascade/create-cascade';
92
+ import { createTextRoll } from '../recipes/text-roll/create-text-roll';
93
+ import { createLetters } from '../recipes/letters/create-letters';
94
+ import { createParallax } from '../recipes/parallax/create-parallax';
95
+ import { createDepthGrid } from '../recipes/depth-grid/create-depth-grid';
96
+ import { createFrameZoom } from '../recipes/frame-zoom/create-frame-zoom';
97
+ import { createContrast } from '../recipes/contrast/create-contrast';
98
+ import { createMarquee } from '../recipes/marquee/create-marquee';
99
+ import { createCardDock } from '../recipes/card-dock/create-card-dock';
100
+ import { createSnapStrip } from '../recipes/snap-strip/create-snap-strip';
101
+ import { createFillText } from '../recipes/fill-text/create-fill-text';
102
+ import { parseOptions } from './parse-options';
103
+ import { createTicketMenu } from '../recipes/ticket-menu/create-ticket-menu';
104
+ import { createInfiniteReel } from '../recipes/infinite-reel/create-infinite-reel';
105
+ import { createRepelBento } from '../recipes/repel-bento/create-repel-bento';
106
+ import { createRotator } from '../recipes/rotator/create-rotator';
107
+ import { createDragRuler } from '../recipes/drag-ruler/create-drag-ruler';
108
+ import { createDockPill } from '../recipes/dock-pill/create-dock-pill';
109
+
110
+ import { createSignaturePad } from '../components/signature-pad/engine';
111
+
112
+ import { createWaveformPlayer } from '../components/waveform-player/engine';
113
+
114
+ import { createVoiceMessageBubble } from '../components/voice-message-bubble/engine';
115
+
116
+ import { createDrilldownMenu } from '../components/drilldown-menu/engine';
117
+
118
+ import { createWheelPicker } from '../components/wheel-picker/engine';
119
+
120
+ type Factory = (el: HTMLElement, options: Record<string, unknown>) => Instance;
121
+
122
+ const factories = {
123
+ 'wheel-picker': createWheelPicker,
124
+ 'drilldown-menu': createDrilldownMenu,
125
+ 'voice-message-bubble': createVoiceMessageBubble,
126
+ 'waveform-player': createWaveformPlayer,
127
+ 'signature-pad': createSignaturePad,
128
+ 'joined-cta': createJoinedCta,
129
+ 'image-zoom': createImageZoom,
130
+ 'font-cycle': createFontCycle,
131
+ 'thumbnail-nav': createThumbnailNav,
132
+ 'action-button': createActionButton,
133
+ 'film-hero': createFilmHero,
134
+ 'editorial-reveal': createEditorialReveal,
135
+ 'studio-dock': createStudioDock,
136
+ 'trailer': createTrailer,
137
+ 'quantity': createQuantity,
138
+ 'pagination': createPagination,
139
+ 'hover-card': createHoverCard,
140
+ 'input-otp': createInputOtp,
141
+ 'calendar': createCalendar,
142
+ 'slot-picker': createSlotPicker,
143
+ 'credit-card': createCreditCard,
144
+ 'command-search': createCommandSearch,
145
+ 'hold-confirm': createHoldConfirm,
146
+ 'image-preview': createImagePreview,
147
+ 'like-button': createLikeButton,
148
+ 'notification-bell': createNotificationBell,
149
+ 'password-strength': createPasswordStrength,
150
+ 'scratch-card': createScratchCard,
151
+ 'star-rating': createStarRating,
152
+ 'swipe-actions': createSwipeActions,
153
+ 'attachment': createAttachment,
154
+ 'skeleton': createSkeleton,
155
+ 'questionnaire': createQuestionnaire,
156
+ 'code-block': createCodeBlock,
157
+ 'context-menu': createContextMenu,
158
+ 'drawer': createDrawer,
159
+ 'link-preview': createLinkPreview,
160
+ 'progress': createProgress,
161
+ 'range-slider': createRangeSlider,
162
+ 'chart': createChart,
163
+ 'color-slider': createColorSlider,
164
+ 'color-area': createColorArea,
165
+ 'color-field': createColorField,
166
+ 'color-picker': createColorPicker,
167
+ 'time-field': createTimeField,
168
+ 'range-calendar': createRangeCalendar,
169
+ 'date-range-picker': createDateRangePicker,
170
+ 'tooltip': createTooltip,
171
+ 'popover': createPopover,
172
+ 'loading-button': createLoadingButton,
173
+ 'breadcrumb': createBreadcrumb,
174
+ 'empty-state': createEmptyState,
175
+ 'stat-card': createStatCard,
176
+ 'chart-tooltip': createChartTooltip,
177
+ 'multi-select': createMultiSelect,
178
+ 'tag-input': createTagInput,
179
+ 'date-time-picker': createDateTimePicker,
180
+ 'filter-builder': createFilterBuilder,
181
+ 'timeline': createTimeline,
182
+ 'activity-feed': createActivityFeed,
183
+ 'tree-view': createTreeView,
184
+ 'file-explorer': createFileExplorer,
185
+ 'json-viewer': createJsonViewer,
186
+ 'virtual-list': createVirtualList,
187
+ 'resizable-panel': createResizablePanel,
188
+ 'split-view': createSplitView,
189
+ 'data-table': createDataTable,
190
+ 'editable-table': createEditableTable,
191
+ 'rich-text-editor': createRichTextEditor,
192
+ 'select': createSelect,
193
+ 'add-to-cart': createAddToCart,
194
+ 'scroll-island': createScrollIsland,
195
+ 'weight-hover': createWeightHover,
196
+ 'sticker': createSticker,
197
+ 'scroll-dock': createScrollDock,
198
+ 'local-clock': createLocalClock,
199
+ 'spring-cards': createSpringCards,
200
+ 'curved-carousel': (el, options) =>
201
+ createCurvedCarousel(el, {
202
+ ...options,
203
+ onSelect: (index, slide) => el.dispatchEvent(new CustomEvent('mk:select', { detail: { index, slide }, bubbles: true })),
204
+ }),
205
+ pile: createPile,
206
+ words: createWords,
207
+ flow: createFlow,
208
+ pop: createPop,
209
+ 'fit-text': createFitText,
210
+ 'stretch-footer': createStretchFooter,
211
+ 'radial-menu': createRadialMenu,
212
+ tabs: createTabs,
213
+ counter: createCounter,
214
+ details: (el) => createDetails(el),
215
+ reveal: createReveal,
216
+ reflow: createReflow,
217
+ 'slot-text': createSlotText,
218
+ sortable: createSortable,
219
+ 'mask-text': createMaskText,
220
+ cascade: createCascade,
221
+ 'text-roll': createTextRoll,
222
+ letters: createLetters,
223
+ parallax: createParallax,
224
+ 'depth-grid': createDepthGrid,
225
+ 'frame-zoom': createFrameZoom,
226
+ contrast: createContrast,
227
+ marquee: createMarquee,
228
+ 'card-dock': createCardDock,
229
+ 'snap-strip': createSnapStrip,
230
+ 'fill-text': createFillText,
231
+ 'ticket-menu': createTicketMenu,
232
+ 'infinite-reel': createInfiniteReel,
233
+ 'repel-bento': createRepelBento,
234
+ 'rotator': createRotator,
235
+ 'drag-ruler': createDragRuler,
236
+ 'dock-pill': createDockPill,
237
+ } satisfies Record<string, Factory>;
238
+
239
+ export type RecipeName = keyof typeof factories;
240
+ export const recipeNames = Object.keys(factories) as RecipeName[];
241
+
242
+ /** Measured text: wait for web fonts, fit before splitting into words. */
243
+ const AFTER_FONTS: RecipeName[] = ['fit-text', 'words', 'slot-text'];
244
+
245
+ const instances = new WeakMap<HTMLElement, Map<RecipeName, Instance>>();
246
+
247
+ export interface AutoInitOptions {
248
+ /** Only start these recipes. */
249
+ only?: RecipeName[];
250
+ }
251
+
252
+ /**
253
+ * Start every `[data-mk]` recipe inside `root` (an element may list several:
254
+ * `data-mk="fit-text words"`). Options come from `data-mk-*` attributes.
255
+ * Returns a function that destroys what this call created. Safe to call again:
256
+ * elements that already run a recipe are skipped.
257
+ */
258
+ export function autoInit(root: ParentNode = document, { only }: AutoInitOptions = {}): () => void {
259
+ if (typeof window === 'undefined') return () => {};
260
+ const created: Array<[HTMLElement, RecipeName, Instance]> = [];
261
+ let cancelled = false;
262
+
263
+ const elements = [...root.querySelectorAll<HTMLElement>('[data-mk]')];
264
+ if (root instanceof HTMLElement && root.matches('[data-mk]')) elements.unshift(root);
265
+
266
+ const start = (el: HTMLElement, name: RecipeName) => {
267
+ if (cancelled) return;
268
+ const running = instances.get(el) ?? new Map<RecipeName, Instance>();
269
+ if (running.has(name)) return;
270
+ const instance = (factories[name] as Factory)(el, parseOptions(el));
271
+ running.set(name, instance);
272
+ instances.set(el, running);
273
+ created.push([el, name, instance]);
274
+ };
275
+
276
+ const now: Array<[HTMLElement, RecipeName]> = [];
277
+ const later: Array<[HTMLElement, RecipeName]> = [];
278
+ for (const el of elements) {
279
+ for (const raw of (el.dataset.mk ?? '').split(/\s+/).filter(Boolean)) {
280
+ if (!(raw in factories)) {
281
+ warnOnce(`autoInit: unknown recipe "${raw}" (known: ${recipeNames.join(', ')})`);
282
+ continue;
283
+ }
284
+ const name = raw as RecipeName;
285
+ if (only && !only.includes(name)) continue;
286
+ (AFTER_FONTS.includes(name) ? later : now).push([el, name]);
287
+ }
288
+ }
289
+
290
+ now.forEach(([el, name]) => start(el, name));
291
+ if (later.length) {
292
+ later.sort((a, b) => AFTER_FONTS.indexOf(a[1]) - AFTER_FONTS.indexOf(b[1]));
293
+ const fonts = document.fonts?.ready ?? Promise.resolve();
294
+ void Promise.race([fonts, new Promise((resolve) => setTimeout(resolve, 1500))]).then(() => {
295
+ later.forEach(([el, name]) => start(el, name));
296
+ if (!cancelled) ScrollTrigger.refresh();
297
+ });
298
+ }
299
+
300
+ return () => {
301
+ cancelled = true;
302
+ for (const [el, name, instance] of created.reverse()) {
303
+ instance.destroy();
304
+ instances.get(el)?.delete(name);
305
+ }
306
+ created.length = 0;
307
+ };
308
+ }