@maz-ui/mcp 4.1.3 → 4.1.6-beta.0
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/dist/mcp.mjs +1 -1
- package/docs/src/composables/use-form-validator.md +0 -2
- package/docs/src/guide/themes.md +383 -0
- package/docs/src/index.md +5 -5
- package/docs/src/theme-editor.md +1 -1
- package/package.json +7 -7
- package/docs/src/demo/ColorPicker.vue +0 -167
- package/docs/src/demo/DemoAuthPage.vue +0 -178
- package/docs/src/demo/DemoDashboardPage.vue +0 -291
- package/docs/src/demo/DemoProductPage.vue +0 -135
- package/docs/src/demo/ThemeEditorPage.vue +0 -396
|
@@ -1,396 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import type { ThemePreset } from '@maz-ui/themes'
|
|
3
|
-
import { useTheme } from '@maz-ui/themes/composables/useTheme'
|
|
4
|
-
import { mazUi } from '@maz-ui/themes/presets/mazUi'
|
|
5
|
-
import { useToast } from 'maz-ui/composables'
|
|
6
|
-
import { codeToHtml } from 'shiki'
|
|
7
|
-
import { computed, nextTick, reactive, ref, watch } from 'vue'
|
|
8
|
-
import ColorPicker from './ColorPicker.vue'
|
|
9
|
-
import DemoAuthPage from './DemoAuthPage.vue'
|
|
10
|
-
import DemoDashboardPage from './DemoDashboardPage.vue'
|
|
11
|
-
import DemoProductPage from './DemoProductPage.vue'
|
|
12
|
-
|
|
13
|
-
const { updateTheme, isDark, toggleDarkMode, presetName } = useTheme()
|
|
14
|
-
const toast = useToast()
|
|
15
|
-
|
|
16
|
-
const currentTab = ref(1)
|
|
17
|
-
const editingMode = ref<'light' | 'dark'>('light')
|
|
18
|
-
const exportedCode = ref('')
|
|
19
|
-
const highlightedCode = ref('')
|
|
20
|
-
const showExportModal = ref(false)
|
|
21
|
-
const isTransitioning = ref(false)
|
|
22
|
-
|
|
23
|
-
const themeData = reactive<ThemePreset>({
|
|
24
|
-
name: mazUi.name,
|
|
25
|
-
foundation: { ...mazUi.foundation },
|
|
26
|
-
colors: {
|
|
27
|
-
light: { ...mazUi.colors.light },
|
|
28
|
-
dark: { ...mazUi.colors.dark },
|
|
29
|
-
},
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
const originalTheme = {
|
|
33
|
-
name: mazUi.name,
|
|
34
|
-
foundation: { ...mazUi.foundation },
|
|
35
|
-
colors: {
|
|
36
|
-
light: { ...mazUi.colors.light },
|
|
37
|
-
dark: { ...mazUi.colors.dark },
|
|
38
|
-
},
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const colorCategories = [
|
|
42
|
-
{
|
|
43
|
-
name: 'Base Colors',
|
|
44
|
-
colors: ['background', 'foreground', 'border', 'muted', 'overlay', 'shadow'] as const,
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
name: 'Colors',
|
|
48
|
-
colors: ['primary', 'primary-foreground', 'secondary', 'secondary-foreground', 'accent', 'accent-foreground', 'success', 'success-foreground', 'warning', 'warning-foreground', 'destructive', 'destructive-foreground', 'info', 'info-foreground', 'contrast', 'contrast-foreground'] as const,
|
|
49
|
-
},
|
|
50
|
-
]
|
|
51
|
-
|
|
52
|
-
watch([themeData, editingMode], async () => {
|
|
53
|
-
await nextTick()
|
|
54
|
-
await updateTheme(themeData)
|
|
55
|
-
}, { deep: true })
|
|
56
|
-
|
|
57
|
-
function handleThemeModeToggle() {
|
|
58
|
-
isTransitioning.value = true
|
|
59
|
-
toggleDarkMode()
|
|
60
|
-
|
|
61
|
-
setTimeout(() => {
|
|
62
|
-
isTransitioning.value = false
|
|
63
|
-
}, 500)
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function resetTheme() {
|
|
67
|
-
Object.assign(themeData.foundation, originalTheme.foundation)
|
|
68
|
-
Object.assign(themeData.colors.light, originalTheme.colors.light)
|
|
69
|
-
Object.assign(themeData.colors.dark, originalTheme.colors.dark)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function copyToClipboard(text: string) {
|
|
73
|
-
navigator.clipboard.writeText(text).then(() => {
|
|
74
|
-
showExportModal.value = false
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
toast.success('Theme copied to clipboard', {
|
|
78
|
-
position: 'top',
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async function exportTheme() {
|
|
83
|
-
const themeCode = `import type { ThemePreset } from '@maz-ui/themes'
|
|
84
|
-
|
|
85
|
-
export const customTheme: ThemePreset = ${JSON.stringify(themeData, null, 2)
|
|
86
|
-
// Escape single quotes within string values
|
|
87
|
-
.replace(/: "([^"]*)"/g, (match, value) => {
|
|
88
|
-
const escapedValue = value.replace(/'/g, '\\\'')
|
|
89
|
-
return `: '${escapedValue}'`
|
|
90
|
-
})
|
|
91
|
-
// Remove quotes from top-level keys and nested object keys
|
|
92
|
-
.replace(/^(\s*)"(name|foundation|colors)":/gm, '$1$2:')
|
|
93
|
-
.replace(/^(\s*)"(light|dark)":/gm, '$1$2:')}`
|
|
94
|
-
|
|
95
|
-
exportedCode.value = themeCode
|
|
96
|
-
|
|
97
|
-
try {
|
|
98
|
-
const html = await codeToHtml(themeCode, {
|
|
99
|
-
lang: 'typescript',
|
|
100
|
-
theme: isDark.value ? 'tokyo-night' : 'github-dark',
|
|
101
|
-
})
|
|
102
|
-
highlightedCode.value = html
|
|
103
|
-
}
|
|
104
|
-
catch (error) {
|
|
105
|
-
console.error('Failed to highlight code:', error)
|
|
106
|
-
highlightedCode.value = ''
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
showExportModal.value = true
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const foundationInputs = computed(() => [
|
|
113
|
-
{
|
|
114
|
-
key: 'base-font-size',
|
|
115
|
-
label: 'Base Font Size',
|
|
116
|
-
type: 'text',
|
|
117
|
-
placeholder: '14px',
|
|
118
|
-
},
|
|
119
|
-
{
|
|
120
|
-
key: 'font-family',
|
|
121
|
-
label: 'Font Family',
|
|
122
|
-
type: 'text',
|
|
123
|
-
placeholder: 'Manrope, sans-serif',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
key: 'radius',
|
|
127
|
-
label: 'Border Radius',
|
|
128
|
-
type: 'text',
|
|
129
|
-
placeholder: '0.7rem',
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
key: 'border-width',
|
|
133
|
-
label: 'Border Width',
|
|
134
|
-
type: 'text',
|
|
135
|
-
placeholder: '0.0625rem',
|
|
136
|
-
},
|
|
137
|
-
])
|
|
138
|
-
|
|
139
|
-
const currentColors = computed(() => themeData.colors[editingMode.value])
|
|
140
|
-
|
|
141
|
-
function formatColorName(colorName: string): string {
|
|
142
|
-
return colorName
|
|
143
|
-
.split('-')
|
|
144
|
-
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
|
|
145
|
-
.join(' ')
|
|
146
|
-
}
|
|
147
|
-
</script>
|
|
148
|
-
|
|
149
|
-
<template>
|
|
150
|
-
<div class="vp-raw theme-configurator" :class="{ 'no-transitions': isTransitioning }">
|
|
151
|
-
<div class="maz-grid maz-min-h-[80vh] maz-grid-cols-1 maz-gap-4 lg:maz-grid-cols-12">
|
|
152
|
-
<!-- Editor Panel -->
|
|
153
|
-
<div class="maz-space-y-6 lg:maz-col-span-4 lg:maz-border-r lg:maz-pr-4">
|
|
154
|
-
<h2 class="maz-text-2xl maz-text-foreground">
|
|
155
|
-
Editor
|
|
156
|
-
</h2>
|
|
157
|
-
|
|
158
|
-
<div class="maz-flex maz-flex-col maz-gap-2 mob-l:maz-flex-row">
|
|
159
|
-
<MazBtn
|
|
160
|
-
size="md"
|
|
161
|
-
block
|
|
162
|
-
color="secondary"
|
|
163
|
-
@click="resetTheme"
|
|
164
|
-
>
|
|
165
|
-
Reset theme
|
|
166
|
-
</MazBtn>
|
|
167
|
-
<MazBtn
|
|
168
|
-
size="md"
|
|
169
|
-
block
|
|
170
|
-
color="primary"
|
|
171
|
-
@click="exportTheme"
|
|
172
|
-
>
|
|
173
|
-
Export theme
|
|
174
|
-
</MazBtn>
|
|
175
|
-
</div>
|
|
176
|
-
|
|
177
|
-
<MazCard block title="Base preset">
|
|
178
|
-
<MazRadioButtons
|
|
179
|
-
:model-value="presetName"
|
|
180
|
-
size="sm"
|
|
181
|
-
:options="[
|
|
182
|
-
{
|
|
183
|
-
label: 'Maz-UI',
|
|
184
|
-
value: 'maz-ui',
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
label: 'Pristine',
|
|
188
|
-
value: 'pristine',
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
label: 'Ocean',
|
|
192
|
-
value: 'ocean',
|
|
193
|
-
}, {
|
|
194
|
-
label: 'Obsidian',
|
|
195
|
-
value: 'obsidian',
|
|
196
|
-
}]"
|
|
197
|
-
@update:model-value="updateTheme($event)"
|
|
198
|
-
/>
|
|
199
|
-
</MazCard>
|
|
200
|
-
|
|
201
|
-
<!-- Foundation Settings -->
|
|
202
|
-
<MazCard title="Foundation" block>
|
|
203
|
-
<div
|
|
204
|
-
class="maz-flex maz-flex-col maz-gap-3"
|
|
205
|
-
>
|
|
206
|
-
<template
|
|
207
|
-
v-for="input in foundationInputs"
|
|
208
|
-
:key="input.key"
|
|
209
|
-
>
|
|
210
|
-
<MazInput
|
|
211
|
-
v-model="themeData.foundation[input.key as keyof typeof themeData.foundation]"
|
|
212
|
-
:label="input.label"
|
|
213
|
-
:placeholder="input.placeholder"
|
|
214
|
-
size="sm"
|
|
215
|
-
block
|
|
216
|
-
debounce
|
|
217
|
-
/>
|
|
218
|
-
</template>
|
|
219
|
-
</div>
|
|
220
|
-
</MazCard>
|
|
221
|
-
|
|
222
|
-
<!-- Colors Settings -->
|
|
223
|
-
<MazCard block>
|
|
224
|
-
<template #title>
|
|
225
|
-
<div class="maz-flex maz-w-full maz-items-center maz-justify-between">
|
|
226
|
-
<h3 class="maz-text-base">
|
|
227
|
-
Colors
|
|
228
|
-
</h3>
|
|
229
|
-
|
|
230
|
-
<div class="maz-flex maz-items-center maz-gap-2">
|
|
231
|
-
<label for="dark-mode-switch" class="maz-cursor-pointer maz-text-sm">
|
|
232
|
-
Edit dark colors
|
|
233
|
-
</label>
|
|
234
|
-
<MazSwitch
|
|
235
|
-
id="dark-mode-switch"
|
|
236
|
-
:model-value="editingMode === 'dark'"
|
|
237
|
-
@update:model-value="editingMode = $event ? 'dark' : 'light'; handleThemeModeToggle()"
|
|
238
|
-
/>
|
|
239
|
-
</div>
|
|
240
|
-
</div>
|
|
241
|
-
</template>
|
|
242
|
-
|
|
243
|
-
<div class="maz-space-y-6">
|
|
244
|
-
<div
|
|
245
|
-
v-for="category in colorCategories"
|
|
246
|
-
:key="category.name"
|
|
247
|
-
class="maz-space-y-4"
|
|
248
|
-
>
|
|
249
|
-
<h4 class="maz-border-border maz-border-b maz-pb-2 maz-text-sm maz-font-semibold maz-text-foreground">
|
|
250
|
-
{{ category.name }}
|
|
251
|
-
</h4>
|
|
252
|
-
|
|
253
|
-
<div class="maz-grid maz-grid-cols-2 maz-gap-4">
|
|
254
|
-
<ColorPicker
|
|
255
|
-
v-for="colorKey in category.colors"
|
|
256
|
-
:key="`${editingMode}-${colorKey}`"
|
|
257
|
-
v-model="currentColors[colorKey]"
|
|
258
|
-
:label="formatColorName(colorKey)"
|
|
259
|
-
class="maz-w-full"
|
|
260
|
-
/>
|
|
261
|
-
</div>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
264
|
-
</MazCard>
|
|
265
|
-
</div>
|
|
266
|
-
|
|
267
|
-
<!-- Preview Panel -->
|
|
268
|
-
<div class="lg:maz-col-span-8">
|
|
269
|
-
<div class="maz-sticky maz-top-4">
|
|
270
|
-
<div class="maz-mb-4 maz-flex maz-items-center maz-justify-between">
|
|
271
|
-
<h2 class="maz-text-2xl maz-text-foreground">
|
|
272
|
-
Preview
|
|
273
|
-
</h2>
|
|
274
|
-
</div>
|
|
275
|
-
|
|
276
|
-
<MazTabs v-model="currentTab">
|
|
277
|
-
<MazTabsBar
|
|
278
|
-
:items="['Dashboard', 'Product', 'Authentication']"
|
|
279
|
-
class="maz-mb-4"
|
|
280
|
-
/>
|
|
281
|
-
|
|
282
|
-
<MazTabsContent>
|
|
283
|
-
<MazTabsContentItem :tab="1">
|
|
284
|
-
<MazCard
|
|
285
|
-
bordered
|
|
286
|
-
:padding="false"
|
|
287
|
-
overflow-hidden
|
|
288
|
-
class="maz-max-h-[70vh] maz-w-full maz-overflow-y-auto"
|
|
289
|
-
>
|
|
290
|
-
<DemoDashboardPage :delay="0" />
|
|
291
|
-
</MazCard>
|
|
292
|
-
</MazTabsContentItem>
|
|
293
|
-
|
|
294
|
-
<MazTabsContentItem :tab="2">
|
|
295
|
-
<MazCard
|
|
296
|
-
bordered
|
|
297
|
-
:padding="false"
|
|
298
|
-
overflow-hidden
|
|
299
|
-
class="maz-max-h-[70vh] maz-w-full maz-overflow-y-auto"
|
|
300
|
-
>
|
|
301
|
-
<DemoProductPage />
|
|
302
|
-
</MazCard>
|
|
303
|
-
</MazTabsContentItem>
|
|
304
|
-
|
|
305
|
-
<MazTabsContentItem :tab="3">
|
|
306
|
-
<MazCard
|
|
307
|
-
bordered
|
|
308
|
-
:padding="false"
|
|
309
|
-
overflow-hidden
|
|
310
|
-
class="maz-max-h-[70vh] maz-w-full maz-overflow-y-auto"
|
|
311
|
-
>
|
|
312
|
-
<DemoAuthPage />
|
|
313
|
-
</MazCard>
|
|
314
|
-
</MazTabsContentItem>
|
|
315
|
-
</MazTabsContent>
|
|
316
|
-
</MazTabs>
|
|
317
|
-
</div>
|
|
318
|
-
</div>
|
|
319
|
-
</div>
|
|
320
|
-
|
|
321
|
-
<!-- Export Modal -->
|
|
322
|
-
<MazDialog v-model="showExportModal" scrollable title="Export Theme">
|
|
323
|
-
<div class="maz-space-y-4">
|
|
324
|
-
<p class="maz-text-muted">
|
|
325
|
-
Copy the generated TypeScript code below to use your custom theme:
|
|
326
|
-
</p>
|
|
327
|
-
|
|
328
|
-
<div class="maz-overflow-y-auto maz-rounded-md">
|
|
329
|
-
<div
|
|
330
|
-
v-if="highlightedCode"
|
|
331
|
-
class="shiki-wrapper"
|
|
332
|
-
v-html="highlightedCode"
|
|
333
|
-
/>
|
|
334
|
-
<div
|
|
335
|
-
v-else
|
|
336
|
-
class="maz-bg-contrast maz-p-4 dark:maz-bg-surface-300"
|
|
337
|
-
>
|
|
338
|
-
<pre class="maz-whitespace-pre-wrap maz-font-mono maz-text-xs maz-text-contrast-foreground dark:maz-text-surface-foreground">{{ exportedCode }}</pre>
|
|
339
|
-
</div>
|
|
340
|
-
</div>
|
|
341
|
-
</div>
|
|
342
|
-
|
|
343
|
-
<template #footer>
|
|
344
|
-
<div class="maz-flex maz-gap-2">
|
|
345
|
-
<MazBtn color="primary" @click="copyToClipboard(exportedCode)">
|
|
346
|
-
Copy to Clipboard
|
|
347
|
-
</MazBtn>
|
|
348
|
-
</div>
|
|
349
|
-
</template>
|
|
350
|
-
</MazDialog>
|
|
351
|
-
</div>
|
|
352
|
-
</template>
|
|
353
|
-
|
|
354
|
-
<style lang="postcss" scoped>
|
|
355
|
-
@media (max-width: 1024px) {
|
|
356
|
-
.theme-configurator {
|
|
357
|
-
@apply maz-space-y-8;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
.theme-configurator .maz-sticky {
|
|
361
|
-
@apply maz-static;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
</style>
|
|
365
|
-
|
|
366
|
-
<style lang="postcss">
|
|
367
|
-
/* Global styles to disable transitions during theme mode switch */
|
|
368
|
-
.no-transitions *,
|
|
369
|
-
.no-transitions *::before,
|
|
370
|
-
.no-transitions *::after {
|
|
371
|
-
transition-duration: 0ms !important;
|
|
372
|
-
transition-delay: 0ms !important;
|
|
373
|
-
animation-duration: 0ms !important;
|
|
374
|
-
animation-delay: 0ms !important;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/* Shiki code highlighting styles */
|
|
378
|
-
.shiki-wrapper {
|
|
379
|
-
@apply maz-rounded-md maz-overflow-hidden maz-bg-contrast dark:maz-bg-surface-400;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
.shiki-wrapper pre {
|
|
383
|
-
@apply maz-p-4 maz-m-0 maz-text-xs maz-overflow-x-auto;
|
|
384
|
-
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace !important;
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
.shiki-wrapper code {
|
|
388
|
-
@apply maz-text-xs;
|
|
389
|
-
font-family: 'Fira Code', 'Consolas', 'Monaco', monospace !important;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
/* Override shiki background to match theme */
|
|
393
|
-
.shiki-wrapper .shiki {
|
|
394
|
-
background-color: transparent !important;
|
|
395
|
-
}
|
|
396
|
-
</style>
|