deja-vue 0.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 ADDED
@@ -0,0 +1,29 @@
1
+ # Déjà Vue
2
+
3
+ Declarative GSAP Animations for Vue 3.
4
+
5
+ ## Development
6
+
7
+ - Install dependencies:
8
+
9
+ ```bash
10
+ npm install
11
+ ```
12
+
13
+ - Run the playground:
14
+
15
+ ```bash
16
+ npm run playground
17
+ ```
18
+
19
+ - Run the unit tests:
20
+
21
+ ```bash
22
+ npm run test
23
+ ```
24
+
25
+ - Build the library:
26
+
27
+ ```bash
28
+ npm run build
29
+ ```
@@ -0,0 +1,166 @@
1
+ import * as _$vue from "vue";
2
+ import { InjectionKey, MaybeRefOrGetter, ShallowRef } from "vue";
3
+
4
+ //#region src/constants.d.ts
5
+ declare const ANIMATION_EVENTS: readonly ["complete", "interrupt", "repeat", "reverseComplete", "start", "update"];
6
+ declare const parentAnimationInjectionKey: InjectionKey<Animation>;
7
+ //#endregion
8
+ //#region src/utils/EventBus.d.ts
9
+ declare class EventBus<E extends string> {
10
+ private bus;
11
+ constructor(events?: E[]);
12
+ on(event: E | E[], callback: CallableFunction): void;
13
+ once(event: E | E[], callback: CallableFunction): void;
14
+ off(event: E | E[], callback: CallableFunction): void;
15
+ dispatch(event: E, ...args: any[]): void;
16
+ dispose(): void;
17
+ }
18
+ //#endregion
19
+ //#region src/utils/Animation.d.ts
20
+ declare class Animation extends EventBus<typeof ANIMATION_EVENTS[number]> {
21
+ timeline: gsap.core.Timeline;
22
+ constructor(options?: gsap.TimelineVars);
23
+ add(child: Animation | gsap.Callback | string, position?: gsap.Position): void;
24
+ remove(child: Animation | gsap.Callback | string): void;
25
+ compose(target: HTMLElement | HTMLCollection, definition: TweenAnimationDefinition | TweenAnimationDefinition[]): void;
26
+ dispose(): void;
27
+ }
28
+ //#endregion
29
+ //#region src/types.d.ts
30
+ interface ControllableAnimation {
31
+ progress?: number;
32
+ toggle?: boolean | undefined;
33
+ }
34
+ interface NestableAnimation {
35
+ parent?: Animation | null;
36
+ position?: gsap.Position;
37
+ }
38
+ interface WrappableAnimation {
39
+ group?: boolean;
40
+ initiallyHidden?: boolean;
41
+ tag?: string;
42
+ }
43
+ type BaseAnimation = ControllableAnimation & NestableAnimation & WrappableAnimation;
44
+ type TimelineAnimation = BaseAnimation & {
45
+ duration?: number;
46
+ options?: gsap.TimelineVars;
47
+ tweens?: TweenAnimationDefinition[];
48
+ };
49
+ type TweenAnimationDefinition = ({
50
+ method: 'from' | 'to';
51
+ vars: gsap.TweenVars;
52
+ } | {
53
+ method: 'fromTo';
54
+ vars: [gsap.TweenVars, gsap.TweenVars];
55
+ } | {
56
+ method: `effect:${string}`;
57
+ vars?: object;
58
+ }) & Pick<NestableAnimation, 'position'>;
59
+ type TweenAnimation = BaseAnimation & TweenAnimationDefinition;
60
+ //#endregion
61
+ //#region src/components/Callback.vue.d.ts
62
+ type __VLS_Props$1 = NestableAnimation & {
63
+ fn: () => void;
64
+ };
65
+ declare const __VLS_export$3: _$vue.DefineComponent<__VLS_Props$1, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {}, string, _$vue.PublicProps, Readonly<__VLS_Props$1> & Readonly<{}>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
66
+ declare const _default: typeof __VLS_export$3;
67
+ //#endregion
68
+ //#region src/components/PositionMarker.vue.d.ts
69
+ type __VLS_Props = NestableAnimation & {
70
+ label: string;
71
+ };
72
+ declare const __VLS_export$2: _$vue.DefineComponent<__VLS_Props, {}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {
73
+ cross: (...args: any[]) => void;
74
+ }, string, _$vue.PublicProps, Readonly<__VLS_Props> & Readonly<{
75
+ onCross?: ((...args: any[]) => any) | undefined;
76
+ }>, {}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
77
+ declare const _default$1: typeof __VLS_export$2;
78
+ //#endregion
79
+ //#region src/components/Timeline.vue.d.ts
80
+ declare var __VLS_9$1: {
81
+ animation: Animation;
82
+ controlled: boolean;
83
+ parent: Animation | null;
84
+ ready: boolean;
85
+ }, __VLS_11: {
86
+ animation: Animation;
87
+ controlled: boolean;
88
+ parent: Animation | null;
89
+ ready: boolean;
90
+ };
91
+ type __VLS_Slots$1 = {} & {
92
+ default?: (props: typeof __VLS_9$1) => any;
93
+ } & {
94
+ default?: (props: typeof __VLS_11) => any;
95
+ };
96
+ declare const __VLS_base$1: _$vue.DefineComponent<TimelineAnimation, {
97
+ animation: Animation;
98
+ controlled: _$vue.ComputedRef<boolean>;
99
+ parent: Animation | null;
100
+ ready: _$vue.ShallowRef<boolean, boolean>;
101
+ }, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {
102
+ complete: (...args: any[]) => void;
103
+ interrupt: (...args: any[]) => void;
104
+ repeat: (...args: any[]) => void;
105
+ reverseComplete: (...args: any[]) => void;
106
+ start: (...args: any[]) => void;
107
+ update: (...args: any[]) => void;
108
+ }, string, _$vue.PublicProps, Readonly<TimelineAnimation> & Readonly<{
109
+ onComplete?: ((...args: any[]) => any) | undefined;
110
+ onInterrupt?: ((...args: any[]) => any) | undefined;
111
+ onRepeat?: ((...args: any[]) => any) | undefined;
112
+ onReverseComplete?: ((...args: any[]) => any) | undefined;
113
+ onStart?: ((...args: any[]) => any) | undefined;
114
+ onUpdate?: ((...args: any[]) => any) | undefined;
115
+ }>, {
116
+ toggle: boolean;
117
+ initiallyHidden: boolean;
118
+ tag: string;
119
+ }, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
120
+ declare const __VLS_export$1: __VLS_WithSlots$1<typeof __VLS_base$1, __VLS_Slots$1>;
121
+ declare const _default$2: typeof __VLS_export$1;
122
+ type __VLS_WithSlots$1<T, S> = T & {
123
+ new (): {
124
+ $slots: S;
125
+ };
126
+ };
127
+ //#endregion
128
+ //#region src/components/Tween.vue.d.ts
129
+ declare var __VLS_9: {
130
+ animation: Animation;
131
+ controlled: boolean;
132
+ parent: Animation | null;
133
+ ready: boolean;
134
+ };
135
+ type __VLS_Slots = {} & {
136
+ default?: (props: typeof __VLS_9) => any;
137
+ };
138
+ declare const __VLS_base: _$vue.DefineSetupFnComponent<Record<string, any>, {}, {}, Record<string, any> & {}, _$vue.PublicProps>;
139
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
140
+ declare const _default$3: typeof __VLS_export;
141
+ type __VLS_WithSlots<T, S> = T & {
142
+ new (): {
143
+ $slots: S;
144
+ };
145
+ };
146
+ //#endregion
147
+ //#region src/composables/useAnimation.d.ts
148
+ declare function useAnimation(wrapper: Readonly<ShallowRef<HTMLElement | null>>, props: TimelineAnimation | TweenAnimation, emit: (event: typeof ANIMATION_EVENTS[number], timeline: gsap.core.Timeline) => void, options?: gsap.TimelineVars): {
149
+ animation: Animation;
150
+ controlled: _$vue.ComputedRef<boolean>;
151
+ parent: Animation | null;
152
+ ready: ShallowRef<boolean, boolean>;
153
+ };
154
+ //#endregion
155
+ //#region src/composables/useAnimationControls.d.ts
156
+ type AnimationControls<C = ControllableAnimation> = { [K in keyof C]?: MaybeRefOrGetter<C[K]> };
157
+ declare function useAnimationControls(animation: Animation, controls: AnimationControls): {
158
+ controlled: _$vue.ComputedRef<boolean>;
159
+ };
160
+ //#endregion
161
+ //#region src/composables/useAnimationNesting.d.ts
162
+ declare function useAnimationNesting(child?: Animation | gsap.Callback | string, options?: NestableAnimation): {
163
+ parent: Animation | null;
164
+ };
165
+ //#endregion
166
+ export { ANIMATION_EVENTS, type Animation, BaseAnimation, _default as Callback, ControllableAnimation, NestableAnimation, _default$1 as PositionMarker, _default$2 as Timeline, TimelineAnimation, _default$3 as Tween, TweenAnimation, TweenAnimationDefinition, WrappableAnimation, parentAnimationInjectionKey, useAnimation, useAnimationControls, useAnimationNesting };
package/dist/index.js ADDED
@@ -0,0 +1,393 @@
1
+ import { Fragment, computed, createBlock, defineComponent, inject, nextTick, normalizeStyle, onMounted, onUnmounted, openBlock, provide, renderSlot, resolveDynamicComponent, shallowRef, toValue, unref, useTemplateRef, watch, withCtx } from "vue";
2
+ import { gsap } from "gsap";
3
+ //#region src/constants.ts
4
+ const ANIMATION_EVENTS = [
5
+ "complete",
6
+ "interrupt",
7
+ "repeat",
8
+ "reverseComplete",
9
+ "start",
10
+ "update"
11
+ ];
12
+ const parentAnimationInjectionKey = Symbol("parent-animation");
13
+ //#endregion
14
+ //#region src/utils/EventBus.ts
15
+ var EventBus = class {
16
+ bus;
17
+ constructor(events) {
18
+ this.bus = /* @__PURE__ */ new Map();
19
+ events?.forEach((event) => this.bus.set(event, /* @__PURE__ */ new Set()));
20
+ }
21
+ on(event, callback) {
22
+ if (Array.isArray(event)) event.forEach((e) => this.on(e, callback));
23
+ else {
24
+ if (!this.bus.has(event)) this.bus.set(event, /* @__PURE__ */ new Set());
25
+ this.bus.get(event).add(callback);
26
+ }
27
+ }
28
+ once(event, callback) {
29
+ const fn = (...args) => {
30
+ this.off(event, fn);
31
+ callback(...args);
32
+ };
33
+ this.on(event, fn);
34
+ }
35
+ off(event, callback) {
36
+ if (Array.isArray(event)) event.forEach((e) => this.off(e, callback));
37
+ else if (this.bus.has(event) && this.bus.get(event).has(callback)) this.bus.get(event).delete(callback);
38
+ }
39
+ dispatch(event, ...args) {
40
+ if (!this.bus.has(event)) return;
41
+ this.bus.get(event).forEach((callback) => callback(...args));
42
+ }
43
+ dispose() {
44
+ this.bus.clear();
45
+ this.bus = null;
46
+ }
47
+ };
48
+ //#endregion
49
+ //#region src/utils/Animation.ts
50
+ var Animation = class extends EventBus {
51
+ timeline;
52
+ constructor(options) {
53
+ super([...ANIMATION_EVENTS]);
54
+ this.timeline = gsap.timeline({
55
+ ...options,
56
+ onComplete: () => this.dispatch("complete"),
57
+ onRepeat: () => this.dispatch("repeat"),
58
+ onReverseComplete: () => this.dispatch("reverseComplete"),
59
+ onStart: () => this.dispatch("start"),
60
+ onUpdate: () => this.dispatch("update")
61
+ });
62
+ (options ? Object.entries(options).filter(([key]) => key.startsWith("on")) : []).forEach(([key, fn]) => {
63
+ const [firstChar, ...rest] = key.replace(/^on/, "");
64
+ const event = `${firstChar.toLowerCase()}${rest.join()}`;
65
+ this.on(event, fn);
66
+ });
67
+ }
68
+ add(child, position) {
69
+ if (typeof child === "string") this.timeline.addLabel(child, position);
70
+ else if (typeof child === "function") this.timeline.add(child, position);
71
+ else {
72
+ this.timeline.add(child.timeline, position);
73
+ const totalDuration = "totalDuration" in (this.timeline.data || {}) ? this.timeline.data.totalDuration : void 0;
74
+ if (totalDuration) this.timeline.duration(totalDuration);
75
+ }
76
+ }
77
+ remove(child) {
78
+ if (typeof child === "string") this.timeline.removeLabel(child);
79
+ else if (typeof child === "function") this.timeline.remove(child);
80
+ else this.once(["complete", "reverseComplete"], () => {
81
+ const startTime = child.timeline.startTime();
82
+ const duration = child.timeline.duration();
83
+ this.timeline.remove(child.timeline);
84
+ this.timeline.getChildren(false, true, true).forEach((child) => child.startTime() > startTime && child.startTime(child.startTime() - duration));
85
+ this.timeline.invalidate();
86
+ });
87
+ }
88
+ compose(target, definition) {
89
+ if (Array.isArray(definition)) definition.forEach((tween) => this.compose(target, tween));
90
+ else if (definition.method.startsWith("effect")) try {
91
+ const [_, effect] = definition.method.split(":");
92
+ this.timeline[effect](target, structuredClone(definition.vars));
93
+ } catch {
94
+ console.warn("Missing or unknown effect");
95
+ }
96
+ else if (definition.method === "fromTo") this.timeline.fromTo(target, ...structuredClone(definition.vars));
97
+ else this.timeline[definition.method](target, structuredClone(definition.vars));
98
+ }
99
+ dispose() {
100
+ super.dispose();
101
+ this.timeline.kill();
102
+ this.timeline = null;
103
+ }
104
+ };
105
+ //#endregion
106
+ //#region src/composables/useAnimationNesting.ts
107
+ function useAnimationNesting(child, options) {
108
+ const parent = options?.parent === null ? null : options?.parent || inject(parentAnimationInjectionKey, null);
109
+ onMounted(async () => {
110
+ if (!parent || !child) return;
111
+ await nextTick();
112
+ parent.add(child, options?.position);
113
+ });
114
+ onUnmounted(() => {
115
+ if (!child) return;
116
+ if (parent) parent.remove(child);
117
+ else if (child instanceof Animation) child.dispose();
118
+ });
119
+ return { parent };
120
+ }
121
+ //#endregion
122
+ //#region src/components/Callback.vue
123
+ var Callback_default = /* @__PURE__ */ defineComponent({
124
+ __name: "Callback",
125
+ props: {
126
+ parent: {
127
+ type: [Object, null],
128
+ required: false
129
+ },
130
+ position: {
131
+ type: null,
132
+ required: false
133
+ },
134
+ fn: {
135
+ type: Function,
136
+ required: true
137
+ }
138
+ },
139
+ setup(__props) {
140
+ const props = __props;
141
+ useAnimationNesting(props.fn, props);
142
+ return (_ctx, _cache) => {
143
+ return openBlock(), createBlock(Fragment);
144
+ };
145
+ }
146
+ });
147
+ //#endregion
148
+ //#region src/components/PositionMarker.vue
149
+ var PositionMarker_default = /* @__PURE__ */ defineComponent({
150
+ __name: "PositionMarker",
151
+ props: {
152
+ parent: {
153
+ type: [Object, null],
154
+ required: false
155
+ },
156
+ position: {
157
+ type: null,
158
+ required: false
159
+ },
160
+ label: {
161
+ type: String,
162
+ required: true
163
+ }
164
+ },
165
+ emits: ["cross"],
166
+ setup(__props, { emit: __emit }) {
167
+ const props = __props;
168
+ const emit = __emit;
169
+ const { parent } = useAnimationNesting(props.label, props);
170
+ useAnimationNesting(() => emit("cross"), {
171
+ parent,
172
+ position: props.label
173
+ });
174
+ return (_ctx, _cache) => {
175
+ return openBlock(), createBlock(Fragment);
176
+ };
177
+ }
178
+ });
179
+ //#endregion
180
+ //#region src/composables/useAnimationControls.ts
181
+ function useAnimationControls(animation, controls) {
182
+ const progress = computed(() => toValue(controls.progress));
183
+ const toggle = computed(() => toValue(controls.toggle));
184
+ const controlled = computed(() => typeof progress.value === "number" || typeof toggle.value === "boolean");
185
+ if (controlled.value && toggle.value !== true) animation.timeline.pause();
186
+ watch(progress, (value) => {
187
+ if (typeof value !== "number") return;
188
+ animation.timeline.progress(value);
189
+ }, { immediate: true });
190
+ watch(toggle, (value) => {
191
+ if (typeof value !== "boolean") return;
192
+ animation.timeline[value ? "play" : "reverse"]();
193
+ });
194
+ return { controlled };
195
+ }
196
+ //#endregion
197
+ //#region src/composables/useAnimation.ts
198
+ function useAnimation(wrapper, props, emit, options) {
199
+ const animation = new Animation(options);
200
+ const ready = shallowRef(false);
201
+ const { controlled } = useAnimationControls(animation, {
202
+ progress: () => props.progress,
203
+ toggle: () => props.toggle
204
+ });
205
+ const { parent } = useAnimationNesting(animation, props);
206
+ ANIMATION_EVENTS.forEach((event) => animation.on(event, () => emit(event, animation.timeline)));
207
+ onMounted(() => {
208
+ if (wrapper.value) {
209
+ const target = props.group ? wrapper.value.children : wrapper.value;
210
+ const definition = "tweens" in props ? props.tweens || [] : props;
211
+ animation.compose(target, definition);
212
+ }
213
+ ready.value = true;
214
+ });
215
+ onUnmounted(() => animation.dispose());
216
+ return {
217
+ animation,
218
+ controlled,
219
+ parent,
220
+ ready
221
+ };
222
+ }
223
+ //#endregion
224
+ //#region src/components/Timeline.vue
225
+ var Timeline_default = /* @__PURE__ */ defineComponent({
226
+ __name: "Timeline",
227
+ props: {
228
+ progress: {
229
+ type: Number,
230
+ required: false
231
+ },
232
+ toggle: {
233
+ type: Boolean,
234
+ required: false,
235
+ skipCheck: true,
236
+ default: void 0
237
+ },
238
+ parent: {
239
+ type: [Object, null],
240
+ required: false
241
+ },
242
+ position: {
243
+ type: null,
244
+ required: false
245
+ },
246
+ group: {
247
+ type: Boolean,
248
+ required: false
249
+ },
250
+ initiallyHidden: {
251
+ type: Boolean,
252
+ required: false,
253
+ default: true
254
+ },
255
+ tag: {
256
+ type: String,
257
+ required: false,
258
+ default: "div"
259
+ },
260
+ duration: {
261
+ type: Number,
262
+ required: false
263
+ },
264
+ options: {
265
+ type: null,
266
+ required: false
267
+ },
268
+ tweens: {
269
+ type: Array,
270
+ required: false
271
+ }
272
+ },
273
+ emits: [...ANIMATION_EVENTS],
274
+ setup(__props, { expose: __expose, emit: __emit }) {
275
+ const props = __props;
276
+ const emit = __emit;
277
+ const wrapper = useTemplateRef("wrapper");
278
+ const { animation, controlled, parent, ready } = useAnimation(wrapper, props, emit, {
279
+ ...props.options,
280
+ data: {
281
+ ...props.options?.data,
282
+ totalDuration: Number(props.duration)
283
+ }
284
+ });
285
+ watch(() => props.duration, (duration) => animation.timeline.data.totalDuration = Number(duration));
286
+ __expose({
287
+ animation,
288
+ controlled,
289
+ parent,
290
+ ready
291
+ });
292
+ provide(parentAnimationInjectionKey, animation);
293
+ return (_ctx, _cache) => {
294
+ return __props.tweens ? (openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
295
+ key: 0,
296
+ ref_key: "wrapper",
297
+ ref: wrapper,
298
+ style: normalizeStyle(__props.initiallyHidden && !unref(ready) ? { visibility: "hidden" } : void 0)
299
+ }, {
300
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
301
+ animation: unref(animation),
302
+ controlled: unref(controlled),
303
+ parent: unref(parent),
304
+ ready: unref(ready)
305
+ })]),
306
+ _: 3
307
+ }, 8, ["style"])) : renderSlot(_ctx.$slots, "default", {
308
+ key: 1,
309
+ animation: unref(animation),
310
+ controlled: unref(controlled),
311
+ parent: unref(parent),
312
+ ready: unref(ready)
313
+ });
314
+ };
315
+ }
316
+ });
317
+ //#endregion
318
+ //#region src/components/Tween.vue
319
+ var Tween_default = /* @__PURE__ */ defineComponent({
320
+ __name: "Tween",
321
+ props: {
322
+ progress: {
323
+ type: Number,
324
+ required: false
325
+ },
326
+ toggle: {
327
+ type: Boolean,
328
+ required: false,
329
+ skipCheck: true,
330
+ default: void 0
331
+ },
332
+ parent: {
333
+ type: [Object, null],
334
+ required: false
335
+ },
336
+ position: {
337
+ type: void 0,
338
+ required: false
339
+ },
340
+ group: {
341
+ type: Boolean,
342
+ required: false
343
+ },
344
+ initiallyHidden: {
345
+ type: Boolean,
346
+ required: false,
347
+ default: true
348
+ },
349
+ tag: {
350
+ type: String,
351
+ required: false,
352
+ default: "div"
353
+ },
354
+ method: {
355
+ type: null,
356
+ required: true
357
+ },
358
+ vars: {
359
+ type: null,
360
+ required: false
361
+ }
362
+ },
363
+ emits: [...ANIMATION_EVENTS],
364
+ setup(__props, { expose: __expose, emit: __emit }) {
365
+ const props = __props;
366
+ const emit = __emit;
367
+ const wrapper = useTemplateRef("wrapper");
368
+ const { animation, controlled, parent, ready } = useAnimation(wrapper, props, emit);
369
+ __expose({
370
+ animation,
371
+ controlled,
372
+ parent,
373
+ ready
374
+ });
375
+ return (_ctx, _cache) => {
376
+ return openBlock(), createBlock(resolveDynamicComponent(__props.tag), {
377
+ ref_key: "wrapper",
378
+ ref: wrapper,
379
+ style: normalizeStyle(__props.initiallyHidden && !unref(ready) ? { visibility: "hidden" } : void 0)
380
+ }, {
381
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {
382
+ animation: unref(animation),
383
+ controlled: unref(controlled),
384
+ parent: unref(parent),
385
+ ready: unref(ready)
386
+ })]),
387
+ _: 3
388
+ }, 8, ["style"]);
389
+ };
390
+ }
391
+ });
392
+ //#endregion
393
+ export { ANIMATION_EVENTS, Callback_default as Callback, PositionMarker_default as PositionMarker, Timeline_default as Timeline, Tween_default as Tween, parentAnimationInjectionKey, useAnimation, useAnimationControls, useAnimationNesting };
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "deja-vue",
3
+ "type": "module",
4
+ "version": "0.1.0",
5
+ "description": "Declarative GSAP Animations for Vue 3",
6
+ "author": "Andrea 'Fiad' Fiadone <hello@fiad.one>",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/fiadone/deja-vue#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/fiadone/deja-vue.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/fiadone/deja-vue/issues"
15
+ },
16
+ "exports": {
17
+ ".": "./dist/index.js",
18
+ "./package.json": "./package.json"
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "scripts": {
27
+ "build": "tsdown",
28
+ "dev": "tsdown --watch && npm run play",
29
+ "play": "vite",
30
+ "test": "vitest",
31
+ "typecheck": "vue-tsc --noEmit",
32
+ "release": "bumpp",
33
+ "prepublishOnly": "pnpm run build",
34
+ "docs:dev": "vitepress dev docs",
35
+ "docs:build": "vitepress build docs",
36
+ "docs:preview": "vitepress preview docs"
37
+ },
38
+ "peerDependencies": {
39
+ "gsap": "^3.0.0",
40
+ "vue": "^3.5.0"
41
+ },
42
+ "devDependencies": {
43
+ "@semantic-release/changelog": "^6.0.3",
44
+ "@semantic-release/commit-analyzer": "^13.0.1",
45
+ "@semantic-release/git": "^10.0.1",
46
+ "@semantic-release/npm": "^12.0.2",
47
+ "@semantic-release/release-notes-generator": "^14.1.0",
48
+ "@tsdown/css": "^0.21.7",
49
+ "@types/node": "^25.5.0",
50
+ "@vitejs/plugin-vue": "^6.0.5",
51
+ "@vitest/browser-playwright": "^4.1.2",
52
+ "bumpp": "^11.0.1",
53
+ "gsap": "^3.15.0",
54
+ "playwright": "^1.58.2",
55
+ "semantic-release": "^24.2.9",
56
+ "tsdown": "^0.21.7",
57
+ "typescript": "^6.0.2",
58
+ "unocss": "^66.6.8",
59
+ "vite": "^8.0.3",
60
+ "vitepress": "^1.6.4",
61
+ "vitest": "^4.1.2",
62
+ "vitest-browser-vue": "^2.1.0",
63
+ "vue": "^3.5.31",
64
+ "vue-tsc": "^3.2.6"
65
+ }
66
+ }