@movk/nuxt 1.0.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 +3 -0
- package/dist/module.d.mts +12 -3
- package/dist/module.json +1 -1
- package/dist/module.mjs +57 -13
- package/dist/runtime/components/AutoForm.vue +1 -0
- package/dist/runtime/components/SlideVerify.d.vue.ts +107 -0
- package/dist/runtime/components/SlideVerify.vue +147 -0
- package/dist/runtime/components/SlideVerify.vue.d.ts +107 -0
- package/dist/runtime/components/StarRating.vue +1 -0
- package/dist/runtime/components/auto-form-renderer/AutoFormRendererArray.vue +1 -1
- package/dist/runtime/components/theme-picker/ThemePicker.d.vue.ts +3 -0
- package/dist/runtime/components/theme-picker/ThemePicker.vue +266 -0
- package/dist/runtime/components/theme-picker/ThemePicker.vue.d.ts +3 -0
- package/dist/runtime/components/theme-picker/ThemePickerButton.d.vue.ts +18 -0
- package/dist/runtime/components/theme-picker/ThemePickerButton.vue +34 -0
- package/dist/runtime/components/theme-picker/ThemePickerButton.vue.d.ts +18 -0
- package/dist/runtime/composables/useApiFetch.js +1 -3
- package/dist/runtime/composables/useAutoForm.d.ts +81 -1425
- package/dist/runtime/composables/useAutoForm.js +3 -1
- package/dist/runtime/composables/useTheme.d.ts +27 -0
- package/dist/runtime/composables/useTheme.js +180 -0
- package/dist/runtime/composables/useUploadWithProgress.js +2 -2
- package/dist/runtime/internal/useAutoFormProvider.js +2 -2
- package/dist/runtime/plugins/api.factory.js +28 -30
- package/dist/runtime/plugins/theme.d.ts +2 -0
- package/dist/runtime/plugins/theme.js +100 -0
- package/dist/runtime/schemas/api.d.ts +336 -100
- package/dist/runtime/schemas/api.js +114 -98
- package/dist/runtime/style.css +1 -0
- package/dist/runtime/types/api.d.ts +108 -108
- package/dist/runtime/types/api.js +0 -8
- package/dist/runtime/utils/api-utils.d.ts +45 -30
- package/dist/runtime/utils/theme.d.ts +135 -0
- package/dist/runtime/utils/theme.js +134 -0
- package/package.json +21 -19
|
@@ -6,6 +6,7 @@ import WithCharacterLimit from "../components/input/WithCharacterLimit.vue";
|
|
|
6
6
|
import DatePicker from "../components/DatePicker.vue";
|
|
7
7
|
import ColorChooser from "../components/ColorChooser.vue";
|
|
8
8
|
import StarRating from "../components/StarRating.vue";
|
|
9
|
+
import SlideVerify from "../components/SlideVerify.vue";
|
|
9
10
|
import {
|
|
10
11
|
UInput,
|
|
11
12
|
UInputNumber,
|
|
@@ -193,7 +194,8 @@ const DEFAULT_CONTROLS = {
|
|
|
193
194
|
withCopy: defineControl({ component: WithCopy, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
194
195
|
withCharacterLimit: defineControl({ component: WithCharacterLimit, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
195
196
|
colorChooser: defineControl({ component: ColorChooser, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
196
|
-
starRating: defineControl({ component: StarRating, controlProps: DEFAULT_CONTROL_PROPS })
|
|
197
|
+
starRating: defineControl({ component: StarRating, controlProps: DEFAULT_CONTROL_PROPS }),
|
|
198
|
+
slideVerify: defineControl({ component: SlideVerify, controlProps: DEFAULT_CONTROL_PROPS })
|
|
197
199
|
};
|
|
198
200
|
export function useAutoForm(controls) {
|
|
199
201
|
function createZodFactory(_controls) {
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export declare function useTheme(): {
|
|
2
|
+
neutralColors: readonly ["slate", "gray", "zinc", "neutral", "stone"];
|
|
3
|
+
neutral: import("vue").WritableComputedRef<any, any>;
|
|
4
|
+
primaryColors: string[];
|
|
5
|
+
primary: import("vue").WritableComputedRef<any, any>;
|
|
6
|
+
setBlackAsPrimary: (value: boolean) => void;
|
|
7
|
+
radiuses: number[];
|
|
8
|
+
radius: import("vue").WritableComputedRef<any, any>;
|
|
9
|
+
fonts: string[];
|
|
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
|
+
}[];
|
|
17
|
+
modes: {
|
|
18
|
+
label: string;
|
|
19
|
+
icon: any;
|
|
20
|
+
}[];
|
|
21
|
+
mode: import("vue").WritableComputedRef<any, any>;
|
|
22
|
+
hasCSSChanges: import("vue").ComputedRef<any>;
|
|
23
|
+
hasAppConfigChanges: import("vue").ComputedRef<boolean>;
|
|
24
|
+
exportCSS: () => string;
|
|
25
|
+
exportAppConfig: () => string;
|
|
26
|
+
resetTheme: () => void;
|
|
27
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { useAppConfig, useColorMode, useSiteConfig } from "#imports";
|
|
2
|
+
import { omit } from "@movk/core";
|
|
3
|
+
import colors from "tailwindcss/colors";
|
|
4
|
+
import { computed } from "vue";
|
|
5
|
+
import { themeIcons } from "../utils/theme.js";
|
|
6
|
+
export function useTheme() {
|
|
7
|
+
const appConfig = useAppConfig();
|
|
8
|
+
const colorMode = useColorMode();
|
|
9
|
+
const site = useSiteConfig();
|
|
10
|
+
const neutralColors = ["slate", "gray", "zinc", "neutral", "stone"];
|
|
11
|
+
const neutral = computed({
|
|
12
|
+
get() {
|
|
13
|
+
return appConfig.ui.colors.neutral;
|
|
14
|
+
},
|
|
15
|
+
set(option) {
|
|
16
|
+
appConfig.ui.colors.neutral = option;
|
|
17
|
+
window.localStorage.setItem(`${site.name}-ui-neutral`, appConfig.ui.colors.neutral);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const colorsToOmit = ["inherit", "current", "transparent", "black", "white", ...neutralColors];
|
|
21
|
+
const primaryColors = Object.keys(omit(colors, [...colorsToOmit]));
|
|
22
|
+
const primary = computed({
|
|
23
|
+
get() {
|
|
24
|
+
return appConfig.ui.colors.primary;
|
|
25
|
+
},
|
|
26
|
+
set(option) {
|
|
27
|
+
appConfig.ui.colors.primary = option;
|
|
28
|
+
window.localStorage.setItem(`${site.name}-ui-primary`, appConfig.ui.colors.primary);
|
|
29
|
+
setBlackAsPrimary(false);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
const radiuses = [0, 0.125, 0.25, 0.375, 0.5];
|
|
33
|
+
const radius = computed({
|
|
34
|
+
get() {
|
|
35
|
+
return appConfig.theme.radius;
|
|
36
|
+
},
|
|
37
|
+
set(option) {
|
|
38
|
+
appConfig.theme.radius = option;
|
|
39
|
+
window.localStorage.setItem(`${site.name}-ui-radius`, String(appConfig.theme.radius));
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
const fonts = ["Public Sans", "DM Sans", "Geist", "Inter", "Poppins", "Outfit", "Raleway"];
|
|
43
|
+
const font = computed({
|
|
44
|
+
get() {
|
|
45
|
+
return appConfig.theme.font;
|
|
46
|
+
},
|
|
47
|
+
set(option) {
|
|
48
|
+
appConfig.theme.font = option;
|
|
49
|
+
if (appConfig.theme.font) {
|
|
50
|
+
window.localStorage.setItem(`${site.name}-ui-font`, appConfig.theme.font);
|
|
51
|
+
}
|
|
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
|
+
});
|
|
79
|
+
const modes = [
|
|
80
|
+
{ label: "light", icon: appConfig.ui.icons.light },
|
|
81
|
+
{ label: "dark", icon: appConfig.ui.icons.dark },
|
|
82
|
+
{ label: "system", icon: appConfig.ui.icons.system }
|
|
83
|
+
];
|
|
84
|
+
const mode = computed({
|
|
85
|
+
get() {
|
|
86
|
+
return colorMode.value;
|
|
87
|
+
},
|
|
88
|
+
set(option) {
|
|
89
|
+
colorMode.preference = option;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
function setBlackAsPrimary(value) {
|
|
93
|
+
appConfig.theme.blackAsPrimary = value;
|
|
94
|
+
window.localStorage.setItem(`${site.name}-ui-black-as-primary`, String(value));
|
|
95
|
+
}
|
|
96
|
+
const hasCSSChanges = computed(() => {
|
|
97
|
+
return appConfig.theme.radius !== 0.25 || appConfig.theme.blackAsPrimary || appConfig.theme.font !== "Public Sans" || appConfig.theme.icons !== "lucide";
|
|
98
|
+
});
|
|
99
|
+
const hasAppConfigChanges = computed(() => {
|
|
100
|
+
return appConfig.ui.colors.primary !== "green" || appConfig.ui.colors.neutral !== "slate";
|
|
101
|
+
});
|
|
102
|
+
function exportCSS() {
|
|
103
|
+
const lines = [
|
|
104
|
+
'@import "tailwindcss";',
|
|
105
|
+
'@import "@nuxt/ui";'
|
|
106
|
+
];
|
|
107
|
+
if (appConfig.theme.font !== "Public Sans") {
|
|
108
|
+
lines.push("", "@theme {", ` --font-sans: '${appConfig.theme.font}', sans-serif;`, "}");
|
|
109
|
+
}
|
|
110
|
+
const rootLines = [];
|
|
111
|
+
if (appConfig.theme.radius !== 0.25) {
|
|
112
|
+
rootLines.push(` --ui-radius: ${appConfig.theme.radius}rem;`);
|
|
113
|
+
}
|
|
114
|
+
if (appConfig.theme.blackAsPrimary) {
|
|
115
|
+
rootLines.push(" --ui-primary: black;");
|
|
116
|
+
}
|
|
117
|
+
if (rootLines.length) {
|
|
118
|
+
lines.push("", ":root {", ...rootLines, "}");
|
|
119
|
+
}
|
|
120
|
+
if (appConfig.theme.blackAsPrimary) {
|
|
121
|
+
lines.push("", ".dark {", " --ui-primary: white;", "}");
|
|
122
|
+
}
|
|
123
|
+
return lines.join("\n");
|
|
124
|
+
}
|
|
125
|
+
function exportAppConfig() {
|
|
126
|
+
const config = {};
|
|
127
|
+
if (appConfig.ui.colors.primary !== "green" || appConfig.ui.colors.neutral !== "slate") {
|
|
128
|
+
config.ui = { colors: {} };
|
|
129
|
+
if (appConfig.ui.colors.primary !== "green") {
|
|
130
|
+
config.ui.colors.primary = appConfig.ui.colors.primary;
|
|
131
|
+
}
|
|
132
|
+
if (appConfig.ui.colors.neutral !== "slate") {
|
|
133
|
+
config.ui.colors.neutral = appConfig.ui.colors.neutral;
|
|
134
|
+
}
|
|
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
|
+
}
|
|
142
|
+
const configString = JSON.stringify(config, null, 2).replace(/"([^"]+)":/g, "$1:").replace(/"/g, "'");
|
|
143
|
+
return `export default defineAppConfig(${configString})`;
|
|
144
|
+
}
|
|
145
|
+
function resetTheme() {
|
|
146
|
+
appConfig.ui.colors.primary = "green";
|
|
147
|
+
window.localStorage.removeItem(`${site.name}-ui-primary`);
|
|
148
|
+
appConfig.ui.colors.neutral = "slate";
|
|
149
|
+
window.localStorage.removeItem(`${site.name}-ui-neutral`);
|
|
150
|
+
appConfig.theme.radius = 0.25;
|
|
151
|
+
window.localStorage.removeItem(`${site.name}-ui-radius`);
|
|
152
|
+
appConfig.theme.font = "Public Sans";
|
|
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`);
|
|
157
|
+
appConfig.theme.blackAsPrimary = false;
|
|
158
|
+
window.localStorage.removeItem(`${site.name}-ui-black-as-primary`);
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
neutralColors,
|
|
162
|
+
neutral,
|
|
163
|
+
primaryColors,
|
|
164
|
+
primary,
|
|
165
|
+
setBlackAsPrimary,
|
|
166
|
+
radiuses,
|
|
167
|
+
radius,
|
|
168
|
+
fonts,
|
|
169
|
+
font,
|
|
170
|
+
icon,
|
|
171
|
+
icons,
|
|
172
|
+
modes,
|
|
173
|
+
mode,
|
|
174
|
+
hasCSSChanges,
|
|
175
|
+
hasAppConfigChanges,
|
|
176
|
+
exportCSS,
|
|
177
|
+
exportAppConfig,
|
|
178
|
+
resetTheme
|
|
179
|
+
};
|
|
180
|
+
}
|
|
@@ -45,8 +45,8 @@ export function useUploadWithProgress() {
|
|
|
45
45
|
currentXhr = null;
|
|
46
46
|
try {
|
|
47
47
|
const response = JSON.parse(xhr.responseText);
|
|
48
|
-
const isSuccess = isBusinessSuccess(response, config.
|
|
49
|
-
const message = extractMessage(response, config.
|
|
48
|
+
const isSuccess = isBusinessSuccess(response, config.response);
|
|
49
|
+
const message = extractMessage(response, config.response);
|
|
50
50
|
if (isSuccess) {
|
|
51
51
|
data.value = response;
|
|
52
52
|
if (import.meta.client && toast !== false) {
|
|
@@ -174,8 +174,8 @@ export function useAutoFormProvider(state, slots) {
|
|
|
174
174
|
return defu(field, {
|
|
175
175
|
meta: {
|
|
176
176
|
fieldSlots: {
|
|
177
|
-
hint: (
|
|
178
|
-
name: open ? "i-lucide-chevron-down" : "i-lucide-chevron-right",
|
|
177
|
+
hint: (props) => h(UIcon, {
|
|
178
|
+
name: props.open ? "i-lucide-chevron-down" : "i-lucide-chevron-right",
|
|
179
179
|
class: "shrink-0 size-5 transition-transform duration-200"
|
|
180
180
|
})
|
|
181
181
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
extractMessage,
|
|
6
6
|
extractToastMessage
|
|
7
7
|
} from "../utils/api-utils.js";
|
|
8
|
-
import { defineNuxtPlugin,
|
|
8
|
+
import { defineNuxtPlugin, navigateTo, useNuxtApp, useUserSession, useRuntimeConfig } from "#imports";
|
|
9
9
|
import defu from "defu";
|
|
10
10
|
function getUserSession() {
|
|
11
11
|
try {
|
|
@@ -27,11 +27,12 @@ function buildAuthHeader(token, config) {
|
|
|
27
27
|
}
|
|
28
28
|
async function handleUnauthorized(config) {
|
|
29
29
|
const userSession = getUserSession();
|
|
30
|
-
|
|
30
|
+
const unauthorizedConfig = config.unauthorized;
|
|
31
|
+
if (unauthorizedConfig?.clearSession && userSession?.clear) {
|
|
31
32
|
await userSession.clear();
|
|
32
33
|
}
|
|
33
|
-
if (
|
|
34
|
-
const loginPath =
|
|
34
|
+
if (unauthorizedConfig?.redirect) {
|
|
35
|
+
const loginPath = unauthorizedConfig.loginPath || "/login";
|
|
35
36
|
const nuxtApp = useNuxtApp();
|
|
36
37
|
await nuxtApp.runWithContext(() => navigateTo(loginPath));
|
|
37
38
|
}
|
|
@@ -39,8 +40,8 @@ async function handleUnauthorized(config) {
|
|
|
39
40
|
function getApiFetchContext(context) {
|
|
40
41
|
return context.options.context || {};
|
|
41
42
|
}
|
|
42
|
-
function createBuiltinHooks(resolvedConfig,
|
|
43
|
-
const { auth: authConfig, toast: toastConfig,
|
|
43
|
+
function createBuiltinHooks(resolvedConfig, publicConfig) {
|
|
44
|
+
const { auth: authConfig, toast: toastConfig, response: responseConfig } = resolvedConfig;
|
|
44
45
|
return {
|
|
45
46
|
onRequest(context) {
|
|
46
47
|
if (authConfig.enabled) {
|
|
@@ -57,25 +58,25 @@ function createBuiltinHooks(resolvedConfig, moduleConfig) {
|
|
|
57
58
|
}
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
|
-
if (
|
|
61
|
+
if (publicConfig.debug) {
|
|
61
62
|
console.log(`[Movk API] Request: ${context.options.method || "GET"} ${resolvedConfig.baseURL}${context.request}`);
|
|
62
63
|
}
|
|
63
64
|
},
|
|
64
65
|
async onRequestError({ error }) {
|
|
65
|
-
if (
|
|
66
|
+
if (publicConfig.debug) {
|
|
66
67
|
console.error("[Movk API] Request Error:", error);
|
|
67
68
|
}
|
|
68
69
|
},
|
|
69
70
|
async onResponse(context) {
|
|
70
71
|
const response = context.response;
|
|
71
72
|
const data = response._data;
|
|
72
|
-
if (
|
|
73
|
+
if (publicConfig.debug) {
|
|
73
74
|
console.log("[Movk API] Response:", data);
|
|
74
75
|
}
|
|
75
76
|
if (!import.meta.client) return;
|
|
76
77
|
const { toast, skipBusinessCheck } = getApiFetchContext(context);
|
|
77
|
-
const isSuccess = skipBusinessCheck || isBusinessSuccess(data,
|
|
78
|
-
const message = extractMessage(data,
|
|
78
|
+
const isSuccess = skipBusinessCheck || isBusinessSuccess(data, responseConfig);
|
|
79
|
+
const message = extractMessage(data, responseConfig);
|
|
79
80
|
if (isSuccess) {
|
|
80
81
|
const successMessage = toast !== false ? toast?.successMessage || message : void 0;
|
|
81
82
|
showToast("success", successMessage, toast, toastConfig);
|
|
@@ -86,20 +87,20 @@ function createBuiltinHooks(resolvedConfig, moduleConfig) {
|
|
|
86
87
|
if (response.status === 401) {
|
|
87
88
|
await handleUnauthorized(authConfig);
|
|
88
89
|
}
|
|
89
|
-
if (
|
|
90
|
+
if (publicConfig.debug) {
|
|
90
91
|
console.error("[Movk API] Error:", response.status, response._data);
|
|
91
92
|
}
|
|
92
93
|
if (!import.meta.client) return;
|
|
93
94
|
const { toast } = getApiFetchContext(context);
|
|
94
95
|
const data = response._data;
|
|
95
|
-
const message = data ? extractMessage(data,
|
|
96
|
+
const message = data ? extractMessage(data, responseConfig) : void 0;
|
|
96
97
|
const errorMessage = toast !== false ? toast?.errorMessage || message || `\u8BF7\u6C42\u5931\u8D25 (${response.status})` : void 0;
|
|
97
98
|
showToast("error", errorMessage, toast, toastConfig);
|
|
98
99
|
}
|
|
99
100
|
};
|
|
100
101
|
}
|
|
101
|
-
function createApiClient(resolvedConfig,
|
|
102
|
-
const builtinHooks = createBuiltinHooks(resolvedConfig,
|
|
102
|
+
function createApiClient(resolvedConfig, publicConfig, getOrCreateEndpoint) {
|
|
103
|
+
const builtinHooks = createBuiltinHooks(resolvedConfig, publicConfig);
|
|
103
104
|
resolvedConfig.builtinHooks = builtinHooks;
|
|
104
105
|
const $fetchInstance = $fetch.create({
|
|
105
106
|
baseURL: resolvedConfig.baseURL,
|
|
@@ -151,36 +152,33 @@ function createApiClient(resolvedConfig, moduleConfig, getOrCreateEndpoint) {
|
|
|
151
152
|
};
|
|
152
153
|
}
|
|
153
154
|
export default defineNuxtPlugin(() => {
|
|
154
|
-
const
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
155
|
+
const runtimeConfig = useRuntimeConfig();
|
|
156
|
+
const publicConfig = runtimeConfig.public.movkApi;
|
|
157
|
+
const privateConfig = import.meta.server ? runtimeConfig.movkApi : void 0;
|
|
158
158
|
const endpointCache = /* @__PURE__ */ new Map();
|
|
159
159
|
const getOrCreateEndpoint = (endpointName) => {
|
|
160
160
|
if (endpointCache.has(endpointName)) {
|
|
161
161
|
return endpointCache.get(endpointName);
|
|
162
162
|
}
|
|
163
|
-
const endpoints =
|
|
163
|
+
const endpoints = publicConfig.endpoints || {};
|
|
164
164
|
const endpointConfig = endpoints[endpointName];
|
|
165
165
|
if (!endpointConfig) {
|
|
166
166
|
console.warn(`[Movk API] Endpoint "${endpointName}" not found, using default`);
|
|
167
|
-
return getOrCreateEndpoint(
|
|
167
|
+
return getOrCreateEndpoint(publicConfig.defaultEndpoint || "default");
|
|
168
168
|
}
|
|
169
|
+
const privateEndpointConfig = privateConfig?.endpoints?.[endpointName];
|
|
169
170
|
const resolvedConfig = {
|
|
170
171
|
...endpointConfig,
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
headers: privateEndpointConfig?.headers,
|
|
173
|
+
auth: defu(endpointConfig.auth, publicConfig.auth),
|
|
174
|
+
toast: defu(endpointConfig.toast, publicConfig.toast),
|
|
175
|
+
response: defu(endpointConfig.response, publicConfig.response)
|
|
174
176
|
};
|
|
175
|
-
const client = createApiClient(
|
|
176
|
-
resolvedConfig,
|
|
177
|
-
moduleConfig,
|
|
178
|
-
getOrCreateEndpoint
|
|
179
|
-
);
|
|
177
|
+
const client = createApiClient(resolvedConfig, publicConfig, getOrCreateEndpoint);
|
|
180
178
|
endpointCache.set(endpointName, client);
|
|
181
179
|
return client;
|
|
182
180
|
};
|
|
183
|
-
const defaultEndpoint =
|
|
181
|
+
const defaultEndpoint = publicConfig.defaultEndpoint || "default";
|
|
184
182
|
const api = getOrCreateEndpoint(defaultEndpoint);
|
|
185
183
|
return {
|
|
186
184
|
provide: { api }
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { defineNuxtPlugin, onNuxtReady, useAppConfig, useHead, useSiteConfig } from "#imports";
|
|
2
|
+
import { themeIcons } from "../utils/theme.js";
|
|
3
|
+
export default defineNuxtPlugin({
|
|
4
|
+
enforce: "post",
|
|
5
|
+
setup() {
|
|
6
|
+
const appConfig = useAppConfig();
|
|
7
|
+
const site = useSiteConfig();
|
|
8
|
+
if (import.meta.client) {
|
|
9
|
+
let updateColor = function(type) {
|
|
10
|
+
const color = localStorage.getItem(`${site.name}-ui-${type}`);
|
|
11
|
+
if (color) {
|
|
12
|
+
appConfig.ui.colors[type] = color;
|
|
13
|
+
}
|
|
14
|
+
}, updateRadius = function() {
|
|
15
|
+
const radius = localStorage.getItem(`${site.name}-ui-radius`);
|
|
16
|
+
if (radius) {
|
|
17
|
+
appConfig.theme.radius = Number.parseFloat(radius);
|
|
18
|
+
}
|
|
19
|
+
}, updateBlackAsPrimary = function() {
|
|
20
|
+
const blackAsPrimary = localStorage.getItem(`${site.name}-ui-black-as-primary`);
|
|
21
|
+
if (blackAsPrimary) {
|
|
22
|
+
appConfig.theme.blackAsPrimary = blackAsPrimary === "true";
|
|
23
|
+
}
|
|
24
|
+
}, updateFont = function() {
|
|
25
|
+
const font = localStorage.getItem(`${site.name}-ui-font`);
|
|
26
|
+
if (font) {
|
|
27
|
+
appConfig.theme.font = font;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
updateColor("primary");
|
|
31
|
+
updateColor("neutral");
|
|
32
|
+
updateRadius();
|
|
33
|
+
updateBlackAsPrimary();
|
|
34
|
+
updateFont();
|
|
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
|
+
});
|
|
46
|
+
if (import.meta.server) {
|
|
47
|
+
useHead({
|
|
48
|
+
script: [{
|
|
49
|
+
innerHTML: `
|
|
50
|
+
let html = document.querySelector('style#nuxt-ui-colors').innerHTML;
|
|
51
|
+
|
|
52
|
+
if (localStorage.getItem('${site.name}-ui-primary')) {
|
|
53
|
+
const primaryColor = localStorage.getItem('${site.name}-ui-primary');
|
|
54
|
+
if (primaryColor !== 'black') {
|
|
55
|
+
html = html.replace(
|
|
56
|
+
/(--ui-color-primary-\\d{2,3}:\\s*var\\(--color-)${appConfig.ui.colors.primary}(-\\d{2,3}.*?\\))/g,
|
|
57
|
+
\`$1\${primaryColor}$2\`
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (localStorage.getItem('${site.name}-ui-neutral')) {
|
|
62
|
+
let neutralColor = localStorage.getItem('${site.name}-ui-neutral');
|
|
63
|
+
html = html.replace(
|
|
64
|
+
/(--ui-color-neutral-\\d{2,3}:\\s*var\\(--color-)${appConfig.ui.colors.neutral}(-\\d{2,3}.*?\\))/g,
|
|
65
|
+
\`$1\${neutralColor === 'neutral' ? 'old-neutral' : neutralColor}$2\`
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
document.querySelector('style#nuxt-ui-colors').innerHTML = html;
|
|
70
|
+
`.replace(/\s+/g, " "),
|
|
71
|
+
type: "text/javascript",
|
|
72
|
+
tagPriority: -1
|
|
73
|
+
}, {
|
|
74
|
+
innerHTML: `
|
|
75
|
+
if (localStorage.getItem('${site.name}-ui-radius')) {
|
|
76
|
+
document.querySelector('style#nuxt-ui-radius').innerHTML = ':root { --ui-radius: ' + localStorage.getItem('${site.name}-ui-radius') + 'rem; }';
|
|
77
|
+
}
|
|
78
|
+
`.replace(/\s+/g, " "),
|
|
79
|
+
type: "text/javascript",
|
|
80
|
+
tagPriority: -1
|
|
81
|
+
}, {
|
|
82
|
+
innerHTML: `
|
|
83
|
+
if (localStorage.getItem('${site.name}-ui-black-as-primary') === 'true') {
|
|
84
|
+
document.querySelector('style#nuxt-ui-black-as-primary').innerHTML = ':root { --ui-primary: black; } .dark { --ui-primary: white; }';
|
|
85
|
+
} else {
|
|
86
|
+
document.querySelector('style#nuxt-ui-black-as-primary').innerHTML = '';
|
|
87
|
+
}
|
|
88
|
+
`.replace(/\s+/g, " ")
|
|
89
|
+
}, {
|
|
90
|
+
innerHTML: `
|
|
91
|
+
if (localStorage.getItem('${site.name}-ui-font')) {
|
|
92
|
+
const font = localStorage.getItem('${site.name}-ui-font');
|
|
93
|
+
document.querySelector('style#nuxt-ui-font').innerHTML = ':root { --font-sans: \\'' + font + '\\', sans-serif; }';
|
|
94
|
+
}
|
|
95
|
+
`.replace(/\s+/g, " ")
|
|
96
|
+
}]
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|