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}', ], }, },