@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.
@@ -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>