@movk/nuxt 1.1.0 → 1.1.1

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 CHANGED
@@ -2,6 +2,9 @@
2
2
 
3
3
  > `@movk/nuxt` 是一个为 Nuxt 4 设计的模块化工程套件,提供 Schema 驱动的自动表单生成、API 集成系统、独立 UI 组件和通用工具函数。
4
4
 
5
+ [![Install MCP in Cursor](https://nuxt.mhaibaraai.cn/mcp/badge.svg)](https://nuxt.mhaibaraai.cn/mcp/deeplink)
6
+ [![Install MCP in VS Code](https://nuxt.mhaibaraai.cn/mcp/badge.svg?ide=vscode)](https://nuxt.mhaibaraai.cn/mcp/deeplink?ide=vscode)
7
+
5
8
  [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
6
9
  [![Nuxt](https://img.shields.io/badge/Nuxt-4-00DC82.svg)](https://nuxt.com/)
7
10
  [![npm version][npm-version-src]][npm-version-href]
package/dist/module.d.mts CHANGED
@@ -26,6 +26,7 @@ declare module 'nuxt/schema' {
26
26
  radius: number;
27
27
  blackAsPrimary: boolean;
28
28
  font: string;
29
+ icons: string;
29
30
  };
30
31
  }
31
32
  }
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@movk/nuxt",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "configKey": "movk",
5
5
  "compatibility": {
6
6
  "nuxt": ">=4.2.0"
package/dist/module.mjs CHANGED
@@ -5,13 +5,14 @@ import defu from 'defu';
5
5
  export * from '../dist/runtime/types/index.js';
6
6
 
7
7
  const name = "@movk/nuxt";
8
- const version = "1.1.0";
8
+ const version = "1.1.1";
9
9
 
10
10
  function setupTheme(nuxt, resolve) {
11
11
  nuxt.options.appConfig.theme = defu(nuxt.options.appConfig.theme || {}, {
12
12
  radius: 0.25,
13
13
  blackAsPrimary: false,
14
- font: "Public Sans"
14
+ font: "Public Sans",
15
+ icons: "lucide"
15
16
  });
16
17
  nuxt.options.app.head.meta = nuxt.options.app.head.meta || [];
17
18
  nuxt.options.app.head.meta.push(
@@ -19,6 +19,8 @@ const {
19
19
  radius,
20
20
  fonts,
21
21
  font,
22
+ icon,
23
+ icons,
22
24
  modes,
23
25
  mode,
24
26
  hasCSSChanges,
@@ -165,6 +167,35 @@ const {
165
167
  </div>
166
168
  </fieldset>
167
169
 
170
+ <fieldset>
171
+ <legend class="text-[11px] leading-none font-semibold mb-2 select-none flex items-center gap-1">
172
+ Icons
173
+
174
+ <UButton
175
+ to="https://ui.nuxt.com/docs/getting-started/integrations/icons"
176
+ size="xs"
177
+ color="neutral"
178
+ variant="link"
179
+ target="_blank"
180
+ icon="i-lucide-circle-help"
181
+ class="p-0 -my-0.5"
182
+ :ui="{ leadingIcon: 'size-3' }"
183
+ />
184
+ </legend>
185
+
186
+ <div class="-mx-2">
187
+ <USelect
188
+ v-model="icon"
189
+ size="sm"
190
+ color="neutral"
191
+ :icon="icons.find((i) => i.value === icon)?.icon"
192
+ :items="icons"
193
+ class="w-full ring-default rounded-sm hover:bg-elevated/50 capitalize text-[11px] data-[state=open]:bg-elevated/50"
194
+ :ui="{ item: 'capitalize text-[11px]', trailingIcon: 'group-data-[state=open]:rotate-180 transition-transform duration-200' }"
195
+ />
196
+ </div>
197
+ </fieldset>
198
+
168
199
  <fieldset>
169
200
  <legend class="text-[11px] leading-none font-semibold mb-2 select-none flex items-center gap-1">
170
201
  Color Mode
@@ -8,6 +8,12 @@ export declare function useTheme(): {
8
8
  radius: import("vue").WritableComputedRef<any, any>;
9
9
  fonts: string[];
10
10
  font: import("vue").WritableComputedRef<any, any>;
11
+ icon: import("vue").WritableComputedRef<any, any>;
12
+ icons: {
13
+ label: string;
14
+ icon: string;
15
+ value: string;
16
+ }[];
11
17
  modes: {
12
18
  label: string;
13
19
  icon: any;
@@ -2,6 +2,7 @@ import { useAppConfig, useColorMode, useSiteConfig } from "#imports";
2
2
  import { omit } from "@movk/core";
3
3
  import colors from "tailwindcss/colors";
4
4
  import { computed } from "vue";
5
+ import { themeIcons } from "../utils/theme.js";
5
6
  export function useTheme() {
6
7
  const appConfig = useAppConfig();
7
8
  const colorMode = useColorMode();
@@ -50,6 +51,31 @@ export function useTheme() {
50
51
  }
51
52
  }
52
53
  });
54
+ const icons = [{
55
+ label: "Lucide",
56
+ icon: "i-lucide-feather",
57
+ value: "lucide"
58
+ }, {
59
+ label: "Phosphor",
60
+ icon: "i-ph-phosphor-logo",
61
+ value: "phosphor"
62
+ }, {
63
+ label: "Tabler",
64
+ icon: "i-tabler-brand-tabler",
65
+ value: "tabler"
66
+ }];
67
+ const icon = computed({
68
+ get() {
69
+ return appConfig.theme.icons;
70
+ },
71
+ set(option) {
72
+ appConfig.theme.icons = option;
73
+ appConfig.ui.icons = themeIcons[option];
74
+ if (appConfig.theme.icons) {
75
+ window.localStorage.setItem(`${site.name}-ui-icons`, appConfig.theme.icons);
76
+ }
77
+ }
78
+ });
53
79
  const modes = [
54
80
  { label: "light", icon: appConfig.ui.icons.light },
55
81
  { label: "dark", icon: appConfig.ui.icons.dark },
@@ -68,7 +94,7 @@ export function useTheme() {
68
94
  window.localStorage.setItem(`${site.name}-ui-black-as-primary`, String(value));
69
95
  }
70
96
  const hasCSSChanges = computed(() => {
71
- return appConfig.theme.radius !== 0.25 || appConfig.theme.blackAsPrimary || appConfig.theme.font !== "Public Sans";
97
+ return appConfig.theme.radius !== 0.25 || appConfig.theme.blackAsPrimary || appConfig.theme.font !== "Public Sans" || appConfig.theme.icons !== "lucide";
72
98
  });
73
99
  const hasAppConfigChanges = computed(() => {
74
100
  return appConfig.ui.colors.primary !== "green" || appConfig.ui.colors.neutral !== "slate";
@@ -107,6 +133,12 @@ export function useTheme() {
107
133
  config.ui.colors.neutral = appConfig.ui.colors.neutral;
108
134
  }
109
135
  }
136
+ if (appConfig.theme.icons !== "lucide") {
137
+ const iconSet = appConfig.theme.icons;
138
+ const icons2 = themeIcons[iconSet];
139
+ config.ui = config.ui || {};
140
+ config.ui.icons = icons2;
141
+ }
110
142
  const configString = JSON.stringify(config, null, 2).replace(/"([^"]+)":/g, "$1:").replace(/"/g, "'");
111
143
  return `export default defineAppConfig(${configString})`;
112
144
  }
@@ -119,6 +151,9 @@ export function useTheme() {
119
151
  window.localStorage.removeItem(`${site.name}-ui-radius`);
120
152
  appConfig.theme.font = "Public Sans";
121
153
  window.localStorage.removeItem(`${site.name}-ui-font`);
154
+ appConfig.theme.icons = "lucide";
155
+ appConfig.ui.icons = themeIcons.lucide;
156
+ window.localStorage.removeItem(`${site.name}-ui-icons`);
122
157
  appConfig.theme.blackAsPrimary = false;
123
158
  window.localStorage.removeItem(`${site.name}-ui-black-as-primary`);
124
159
  }
@@ -132,6 +167,8 @@ export function useTheme() {
132
167
  radius,
133
168
  fonts,
134
169
  font,
170
+ icon,
171
+ icons,
135
172
  modes,
136
173
  mode,
137
174
  hasCSSChanges,
@@ -1,4 +1,5 @@
1
- import { defineNuxtPlugin, useAppConfig, useHead, useSiteConfig } from "#imports";
1
+ import { defineNuxtPlugin, onNuxtReady, useAppConfig, useHead, useSiteConfig } from "#imports";
2
+ import { themeIcons } from "../utils/theme.js";
2
3
  export default defineNuxtPlugin({
3
4
  enforce: "post",
4
5
  setup() {
@@ -32,6 +33,16 @@ export default defineNuxtPlugin({
32
33
  updateBlackAsPrimary();
33
34
  updateFont();
34
35
  }
36
+ onNuxtReady(() => {
37
+ function updateIcons() {
38
+ const icons = localStorage.getItem(`${site.name}-ui-icons`);
39
+ if (icons) {
40
+ appConfig.theme.icons = icons;
41
+ appConfig.ui.icons = themeIcons[icons];
42
+ }
43
+ }
44
+ updateIcons();
45
+ });
35
46
  if (import.meta.server) {
36
47
  useHead({
37
48
  script: [{
@@ -0,0 +1,135 @@
1
+ export declare const themeIcons: {
2
+ lucide: {
3
+ arrowDown: string;
4
+ arrowLeft: string;
5
+ arrowRight: string;
6
+ arrowUp: string;
7
+ caution: string;
8
+ check: string;
9
+ chevronDoubleLeft: string;
10
+ chevronDoubleRight: string;
11
+ chevronDown: string;
12
+ chevronLeft: string;
13
+ chevronRight: string;
14
+ chevronUp: string;
15
+ close: string;
16
+ copy: string;
17
+ copyCheck: string;
18
+ dark: string;
19
+ drag: string;
20
+ ellipsis: string;
21
+ error: string;
22
+ external: string;
23
+ eye: string;
24
+ eyeOff: string;
25
+ file: string;
26
+ folder: string;
27
+ folderOpen: string;
28
+ hash: string;
29
+ info: string;
30
+ light: string;
31
+ loading: string;
32
+ menu: string;
33
+ minus: string;
34
+ panelClose: string;
35
+ panelOpen: string;
36
+ plus: string;
37
+ reload: string;
38
+ search: string;
39
+ stop: string;
40
+ success: string;
41
+ system: string;
42
+ tip: string;
43
+ upload: string;
44
+ warning: string;
45
+ };
46
+ phosphor: {
47
+ arrowDown: string;
48
+ arrowLeft: string;
49
+ arrowRight: string;
50
+ arrowUp: string;
51
+ caution: string;
52
+ check: string;
53
+ chevronDoubleLeft: string;
54
+ chevronDoubleRight: string;
55
+ chevronDown: string;
56
+ chevronLeft: string;
57
+ chevronRight: string;
58
+ chevronUp: string;
59
+ close: string;
60
+ copy: string;
61
+ copyCheck: string;
62
+ dark: string;
63
+ drag: string;
64
+ ellipsis: string;
65
+ error: string;
66
+ external: string;
67
+ eye: string;
68
+ eyeOff: string;
69
+ file: string;
70
+ folder: string;
71
+ folderOpen: string;
72
+ hash: string;
73
+ info: string;
74
+ light: string;
75
+ loading: string;
76
+ menu: string;
77
+ minus: string;
78
+ panelClose: string;
79
+ panelOpen: string;
80
+ plus: string;
81
+ reload: string;
82
+ search: string;
83
+ stop: string;
84
+ success: string;
85
+ system: string;
86
+ tip: string;
87
+ upload: string;
88
+ warning: string;
89
+ };
90
+ tabler: {
91
+ arrowDown: string;
92
+ arrowLeft: string;
93
+ arrowRight: string;
94
+ arrowUp: string;
95
+ caution: string;
96
+ check: string;
97
+ chevronDoubleLeft: string;
98
+ chevronDoubleRight: string;
99
+ chevronDown: string;
100
+ chevronLeft: string;
101
+ chevronRight: string;
102
+ chevronUp: string;
103
+ close: string;
104
+ copy: string;
105
+ copyCheck: string;
106
+ dark: string;
107
+ drag: string;
108
+ ellipsis: string;
109
+ error: string;
110
+ external: string;
111
+ eye: string;
112
+ eyeOff: string;
113
+ file: string;
114
+ folder: string;
115
+ folderOpen: string;
116
+ hash: string;
117
+ info: string;
118
+ light: string;
119
+ loading: string;
120
+ menu: string;
121
+ minus: string;
122
+ panelClose: string;
123
+ panelOpen: string;
124
+ plus: string;
125
+ reload: string;
126
+ search: string;
127
+ stop: string;
128
+ success: string;
129
+ system: string;
130
+ tip: string;
131
+ upload: string;
132
+ warning: string;
133
+ };
134
+ };
135
+ export type ThemeIcons = keyof typeof themeIcons;
@@ -0,0 +1,134 @@
1
+ export const themeIcons = {
2
+ lucide: {
3
+ arrowDown: "i-lucide-arrow-down",
4
+ arrowLeft: "i-lucide-arrow-left",
5
+ arrowRight: "i-lucide-arrow-right",
6
+ arrowUp: "i-lucide-arrow-up",
7
+ caution: "i-lucide-circle-alert",
8
+ check: "i-lucide-check",
9
+ chevronDoubleLeft: "i-lucide-chevrons-left",
10
+ chevronDoubleRight: "i-lucide-chevrons-right",
11
+ chevronDown: "i-lucide-chevron-down",
12
+ chevronLeft: "i-lucide-chevron-left",
13
+ chevronRight: "i-lucide-chevron-right",
14
+ chevronUp: "i-lucide-chevron-up",
15
+ close: "i-lucide-x",
16
+ copy: "i-lucide-copy",
17
+ copyCheck: "i-lucide-copy-check",
18
+ dark: "i-lucide-moon",
19
+ drag: "i-lucide-grip-vertical",
20
+ ellipsis: "i-lucide-ellipsis",
21
+ error: "i-lucide-circle-x",
22
+ external: "i-lucide-arrow-up-right",
23
+ eye: "i-lucide-eye",
24
+ eyeOff: "i-lucide-eye-off",
25
+ file: "i-lucide-file",
26
+ folder: "i-lucide-folder",
27
+ folderOpen: "i-lucide-folder-open",
28
+ hash: "i-lucide-hash",
29
+ info: "i-lucide-info",
30
+ light: "i-lucide-sun",
31
+ loading: "i-lucide-loader-circle",
32
+ menu: "i-lucide-menu",
33
+ minus: "i-lucide-minus",
34
+ panelClose: "i-lucide-panel-left-close",
35
+ panelOpen: "i-lucide-panel-left-open",
36
+ plus: "i-lucide-plus",
37
+ reload: "i-lucide-rotate-ccw",
38
+ search: "i-lucide-search",
39
+ stop: "i-lucide-square",
40
+ success: "i-lucide-circle-check",
41
+ system: "i-lucide-monitor",
42
+ tip: "i-lucide-lightbulb",
43
+ upload: "i-lucide-upload",
44
+ warning: "i-lucide-triangle-alert"
45
+ },
46
+ phosphor: {
47
+ arrowDown: "i-ph-arrow-down",
48
+ arrowLeft: "i-ph-arrow-left",
49
+ arrowRight: "i-ph-arrow-right",
50
+ arrowUp: "i-ph-arrow-up",
51
+ caution: "i-ph-warning-circle",
52
+ check: "i-ph-check",
53
+ chevronDoubleLeft: "i-ph-caret-double-left",
54
+ chevronDoubleRight: "i-ph-caret-double-right",
55
+ chevronDown: "i-ph-caret-down",
56
+ chevronLeft: "i-ph-caret-left",
57
+ chevronRight: "i-ph-caret-right",
58
+ chevronUp: "i-ph-caret-up",
59
+ close: "i-ph-x",
60
+ copy: "i-ph-copy",
61
+ copyCheck: "i-ph-check-circle",
62
+ dark: "i-ph-moon",
63
+ drag: "i-ph-dots-six-vertical",
64
+ ellipsis: "i-ph-dots-three",
65
+ error: "i-ph-x-circle",
66
+ external: "i-ph-arrow-up-right",
67
+ eye: "i-ph-eye",
68
+ eyeOff: "i-ph-eye-slash",
69
+ file: "i-ph-file",
70
+ folder: "i-ph-folder",
71
+ folderOpen: "i-ph-folder-open",
72
+ hash: "i-ph-hash",
73
+ info: "i-ph-info",
74
+ light: "i-ph-sun",
75
+ loading: "i-ph-circle-notch",
76
+ menu: "i-ph-list",
77
+ minus: "i-ph-minus",
78
+ panelClose: "i-ph-caret-left",
79
+ panelOpen: "i-ph-caret-right",
80
+ plus: "i-ph-plus",
81
+ reload: "i-ph-arrow-counter-clockwise",
82
+ search: "i-ph-magnifying-glass",
83
+ stop: "i-ph-square",
84
+ success: "i-ph-check-circle",
85
+ system: "i-ph-monitor",
86
+ tip: "i-ph-lightbulb",
87
+ upload: "i-ph-upload",
88
+ warning: "i-ph-warning"
89
+ },
90
+ tabler: {
91
+ arrowDown: "i-tabler-arrow-down",
92
+ arrowLeft: "i-tabler-arrow-left",
93
+ arrowRight: "i-tabler-arrow-right",
94
+ arrowUp: "i-tabler-arrow-up",
95
+ caution: "i-tabler-alert-square-rounded",
96
+ check: "i-tabler-check",
97
+ chevronDoubleLeft: "i-tabler-chevrons-left",
98
+ chevronDoubleRight: "i-tabler-chevrons-right",
99
+ chevronDown: "i-tabler-chevron-down",
100
+ chevronLeft: "i-tabler-chevron-left",
101
+ chevronRight: "i-tabler-chevron-right",
102
+ chevronUp: "i-tabler-chevron-up",
103
+ close: "i-tabler-x",
104
+ copy: "i-tabler-copy",
105
+ copyCheck: "i-tabler-copy-check",
106
+ dark: "i-tabler-moon",
107
+ drag: "i-tabler-grip-vertical",
108
+ ellipsis: "i-tabler-dots",
109
+ error: "i-tabler-square-rounded-x",
110
+ external: "i-tabler-external-link",
111
+ eye: "i-tabler-eye",
112
+ eyeOff: "i-tabler-eye-off",
113
+ file: "i-tabler-file",
114
+ folder: "i-tabler-folder",
115
+ folderOpen: "i-tabler-folder-open",
116
+ hash: "i-tabler-hash",
117
+ info: "i-tabler-info-square-rounded",
118
+ light: "i-tabler-sun",
119
+ loading: "i-tabler-loader-2",
120
+ menu: "i-tabler-menu",
121
+ minus: "i-tabler-minus",
122
+ panelClose: "i-tabler-layout-sidebar-left-collapse",
123
+ panelOpen: "i-tabler-layout-sidebar-left-expand",
124
+ plus: "i-tabler-plus",
125
+ reload: "i-tabler-reload",
126
+ search: "i-tabler-search",
127
+ stop: "i-tabler-player-stop",
128
+ success: "i-tabler-square-rounded-check",
129
+ system: "i-tabler-device-desktop",
130
+ tip: "i-tabler-bulb",
131
+ upload: "i-tabler-upload",
132
+ warning: "i-tabler-alert-triangle"
133
+ }
134
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@movk/nuxt",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.1.1",
5
5
  "packageManager": "pnpm@10.28.0",
6
6
  "description": "Modular engineering suite for Nuxt 4 with schema-driven forms, API integration, UI components and composables",
7
7
  "author": "YiXuan <mhaibaraai@gmail.com>",
@@ -66,6 +66,8 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@iconify-json/lucide": "^1.2.86",
69
+ "@iconify-json/ph": "^1.2.2",
70
+ "@iconify-json/tabler": "^1.2.26",
69
71
  "@internationalized/date": "^3.10.1",
70
72
  "@movk/core": "^1.1.0",
71
73
  "@nuxt/image": "^2.0.0",