Browse Source

perf: optimize interface color matching

vince 8 months ago
parent
commit
caf1fc4375
27 changed files with 270 additions and 249 deletions
  1. 108 89
      internal/tailwind-config/src/index.ts
  2. 0 1
      package.json
  3. 1 1
      packages/@core/forward/preferences/src/config.ts
  4. 2 2
      packages/@core/forward/preferences/src/constants.ts
  5. 1 1
      packages/@core/forward/preferences/src/preferences.test.ts
  6. 17 9
      packages/@core/shared/design/src/design-tokens/dark/index.css
  7. 31 23
      packages/@core/shared/design/src/design-tokens/default/index.css
  8. 2 2
      packages/@core/shared/toolkit/package.json
  9. 14 16
      packages/@core/shared/toolkit/src/colorful/generator.ts
  10. 1 1
      packages/@core/ui-kit/layout-ui/src/components/layout-content.vue
  11. 5 8
      packages/@core/ui-kit/layout-ui/src/components/layout-footer.vue
  12. 2 10
      packages/@core/ui-kit/layout-ui/src/components/layout-header.vue
  13. 1 1
      packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue
  14. 5 15
      packages/@core/ui-kit/layout-ui/src/components/layout-tabbar.vue
  15. 3 3
      packages/@core/ui-kit/layout-ui/src/vben-layout.vue
  16. 3 1
      packages/@core/ui-kit/shadcn-ui/src/components/ui/context-menu/ContextMenu.vue
  17. 3 1
      packages/@core/ui-kit/shadcn-ui/src/components/ui/dropdown-menu/DropdownMenu.vue
  18. 15 15
      packages/@core/ui-kit/tabs-ui/src/components/tabs-chrome/tabs.vue
  19. 13 9
      packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue
  20. 1 1
      packages/@core/ui-kit/tabs-ui/src/components/widgets/tool-more.vue
  21. 1 1
      packages/@core/ui-kit/tabs-ui/src/components/widgets/tool-screen.vue
  22. 21 23
      packages/effects/layouts/src/authentication/authentication.vue
  23. 4 2
      packages/effects/layouts/src/authentication/form.vue
  24. 1 1
      packages/effects/layouts/src/authentication/toolbar.vue
  25. 1 1
      packages/effects/layouts/src/widgets/global-search/global-search.vue
  26. 1 3
      packages/effects/layouts/src/widgets/preferences/preferences-sheet.vue
  27. 13 9
      pnpm-lock.yaml

+ 108 - 89
internal/tailwind-config/src/index.ts

@@ -24,30 +24,86 @@ packages.forEach((pkg) => {
   }
 });
 
-function createColorsPattern(name: string) {
-  return {
-    100: `hsl(var(--${name}-100))`,
-    200: `hsl(var(--${name}-200))`,
-    300: `hsl(var(--${name}-300))`,
-    400: `hsl(var(--${name}-400))`,
-    500: `hsl(var(--${name}-500))`,
-    600: `hsl(var(--${name}-600))`,
-    700: `hsl(var(--${name}-700))`,
-    800: `hsl(var(--${name}-800))`,
-    900: `hsl(var(--${name}-900))`,
-    1000: `hsl(var(--${name}-1000))`,
-    active: `hsl(var(--${name}-700))`,
-    background: `hsl(var(--${name}-100))`,
-    'background-hover': `hsl(var(--${name}-200))`,
-    border: `hsl(var(--${name}-300))`,
-    'border-hover': `hsl(var(--${name}-400))`,
-    foreground: `hsl(var(--${name}-foreground))`,
-    hover: `hsl(var(--${name}-500))`,
-    text: `hsl(var(--${name}-900))`,
-    'text-active': `hsl(var(--${name}-1000))`,
-    'text-hover': `hsl(var(--${name}-800))`,
-  };
-}
+const shadcnUiColors = {
+  accent: {
+    DEFAULT: 'hsl(var(--accent))',
+    foreground: 'hsl(var(--accent-foreground))',
+    hover: 'hsl(var(--accent-hover))',
+  },
+  background: {
+    DEFAULT: 'hsl(var(--background))',
+    content: 'hsl(var(--background-content))',
+  },
+  border: 'hsl(var(--border))',
+  card: {
+    DEFAULT: 'hsl(var(--card))',
+    foreground: 'hsl(var(--card-foreground))',
+  },
+  destructive: {
+    ...createColorsPattern('destructive'),
+    DEFAULT: 'hsl(var(--destructive))',
+  },
+
+  foreground: 'hsl(var(--foreground))',
+
+  input: {
+    DEFAULT: 'hsl(var(--input))',
+    background: 'hsl(var(--input-background))',
+  },
+  muted: {
+    DEFAULT: 'hsl(var(--muted))',
+    foreground: 'hsl(var(--muted-foreground))',
+  },
+  popover: {
+    DEFAULT: 'hsl(var(--popover))',
+    foreground: 'hsl(var(--popover-foreground))',
+  },
+  primary: {
+    ...createColorsPattern('primary'),
+    DEFAULT: 'hsl(var(--primary))',
+  },
+
+  ring: 'hsl(var(--ring))',
+  secondary: {
+    DEFAULT: 'hsl(var(--secondary))',
+    desc: 'hsl(var(--secondary-desc))',
+    foreground: 'hsl(var(--secondary-foreground))',
+  },
+};
+
+const customColors = {
+  authentication: {
+    DEFAULT: 'hsl(var(--authentication))',
+  },
+  green: {
+    ...createColorsPattern('green'),
+    foreground: 'hsl(var(--success-foreground))',
+  },
+  heavy: {
+    DEFAULT: 'hsl(var(--heavy))',
+    foreground: 'hsl(var(--heavy-foreground))',
+  },
+  main: {
+    DEFAULT: 'hsl(var(--main))',
+  },
+  overlay: 'hsl(var(--overlay))',
+  red: {
+    ...createColorsPattern('red'),
+    foreground: 'hsl(var(--destructive-foreground))',
+  },
+  success: {
+    ...createColorsPattern('success'),
+    DEFAULT: 'hsl(var(--success))',
+  },
+  warning: {
+    ...createColorsPattern('warning'),
+    DEFAULT: 'hsl(var(--warning))',
+  },
+  yellow: {
+    ...createColorsPattern('yellow'),
+    foreground: 'hsl(var(--warning-foreground))',
+  },
+};
 
 export default {
   content: [
@@ -93,71 +149,8 @@ export default {
         xl: 'calc(var(--radius) + 4px)',
       },
       colors: {
-        accent: {
-          DEFAULT: 'hsl(var(--accent))',
-          foreground: 'hsl(var(--accent-foreground))',
-          hover: 'hsl(var(--accent-hover))',
-        },
-        authentication: 'hsl(var(--authentication))',
-        background: 'hsl(var(--background))',
-        border: 'hsl(var(--border))',
-        card: {
-          DEFAULT: 'hsl(var(--card))',
-          foreground: 'hsl(var(--card-foreground))',
-        },
-        destructive: {
-          ...createColorsPattern('destructive'),
-          DEFAULT: 'hsl(var(--destructive))',
-        },
-
-        foreground: 'hsl(var(--foreground))',
-        green: {
-          ...createColorsPattern('green'),
-          foreground: 'hsl(var(--success-foreground))',
-        },
-        heavy: {
-          DEFAULT: 'hsl(var(--heavy))',
-          foreground: 'hsl(var(--heavy-foreground))',
-        },
-        input: {
-          DEFAULT: 'hsl(var(--input))',
-          background: 'hsl(var(--input-background))',
-        },
-        muted: {
-          DEFAULT: 'hsl(var(--muted))',
-          foreground: 'hsl(var(--muted-foreground))',
-        },
-        overlay: 'hsl(var(--overlay))',
-        popover: {
-          DEFAULT: 'hsl(var(--popover))',
-          foreground: 'hsl(var(--popover-foreground))',
-        },
-        primary: {
-          ...createColorsPattern('primary'),
-          DEFAULT: 'hsl(var(--primary))',
-        },
-        red: {
-          ...createColorsPattern('red'),
-          foreground: 'hsl(var(--destructive-foreground))',
-        },
-        ring: 'hsl(var(--ring))',
-        secondary: {
-          DEFAULT: 'hsl(var(--secondary))',
-          desc: 'hsl(var(--secondary-desc))',
-          foreground: 'hsl(var(--secondary-foreground))',
-        },
-        success: {
-          ...createColorsPattern('success'),
-          DEFAULT: 'hsl(var(--success))',
-        },
-        warning: {
-          ...createColorsPattern('warning'),
-          DEFAULT: 'hsl(var(--warning))',
-        },
-        yellow: {
-          ...createColorsPattern('yellow'),
-          foreground: 'hsl(var(--warning-foreground))',
-        },
+        ...customColors,
+        ...shadcnUiColors,
       },
       fontFamily: {
         sans: [
@@ -195,3 +188,29 @@ export default {
     },
   },
 } as Config;
+
+function createColorsPattern(name: string) {
+  return {
+    50: `hsl(var(--${name}-50))`,
+    100: `hsl(var(--${name}-100))`,
+    200: `hsl(var(--${name}-200))`,
+    300: `hsl(var(--${name}-300))`,
+    400: `hsl(var(--${name}-400))`,
+    500: `hsl(var(--${name}-500))`,
+    600: `hsl(var(--${name}-600))`,
+    700: `hsl(var(--${name}-700))`,
+    800: `hsl(var(--${name}-800))`,
+    900: `hsl(var(--${name}-900))`,
+    950: `hsl(var(--${name}-950))`,
+    active: `hsl(var(--${name}-600))`,
+    background: `hsl(var(--${name}-50))`,
+    'background-hover': `hsl(var(--${name}-100))`,
+    border: `hsl(var(--${name}-200))`,
+    'border-hover': `hsl(var(--${name}-300))`,
+    foreground: `hsl(var(--${name}-foreground))`,
+    hover: `hsl(var(--${name}-400))`,
+    text: `hsl(var(--${name}-800))`,
+    'text-active': `hsl(var(--${name}-900))`,
+    'text-hover': `hsl(var(--${name}-700))`,
+  };
+}

+ 0 - 1
package.json

@@ -84,7 +84,6 @@
   "packageManager": "pnpm@9.5.0",
   "pnpm": {
     "overrides": {
-      "@ant-design/colors": "^7.1.0",
       "@ctrl/tinycolor": "^4.1.0",
       "clsx": "^2.1.1",
       "eslint": "^8.57.0",

+ 1 - 1
packages/@core/forward/preferences/src/config.ts

@@ -79,7 +79,7 @@ const defaultPreferences: Preferences = {
   theme: {
     builtinType: 'default',
     colorDestructive: 'hsl(348 100% 61%)',
-    colorPrimary: 'hsl(245 82% 67%)',
+    colorPrimary: 'hsl(231 98% 65%)',
     colorSuccess: 'hsl(144 57% 58%)',
     colorWarning: 'hsl(42 84% 61%)',
     mode: 'dark',

+ 2 - 2
packages/@core/forward/preferences/src/constants.ts

@@ -31,11 +31,11 @@ const SUPPORT_LANGUAGES: Language[] = [
 
 const BUILT_IN_THEME_PRESETS: BuiltinThemePreset[] = [
   {
-    color: 'hsl(245 82% 67%)',
+    color: 'hsl(231 98% 65%)',
     type: 'default',
   },
   {
-    color: 'hsl(231 98% 65%)',
+    color: 'hsl(245 82% 67%)',
     type: 'violet',
   },
   {

+ 1 - 1
packages/@core/forward/preferences/src/preferences.test.ts

@@ -25,7 +25,7 @@ describe('preferences', () => {
   });
 
   it('initPreferences should initialize preferences with overrides and namespace', async () => {
-    const overrides = { theme: { colorPrimary: 'hsl(245 82% 67%)' } };
+    const overrides = { theme: { colorPrimary: 'hsl(231 98% 65%)' } };
     const namespace = 'testNamespace';
 
     await preferenceManager.initPreferences({ namespace, overrides });

+ 17 - 9
packages/@core/shared/design/src/design-tokens/dark/index.css

@@ -2,17 +2,20 @@
 :root.dark[data-theme='custom'],
 :root.dark[data-theme='default'] {
   /* Default background color of <body />...etc */
-  --background: 220deg 13.04% 8%;
+  --background: 222.34deg 10.43% 12.27%;
+
+  /* 主体区域背景色 */
+  --background-content: 220deg 13.06% 9%;
   --foreground: 220 13% 91%;
 
   /* Background color for <Card /> */
-  --card: 222.86deg 8.43% 16.27%;
+  --card: 222.34deg 10.43% 12.27%;
 
   /* --card: 222.2 84% 4.9%; */
   --card-foreground: 210 40% 98%;
 
   /* Background color for popovers such as <DropdownMenu />, <HoverCard />, <Popover /> */
-  --popover: 222.86deg 8.43% 16.27%;
+  --popover: 222.82deg 8.43% 16.27%;
   --popover-foreground: 210 40% 98%;
 
   /* Muted backgrounds such as <TabsList />, <Skeleton /> and <Switch /> */
@@ -53,7 +56,7 @@
   --heavy-foreground: var(--accent-foreground);
 
   /* Default border color */
-  --border: 0deg 0% 100% / 10%;
+  --border: 215 27.9% 16.9%;
 
   /* Border color for inputs such as <Input />, <Select />, <Textarea /> */
   --input: 0deg 0% 100% / 10%;
@@ -63,19 +66,24 @@
   /* Used for focus ring */
   --ring: 222.2 84% 4.9%;
 
+  /* 基本圆角大小 */
+  --radius: 0.5rem;
+
+  /* ============= Custom ============= */
+
   /* 遮罩颜色 */
   --overlay: 0deg 0% 0% / 40%;
 
   /* 基本文字大小 */
   --font-size-base: 16px;
 
-  /* 基本圆角大小 */
-  --radius: 0.5rem;
+  /* 主体内容背景色 */
+  --content: 240 11% 96%;
 
-  /* =============component & UI============= */
+  /* 登录背景色 */
+  --authentication: 220deg 13.06% 3.04%;
 
-  /* authentication */
-  --authentication: 240deg 11% 2%;
+  /* =============component & UI============= */
 
   color-scheme: dark;
 }

+ 31 - 23
packages/@core/shared/design/src/design-tokens/default/index.css

@@ -5,7 +5,10 @@
     'Segoe UI Symbol';
 
   /* Default background color of <body />...etc */
-  --background: 0 0% 100%;
+  --background: 0 0 100%;
+
+  /* 主体区域背景色 */
+  --background-content: 210 11.11% 96.47%;
   --foreground: 210 6% 21%;
 
   /* Background color for <Card /> */
@@ -55,7 +58,7 @@
   --heavy-foreground: var(--accent-foreground);
 
   /* Default border color */
-  --border: 240 6% 90%;
+  --border: 240 5.9% 90%;
 
   /* Border color for inputs such as <Input />, <Select />, <Textarea /> */
   --input: 240deg 5.88% 90%;
@@ -65,14 +68,22 @@
   /* Used for focus ring */
   --ring: 222.2 84% 4.9%;
 
+  /* Border radius for card, input and buttons */
+  --radius: 0.5rem;
+
+  /* ============= custom ============= */
+
   /* 遮罩颜色 */
   --overlay: 0deg 0% 0% / 40%;
 
   /* 基本文字大小 */
   --font-size-base: 16px;
 
-  /* Border radius for card, input and buttons */
-  --radius: 0.5rem;
+  /* 主体内容背景色 */
+  --content: 240 11% 96%;
+
+  /* 登录背景色 */
+  --authentication: 231deg 61% 44%;
 
   /* 用于浅色主题下一些暗色主题的颜色 */
   --dark-foreground: 220 13% 91%;
@@ -82,23 +93,20 @@
 
   /* =============component & UI============= */
 
-  /* authentication */
-  --authentication: 231deg 61% 44%;
-
   /* menu */
   --menu: 0deg 0% 100%;
-  --menu-darken: 0deg 0% 95%;
+  --menu-deep: 0deg 0% 95%;
 
   /* menu-dark */
-  --menu-dark: 225deg 12% 13%;
-  --menu-dark-darken: 223deg 11% 10%;
+  --menu-dark: 222.34deg 10.43% 12.27%;
+  --menu-dark-deep: 223deg 11% 10%;
 
   accent-color: var(--primary);
   color-scheme: light;
 }
 
 :root[data-theme='violet'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 224 71.4% 4.1%;
   --card: 0 0% 100%;
   --card-foreground: 224 71.4% 4.1%;
@@ -119,7 +127,7 @@
 }
 
 :root[data-theme='pink'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 240 10% 3.9%;
   --card: 0 0% 100%;
   --card-foreground: 240 10% 3.9%;
@@ -140,7 +148,7 @@
 }
 
 :root[data-theme='rose'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 240 10% 3.9%;
   --card: 0 0% 100%;
   --card-foreground: 240 10% 3.9%;
@@ -161,7 +169,7 @@
 }
 
 :root[data-theme='sky-blue'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 222.2 84% 4.9%;
   --card: 0 0% 100%;
   --card-foreground: 222.2 84% 4.9%;
@@ -182,7 +190,7 @@
 }
 
 :root[data-theme='deep-blue'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 222.2 84% 4.9%;
   --card: 0 0% 100%;
   --card-foreground: 222.2 84% 4.9%;
@@ -203,7 +211,7 @@
 }
 
 :root[data-theme='green'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 240 10% 3.9%;
   --card: 0 0% 100%;
   --card-foreground: 240 10% 3.9%;
@@ -224,7 +232,7 @@
 }
 
 :root[data-theme='deep-green'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 240 10% 3.9%;
   --card: 0 0% 100%;
   --card-foreground: 240 10% 3.9%;
@@ -245,7 +253,7 @@
 }
 
 :root[data-theme='orange'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 20 14.3% 4.1%;
   --card: 0 0% 100%;
   --card-foreground: 20 14.3% 4.1%;
@@ -266,7 +274,7 @@
 }
 
 :root[data-theme='yellow'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 20 14.3% 4.1%;
   --card: 0 0% 100%;
   --card-foreground: 20 14.3% 4.1%;
@@ -287,7 +295,7 @@
 }
 
 :root[data-theme='zinc'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 240 10% 3.9%;
   --card: 0 0% 100%;
   --card-foreground: 240 10% 3.9%;
@@ -308,7 +316,7 @@
 }
 
 :root[data-theme='neutral'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 0 0% 3.9%;
   --card: 0 0% 100%;
   --card-foreground: 0 0% 3.9%;
@@ -329,7 +337,7 @@
 }
 
 :root[data-theme='slate'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 222.2 84% 4.9%;
   --card: 0 0% 100%;
   --card-foreground: 222.2 84% 4.9%;
@@ -350,7 +358,7 @@
 }
 
 :root[data-theme='gray'] {
-  --background: 0 0% 100%;
+  /* --background: 0 0% 100%; */
   --foreground: 224 71.4% 4.1%;
   --card: 0 0% 100%;
   --card-foreground: 224 71.4% 4.1%;

+ 2 - 2
packages/@core/shared/toolkit/package.json

@@ -36,14 +36,14 @@
     }
   },
   "dependencies": {
-    "@ant-design/colors": "^7.1.0",
     "@ctrl/tinycolor": "^4.1.0",
     "@vue/shared": "^3.4.31",
     "clsx": "^2.1.1",
     "defu": "^6.1.4",
     "lodash.clonedeep": "^4.5.0",
     "nprogress": "^0.2.0",
-    "tailwind-merge": "^2.4.0"
+    "tailwind-merge": "^2.4.0",
+    "theme-colors": "^0.1.0"
   },
   "devDependencies": {
     "@types/lodash.clonedeep": "^4.5.9",

+ 14 - 16
packages/@core/shared/toolkit/src/colorful/generator.ts

@@ -1,35 +1,34 @@
-import { generate } from '@ant-design/colors';
+import { TinyColor } from '@ctrl/tinycolor';
+import { getColors } from 'theme-colors';
 
 import { convertToHslCssVar } from './convert';
 
-export * from '@ant-design/colors';
-
-interface Opts {
-  backgroundColor?: string;
-  theme?: 'dark' | 'default';
-}
-
 interface ColorItem {
   alias?: string;
   color: string;
   name: string;
 }
 
-function generatorColorVariables(colorItems: ColorItem[], opts?: Opts) {
+function generatorColorVariables(colorItems: ColorItem[]) {
   const colorVariables: Record<string, string> = {};
 
   colorItems.forEach(({ alias, color, name }) => {
     if (color) {
-      const colors = generate(color, opts);
-      let mainColor = colors[5];
-      colors.forEach((colorValue, colorIndex) => {
+      const colorsMap = getColors(new TinyColor(color).toHexString());
+      let mainColor = colorsMap['500'];
+
+      const colorKeys = Object.keys(colorsMap);
+
+      colorKeys.forEach((key) => {
+        const colorValue = colorsMap[key];
+
         const hslColor = convertToHslCssVar(colorValue);
-        colorVariables[`--${name}-${colorIndex + 1}00`] = hslColor;
+        colorVariables[`--${name}-${key}`] = hslColor;
         if (alias) {
-          colorVariables[`--${alias}-${colorIndex + 1}00`] = hslColor;
+          colorVariables[`--${alias}-${key}`] = hslColor;
         }
 
-        if (colorIndex === 5) {
+        if (key === '500') {
           mainColor = hslColor;
         }
       });
@@ -38,7 +37,6 @@ function generatorColorVariables(colorItems: ColorItem[], opts?: Opts) {
       }
     }
   });
-
   return colorVariables;
 }
 

+ 1 - 1
packages/@core/ui-kit/layout-ui/src/components/layout-content.vue

@@ -99,7 +99,7 @@ onMounted(() => {
 </script>
 
 <template>
-  <main ref="contentElement" :style="style">
+  <main ref="contentElement" :style="style" class="bg-background-content">
     <slot></slot>
   </main>
 </template>

+ 5 - 8
packages/@core/ui-kit/layout-ui/src/components/layout-footer.vue

@@ -3,10 +3,6 @@ import type { CSSProperties } from 'vue';
 import { computed } from 'vue';
 
 interface Props {
-  /**
-   * 背景颜色
-   */
-  backgroundColor?: string;
   /**
    * 是否固定在顶部
    * @default true
@@ -35,7 +31,6 @@ interface Props {
 }
 
 const props = withDefaults(defineProps<Props>(), {
-  backgroundColor: 'hsl(var(--background))',
   fixed: true,
   height: 32,
   show: true,
@@ -44,9 +39,8 @@ const props = withDefaults(defineProps<Props>(), {
 });
 
 const style = computed((): CSSProperties => {
-  const { backgroundColor, fixed, height, show, width, zIndex } = props;
+  const { fixed, height, show, width, zIndex } = props;
   return {
-    backgroundColor,
     height: `${height}px`,
     marginBottom: show ? '0' : `-${height}px`,
     position: fixed ? 'fixed' : 'static',
@@ -57,7 +51,10 @@ const style = computed((): CSSProperties => {
 </script>
 
 <template>
-  <footer :style="style" class="bottom-0 w-full transition-all duration-200">
+  <footer
+    :style="style"
+    class="bg-background-content bottom-0 w-full transition-all duration-200"
+  >
     <slot></slot>
   </footer>
 </template>

+ 2 - 10
packages/@core/ui-kit/layout-ui/src/components/layout-header.vue

@@ -6,11 +6,6 @@ import { IcRoundMenu } from '@vben-core/icons';
 import { VbenIconButton } from '@vben-core/shadcn-ui';
 
 interface Props {
-  /**
-   * 背景颜色
-   */
-  backgroundColor?: string;
-
   /**
    * 横屏
    * @default false
@@ -60,8 +55,6 @@ interface Props {
 }
 
 const props = withDefaults(defineProps<Props>(), {
-  backgroundColor: 'hsl(var(--background))',
-  // fixed: true,
   height: 60,
   isMixedNav: false,
   show: true,
@@ -76,12 +69,11 @@ const emit = defineEmits<{ openMenu: []; toggleSidebar: [] }>();
 const slots = useSlots();
 
 const style = computed((): CSSProperties => {
-  const { backgroundColor, fullWidth, height, show } = props;
+  const { fullWidth, height, show } = props;
   const right = !show || !fullWidth ? undefined : 0;
 
   return {
     // ...(props.isMixedNav ? { left: 0, position: `fixed` } : {}),
-    backgroundColor,
     height: `${height}px`,
     marginTop: show ? 0 : `-${height}px`,
     right,
@@ -106,7 +98,7 @@ function handleToggleMenu() {
 <template>
   <header
     :style="style"
-    class="border-border top-0 flex w-full flex-[0_0_auto] items-center border-b transition-[margin-top] duration-200"
+    class="border-border bg-background top-0 flex w-full flex-[0_0_auto] items-center border-b transition-[margin-top] duration-200"
   >
     <div v-if="slots.logo" :style="logoStyle">
       <slot name="logo"></slot>

+ 1 - 1
packages/@core/ui-kit/layout-ui/src/components/layout-sidebar.vue

@@ -255,7 +255,7 @@ function handleMouseleave() {
   ></div>
   <aside
     :style="style"
-    class="fixed left-0 top-0 h-full transition-all duration-200"
+    class="border-border fixed left-0 top-0 h-full border-r transition-all duration-200"
     @mouseenter="handleMouseenter"
     @mouseleave="handleMouseleave"
   >

+ 5 - 15
packages/@core/ui-kit/layout-ui/src/components/layout-tabbar.vue

@@ -3,10 +3,6 @@ import type { CSSProperties } from 'vue';
 import { computed } from 'vue';
 
 interface Props {
-  /**
-   * 背景颜色
-   */
-  backgroundColor?: string;
   /**
    * 高度
    * @default 30
@@ -15,29 +11,23 @@ interface Props {
 }
 
 const props = withDefaults(defineProps<Props>(), {
-  backgroundColor: 'hsl(var(--background))',
   fixed: true,
   height: 30,
 });
 
-const hiddenStyle = computed((): CSSProperties => {
+const style = computed((): CSSProperties => {
   const { height } = props;
   return {
     height: `${height}px`,
   };
 });
-
-const style = computed((): CSSProperties => {
-  const { backgroundColor } = props;
-  return {
-    ...hiddenStyle.value,
-    backgroundColor,
-  };
-});
 </script>
 
 <template>
-  <section :style="style" class="border-border flex w-full">
+  <section
+    :style="style"
+    class="border-border bg-background flex w-full border-b"
+  >
     <slot></slot>
   </section>
 </template>

+ 3 - 3
packages/@core/ui-kit/layout-ui/src/vben-layout.vue

@@ -45,7 +45,7 @@ const props = withDefaults(defineProps<Props>(), {
   sidebarTheme: 'dark',
   sidebarWidth: 180,
   tabbarEnable: true,
-  tabbarHeight: 36,
+  tabbarHeight: 38,
   zIndex: 200,
 });
 
@@ -211,11 +211,11 @@ const sidebarFace = computed(() => {
 
   if (isDark) {
     backgroundColor = isSidebarMixedNav.value
-      ? 'hsl(var(--menu-dark-darken))'
+      ? 'hsl(var(--menu-dark-deep))'
       : 'hsl(var(--menu-dark))';
   } else {
     backgroundColor = isSidebarMixedNav.value
-      ? 'hsl(var(--menu-darken))'
+      ? 'hsl(var(--menu-deep))'
       : 'hsl(var(--menu))';
   }
 

+ 3 - 1
packages/@core/ui-kit/shadcn-ui/src/components/ui/context-menu/ContextMenu.vue

@@ -3,7 +3,9 @@ import type { ContextMenuRootEmits, ContextMenuRootProps } from 'radix-vue';
 
 import { ContextMenuRoot, useForwardPropsEmits } from 'radix-vue';
 
-const props = defineProps<ContextMenuRootProps>();
+const props = withDefaults(defineProps<ContextMenuRootProps>(), {
+  modal: false,
+});
 const emits = defineEmits<ContextMenuRootEmits>();
 
 const forwarded = useForwardPropsEmits(props, emits);

+ 3 - 1
packages/@core/ui-kit/shadcn-ui/src/components/ui/dropdown-menu/DropdownMenu.vue

@@ -6,7 +6,9 @@ import {
   useForwardPropsEmits,
 } from 'radix-vue';
 
-const props = defineProps<DropdownMenuRootProps>();
+const props = withDefaults(defineProps<DropdownMenuRootProps>(), {
+  modal: false,
+});
 const emits = defineEmits<DropdownMenuRootEmits>();
 
 const forwarded = useForwardPropsEmits(props, emits);

+ 15 - 15
packages/@core/ui-kit/tabs-ui/src/components/tabs-chrome/tabs.vue

@@ -94,10 +94,7 @@ function handleUnpinTab(tab: TabConfig) {
 </script>
 
 <template>
-  <div
-    :style="style"
-    class="tabs-chrome bg-accent size-full flex-1 overflow-hidden pt-1"
-  >
+  <div :style="style" class="tabs-chrome size-full flex-1 overflow-hidden pt-1">
     <!-- footer -> 4px -->
     <div
       ref="contentRef"
@@ -130,7 +127,7 @@ function handleUnpinTab(tab: TabConfig) {
               <!-- divider -->
               <div
                 v-if="i !== 0"
-                class="tabs-chrome__divider bg-accent absolute left-[var(--gap)] top-1/2 z-0 h-5 w-[1px] translate-y-[-50%]"
+                class="tabs-chrome__divider bg-foreground/80 absolute left-[var(--gap)] top-1/2 z-0 h-4 w-[1px] translate-y-[-50%] transition-all"
               ></div>
               <!-- background -->
               <div
@@ -157,24 +154,27 @@ function handleUnpinTab(tab: TabConfig) {
 
               <!-- extra -->
               <div
-                class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%] opacity-0 transition-opacity group-hover:opacity-100"
+                class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%]"
               >
+                <!-- <div
+                class="tabs-chrome__extra absolute right-[calc(var(--gap)*2)] top-1/2 z-[3] size-4 translate-y-[-50%] opacity-0 transition-opacity group-hover:opacity-100"
+              > -->
                 <!-- close-icon -->
                 <IcRoundClose
                   v-show="!tab.affixTab && tabsView.length > 1 && tab.closable"
-                  class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground mt-[2px] size-3 cursor-pointer rounded-full transition-all"
+                  class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3 cursor-pointer rounded-full transition-all"
                   @click.stop="handleClose(tab.key)"
                 />
                 <MdiPin
                   v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
-                  class="hover:bg-accent hover:stroke-accent-foreground mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
+                  class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
                   @click.stop="handleUnpinTab(tab)"
                 />
               </div>
 
               <!-- tab-item-main -->
               <div
-                class="tabs-chrome__item-main group-[.is-active]:text-primary text-accent-foreground absolute left-0 right-0 z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] duration-150 group-hover:pr-3"
+                class="tabs-chrome__item-main group-[.is-active]:text-primary text-accent-foreground absolute left-0 right-0 z-[2] mx-[calc(var(--gap)*2)] my-0 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-4 duration-150 group-hover:pr-3 group-[.is-active]:font-semibold"
               >
                 <VbenIcon
                   v-if="showIcon"
@@ -200,7 +200,7 @@ function handleUnpinTab(tab: TabConfig) {
 </template>
 
 <style scoped>
-html.dark {
+/* html.dark {
   .tabs-chrome {
     .is-active {
       .tabs-chrome__item-main {
@@ -208,7 +208,7 @@ html.dark {
       }
     }
   }
-}
+} */
 
 .tabs-chrome {
   .dragging {
@@ -235,12 +235,12 @@ html.dark {
 
       .tabs-chrome__background {
         &-content {
-          @apply bg-accent;
+          @apply bg-heavy;
         }
 
         &-before,
         &-after {
-          @apply fill-accent;
+          @apply fill-heavy;
         }
       }
     }
@@ -252,12 +252,12 @@ html.dark {
         @apply opacity-100;
 
         &-content {
-          @apply bg-background;
+          @apply bg-background-content;
         }
 
         &-before,
         &-after {
-          @apply fill-background;
+          @apply fill-background-content;
         }
       }
     }

+ 13 - 9
packages/@core/ui-kit/tabs-ui/src/components/tabs/tabs.vue

@@ -29,7 +29,8 @@ const typeWithClass = computed(() => {
       content: `h-full  after:content-['']  after:absolute after:bottom-0 after:left-0 after:w-full after:h-[1.5px] after:bg-primary after:scale-x-0 after:transition-[transform] after:ease-out after:duration-300 hover:after:scale-x-100 after:origin-left [&.is-active]:after:scale-x-100`,
     },
     card: {
-      content: 'h-[90%] rounded-md mr-1',
+      content:
+        'h-[calc(100%-6px)] rounded-md mr-2 border-border [&.is-active]:border-primary border transition-all',
     },
     plain: {
       content: 'h-full',
@@ -64,7 +65,7 @@ function handleUnpinTab(tab: TabConfig) {
 </script>
 
 <template>
-  <div class="bg-accent h-full flex-1 overflow-hidden">
+  <div class="h-full flex-1 overflow-hidden">
     <VbenScrollbar class="h-full" horizontal>
       <div
         :class="contentClass"
@@ -76,7 +77,7 @@ function handleUnpinTab(tab: TabConfig) {
             :key="tab.key"
             :class="[
               {
-                'tabs-item is-active bg-background': tab.key === active,
+                'tabs-item is-active bg-background-content': tab.key === active,
                 dragable: !tab.affixTab,
               },
               typeWithClass.content,
@@ -94,26 +95,29 @@ function handleUnpinTab(tab: TabConfig) {
               <div class="relative flex size-full items-center">
                 <!-- extra -->
                 <div
-                  class="absolute right-1.5 top-1/2 z-[3] translate-y-[-50%] overflow-hidden opacity-0 transition-opacity group-hover:opacity-100 group-[.is-active]:opacity-100"
+                  class="absolute right-1.5 top-1/2 z-[3] translate-y-[-50%] overflow-hidden"
                 >
+                  <!-- <div
+                  class="absolute right-1.5 top-1/2 z-[3] translate-y-[-50%] overflow-hidden opacity-0 transition-opacity group-hover:opacity-100 group-[.is-active]:opacity-100"
+                > -->
                   <!-- close-icon -->
                   <IcRoundClose
                     v-show="
                       !tab.affixTab && tabsView.length > 1 && tab.closable
                     "
-                    class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground size-3 cursor-pointer rounded-full transition-all"
+                    class="hover:bg-accent stroke-accent-foreground/80 hover:stroke-accent-foreground group-[.is-active]:text-primary size-3 cursor-pointer rounded-full transition-all"
                     @click.stop="handleClose(tab.key)"
                   />
                   <MdiPin
                     v-show="tab.affixTab && tabsView.length > 1 && tab.closable"
-                    class="hover:bg-accent hover:stroke-accent-foreground mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
+                    class="hover:bg-accent hover:stroke-accent-foreground group-[.is-active]:text-primary mt-[2px] size-3.5 cursor-pointer rounded-full transition-all"
                     @click.stop="handleUnpinTab(tab)"
                   />
                 </div>
 
                 <!-- tab-item-main -->
                 <div
-                  class="tabs-item__main group-[.is-active]:text-primary text-accent-foreground mx-3 mr-3 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-3 transition-all duration-300"
+                  class="tabs-item__main group-[.is-active]:text-primary text-accent-foreground mx-3 mr-4 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] pr-3 transition-all duration-300"
                 >
                   <!-- <div
                   class="mx-3 ml-3 mr-2 flex h-full items-center overflow-hidden rounded-tl-[5px] rounded-tr-[5px] transition-all duration-300 group-hover:mr-2 group-hover:pr-4 group-[.is-active]:pr-4"
@@ -139,7 +143,7 @@ function handleUnpinTab(tab: TabConfig) {
 </template>
 
 <style scoped>
-html.dark {
+/* html.dark {
   .tabs-item {
     &.is-active {
       .tabs-item__main {
@@ -147,5 +151,5 @@ html.dark {
       }
     }
   }
-}
+} */
 </style>

+ 1 - 1
packages/@core/ui-kit/tabs-ui/src/components/widgets/tool-more.vue

@@ -10,7 +10,7 @@ defineProps<DropdownMenuProps>();
 <template>
   <VbenDropdownMenu :menus="menus" :modal="false">
     <div
-      class="flex-center hover:bg-muted bg-accent hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-1.5 text-lg font-semibold"
+      class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-1.5 text-lg font-semibold"
     >
       <IcRoundKeyboardArrowDown class="size-5" />
     </div>

+ 1 - 1
packages/@core/ui-kit/tabs-ui/src/components/widgets/tool-screen.vue

@@ -10,7 +10,7 @@ function toggleScreen() {
 
 <template>
   <div
-    class="flex-center hover:bg-muted bg-accent hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-2 text-lg font-semibold"
+    class="flex-center hover:bg-muted hover:text-foreground text-muted-foreground border-border h-full cursor-pointer border-l px-2 text-lg font-semibold"
     @click="toggleScreen"
   >
     <IcTwotoneFitScreen v-if="screen" />

+ 21 - 23
packages/effects/layouts/src/authentication/authentication.vue

@@ -4,46 +4,40 @@ import { computed } from 'vue';
 import { $t } from '@vben-core/locales';
 import { preferences, usePreferences } from '@vben-core/preferences';
 
-import AuthenticationFromView from './from-view.vue';
+import AuthenticationFormView from './form.vue';
 import SloganIcon from './icons/slogan.vue';
 import Toolbar from './toolbar.vue';
 
-defineOptions({
-  name: 'Authentication',
-});
+defineOptions({ name: 'Authentication' });
 
 const { authPanelCenter, authPanelLeft, authPanelRight } = usePreferences();
 const appName = computed(() => preferences.app.name);
+const logoSource = computed(() => preferences.logo.source);
 </script>
 
 <template>
   <div class="flex min-h-full flex-1 select-none overflow-x-hidden">
-    <AuthenticationFromView
+    <!-- 左侧认证面板 -->
+    <AuthenticationFormView
       v-if="authPanelLeft"
-      class="-enter-x min-h-full w-2/5"
+      class="min-h-full w-2/5"
       transition-name="slide-left"
     />
 
+    <!-- 头部 Logo 和应用名称 -->
     <div class="absolute left-0 top-0 z-10 flex flex-1">
       <div
-        :class="
-          authPanelLeft || authPanelCenter
-            ? 'lg:text-foreground'
-            : 'lg:text-white'
-        "
+        :class="authPanelLeft ? 'lg:text-foreground' : 'lg:text-white'"
         class="text-foreground ml-4 mt-4 flex flex-1 items-center sm:left-6 sm:top-6"
       >
-        <img
-          :alt="appName"
-          :src="preferences.logo.source"
-          :width="42"
-          class="mr-2"
-        />
+        <img :alt="appName" :src="logoSource" class="mr-2" width="42" />
         <p class="text-xl font-medium">
           {{ appName }}
         </p>
       </div>
     </div>
+
+    <!-- 中间内容 -->
     <div v-if="!authPanelCenter" class="relative hidden w-0 flex-1 lg:block">
       <div class="bg-authentication absolute inset-0 h-full w-full">
         <div class="flex-col-center -enter-x mr-20 h-full">
@@ -57,18 +51,22 @@ const appName = computed(() => preferences.app.name);
         </div>
       </div>
     </div>
+
+    <!-- 中心认证面板 -->
     <div v-if="authPanelCenter" class="flex-center bg-authentication w-full">
-      <AuthenticationFromView
-        class="enter-y md:bg-background w-full rounded-3xl pb-20 shadow-2xl md:w-2/3 lg:w-1/2 xl:w-2/5"
+      <AuthenticationFormView
+        class="md:bg-background w-full rounded-3xl pb-20 shadow-2xl md:w-2/3 lg:w-1/2 xl:w-2/5"
       >
         <template #toolbar>
-          <Toolbar class="bg-muted" />
+          <Toolbar />
         </template>
-      </AuthenticationFromView>
+      </AuthenticationFormView>
     </div>
-    <AuthenticationFromView
+
+    <!-- 右侧认证面板 -->
+    <AuthenticationFormView
       v-if="authPanelRight"
-      class="enter-x min-h-full w-2/5 flex-1"
+      class="min-h-full w-2/5 flex-1"
     />
   </div>
 </template>

+ 4 - 2
packages/effects/layouts/src/authentication/from-view.vue → packages/effects/layouts/src/authentication/form.vue

@@ -9,7 +9,9 @@ defineOptions({
 });
 </script>
 <template>
-  <div class="flex-col-center relative px-6 py-10 lg:flex-initial lg:px-8">
+  <div
+    class="flex-col-center bg-background-content relative px-6 py-10 lg:flex-initial lg:px-8"
+  >
     <slot name="toolbar">
       <Toolbar />
     </slot>
@@ -20,7 +22,7 @@ defineOptions({
           <component
             :is="Component"
             :key="route.fullPath"
-            class="mt-6 w-full sm:mx-auto md:max-w-md"
+            class="enter-x mt-6 w-full sm:mx-auto md:max-w-md"
           />
         </KeepAlive>
       </Transition>

+ 1 - 1
packages/effects/layouts/src/authentication/toolbar.vue

@@ -12,7 +12,7 @@ defineOptions({
 </script>
 <template>
   <div
-    class="flex-center bg-accent absolute right-2 top-4 rounded-3xl px-3 py-1"
+    class="flex-center bg-background dark:bg-accent absolute right-2 top-4 rounded-3xl px-3 py-1"
   >
     <div class="hidden md:flex">
       <AuthenticationColorToggle />

+ 1 - 1
packages/effects/layouts/src/widgets/global-search/global-search.vue

@@ -91,7 +91,7 @@ onMounted(() => {
             class="text-muted-foreground group-hover:text-foreground size-4 group-hover:opacity-100"
           />
           <span
-            class="text-muted-foreground group-hover:text-foreground hidden text-sm duration-300 md:block"
+            class="text-muted-foreground group-hover:text-foreground hidden text-xs duration-300 md:block"
           >
             {{ $t('widgets.search.title') }}
           </span>

+ 1 - 3
packages/effects/layouts/src/widgets/preferences/preferences-sheet.vue

@@ -227,9 +227,7 @@ async function handleReset() {
           :title="$t('preferences.title')"
           class="bg-primary flex-col-center h-12 w-12 cursor-pointer rounded-l-lg rounded-r-none border-none"
         >
-          <IconSetting
-            class="duration-3000 fill-primary-foreground animate-spin text-2xl"
-          />
+          <IconSetting class="duration-3000 fill-primary-foreground text-2xl" />
         </VbenButton>
       </template>
       <template #extra>

+ 13 - 9
pnpm-lock.yaml

@@ -5,7 +5,6 @@ settings:
   excludeLinksFromLockfile: false
 
 overrides:
-  '@ant-design/colors': ^7.1.0
   '@ctrl/tinycolor': ^4.1.0
   clsx: ^2.1.1
   eslint: ^8.57.0
@@ -682,9 +681,6 @@ importers:
 
   packages/@core/shared/toolkit:
     dependencies:
-      '@ant-design/colors':
-        specifier: ^7.1.0
-        version: 7.1.0
       '@ctrl/tinycolor':
         specifier: ^4.1.0
         version: 4.1.0
@@ -706,6 +702,9 @@ importers:
       tailwind-merge:
         specifier: ^2.4.0
         version: 2.4.0
+      theme-colors:
+        specifier: ^0.1.0
+        version: 0.1.0
     devDependencies:
       '@types/lodash.clonedeep':
         specifier: ^4.5.9
@@ -1096,8 +1095,8 @@ packages:
     resolution: {integrity: sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==}
     engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'}
 
-  '@ant-design/colors@7.1.0':
-    resolution: {integrity: sha512-MMoDGWn1y9LdQJQSHiCC20x3uZ3CwQnv9QMz6pCmJOrqdgM9YxsoVVY0wtrdXbmfSgnV0KNk6zi09NAhMR2jvg==}
+  '@ant-design/colors@6.0.0':
+    resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
 
   '@ant-design/icons-svg@4.4.2':
     resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==}
@@ -8576,6 +8575,9 @@ packages:
   text-table@0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
 
+  theme-colors@0.1.0:
+    resolution: {integrity: sha512-6gTEHQqWlQNiOEGHCSSQmU//E5SnXHJ4H7oHQOD8x77CvNYNQAmt73dqR71mzw5ULV87zaHLxK5pIBnsToFuZw==}
+
   thenify-all@1.6.0:
     resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
     engines: {node: '>=0.8'}
@@ -9610,7 +9612,7 @@ snapshots:
     transitivePeerDependencies:
       - chokidar
 
-  '@ant-design/colors@7.1.0':
+  '@ant-design/colors@6.0.0':
     dependencies:
       '@ctrl/tinycolor': 4.1.0
 
@@ -9618,7 +9620,7 @@ snapshots:
 
   '@ant-design/icons-vue@7.0.1(vue@3.4.31(typescript@5.5.3))':
     dependencies:
-      '@ant-design/colors': 7.1.0
+      '@ant-design/colors': 6.0.0
       '@ant-design/icons-svg': 4.4.2
       vue: 3.4.31(typescript@5.5.3)
 
@@ -12916,7 +12918,7 @@ snapshots:
 
   ant-design-vue@4.2.3(vue@3.4.31(typescript@5.5.3)):
     dependencies:
-      '@ant-design/colors': 7.1.0
+      '@ant-design/colors': 6.0.0
       '@ant-design/icons-vue': 7.0.1(vue@3.4.31(typescript@5.5.3))
       '@babel/runtime': 7.24.8
       '@ctrl/tinycolor': 4.1.0
@@ -17865,6 +17867,8 @@ snapshots:
 
   text-table@0.2.0: {}
 
+  theme-colors@0.1.0: {}
+
   thenify-all@1.6.0:
     dependencies:
       thenify: 3.3.1