morphicons 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/LICENSE +21 -0
- package/README.md +273 -0
- package/dist/dom.d.ts +36 -0
- package/dist/dom.js +192 -0
- package/dist/index.d.ts +60 -0
- package/dist/index.js +2 -0
- package/dist/react.d.ts +31 -0
- package/dist/react.js +114 -0
- package/dist/spring-Dbj7NCw2.js +1099 -0
- package/dist/types-JAF3s76Y.d.ts +60 -0
- package/package.json +106 -0
package/dist/react.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { a as resampleIcon, d as interpPolar, i as serialize, l as allocOutputs, s as buildPlan } from "./spring-Dbj7NCw2.js";
|
|
2
|
+
import { canonicalD, createMorph } from "./dom.js";
|
|
3
|
+
import { forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/react/index.tsx
|
|
6
|
+
const useIsoLayoutEffect = typeof document === "undefined" ? useEffect : useLayoutEffect;
|
|
7
|
+
/** Frozen shape of the from→to pair at t, using the pure core (SSR-safe).
|
|
8
|
+
* At exact endpoints returns the canonical `d` (real curves, not polyline). */
|
|
9
|
+
function frozenD(from, to, t) {
|
|
10
|
+
if (t <= 0) return canonicalD(from);
|
|
11
|
+
if (t >= 1) return canonicalD(to);
|
|
12
|
+
const plan = buildPlan(resampleIcon(from), resampleIcon(to));
|
|
13
|
+
const out = allocOutputs(plan);
|
|
14
|
+
interpPolar(plan, t, out);
|
|
15
|
+
return serialize(out, plan.items.map((it) => it.closed));
|
|
16
|
+
}
|
|
17
|
+
const MorphIcon = forwardRef(function MorphIcon(props, ref) {
|
|
18
|
+
const { icon, from, to, progress, spring, size = 24, color = "currentColor", strokeWidth = 2, absoluteStrokeWidth, label, ...rest } = props;
|
|
19
|
+
const controlled = from !== void 0 && to !== void 0;
|
|
20
|
+
const initialIcon = icon ?? from ?? to;
|
|
21
|
+
const [initialD] = useState(() => {
|
|
22
|
+
if (controlled) return frozenD(from, to, progress ?? 0);
|
|
23
|
+
return initialIcon !== void 0 ? canonicalD(initialIcon) : "";
|
|
24
|
+
});
|
|
25
|
+
const pathRef = useRef(null);
|
|
26
|
+
const morphRef = useRef(null);
|
|
27
|
+
const springRef = useRef(spring);
|
|
28
|
+
springRef.current = spring;
|
|
29
|
+
const firstIcon = useRef(true);
|
|
30
|
+
const based = useRef(false);
|
|
31
|
+
const pair = useRef(null);
|
|
32
|
+
useIsoLayoutEffect(() => {
|
|
33
|
+
const el = pathRef.current;
|
|
34
|
+
if (!el || initialIcon === void 0) return;
|
|
35
|
+
const m = createMorph(el, controlled ? from : initialIcon);
|
|
36
|
+
morphRef.current = m;
|
|
37
|
+
if (controlled) {
|
|
38
|
+
pair.current = [from, to];
|
|
39
|
+
const t = progress ?? 0;
|
|
40
|
+
if (t <= 0) m.set(from);
|
|
41
|
+
else if (t >= 1) m.set(to);
|
|
42
|
+
else {
|
|
43
|
+
m.seek(to, t);
|
|
44
|
+
based.current = true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return () => {
|
|
48
|
+
m.destroy();
|
|
49
|
+
morphRef.current = null;
|
|
50
|
+
based.current = false;
|
|
51
|
+
pair.current = null;
|
|
52
|
+
};
|
|
53
|
+
}, []);
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (icon === void 0) return;
|
|
56
|
+
if (firstIcon.current) {
|
|
57
|
+
firstIcon.current = false;
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
morphRef.current?.morphTo(icon, springRef.current);
|
|
61
|
+
}, [icon]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
const m = morphRef.current;
|
|
64
|
+
if (!m || !controlled) return;
|
|
65
|
+
const t = progress ?? 0;
|
|
66
|
+
if (!pair.current || pair.current[0] !== from || pair.current[1] !== to) {
|
|
67
|
+
pair.current = [from, to];
|
|
68
|
+
based.current = false;
|
|
69
|
+
}
|
|
70
|
+
if (t <= 0) {
|
|
71
|
+
m.set(from);
|
|
72
|
+
based.current = false;
|
|
73
|
+
} else if (t >= 1) {
|
|
74
|
+
m.set(to);
|
|
75
|
+
based.current = false;
|
|
76
|
+
} else {
|
|
77
|
+
if (!based.current) {
|
|
78
|
+
m.set(from);
|
|
79
|
+
based.current = true;
|
|
80
|
+
}
|
|
81
|
+
m.seek(to, t);
|
|
82
|
+
}
|
|
83
|
+
}, [
|
|
84
|
+
controlled,
|
|
85
|
+
from,
|
|
86
|
+
to,
|
|
87
|
+
progress
|
|
88
|
+
]);
|
|
89
|
+
useImperativeHandle(ref, () => ({
|
|
90
|
+
morphTo: (i, s) => morphRef.current?.morphTo(i, s ?? springRef.current),
|
|
91
|
+
set: (i) => morphRef.current?.set(i)
|
|
92
|
+
}), []);
|
|
93
|
+
const sw = absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth;
|
|
94
|
+
return /* @__PURE__ */ jsxs("svg", {
|
|
95
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
96
|
+
width: size,
|
|
97
|
+
height: size,
|
|
98
|
+
viewBox: "0 0 24 24",
|
|
99
|
+
fill: "none",
|
|
100
|
+
stroke: color,
|
|
101
|
+
strokeWidth: sw,
|
|
102
|
+
strokeLinecap: "round",
|
|
103
|
+
strokeLinejoin: "round",
|
|
104
|
+
role: label ? "img" : void 0,
|
|
105
|
+
"aria-hidden": label ? void 0 : true,
|
|
106
|
+
...rest,
|
|
107
|
+
children: [label ? /* @__PURE__ */ jsx("title", { children: label }) : null, /* @__PURE__ */ jsx("path", {
|
|
108
|
+
ref: pathRef,
|
|
109
|
+
d: initialD
|
|
110
|
+
})]
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
//#endregion
|
|
114
|
+
export { MorphIcon };
|