motion-plus-vue 1.1.5 → 1.2.0-alpha.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 (34) hide show
  1. package/dist/cjs/index.js +2 -2
  2. package/dist/components/AnimateNumber/AnimateNumber.d.ts +2 -2
  3. package/dist/components/AnimateNumber/Mask.d.ts +7 -4
  4. package/dist/components/AnimateNumber/NumberSection.d.ts +1 -0
  5. package/dist/components/AnimateNumber/NumberSymbol.d.ts +4 -1
  6. package/dist/components/AnimateNumber/types.d.ts +5 -2
  7. package/dist/components/Cursor/Cursor.d.ts +3 -3
  8. package/dist/components/Ticker/Ticker.d.ts +28 -0
  9. package/dist/components/Ticker/TickerItem.d.ts +31 -0
  10. package/dist/components/Ticker/const.d.ts +4 -0
  11. package/dist/components/Ticker/context.d.ts +14 -0
  12. package/dist/components/Ticker/index.d.ts +7 -0
  13. package/dist/components/Ticker/use-item-offset.d.ts +1 -0
  14. package/dist/components/Ticker/use-keyboard-focus.d.ts +3 -0
  15. package/dist/es/components/AnimateNumber/AnimateNumber.vue.mjs +57 -46
  16. package/dist/es/components/AnimateNumber/Mask.vue.mjs +18 -14
  17. package/dist/es/components/AnimateNumber/NumberDigit.vue.mjs +55 -50
  18. package/dist/es/components/AnimateNumber/NumberSection.vue.mjs +79 -83
  19. package/dist/es/components/AnimateNumber/NumberSymbol.vue.mjs +30 -28
  20. package/dist/es/components/AnimateNumber/use-animate.mjs +5 -5
  21. package/dist/es/components/Ticker/Ticker.vue.mjs +183 -0
  22. package/dist/es/components/Ticker/Ticker.vue2.mjs +4 -0
  23. package/dist/es/components/Ticker/TickerItem.vue.mjs +46 -0
  24. package/dist/es/components/Ticker/TickerItem.vue2.mjs +4 -0
  25. package/dist/es/components/Ticker/const.mjs +4 -0
  26. package/dist/es/components/Ticker/context.mjs +6 -0
  27. package/dist/es/components/Ticker/index.mjs +5 -0
  28. package/dist/es/components/Ticker/use-item-offset.mjs +12 -0
  29. package/dist/es/components/Ticker/use-keyboard-focus.mjs +68 -0
  30. package/dist/es/index.mjs +20 -12
  31. package/dist/es/utils/flatten-slots.mjs +10 -0
  32. package/dist/index.d.ts +3 -2
  33. package/dist/utils/flatten-slots.d.ts +2 -0
  34. package/package.json +14 -6
@@ -0,0 +1,183 @@
1
+ import { defineComponent as ae, reactive as oe, ref as se, computed as s, useSlots as re, watch as le, createVNode as A, toRef as ue, createBlock as z, openBlock as d, unref as u, mergeProps as ce, withCtx as F, normalizeStyle as de, createElementBlock as N, Fragment as q, renderList as H, resolveDynamicComponent as K, isVNode as fe } from "vue";
2
+ import { useMotionValue as y, useTransform as pe, wrap as me, useDomRef as W, useInView as ge, useReducedMotion as Se, resize as ve, useAnimationFrame as ze, motion as G, animate as J } from "motion-v";
3
+ import Q from "./TickerItem.vue.mjs";
4
+ import { useKeyboardFocus as ye } from "./use-keyboard-focus.mjs";
5
+ import { defaultBounds as U } from "./const.mjs";
6
+ import { flattenSlots as xe } from "../../utils/flatten-slots.mjs";
7
+ function Pe(f) {
8
+ return typeof f == "function" || Object.prototype.toString.call(f) === "[object Object]" && !fe(f);
9
+ }
10
+ const be = /* @__PURE__ */ ae({
11
+ __name: "Ticker",
12
+ props: {
13
+ axis: {
14
+ default: "x"
15
+ },
16
+ style: {},
17
+ velocity: {
18
+ default: 50
19
+ },
20
+ hoverFactor: {
21
+ default: 1
22
+ },
23
+ gap: {
24
+ default: 10
25
+ },
26
+ align: {
27
+ default: "center"
28
+ },
29
+ offset: {}
30
+ },
31
+ setup(f) {
32
+ const a = f, e = oe({
33
+ listSize: 0,
34
+ containerSize: 0,
35
+ containerPaddingStart: 0,
36
+ containerPaddingEnd: 0,
37
+ itemSizes: []
38
+ }), x = se(!1), P = y(1), O = y(0), p = s(() => a.offset ?? O), h = y(0);
39
+ pe(() => (h.set(me(-e.listSize - a.gap - e.containerPaddingStart, -e.containerPaddingStart, p.value.get())), h.get()));
40
+ const w = y(0), v = s(() => x.value ? w : h), X = s(() => a.align === "start" ? "flex-start" : a.align === "center" ? "center" : "flex-end"), r = W(), k = W(), C = ge(r, {
41
+ margin: "100px"
42
+ }), Y = Se();
43
+ function M() {
44
+ if (!r.value || !k.value) return;
45
+ const {
46
+ axis: n
47
+ } = a, t = n === "x" ? "offsetWidth" : "offsetHeight", i = n === "x" ? "offsetLeft" : "offsetTop", o = n === "x" ? "paddingLeft" : "paddingTop", g = n === "x" ? "paddingRight" : "paddingBottom", S = r.value, b = k.value.querySelectorAll(".ticker-item");
48
+ if (!b.length) return;
49
+ let T = !1;
50
+ const c = [];
51
+ for (let l = 0; l < b.length; l++) {
52
+ const B = b[l];
53
+ c.push({
54
+ start: B[i],
55
+ end: B[i] + B[t]
56
+ }), (!e.itemSizes[l] || c[l].start !== e.itemSizes[l].start || c[l].end !== e.itemSizes[l].end) && (T = !0);
57
+ }
58
+ const j = S[t], L = c[c.length - 1].end - c[0].start, D = window.getComputedStyle(S), ne = parseInt(D[o] ?? 0), ie = parseInt(D[g] ?? 0);
59
+ (L !== e.listSize || j !== e.containerSize || T) && (e.listSize = L, e.containerSize = j, e.containerPaddingStart = ne, e.containerPaddingEnd = ie, e.itemSizes = c);
60
+ }
61
+ const m = re(), I = s(() => {
62
+ var n;
63
+ return xe((n = m == null ? void 0 : m.items) == null ? void 0 : n.call(m));
64
+ });
65
+ le([I, C, r], (n, t, i) => {
66
+ if (!C.value || !r.value) return;
67
+ M();
68
+ const o = ve(r.value, M);
69
+ i(o);
70
+ }, {
71
+ immediate: !0,
72
+ flush: "pre"
73
+ });
74
+ const R = s(() => e.containerSize > 0 && e.listSize > 0);
75
+ ze((n, t) => {
76
+ if (R.value && C.value && p.value === O && !Y.value) {
77
+ const i = t / 1e3 * (a.velocity * P.get());
78
+ p.value.set(p.value.get() - i);
79
+ }
80
+ });
81
+ const _ = s(() => {
82
+ let n = 0;
83
+ if (!R.value || !e.containerSize) return 0;
84
+ let t = 0;
85
+ const i = Math.max(...e.itemSizes.map((o) => o.end - o.start));
86
+ for (; t < e.containerSize + e.containerPaddingStart; )
87
+ t = (e.listSize + a.gap) * (n + 1) - i, n++;
88
+ return Math.max(n - 1, 0);
89
+ }), E = s(() => e.listSize === 0 ? 0 : (e.listSize + a.gap) * (_.value + 1)), Z = s(() => {
90
+ const n = [];
91
+ for (let t = 0; t < _.value; t++)
92
+ I.value.forEach((i, o) => {
93
+ const g = e.itemSizes[o], S = (e.listSize + a.gap) * (t + 1), $ = g ? {
94
+ start: g.start + S,
95
+ end: g.end + S
96
+ } : U;
97
+ n.push(A(Q, {
98
+ key: `clone-${t}-${o}`,
99
+ offset: v.value,
100
+ axis: a.axis,
101
+ listSize: E.value,
102
+ cloneIndex: o,
103
+ bounds: $,
104
+ containerPaddingStart: e.containerPaddingStart
105
+ }, Pe(i) ? i : {
106
+ default: () => [i]
107
+ }));
108
+ });
109
+ return n;
110
+ }), V = ue(a, "axis");
111
+ ye(r, V, w);
112
+ const ee = {
113
+ display: "flex",
114
+ position: "relative",
115
+ overflow: "hidden"
116
+ }, te = s(() => ({
117
+ display: "flex",
118
+ position: "relative",
119
+ willChange: "transform",
120
+ listStyleType: "none",
121
+ padding: 0,
122
+ margin: 0,
123
+ justifyContent: "flex-start",
124
+ flexDirection: a.axis === "x" ? "row" : "column",
125
+ gap: `${a.gap}px`,
126
+ alignItems: X.value,
127
+ x: a.axis === "x" ? v.value : 0,
128
+ y: a.axis === "y" ? v.value : 0,
129
+ opacity: R.value ? 1 : 0
130
+ }));
131
+ return (n, t) => (d(), z(u(G).div, ce({
132
+ ...n.$attrs
133
+ }, {
134
+ ref_key: "containerRef",
135
+ ref: r,
136
+ "data-size": e.listSize,
137
+ style: {
138
+ ...ee,
139
+ ...a.style
140
+ },
141
+ onFocusCapture: t[0] || (t[0] = () => {
142
+ x.value = !0;
143
+ }),
144
+ onBlurCapture: t[1] || (t[1] = () => {
145
+ x.value = !1, p.value.set(u(w).get());
146
+ }),
147
+ onPointerenter: t[2] || (t[2] = () => {
148
+ u(J)(u(P), n.hoverFactor);
149
+ }),
150
+ onPointerleave: t[3] || (t[3] = () => {
151
+ u(J)(u(P), 1);
152
+ })
153
+ }), {
154
+ default: F(() => [A(u(G).ul, {
155
+ ref_key: "listRef",
156
+ ref: k,
157
+ style: de(te.value)
158
+ }, {
159
+ default: F(() => [(d(!0), N(q, null, H(I.value, (i, o) => (d(), z(Q, {
160
+ key: `original-${o}`,
161
+ axis: V.value,
162
+ offset: v.value,
163
+ "list-size": E.value,
164
+ "item-index": o,
165
+ bounds: e.itemSizes[o] ?? u(U),
166
+ "container-padding-start": e.containerPaddingStart
167
+ }, {
168
+ default: F(() => [(d(), z(K(i), {
169
+ index: o
170
+ }, null, 8, ["index"]))]),
171
+ _: 2
172
+ }, 1032, ["axis", "offset", "list-size", "item-index", "bounds", "container-padding-start"]))), 128)), (d(!0), N(q, null, H(Z.value, (i) => (d(), z(K(i), {
173
+ key: i.key
174
+ }))), 128))]),
175
+ _: 1
176
+ }, 8, ["style"])]),
177
+ _: 1
178
+ }, 16, ["data-size", "style"]));
179
+ }
180
+ });
181
+ export {
182
+ be as default
183
+ };
@@ -0,0 +1,4 @@
1
+ import f from "./Ticker.vue.mjs";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,46 @@
1
+ import { defineComponent as p, createBlock as x, openBlock as S, unref as i, mergeProps as g, withCtx as k, renderSlot as I } from "vue";
2
+ import { useMotionValue as a, useTransform as d, motion as h } from "motion-v";
3
+ import { provideTickerItemContext as v } from "./context.mjs";
4
+ const b = /* @__PURE__ */ p({
5
+ __name: "TickerItem",
6
+ props: {
7
+ offset: {},
8
+ axis: {},
9
+ listSize: {},
10
+ containerPaddingStart: {},
11
+ bounds: {},
12
+ itemIndex: {},
13
+ cloneIndex: {}
14
+ },
15
+ setup(c) {
16
+ const t = c, r = a(0);
17
+ d(() => {
18
+ const e = t.offset.get(), { start: n, end: s } = t.bounds;
19
+ return !n && !s || !t.listSize ? r.set(0) : e + s <= -t.containerPaddingStart ? r.set(t.listSize) : r.set(0);
20
+ });
21
+ const o = a(0);
22
+ return d(() => {
23
+ const { offset: e, listSize: n, bounds: s } = t, { start: f, end: l } = s, u = e.get(), m = r.get();
24
+ return !f && !l || !n ? o.set(0) : o.set(u + f + m);
25
+ }), v({
26
+ offset: o
27
+ }), (e, n) => (S(), x(i(h).li, g(e.$attrs, {
28
+ class: e.cloneIndex === void 0 ? "ticker-item" : "clone-item",
29
+ "aria-hidden": e.cloneIndex !== void 0 ? !0 : void 0,
30
+ style: {
31
+ flexShrink: 0,
32
+ flexGrow: 0,
33
+ x: e.axis === "x" ? i(r) : 0,
34
+ y: e.axis === "y" ? i(r) : 0
35
+ }
36
+ }), {
37
+ default: k(() => [
38
+ I(e.$slots, "default")
39
+ ]),
40
+ _: 3
41
+ }, 16, ["class", "aria-hidden", "style"]));
42
+ }
43
+ });
44
+ export {
45
+ b as default
46
+ };
@@ -0,0 +1,4 @@
1
+ import f from "./TickerItem.vue.mjs";
2
+ export {
3
+ f as default
4
+ };
@@ -0,0 +1,4 @@
1
+ const t = { start: 0, end: 0 };
2
+ export {
3
+ t as defaultBounds
4
+ };
@@ -0,0 +1,6 @@
1
+ import { createContext as e } from "motion-v";
2
+ const [o, r] = e("TickerItemContext");
3
+ export {
4
+ r as provideTickerItemContext,
5
+ o as useTickerItemContext
6
+ };
@@ -0,0 +1,5 @@
1
+ import o from "./Ticker.vue.mjs";
2
+ const c = o;
3
+ export {
4
+ c as Ticker
5
+ };
@@ -0,0 +1,12 @@
1
+ import { invariant as t } from "motion-v";
2
+ import { useTickerItemContext as o } from "./context.mjs";
3
+ function n() {
4
+ const e = o(null);
5
+ return t(
6
+ !!e,
7
+ "useItemOffset must be used within a TickerItem"
8
+ ), e == null ? void 0 : e.offset;
9
+ }
10
+ export {
11
+ n as useItemOffset
12
+ };
@@ -0,0 +1,68 @@
1
+ import { isHTMLElement as f, frame as F, wrap as T } from "motion-v";
2
+ import { onMounted as A, onUnmounted as K } from "vue";
3
+ function D(s, r, w) {
4
+ let i = !1;
5
+ A(() => {
6
+ const t = s.value;
7
+ if (!t)
8
+ return;
9
+ const d = r.value === "x" ? "scrollLeft" : "scrollTop", y = r.value === "x" ? "offsetLeft" : "offsetTop", E = r.value === "x" ? "ArrowLeft" : "ArrowUp", L = r.value === "x" ? "ArrowRight" : "ArrowDown";
10
+ let c = [], o = 0;
11
+ const m = () => {
12
+ const e = c[o];
13
+ e.focus(), w.set(-e[y]), t[d] = 0, F.render(() => {
14
+ t[d] = 0;
15
+ });
16
+ }, b = (e) => {
17
+ if (e.key === "Tab") {
18
+ e.preventDefault(), u();
19
+ const n = Array.from(
20
+ document.querySelectorAll(
21
+ 'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"]), [contenteditable="true"]'
22
+ )
23
+ ).filter(f);
24
+ n.sort(M);
25
+ const g = n[e.shiftKey ? 0 : n.length - 1], h = e.shiftKey ? n.length - 1 : 0;
26
+ if (t.contains(g)) {
27
+ n[h].focus();
28
+ return;
29
+ } else {
30
+ const v = n.indexOf(
31
+ c[o]
32
+ ), I = e.shiftKey ? -1 : 1;
33
+ for (let l = v; l < n.length && l >= 0; l += I) {
34
+ const p = n[l];
35
+ if (!t.contains(p)) {
36
+ p.focus();
37
+ return;
38
+ }
39
+ }
40
+ }
41
+ return;
42
+ } else e.key === E ? o-- : e.key === L && o++;
43
+ o = T(0, c.length, o), m();
44
+ }, k = () => {
45
+ i || (i = !0, c = Array.from(
46
+ t.querySelectorAll(
47
+ '.ticker-item a, .ticker-item button, .ticker-item input, .ticker-item textarea, .ticker-item select, .ticker-item [tabindex]:not([tabindex="-1"]), .ticker-item [contenteditable="true"]'
48
+ )
49
+ ).filter(f), o = 0, m(), window.addEventListener("focus", a, !0), window.addEventListener("blur", a, !0), t.addEventListener("keydown", b));
50
+ }, a = (e) => {
51
+ (!e.target || !(e.target instanceof HTMLElement) || !t.contains(e.target)) && u();
52
+ }, u = () => {
53
+ i && (i = !1, window.removeEventListener("focus", a, !0), window.removeEventListener("blur", a, !0), t.removeEventListener("keydown", b));
54
+ }, x = (e) => {
55
+ const { target: n } = e;
56
+ f(n) && (i || k());
57
+ };
58
+ t.addEventListener("focus", x, !0), K(() => {
59
+ t.removeEventListener("focus", x), u();
60
+ });
61
+ });
62
+ }
63
+ function M(s, r) {
64
+ return s.tabIndex >= 1 && r.tabIndex >= 1 ? s.tabIndex - r.tabIndex : s.tabIndex >= 1 && r.tabIndex <= 0 ? -1 : r.tabIndex >= 1 && s.tabIndex <= 0 ? 1 : 0;
65
+ }
66
+ export {
67
+ D as useKeyboardFocus
68
+ };
package/dist/es/index.mjs CHANGED
@@ -1,14 +1,22 @@
1
- import { AnimateNumber as e } from "./components/AnimateNumber/index.mjs";
2
- import { default as s } from "./components/Cursor/Cursor.vue.mjs";
3
- import { useCursorState as m } from "./components/Cursor/hooks/use-cursor-state/index.mjs";
4
- import { useCursorIsInView as i } from "./components/Cursor/hooks/use-cursor-in-view.mjs";
5
- import { usePointerPosition as x } from "./components/Cursor/hooks/use-pointer-position.mjs";
6
- import { useMagneticPull as n } from "./components/Cursor/magnetic/use-magnetic-pull.mjs";
1
+ import { AnimateNumber as o } from "./components/AnimateNumber/index.mjs";
2
+ import { Ticker as s } from "./components/Ticker/index.mjs";
3
+ import { default as m } from "./components/Cursor/Cursor.vue.mjs";
4
+ import { default as p } from "./components/Ticker/TickerItem.vue.mjs";
5
+ import { useCursorState as a } from "./components/Cursor/hooks/use-cursor-state/index.mjs";
6
+ import { useCursorIsInView as n } from "./components/Cursor/hooks/use-cursor-in-view.mjs";
7
+ import { usePointerPosition as l } from "./components/Cursor/hooks/use-pointer-position.mjs";
8
+ import { useMagneticPull as d } from "./components/Cursor/magnetic/use-magnetic-pull.mjs";
9
+ import { useItemOffset as P } from "./components/Ticker/use-item-offset.mjs";
10
+ import { useKeyboardFocus as k } from "./components/Ticker/use-keyboard-focus.mjs";
7
11
  export {
8
- e as AnimateNumber,
9
- s as Cursor,
10
- i as useCursorIsInView,
11
- m as useCursorState,
12
- n as useMagneticPull,
13
- x as usePointerPosition
12
+ o as AnimateNumber,
13
+ m as Cursor,
14
+ s as Ticker,
15
+ p as TickerItem,
16
+ n as useCursorIsInView,
17
+ a as useCursorState,
18
+ P as useItemOffset,
19
+ k as useKeyboardFocus,
20
+ d as useMagneticPull,
21
+ l as usePointerPosition
14
22
  };
@@ -0,0 +1,10 @@
1
+ import { Comment as n, Fragment as o } from "vue";
2
+ function i(r = []) {
3
+ const e = [];
4
+ for (const t of r)
5
+ t.type !== n && (t.type === o && Array.isArray(t.children) ? e.push(...i(t.children)) : e.push(t));
6
+ return e;
7
+ }
8
+ export {
9
+ i as flattenSlots
10
+ };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
- export * from './components/AnimateNumber/index';
2
- export * from './components/Cursor/index';
1
+ export * from './components/AnimateNumber';
2
+ export * from './components/Cursor';
3
+ export * from './components/Ticker';
@@ -0,0 +1,2 @@
1
+ import { VNode } from 'vue';
2
+ export declare function flattenSlots(slots?: VNode[]): VNode[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "motion-plus-vue",
3
- "version": "1.1.5",
3
+ "version": "1.2.0-alpha.0",
4
4
  "description": "Motion Plus Vue",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -25,25 +25,33 @@
25
25
  ],
26
26
  "typings": "./dist/index.d.ts",
27
27
  "peerDependencies": {
28
- "motion-v": ">=0.13.0-beta.1",
28
+ "motion-v": ">=1.2.0",
29
29
  "vue": ">=3.0.0"
30
30
  },
31
31
  "devDependencies": {
32
- "motion-v": "^0.13.0-beta.1",
32
+ "motion-v": "^1.2.0",
33
33
  "vue": "^3.5.13"
34
34
  },
35
35
  "size-limit": [
36
36
  {
37
37
  "path": "dist/es/components/AnimateNumber/index.mjs",
38
- "limit": "3.6 kb",
38
+ "limit": "3.75 kb",
39
39
  "ignore": [
40
40
  "vue",
41
41
  "motion-v"
42
42
  ]
43
43
  },
44
44
  {
45
- "path": "dist/es/components/Cursor/index.mjs",
46
- "limit": "2.7 kb",
45
+ "path": "dist/es/components/Cursor/Cursor.vue.mjs",
46
+ "limit": "3.1 kb",
47
+ "ignore": [
48
+ "vue",
49
+ "motion-v"
50
+ ]
51
+ },
52
+ {
53
+ "path": "dist/es/components/Ticker/index.mjs",
54
+ "limit": "2.8 kb",
47
55
  "ignore": [
48
56
  "vue",
49
57
  "motion-v"