apex-ui-kit 2.7.0 → 2.8.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 +19 -9
- package/dist/ApexUI-Kit/templates/AnimatedTabs/AnimatedTabs.jsx +1 -1
- package/dist/ApexUI-Kit/templates/CommandPalette/CommandPalette.jsx +250 -0
- package/dist/ApexUI-Kit/templates/CrossedMarquee/CrossedMarquee.jsx +158 -0
- package/dist/ApexUI-Kit/templates/DitherWaves/DitherWaves.jsx +207 -0
- package/dist/ApexUI-Kit/templates/GlassLens/GlassLens.jsx +274 -0
- package/dist/ApexUI-Kit/templates/GooeyNav/GooeyNav.jsx +1 -1
- package/dist/ApexUI-Kit/templates/ImageAccordion/ImageAccordion.jsx +116 -0
- package/dist/ApexUI-Kit/templates/InfiniteCanvas/InfiniteCanvas.jsx +230 -0
- package/dist/ApexUI-Kit/templates/OrbitIcons/OrbitIcons.jsx +169 -0
- package/dist/ApexUI-Kit/templates/RadialMenu/RadialMenu.jsx +20 -4
- package/dist/ApexUI-Kit/templates/TextRing3D/TextRing3D.jsx +18 -3
- package/dist/ApexUI-Kit/templates/ThemeSwitcher/ThemeSwitcher.jsx +215 -0
- package/dist/ApexUI-Kit/templates/ThemeSwitcher/themes.js +38 -0
- package/dist/ApexUI-Kit/templates/ToastStack/ToastStack.jsx +21 -13
- package/dist/cli/index.js +9 -0
- package/package.json +2 -2
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/* eslint-disable react-refresh/only-export-components -- the hook and helpers ship with the component on purpose */
|
|
2
|
+
import React, { useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
3
|
+
import { flushSync } from "react-dom";
|
|
4
|
+
import { AnimatePresence, motion } from "framer-motion";
|
|
5
|
+
import { applyTheme, defaultThemes } from "./themes.js";
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Theme Switcher: a palette button that opens a grid of colour themes. Picking
|
|
9
|
+
* one reveals it with a soft circle growing from the swatch you clicked (View
|
|
10
|
+
* Transitions API), and every component calling useTheme stays in sync.
|
|
11
|
+
*
|
|
12
|
+
* Props: themes = defaultThemes, placement = "down" | "up", align = "right" |
|
|
13
|
+
* "left", label (text on the trigger; without it the trigger is a round icon
|
|
14
|
+
* button), storageKey = "theme", target (element or ref to theme instead of
|
|
15
|
+
* <html>, e.g. one preview box), className, buttonClassName.
|
|
16
|
+
*
|
|
17
|
+
* Hook: const [themeId, setTheme] = useTheme(themes, { storageKey, defaultTheme });
|
|
18
|
+
* setTheme("grape", event.currentTarget) reveals from that element.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export { defaultThemes, applyTheme, themeScript } from "./themes.js";
|
|
22
|
+
|
|
23
|
+
const REVEAL_CSS = `@property --reveal { syntax: '<length>'; inherits: false; initial-value: 0px; }
|
|
24
|
+
@keyframes theme-reveal { from { --reveal: -10vmax; } to { --reveal: 160vmax; } }
|
|
25
|
+
html[data-theme-switching]::view-transition-old(root) { animation: none; }
|
|
26
|
+
html[data-theme-switching]::view-transition-new(root) {
|
|
27
|
+
mix-blend-mode: normal;
|
|
28
|
+
mask-image: radial-gradient(circle at var(--reveal-x, 100%) var(--reveal-y, 0px), #000 var(--reveal), transparent calc(var(--reveal) + 10vmax));
|
|
29
|
+
animation: theme-reveal 0.9s cubic-bezier(0.65, 0, 0.35, 1) both;
|
|
30
|
+
}`;
|
|
31
|
+
|
|
32
|
+
const injectCss = () => {
|
|
33
|
+
if (typeof document === "undefined" || document.getElementById("apex-theme-reveal")) return;
|
|
34
|
+
const style = document.createElement("style");
|
|
35
|
+
style.id = "apex-theme-reveal";
|
|
36
|
+
style.textContent = REVEAL_CSS;
|
|
37
|
+
document.head.appendChild(style);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const read = (key) => {
|
|
41
|
+
try {
|
|
42
|
+
return localStorage.getItem(key);
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const write = (key, value) => {
|
|
48
|
+
try {
|
|
49
|
+
localStorage.setItem(key, value);
|
|
50
|
+
} catch {
|
|
51
|
+
/* storage blocked: the theme still applies for this visit */
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// One small store per storage key, so every useTheme with that key shares state.
|
|
56
|
+
const stores = new Map();
|
|
57
|
+
function storeFor(key, themes, defaultTheme) {
|
|
58
|
+
if (stores.has(key)) return stores.get(key);
|
|
59
|
+
const prefersDark = typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches;
|
|
60
|
+
const saved = read(key);
|
|
61
|
+
const initial = (themes.find((x) => x.id === saved) ?? themes.find((x) => x.id === defaultTheme) ?? themes.find((x) => x.scheme === (prefersDark ? "dark" : "light")) ?? themes[0])?.id;
|
|
62
|
+
const subs = new Set();
|
|
63
|
+
const store = {
|
|
64
|
+
id: initial,
|
|
65
|
+
get: () => store.id,
|
|
66
|
+
subscribe: (fn) => {
|
|
67
|
+
subs.add(fn);
|
|
68
|
+
return () => subs.delete(fn);
|
|
69
|
+
},
|
|
70
|
+
set: (id) => {
|
|
71
|
+
store.id = id;
|
|
72
|
+
subs.forEach((fn) => fn());
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
stores.set(key, store);
|
|
76
|
+
return store;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function useTheme(themes = defaultThemes, { storageKey = "theme", defaultTheme, target } = {}) {
|
|
80
|
+
const store = storeFor(storageKey, themes, defaultTheme);
|
|
81
|
+
const id = useSyncExternalStore(store.subscribe, store.get, store.get);
|
|
82
|
+
const rootEl = () => target?.current ?? (target instanceof Element ? target : null) ?? document.documentElement;
|
|
83
|
+
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
injectCss();
|
|
86
|
+
applyTheme(themes.find((x) => x.id === store.get()), rootEl());
|
|
87
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
88
|
+
}, [themes, store, id]);
|
|
89
|
+
|
|
90
|
+
const setTheme = (next, origin) => {
|
|
91
|
+
const theme = themes.find((x) => x.id === next);
|
|
92
|
+
if (!theme || next === store.get()) return;
|
|
93
|
+
write(storageKey, next);
|
|
94
|
+
const commit = () => {
|
|
95
|
+
applyTheme(theme, rootEl());
|
|
96
|
+
flushSync(() => store.set(next));
|
|
97
|
+
};
|
|
98
|
+
const reduced = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
99
|
+
if (!document.startViewTransition || reduced) {
|
|
100
|
+
commit();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const root = document.documentElement;
|
|
104
|
+
if (origin?.getBoundingClientRect) {
|
|
105
|
+
const r = origin.getBoundingClientRect();
|
|
106
|
+
root.style.setProperty("--reveal-x", `${r.left + r.width / 2}px`);
|
|
107
|
+
root.style.setProperty("--reveal-y", `${r.top + r.height / 2}px`);
|
|
108
|
+
} else {
|
|
109
|
+
root.style.setProperty("--reveal-x", "100%");
|
|
110
|
+
root.style.setProperty("--reveal-y", "0px");
|
|
111
|
+
}
|
|
112
|
+
root.setAttribute("data-theme-switching", "");
|
|
113
|
+
const transition = document.startViewTransition(commit);
|
|
114
|
+
transition.ready.catch(() => {});
|
|
115
|
+
transition.finished.catch(() => {}).finally(() => root.removeAttribute("data-theme-switching"));
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return [id, setTheme];
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const Palette = () => (
|
|
122
|
+
<svg viewBox="0 0 24 24" className="h-[18px] w-[18px]" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
123
|
+
<path d="M12 22a10 10 0 1 1 10-10c0 2.8-2.2 4-4 4h-1.8a2 2 0 0 0-1.5 3.3A1.6 1.6 0 0 1 12 22z" />
|
|
124
|
+
<circle cx="7.5" cy="10.5" r="1" fill="currentColor" />
|
|
125
|
+
<circle cx="10.5" cy="6.5" r="1" fill="currentColor" />
|
|
126
|
+
<circle cx="15.5" cy="7.5" r="1" fill="currentColor" />
|
|
127
|
+
</svg>
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const ThemeSwitcher = ({ themes = defaultThemes, placement = "down", align = "right", label, storageKey = "theme", target, className = "", buttonClassName = "" }) => {
|
|
131
|
+
const [id, setTheme] = useTheme(themes, { storageKey, target });
|
|
132
|
+
const [open, setOpen] = useState(false);
|
|
133
|
+
const root = useRef(null);
|
|
134
|
+
const current = themes.find((x) => x.id === id) ?? themes[0];
|
|
135
|
+
const up = placement === "up";
|
|
136
|
+
|
|
137
|
+
useEffect(() => {
|
|
138
|
+
if (!open) return undefined;
|
|
139
|
+
const down = (e) => !root.current?.contains(e.target) && setOpen(false);
|
|
140
|
+
const key = (e) => e.key === "Escape" && setOpen(false);
|
|
141
|
+
document.addEventListener("pointerdown", down);
|
|
142
|
+
document.addEventListener("keydown", key);
|
|
143
|
+
return () => {
|
|
144
|
+
document.removeEventListener("pointerdown", down);
|
|
145
|
+
document.removeEventListener("keydown", key);
|
|
146
|
+
};
|
|
147
|
+
}, [open]);
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<div ref={root} className={`relative inline-block ${className}`}>
|
|
151
|
+
<button
|
|
152
|
+
type="button"
|
|
153
|
+
aria-label="Choose colour theme"
|
|
154
|
+
aria-haspopup="true"
|
|
155
|
+
aria-expanded={open}
|
|
156
|
+
onClick={() => setOpen((o) => !o)}
|
|
157
|
+
className={`relative inline-flex items-center justify-center gap-2 border border-[var(--line)] bg-[var(--surface)] text-[var(--ink)] transition-colors hover:border-[var(--accent)] ${label ? "h-9 rounded-full px-3.5 text-sm font-medium" : "h-9 w-9 rounded-full"} ${buttonClassName}`}
|
|
158
|
+
>
|
|
159
|
+
<Palette />
|
|
160
|
+
{label && <span>{label}</span>}
|
|
161
|
+
<span aria-hidden="true" className="absolute right-0.5 top-0.5 h-2 w-2 rounded-full ring-2 ring-[var(--surface)]" style={{ background: current?.vars["--accent"] }} />
|
|
162
|
+
</button>
|
|
163
|
+
<AnimatePresence>
|
|
164
|
+
{open && (
|
|
165
|
+
<motion.div
|
|
166
|
+
role="dialog"
|
|
167
|
+
aria-label="Colour themes"
|
|
168
|
+
initial={{ opacity: 0, y: up ? 8 : -8, scale: 0.96 }}
|
|
169
|
+
animate={{ opacity: 1, y: 0, scale: 1 }}
|
|
170
|
+
exit={{ opacity: 0, y: up ? 8 : -8, scale: 0.96 }}
|
|
171
|
+
transition={{ type: "spring", stiffness: 380, damping: 28 }}
|
|
172
|
+
className={`absolute z-50 w-[17.5rem] max-w-[calc(100vw-2rem)] rounded-2xl border border-[var(--line)] bg-[var(--surface)] p-3 text-[var(--ink)] shadow-[0_24px_60px_-16px_rgba(0,0,0,0.35)] ${up ? "bottom-full mb-2" : "top-full mt-2"} ${align === "left" ? "left-0" : "right-0"}`}
|
|
173
|
+
style={{ transformOrigin: `${up ? "bottom" : "top"} ${align === "left" ? "left" : "right"}` }}
|
|
174
|
+
>
|
|
175
|
+
<p className="mb-2.5 px-1 font-mono text-[0.65rem] uppercase tracking-[0.16em] text-[var(--muted)]">Pick a colour vibe</p>
|
|
176
|
+
<div className="grid grid-cols-2 gap-1.5">
|
|
177
|
+
{themes.map((theme, i) => {
|
|
178
|
+
const active = theme.id === id;
|
|
179
|
+
return (
|
|
180
|
+
<motion.button
|
|
181
|
+
key={theme.id}
|
|
182
|
+
type="button"
|
|
183
|
+
aria-pressed={active}
|
|
184
|
+
initial={{ y: 6 }}
|
|
185
|
+
animate={{ y: 0 }}
|
|
186
|
+
transition={{ delay: 0.03 * i, type: "spring", stiffness: 380, damping: 28 }}
|
|
187
|
+
onClick={(e) => {
|
|
188
|
+
setTheme(theme.id, e.currentTarget.querySelector("[data-swatch]"));
|
|
189
|
+
setOpen(false);
|
|
190
|
+
}}
|
|
191
|
+
className={`relative flex items-center gap-2.5 rounded-xl py-2 pl-2 pr-5 text-left text-[0.82rem] font-medium transition-colors hover:bg-[var(--bg)] ${active ? "bg-[var(--bg)]" : ""}`}
|
|
192
|
+
style={{ animation: `apex-theme-in 240ms ease-out ${30 * i}ms backwards` }}
|
|
193
|
+
>
|
|
194
|
+
<span data-swatch="" className="grid h-7 w-7 shrink-0 place-items-center rounded-full border border-[var(--line)]" style={{ background: theme.vars["--bg"] }}>
|
|
195
|
+
<span className="h-3 w-3 rounded-full" style={{ background: theme.vars["--accent"] }} />
|
|
196
|
+
</span>
|
|
197
|
+
<span className="flex-1 truncate">{theme.name}</span>
|
|
198
|
+
{active && (
|
|
199
|
+
<svg viewBox="0 0 24 24" className="absolute right-1.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-[var(--accent)]" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
|
|
200
|
+
<path d="M5 12l5 5L20 7" />
|
|
201
|
+
</svg>
|
|
202
|
+
)}
|
|
203
|
+
</motion.button>
|
|
204
|
+
);
|
|
205
|
+
})}
|
|
206
|
+
</div>
|
|
207
|
+
<style>{"@keyframes apex-theme-in{from{opacity:0}to{opacity:1}}"}</style>
|
|
208
|
+
</motion.div>
|
|
209
|
+
)}
|
|
210
|
+
</AnimatePresence>
|
|
211
|
+
</div>
|
|
212
|
+
);
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export default ThemeSwitcher;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Default themes for ThemeSwitcher, plus helpers to apply one and to inline
|
|
3
|
+
* a no-flash script in index.html. Each theme sets seven CSS variables on
|
|
4
|
+
* <html>: --bg, --surface, --ink, --muted, --line, --accent, --accent-ink.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const t = (id, name, scheme, bg, surface, ink, muted, line, accent, accentInk) => ({
|
|
8
|
+
id,
|
|
9
|
+
name,
|
|
10
|
+
scheme,
|
|
11
|
+
vars: { "--bg": bg, "--surface": surface, "--ink": ink, "--muted": muted, "--line": line, "--accent": accent, "--accent-ink": accentInk },
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const defaultThemes = [
|
|
15
|
+
t("sunrise", "Sunrise", "light", "#f4f2ed", "#ffffff", "#121110", "#6f6b64", "rgb(18 17 16 / .12)", "#ff5b1f", "#ffffff"),
|
|
16
|
+
t("ember", "Ember", "dark", "#0e0d0c", "#171615", "#f1efe9", "#9a958c", "rgb(241 239 233 / .12)", "#ff7a3d", "#120a05"),
|
|
17
|
+
t("paper", "Paper", "light", "#fafaf7", "#ffffff", "#111111", "#6b6b66", "rgb(17 17 17 / .12)", "#111111", "#fafaf7"),
|
|
18
|
+
t("noir", "Noir", "dark", "#0c0c0c", "#161616", "#f5f5f2", "#8f8f8a", "rgb(245 245 242 / .12)", "#f5f5f2", "#0c0c0c"),
|
|
19
|
+
t("meadow", "Meadow", "light", "#f2f7ef", "#ffffff", "#10200f", "#5d6f5a", "rgb(16 32 15 / .12)", "#2fb562", "#ffffff"),
|
|
20
|
+
t("matrix", "Matrix", "dark", "#07110a", "#0d1a11", "#d7f5dd", "#6f9a78", "rgb(215 245 221 / .12)", "#4ade80", "#04130a"),
|
|
21
|
+
t("ocean", "Ocean", "light", "#eef3fa", "#ffffff", "#0c1a2b", "#5b6b80", "rgb(12 26 43 / .12)", "#2563eb", "#ffffff"),
|
|
22
|
+
t("grape", "Grape", "dark", "#0f0b1a", "#181229", "#ece8f7", "#9890b0", "rgb(236 232 247 / .12)", "#a78bfa", "#140d24"),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
export function applyTheme(theme, root = typeof document !== "undefined" ? document.documentElement : null) {
|
|
26
|
+
if (!theme || !root) return;
|
|
27
|
+
Object.entries(theme.vars).forEach(([k, v]) => root.style.setProperty(k, v));
|
|
28
|
+
root.setAttribute("data-theme", theme.id);
|
|
29
|
+
root.setAttribute("data-scheme", theme.scheme);
|
|
30
|
+
root.style.colorScheme = theme.scheme;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// A string to inline in <head> (before your app script) so the saved theme
|
|
34
|
+
// is applied before React loads: no flash of the wrong colours.
|
|
35
|
+
export function themeScript(storageKey = "theme", themes = defaultThemes) {
|
|
36
|
+
const data = JSON.stringify(themes.map(({ id, scheme, vars }) => ({ id, scheme, vars })));
|
|
37
|
+
return `(function(){try{var T=${data};var id=localStorage.getItem(${JSON.stringify(storageKey)});var t=T.find(function(x){return x.id===id});if(!t)return;var r=document.documentElement;for(var k in t.vars)r.style.setProperty(k,t.vars[k]);r.setAttribute("data-theme",t.id);r.setAttribute("data-scheme",t.scheme);r.style.colorScheme=t.scheme;}catch(e){}})();`;
|
|
38
|
+
}
|
|
@@ -66,6 +66,7 @@ const ToastStack = forwardRef(function ToastStack({ position = "bottom-right", d
|
|
|
66
66
|
onPointerLeave={() => setHovered(false)}
|
|
67
67
|
className={`${contained ? "absolute" : "fixed"} z-[200] flex w-[min(22rem,calc(100%-2rem))] flex-col ${place} ${className}`}
|
|
68
68
|
>
|
|
69
|
+
<style>{"@keyframes apex-toast-in{from{opacity:0}to{opacity:1}}"}</style>
|
|
69
70
|
<AnimatePresence initial={false}>
|
|
70
71
|
{toasts.map((t, i) => {
|
|
71
72
|
const fromEnd = toasts.length - 1 - i;
|
|
@@ -75,27 +76,34 @@ const ToastStack = forwardRef(function ToastStack({ position = "bottom-right", d
|
|
|
75
76
|
return (
|
|
76
77
|
<motion.li
|
|
77
78
|
key={t.id}
|
|
78
|
-
layout
|
|
79
79
|
drag="x"
|
|
80
80
|
dragConstraints={{ left: 0, right: 0 }}
|
|
81
81
|
dragElastic={0.6}
|
|
82
82
|
onDragEnd={(_, info) => Math.abs(info.offset.x) > 90 && dismiss(t.id)}
|
|
83
|
-
initial={{
|
|
84
|
-
animate={{
|
|
85
|
-
exit={{
|
|
83
|
+
initial={{ y: top ? -30 : 30, scale: 0.94 }}
|
|
84
|
+
animate={{ y: top ? offset : -offset, scale: hovered ? 1 : 1 - fromEnd * 0.05 }}
|
|
85
|
+
exit={{ scale: 0.9, transition: { duration: 0.18 } }}
|
|
86
86
|
transition={{ type: "spring", stiffness: 380, damping: 32 }}
|
|
87
87
|
className={`absolute w-full cursor-grab touch-pan-y list-none active:cursor-grabbing ${top ? "top-0" : "bottom-0"}`}
|
|
88
88
|
style={{ zIndex: i }}
|
|
89
89
|
>
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
90
|
+
{/* Cards deeper than three fade out of the collapsed stack. */}
|
|
91
|
+
<div className="transition-opacity duration-300" style={{ opacity: fromEnd > 2 && !hovered ? 0 : 1 }}>
|
|
92
|
+
{/* The fade-in is a CSS animation: framer hands opacity to the browser
|
|
93
|
+
and, when that finishes, can show the start value for one frame. */}
|
|
94
|
+
<motion.div
|
|
95
|
+
exit={{ opacity: 0, transition: { duration: 0.18 } }}
|
|
96
|
+
style={{ animation: "apex-toast-in 0.22s ease-out backwards" }}
|
|
97
|
+
className={`relative flex items-start gap-3 rounded-2xl border p-3.5 pr-9 shadow-[0_18px_40px_-18px_rgba(0,0,0,0.5)] backdrop-blur ${dark ? "border-white/10 bg-neutral-900/95 text-white" : "border-black/10 bg-white/95 text-neutral-900"}`}>
|
|
98
|
+
<Icon className="mt-0.5 h-5 w-5 shrink-0" style={{ color }} />
|
|
99
|
+
<div className="min-w-0">
|
|
100
|
+
<p className="text-[0.88rem] font-semibold">{t.title}</p>
|
|
101
|
+
{t.description && <p className={`mt-0.5 text-[0.8rem] ${dark ? "text-white/60" : "text-neutral-500"}`}>{t.description}</p>}
|
|
102
|
+
</div>
|
|
103
|
+
<button type="button" aria-label="Dismiss" onClick={() => dismiss(t.id)} className={`absolute right-2.5 top-2.5 grid h-6 w-6 place-items-center rounded-full ${dark ? "text-white/50 hover:bg-white/10 hover:text-white" : "text-neutral-400 hover:bg-black/5 hover:text-neutral-900"}`}>
|
|
104
|
+
<X className="h-3.5 w-3.5" />
|
|
105
|
+
</button>
|
|
106
|
+
</motion.div>
|
|
99
107
|
</div>
|
|
100
108
|
</motion.li>
|
|
101
109
|
);
|
package/dist/cli/index.js
CHANGED
|
@@ -131,6 +131,14 @@ const componentMap = {
|
|
|
131
131
|
"scroll-stack": "ScrollStack",
|
|
132
132
|
"sunrise-background": "SunriseBackground",
|
|
133
133
|
"horizon-glow": "HorizonGlow",
|
|
134
|
+
"glass-lens": "GlassLens",
|
|
135
|
+
"dither-waves": "DitherWaves",
|
|
136
|
+
"infinite-canvas": "InfiniteCanvas",
|
|
137
|
+
"image-accordion": "ImageAccordion",
|
|
138
|
+
"orbit-icons": "OrbitIcons",
|
|
139
|
+
"command-palette": "CommandPalette",
|
|
140
|
+
"crossed-marquee": "CrossedMarquee",
|
|
141
|
+
"theme-switcher": "ThemeSwitcher",
|
|
134
142
|
"water-drop-reveal": "MaskView",
|
|
135
143
|
};
|
|
136
144
|
// Packages only some components need, installed on top of the shared ones.
|
|
@@ -140,6 +148,7 @@ const extraDeps = {
|
|
|
140
148
|
SmokeBackground: ["ogl"],
|
|
141
149
|
LiquidGradient: ["ogl"],
|
|
142
150
|
WebGLCarousel: ["ogl"],
|
|
151
|
+
CrossedMarquee: ["simple-icons"],
|
|
143
152
|
};
|
|
144
153
|
async function main() {
|
|
145
154
|
const args = process.argv.slice(2);
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "apex-ui-kit",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.8.0",
|
|
4
4
|
"license": "MIT",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "115 free, animated UI components for React, styled with Tailwind CSS. Add any of them with one CLI command.",
|
|
6
6
|
"homepage": "https://apex-ui.in",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|