From a3a9f65ae3fb325555a068263a1c910020c7d3e4 Mon Sep 17 00:00:00 2001 From: Huakun Shen Date: Sun, 9 Mar 2025 21:55:24 -0400 Subject: [PATCH] feat(ui): add new animation components and keyframes utility --- packages/svelte-animation/.gitignore | 34 +++++++++ packages/svelte-animation/README.md | 0 packages/svelte-animation/index.ts | 1 + packages/svelte-animation/package.json | 12 ++++ packages/svelte-animation/src/keyframes.ts | 63 ++++++++++++++++ packages/svelte-animation/src/utils.ts | 6 ++ packages/svelte-animation/tsconfig.json | 27 +++++++ .../permissions/autogenerated/reference.md | 2 - packages/ui/package.json | 4 ++ .../components/animation/AuroraText.svelte | 24 +++++++ .../src/components/animation/MagicCard.svelte | 72 +++++++++++++++++++ .../src/components/animation/RetroGrid.svelte | 35 +++++++++ .../components/animation/ShineBorder.svelte | 39 ++++++++++ .../components/animation/WordRotate.svelte | 35 +++++++++ packages/ui/src/components/animation/index.ts | 7 ++ .../src/components/animation/meteros.svelte | 36 ++++++++++ packages/ui/src/index.ts | 3 + pnpm-lock.yaml | 72 ++++++++++++++++++- 18 files changed, 467 insertions(+), 5 deletions(-) create mode 100644 packages/svelte-animation/.gitignore create mode 100644 packages/svelte-animation/README.md create mode 100644 packages/svelte-animation/index.ts create mode 100644 packages/svelte-animation/package.json create mode 100644 packages/svelte-animation/src/keyframes.ts create mode 100644 packages/svelte-animation/src/utils.ts create mode 100644 packages/svelte-animation/tsconfig.json create mode 100644 packages/ui/src/components/animation/AuroraText.svelte create mode 100644 packages/ui/src/components/animation/MagicCard.svelte create mode 100644 packages/ui/src/components/animation/RetroGrid.svelte create mode 100644 packages/ui/src/components/animation/ShineBorder.svelte create mode 100644 packages/ui/src/components/animation/WordRotate.svelte create mode 100644 packages/ui/src/components/animation/index.ts create mode 100644 packages/ui/src/components/animation/meteros.svelte diff --git a/packages/svelte-animation/.gitignore b/packages/svelte-animation/.gitignore new file mode 100644 index 00000000..a14702c4 --- /dev/null +++ b/packages/svelte-animation/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/packages/svelte-animation/README.md b/packages/svelte-animation/README.md new file mode 100644 index 00000000..e69de29b diff --git a/packages/svelte-animation/index.ts b/packages/svelte-animation/index.ts new file mode 100644 index 00000000..cc2d4eed --- /dev/null +++ b/packages/svelte-animation/index.ts @@ -0,0 +1 @@ +export * as keyframes from "./src/keyframes" diff --git a/packages/svelte-animation/package.json b/packages/svelte-animation/package.json new file mode 100644 index 00000000..c99ebf50 --- /dev/null +++ b/packages/svelte-animation/package.json @@ -0,0 +1,12 @@ +{ + "name": "@kksh/svelte-animation", + "module": "index.ts", + "type": "module", + "private": true, + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5" + } +} diff --git a/packages/svelte-animation/src/keyframes.ts b/packages/svelte-animation/src/keyframes.ts new file mode 100644 index 00000000..6435adda --- /dev/null +++ b/packages/svelte-animation/src/keyframes.ts @@ -0,0 +1,63 @@ +import type { Config } from "tailwindcss" + +export const shinePulse: NonNullable["extend"]>["keyframes"] = { + "border-beam": { + "100%": { + "offset-distance": "100%" + } + }, + "text-gradient": { + to: { + backgroundPosition: "200% center" + } + }, + meteor: { + "0%": { transform: "rotate(215deg) translateX(0)", opacity: "1" }, + "70%": { opacity: "1" }, + "100%": { + transform: "rotate(215deg) translateX(-500px)", + opacity: "0" + } + }, + grid: { + "0%": { transform: "translateY(-50%)" }, + "100%": { transform: "translateY(0)" } + }, + "aurora-border": { + "0%, 100%": { borderRadius: "37% 29% 27% 27% / 28% 25% 41% 37%" }, + "25%": { borderRadius: "47% 29% 39% 49% / 61% 19% 66% 26%" }, + "50%": { borderRadius: "57% 23% 47% 72% / 63% 17% 66% 33%" }, + "75%": { borderRadius: "28% 49% 29% 100% / 93% 20% 64% 25%" } + }, + "aurora-1": { + "0%, 100%": { top: "0", right: "0" }, + "50%": { top: "50%", right: "25%" }, + "75%": { top: "25%", right: "50%" } + }, + "aurora-2": { + "0%, 100%": { top: "0", left: "0" }, + "60%": { top: "75%", left: "25%" }, + "85%": { top: "50%", left: "50%" } + }, + "aurora-3": { + "0%, 100%": { bottom: "0", left: "0" }, + "40%": { bottom: "50%", left: "25%" }, + "65%": { bottom: "25%", left: "50%" } + }, + "aurora-4": { + "0%, 100%": { bottom: "0", right: "0" }, + "50%": { bottom: "25%", right: "40%" }, + "90%": { bottom: "50%", right: "25%" } + }, + "shine-pulse": { + "0%": { + "background-position": "0% 0%" + }, + "50%": { + "background-position": "100% 100%" + }, + to: { + "background-position": "0% 0%" + } + } +} diff --git a/packages/svelte-animation/src/utils.ts b/packages/svelte-animation/src/utils.ts new file mode 100644 index 00000000..9a7122c3 --- /dev/null +++ b/packages/svelte-animation/src/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/packages/svelte-animation/tsconfig.json b/packages/svelte-animation/tsconfig.json new file mode 100644 index 00000000..238655f2 --- /dev/null +++ b/packages/svelte-animation/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md b/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md index 43a78fde..0475fc52 100644 --- a/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md +++ b/packages/tauri-plugins/jarvis/permissions/autogenerated/reference.md @@ -1,4 +1,3 @@ - ## Permission Table @@ -7,7 +6,6 @@ -
Description
diff --git a/packages/ui/package.json b/packages/ui/package.json index d38dd415..e8c148c6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -28,6 +28,10 @@ "./extension": { "types": "./src/components/extension/index.ts", "svelte": "./src/components/extension/index.ts" + }, + "./animation": { + "types": "./src/components/animation/index.ts", + "svelte": "./src/components/animation/index.ts" } }, "scripts": { diff --git a/packages/ui/src/components/animation/AuroraText.svelte b/packages/ui/src/components/animation/AuroraText.svelte new file mode 100644 index 00000000..1b73fa70 --- /dev/null +++ b/packages/ui/src/components/animation/AuroraText.svelte @@ -0,0 +1,24 @@ + + + + {@render children()} + + + + + + + diff --git a/packages/ui/src/components/animation/MagicCard.svelte b/packages/ui/src/components/animation/MagicCard.svelte new file mode 100644 index 00000000..b5097754 --- /dev/null +++ b/packages/ui/src/components/animation/MagicCard.svelte @@ -0,0 +1,72 @@ + + + + +
+
+ + +
+

Magic Card

+
+
+
+ +
+ +
+ + diff --git a/packages/ui/src/components/animation/RetroGrid.svelte b/packages/ui/src/components/animation/RetroGrid.svelte new file mode 100644 index 00000000..e1100622 --- /dev/null +++ b/packages/ui/src/components/animation/RetroGrid.svelte @@ -0,0 +1,35 @@ + + +
+ +
+
+
+ + +
+
diff --git a/packages/ui/src/components/animation/ShineBorder.svelte b/packages/ui/src/components/animation/ShineBorder.svelte new file mode 100644 index 00000000..2af25999 --- /dev/null +++ b/packages/ui/src/components/animation/ShineBorder.svelte @@ -0,0 +1,39 @@ + + +
+
+ + Default +
diff --git a/packages/ui/src/components/animation/WordRotate.svelte b/packages/ui/src/components/animation/WordRotate.svelte new file mode 100644 index 00000000..fac01438 --- /dev/null +++ b/packages/ui/src/components/animation/WordRotate.svelte @@ -0,0 +1,35 @@ + + +
+ {#key index} + +

+ {words[index]} +

+ {/key} +
diff --git a/packages/ui/src/components/animation/index.ts b/packages/ui/src/components/animation/index.ts new file mode 100644 index 00000000..4beeff88 --- /dev/null +++ b/packages/ui/src/components/animation/index.ts @@ -0,0 +1,7 @@ +export { default as GridAnimation } from "./grid-animation.svelte" +export { default as BorderBeam } from "./BorderBeam.svelte" +export { default as Meteors } from "./meteros.svelte" +export { default as RetroGrid } from "./RetroGrid.svelte" +export { default as AuroraText } from "./AuroraText.svelte" +export { default as WordRotate } from "./WordRotate.svelte" +export { default as MagicCard } from "./MagicCard.svelte" diff --git a/packages/ui/src/components/animation/meteros.svelte b/packages/ui/src/components/animation/meteros.svelte new file mode 100644 index 00000000..7b59cad4 --- /dev/null +++ b/packages/ui/src/components/animation/meteros.svelte @@ -0,0 +1,36 @@ + + +{#each meteorStyles as style, idx} + + +
+
+{/each} diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 19977088..aec96348 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -10,6 +10,9 @@ export * as Extension from "./components/extension/index" export { default as GridAnimation } from "./components/animation/grid-animation.svelte" export { default as ViewTransition } from "./components/transition/view-transition.svelte" export { default as BorderBeam } from "./components/animation/BorderBeam.svelte" +export { default as Meteors } from "./components/animation/meteros.svelte" +export { default as RetroGrid } from "./components/animation/RetroGrid.svelte" +export { default as AuroraText } from "./components/animation/AuroraText.svelte" export * as Constants from "./constants" export * as Form from "./components/ui/form" export { default as ModeToggle } from "./components/theme/mode-toggle.svelte" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f862101b..0b23f7bf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -335,7 +335,7 @@ importers: version: 8.25.0(eslint@9.21.0(jiti@2.4.0))(typescript@5.6.3) autoprefixer: specifier: ^10.4.20 - version: 10.4.20(postcss@8.4.49) + version: 10.4.20(postcss@8.5.3) bits-ui: specifier: 1.0.0-next.86 version: 1.0.0-next.86(svelte@5.20.5) @@ -791,6 +791,16 @@ importers: specifier: latest version: 1.2.4 + packages/svelte-animation: + dependencies: + typescript: + specifier: ^5 + version: 5.7.3 + devDependencies: + '@types/bun': + specifier: latest + version: 1.2.4 + packages/tauri-plugins/jarvis: dependencies: typescript: @@ -1246,6 +1256,9 @@ importers: svelte-markdown: specifier: ^0.4.1 version: 0.4.1(svelte@5.20.5) + svelte-motion: + specifier: ^0.12.2 + version: 0.12.2(svelte@5.20.5) valibot: specifier: 1.0.0-beta.12 version: 1.0.0-beta.12(typescript@5.7.3) @@ -7835,6 +7848,9 @@ packages: fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + framesync@6.1.2: + resolution: {integrity: sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==} + fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} @@ -8121,6 +8137,9 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -9660,6 +9679,9 @@ packages: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} + popmotion@11.0.5: + resolution: {integrity: sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==} + portfinder@1.0.32: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} engines: {node: '>= 0.12.0'} @@ -10829,6 +10851,9 @@ packages: style-to-object@1.0.8: resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==} + style-value-types@5.1.2: + resolution: {integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==} + styled-jsx@5.1.1: resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} @@ -10928,6 +10953,11 @@ packages: peerDependencies: svelte: ^4.0.0 + svelte-motion@0.12.2: + resolution: {integrity: sha512-7RrdRz9iVP55B9HT/C0hYW3pyrKlF61kAby/AkDtOAP0uHFQDrfd0qQetDC81cEsK9b40jt+jfcqSAXcA7LPEw==} + peerDependencies: + svelte: '>=3.35.0 || ^4.0.0 || ^5.0.0 || ^5.0.0-next.0' + svelte-persisted-store@0.12.0: resolution: {integrity: sha512-BdBQr2SGSJ+rDWH8/aEV5GthBJDapVP0GP3fuUCA7TjYG5ctcB+O9Mj9ZC0+Jo1oJMfZUd1y9H68NFRR5MyIJA==} engines: {node: '>=0.14'} @@ -18489,6 +18519,16 @@ snapshots: postcss: 8.5.1 postcss-value-parser: 4.2.0 + autoprefixer@10.4.20(postcss@8.5.3): + dependencies: + browserslist: 4.24.2 + caniuse-lite: 1.0.30001676 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.1.1 + postcss: 8.5.3 + postcss-value-parser: 4.2.0 + available-typed-arrays@1.0.7: dependencies: possible-typed-array-names: 1.0.0 @@ -20458,6 +20498,10 @@ snapshots: fraction.js@4.3.7: {} + framesync@6.1.2: + dependencies: + tslib: 2.4.0 + fresh@0.5.2: {} fs-extra@10.1.0: @@ -20777,6 +20821,8 @@ snapshots: he@1.2.0: {} + hey-listen@1.0.8: {} + highlight.js@11.11.1: {} hookable@5.5.3: {} @@ -22432,6 +22478,13 @@ snapshots: pluralize@8.0.0: {} + popmotion@11.0.5: + dependencies: + framesync: 6.1.2 + hey-listen: 1.0.8 + style-value-types: 5.1.2 + tslib: 2.4.0 + portfinder@1.0.32: dependencies: async: 2.6.4 @@ -23653,6 +23706,11 @@ snapshots: dependencies: inline-style-parser: 0.2.4 + style-value-types@5.1.2: + dependencies: + hey-listen: 1.0.8 + tslib: 2.4.0 + styled-jsx@5.1.1(react@18.3.1): dependencies: client-only: 0.0.1 @@ -23769,6 +23827,15 @@ snapshots: marked: 5.1.2 svelte: 5.20.5 + svelte-motion@0.12.2(svelte@5.20.5): + dependencies: + '@types/react': 18.3.12 + framesync: 6.1.2 + popmotion: 11.0.5 + style-value-types: 5.1.2 + svelte: 5.20.5 + tslib: 2.8.1 + svelte-persisted-store@0.12.0(svelte@5.16.6): dependencies: svelte: 5.16.6 @@ -24374,8 +24441,7 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 - tslib@2.4.0: - optional: true + tslib@2.4.0: {} tslib@2.8.1: {}