diff --git a/.prettierignore b/.prettierignore
index 997f63f..b77e5a0 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1 +1,2 @@
-/src/shadcn
\ No newline at end of file
+/src/shadcn
+/src/components/InspiraUI/
\ No newline at end of file
diff --git a/package.json b/package.json
index bf40c96..7f84ce8 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"@intlify/unplugin-vue-i18n": "^6.0.5",
"@pinia/colada": "^0.14.2",
"@primeuix/themes": "^1.0.0",
+ "@splinetool/runtime": "^1.9.82",
"@unhead/vue": "^2.0.2",
"@vant/use": "^1.6.0",
"@vueuse/core": "^13.0.0",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d25a3eb..f67c409 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -28,6 +28,9 @@ importers:
'@primeuix/themes':
specifier: ^1.0.0
version: 1.0.0
+ '@splinetool/runtime':
+ specifier: ^1.9.82
+ version: 1.9.82
'@unhead/vue':
specifier: ^2.0.2
version: 2.0.2(vue@3.5.13(typescript@5.8.2))
@@ -1346,6 +1349,9 @@ packages:
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
engines: {node: '>=18'}
+ '@splinetool/runtime@1.9.82':
+ resolution: {integrity: sha512-qfNTnezSGuh7nPUPgRVfpH+g2FYywvYmHzOLmp8dahMxuY7HshOwLEhKVapaaWxIpq4h/WweU83pBWb48bwA8A==}
+
'@swc/helpers@0.5.15':
resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==}
@@ -3511,6 +3517,10 @@ packages:
ohash@2.0.11:
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
+ on-change@4.0.2:
+ resolution: {integrity: sha512-cMtCyuJmTx/bg2HCpHo3ZLeF7FZnBOapLqZHr2AlLeJ5Ul0Zu2mUJJz051Fdwu/Et2YW04ZD+TtU+gVy0ACNCA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
onetime@6.0.0:
resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
engines: {node: '>=12'}
@@ -5707,6 +5717,11 @@ snapshots:
'@sindresorhus/merge-streams@4.0.0': {}
+ '@splinetool/runtime@1.9.82':
+ dependencies:
+ on-change: 4.0.2
+ semver-compare: 1.0.0
+
'@swc/helpers@0.5.15':
dependencies:
tslib: 2.8.1
@@ -8149,6 +8164,8 @@ snapshots:
ohash@2.0.11: {}
+ on-change@4.0.2: {}
+
onetime@6.0.0:
dependencies:
mimic-fn: 4.0.0
diff --git a/src/components/InspiraUI/FluidCursor.vue b/src/components/InspiraUI/FluidCursor.vue
new file mode 100644
index 0000000..8847a28
--- /dev/null
+++ b/src/components/InspiraUI/FluidCursor.vue
@@ -0,0 +1,1323 @@
+
+
+
+
+
+
+
diff --git a/src/components/InspiraUI/pattern-background/PatternBackground.vue b/src/components/InspiraUI/pattern-background/PatternBackground.vue
new file mode 100644
index 0000000..d3f43e1
--- /dev/null
+++ b/src/components/InspiraUI/pattern-background/PatternBackground.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/src/components/InspiraUI/pattern-background/index.ts b/src/components/InspiraUI/pattern-background/index.ts
new file mode 100644
index 0000000..c5fd465
--- /dev/null
+++ b/src/components/InspiraUI/pattern-background/index.ts
@@ -0,0 +1,87 @@
+import { cva, type VariantProps } from "class-variance-authority";
+import type { HTMLAttributes } from "vue";
+
+type ObjectValues = T[keyof T];
+
+export const PATTERN_BACKGROUND_DIRECTION = {
+ Top: "top",
+ Bottom: "bottom",
+ Left: "left",
+ Right: "right",
+ TopLeft: "top-left",
+ TopRight: "top-right",
+ BottomLeft: "bottom-left",
+ BottomRight: "bottom-right",
+} as const;
+
+export type PatternBackgroundDirection = ObjectValues;
+
+export interface BaseProps {
+ class?: HTMLAttributes["class"];
+ animate?: boolean;
+ direction?: PatternBackgroundDirection;
+ variant?: PatternBackgroundVariants["variant"];
+ size?: PatternBackgroundVariants["size"];
+ mask?: PatternBackgroundMaskVariants["mask"];
+ speed?: ObjectValues;
+}
+
+export const PATTERN_BACKGROUND_VARIANT = {
+ Grid: "grid",
+ Dot: "dot",
+ BigDot: "big-dot",
+} as const;
+
+export const PATTERN_BACKGROUND_SPEED = {
+ Default: 10000,
+ Slow: 25000,
+ Fast: 5000,
+} as const;
+
+export const patternBackgroundVariants = cva("relative text-clip", {
+ variants: {
+ variant: {
+ [PATTERN_BACKGROUND_VARIANT.Grid]:
+ "bg-[linear-gradient(to_right,hsl(var(--foreground)/0.3)_1px,transparent_1px),linear-gradient(to_bottom,hsl(var(--foreground)/0.3)_1px,transparent_1px)]",
+ [PATTERN_BACKGROUND_VARIANT.Dot]:
+ "bg-[radial-gradient(hsl(var(--foreground)/0.3)_1px,transparent_1px)]",
+ [PATTERN_BACKGROUND_VARIANT.BigDot]:
+ "bg-[radial-gradient(hsl(var(--foreground)/0.3)_3px,transparent_3px)]",
+ },
+ size: {
+ xs: "bg-[size:8px_8px]",
+ sm: "bg-[size:16px_16px]",
+ md: "bg-[size:24px_24px]",
+ lg: "bg-[size:32px_32px]",
+ },
+ },
+ defaultVariants: {
+ variant: "grid",
+ size: "md",
+ },
+});
+
+export type PatternBackgroundVariants = VariantProps;
+
+export const PATTERN_BACKGROUND_MASK = {
+ Ellipse: "ellipse",
+ EllipseTop: "ellipse-top",
+} as const;
+
+export const patternBackgroundMaskVariants = cva("bg-background", {
+ variants: {
+ mask: {
+ [PATTERN_BACKGROUND_MASK.Ellipse]:
+ "[mask-image:radial-gradient(ellipse_at_center,transparent,black_80%)]",
+ [PATTERN_BACKGROUND_MASK.EllipseTop]:
+ "[mask-image:radial-gradient(ellipse_at_top,transparent,black_80%)]",
+ },
+ },
+ defaultVariants: {
+ mask: "ellipse",
+ },
+});
+
+export type PatternBackgroundMaskVariants = VariantProps;
+
+export { default as PatternBackground } from "./PatternBackground.vue";
diff --git a/src/components/InspiraUI/spline/ParentSize.vue b/src/components/InspiraUI/spline/ParentSize.vue
new file mode 100644
index 0000000..c33b006
--- /dev/null
+++ b/src/components/InspiraUI/spline/ParentSize.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/InspiraUI/spline/Spline.vue b/src/components/InspiraUI/spline/Spline.vue
new file mode 100644
index 0000000..608a021
--- /dev/null
+++ b/src/components/InspiraUI/spline/Spline.vue
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/InspiraUI/spline/index.ts b/src/components/InspiraUI/spline/index.ts
new file mode 100644
index 0000000..ae71b89
--- /dev/null
+++ b/src/components/InspiraUI/spline/index.ts
@@ -0,0 +1,2 @@
+export { default as Spline } from "./Spline.vue";
+export { default as ParentSize } from "./ParentSize.vue";
diff --git a/src/layouts/sakai-vue/composables/layout.ts b/src/layouts/sakai-vue/composables/layout.ts
index fbdd010..e4d3333 100644
--- a/src/layouts/sakai-vue/composables/layout.ts
+++ b/src/layouts/sakai-vue/composables/layout.ts
@@ -1,4 +1,4 @@
-import { computed, reactive, watch } from 'vue';
+import { computed, reactive, watch, type WatchHandle } from 'vue';
const layoutConfig = reactive({
darkTheme: false,
@@ -23,15 +23,17 @@ const layoutState = reactive({
staticMenuDesktopInactive: getStoredMenuState(),
staticMenuMobileActive: false,
});
-
+let _watcher: WatchHandle;
export function useLayout() {
- // 监听 staticMenuDesktopInactive 的变化并保存到 localStorage
- watch(
- () => layoutState.staticMenuDesktopInactive,
- (newValue) => {
- localStorage.setItem('staticMenuDesktopInactive', JSON.stringify(newValue));
- },
- );
+ if (!_watcher) {
+ // 监听 staticMenuDesktopInactive 的变化并保存到 localStorage
+ _watcher = watch(
+ () => layoutState.staticMenuDesktopInactive,
+ (newValue) => {
+ localStorage.setItem('staticMenuDesktopInactive', JSON.stringify(newValue));
+ },
+ );
+ }
const setActiveMenuItem = (item: Record) => {
layoutState.activeMenuItem = item.value || item;
diff --git a/src/pages/index-new.page.vue b/src/pages/index-new.page.vue
new file mode 100644
index 0000000..b200140
--- /dev/null
+++ b/src/pages/index-new.page.vue
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+meta:
+ layout: false
+
diff --git a/typed-router.d.ts b/typed-router.d.ts
index 24ed803..248e596 100644
--- a/typed-router.d.ts
+++ b/typed-router.d.ts
@@ -23,6 +23,7 @@ declare module 'vue-router/auto-routes' {
'DataLoadersId': RouteRecordInfo<'DataLoadersId', '/data-loaders/:id', { id: ParamValue }, { id: ParamValue }>,
'DataLoadersIdSub1UserId': RouteRecordInfo<'DataLoadersIdSub1UserId', '/data-loaders/:id/sub-1/:userId', { id: ParamValue, userId: ParamValue }, { id: ParamValue, userId: ParamValue }>,
'FlowbiteSidebar': RouteRecordInfo<'FlowbiteSidebar', '/FlowbiteSidebar', Record, Record>,
+ 'IndexNew': RouteRecordInfo<'IndexNew', '/index-new', Record, Record>,
'PageAPI': RouteRecordInfo<'PageAPI', '/Page/API', Record, Record>,
'PageFonts': RouteRecordInfo<'PageFonts', '/Page/fonts', Record, Record>,
'PageIcons': RouteRecordInfo<'PageIcons', '/Page/Icons', Record, Record>,
diff --git a/unocss.config.ts b/unocss.config.ts
index 561771d..fdf034e 100644
--- a/unocss.config.ts
+++ b/unocss.config.ts
@@ -15,6 +15,7 @@ export default defineConfig({
// the default
/\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
'src/shadcn/components/**/*.{js,ts}',
+ 'src/components/InspiraUI/**/*.{js,ts}',
],
},
},