@maz-ui/mcp 4.1.1 → 4.1.3
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 +2 -2
- package/docs/generated-docs/maz-radio-buttons.doc.md +1 -0
- package/docs/src/blog/v4.md +276 -0
- package/docs/src/components/maz-popover.md +1 -1
- package/docs/src/components/maz-select-country.md +1 -1
- package/docs/src/components/maz-slider.md +3 -2
- package/docs/src/composables/use-display-names.md +3 -3
- package/docs/src/composables/use-form-validator.md +2 -2
- package/docs/src/composables/use-idle-timeout.md +1 -1
- package/docs/src/composables/use-swipe.md +1 -1
- package/docs/src/composables/use-timer.md +1 -1
- package/docs/src/demo/ColorPicker.vue +167 -0
- package/docs/src/demo/DemoDashboardPage.vue +2 -9
- package/docs/src/demo/ThemeEditorPage.vue +396 -0
- package/docs/src/directives/click-outside.md +1 -1
- package/docs/src/directives/lazy-img.md +1 -1
- package/docs/src/directives/tooltip.md +1 -1
- package/docs/src/directives/zoom-img.md +1 -1
- package/docs/src/guide/getting-started.md +3 -3
- package/docs/src/guide/icon-set.md +46 -12
- package/docs/src/guide/icons.md +3 -3
- package/docs/src/guide/migration-v4.md +68 -63
- package/docs/src/guide/themes.md +4 -0
- package/docs/src/index.md +4 -4
- package/docs/src/theme-editor.md +21 -0
- package/package.json +5 -5
|
@@ -0,0 +1,396 @@
|
|
|
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>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: vClickOutside
|
|
3
|
-
description: vClickOutside is a Vue
|
|
3
|
+
description: vClickOutside is a Vue directive to trigger a function when the user clicks outside an element
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# {{ $frontmatter.title }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: vLazyImg
|
|
3
|
-
description: vLazyImg is a Vue
|
|
3
|
+
description: vLazyImg is a Vue directive to lazy load images with many options. The image will be loaded on user's scroll
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# {{ $frontmatter.title }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: vZoomImg
|
|
3
|
-
description: vZoomImg is a Vue
|
|
3
|
+
description: vZoomImg is a Vue directive to enlarge an image like a modal on click, if you have several images, you can pass them like a carousel
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# {{ $frontmatter.title }}
|
|
@@ -4,7 +4,7 @@ description: Build Vue and Nuxt applications faster with Maz-UI v4 - The modern,
|
|
|
4
4
|
head:
|
|
5
5
|
- - meta
|
|
6
6
|
- name: keywords
|
|
7
|
-
content: vue ui library, vue components, nuxt ui, maz-ui installation, vue
|
|
7
|
+
content: vue ui library, vue components, nuxt ui, maz-ui installation, components, nuxt, vue, themes, translations, icons, mcp, maz-ui
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# {{ $frontmatter.title }}
|
|
@@ -19,7 +19,7 @@ head:
|
|
|
19
19
|
- 🆕 **New components** - MazPopover & MazSelectCountry
|
|
20
20
|
- 🎨 **Theming system** - Customizable themes and dark mode support (4 presets available) - [@maz-ui/themes](./themes.md)
|
|
21
21
|
- 🌐 **Internationalization** - Locale management and tree-shakable imports - [@maz-ui/translations](./translations.md)
|
|
22
|
-
- 🎨 **Icon library** - Comprehensive collection of SVG icons designed for performance and flexibility (
|
|
22
|
+
- 🎨 **Icon library** - Comprehensive collection of SVG icons designed for performance and flexibility (400+ icons) - [@maz-ui/icons](./icons.md)
|
|
23
23
|
- 🧰 **Nuxt module** - Effortless Maz-UI integration with auto-imports - [@maz-ui/nuxt](./nuxt.md)
|
|
24
24
|
- 🤖 **MCP** - Connect your IA agents to the documentation - [@maz-ui/mcp](./mcp.md)
|
|
25
25
|
|
|
@@ -131,7 +131,7 @@ npm install @maz-ui/icons
|
|
|
131
131
|
|
|
132
132
|
**Features:**
|
|
133
133
|
|
|
134
|
-
-
|
|
134
|
+
- 840+ icons
|
|
135
135
|
- Usable as Vue components (e.g. `<MazStar />`)
|
|
136
136
|
- Tree-shakable imports
|
|
137
137
|
- Multiple sizes and variants
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# Icon Set (
|
|
1
|
+
# Icon Set (840+ icons)
|
|
2
2
|
|
|
3
|
-
The library includes **
|
|
3
|
+
The library includes **840+ carefully**
|
|
4
4
|
|
|
5
5
|
## Icon Naming Convention
|
|
6
6
|
|
|
@@ -16,13 +16,16 @@ All icons follow a consistent naming pattern:
|
|
|
16
16
|
<div class="maz-flex maz-gap-2 maz-items-start">
|
|
17
17
|
<MazInput v-model="search" label="Search icon" @update:model-value="search = $event.trim()" :left-icon="MazIcons.MazMagnifyingGlass" class="flex-1" :assistive-text="`${filteredIcons.length} icons found`" />
|
|
18
18
|
</div>
|
|
19
|
+
<MazTabs v-model="currentTab">
|
|
20
|
+
<MazTabsBar :items="tabs" />
|
|
21
|
+
</MazTabs>
|
|
19
22
|
<div class="maz-grid maz-grid-cols-3 maz-gap-2">
|
|
20
|
-
<div v-for="icon in filteredIcons" :key="icon.
|
|
21
|
-
<Component :is="icon.
|
|
22
|
-
<span class="maz-text-xs maz-text-muted maz-truncate">{{ icon.
|
|
23
|
+
<div v-for="icon in filteredIcons" :key="icon.name" class="maz-flex maz-flex-col maz-items-center maz-gap-3 maz-text-center maz-border maz-border-solid maz-border-divider maz-rounded maz-p-4 maz-truncate hover:maz-bg-surface-600/50 dark:hover:maz-bg-surface-400">
|
|
24
|
+
<Component :is="icon.component" class="maz-size-8" />
|
|
25
|
+
<span class="maz-text-xs maz-text-muted maz-truncate">{{ icon.name }}</span>
|
|
23
26
|
<div class="maz-flex maz-flex-row maz-gap-2 maz-w-full">
|
|
24
|
-
<MazBtn v-tooltip="'Copy Name'" class="maz-flex-1" size="xs" color="background" outlined @click="copyIcon(icon.
|
|
25
|
-
<MazBtn v-tooltip="'Copy Import'" class="maz-flex-1" size="xs" color="background" outlined @click="copyIconImport(icon.
|
|
27
|
+
<MazBtn v-tooltip="{ text: 'Copy Name', panelClass: 'maz-text-xs' }" class="maz-flex-1" size="xs" color="background" outlined @click="copyIcon(icon.name)" :icon="MazClipboardDocument" />
|
|
28
|
+
<MazBtn v-tooltip="{ text: 'Copy Import', panelClass: 'maz-text-xs' }" class="maz-flex-1" size="xs" color="background" outlined @click="copyIconImport(icon.name)" :icon="MazClipboardDocumentList" />
|
|
26
29
|
</div>
|
|
27
30
|
</div>
|
|
28
31
|
</div>
|
|
@@ -36,20 +39,51 @@ import { vTooltip } from 'maz-ui/directives/vTooltip'
|
|
|
36
39
|
import { MazClipboardDocument, MazClipboardDocumentList } from '@maz-ui/icons'
|
|
37
40
|
|
|
38
41
|
const MazIcons = await import('@maz-ui/icons')
|
|
39
|
-
const { success} = useToast()
|
|
40
42
|
|
|
41
43
|
const icons = Object.entries(MazIcons).sort(([nameA, _], [nameB, __]) => nameA.localeCompare(nameB)).map(([name, component]) => ({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
name,
|
|
45
|
+
component,
|
|
44
46
|
}))
|
|
45
47
|
|
|
48
|
+
const { commonIcons, flags, flagsSquare, all } = icons.reduce((acc, iconComponent) => {
|
|
49
|
+
if (iconComponent.name.startsWith('MazFlagSquare')) {
|
|
50
|
+
acc.flagsSquare.push(iconComponent)
|
|
51
|
+
}
|
|
52
|
+
else if (iconComponent.name.startsWith('MazFlag') && iconComponent.name.length >= 8) acc.flags.push(iconComponent)
|
|
53
|
+
else if (iconComponent.name.startsWith('Maz')) acc.commonIcons.push(iconComponent)
|
|
54
|
+
|
|
55
|
+
acc.all.push(iconComponent)
|
|
56
|
+
|
|
57
|
+
return acc
|
|
58
|
+
}, {
|
|
59
|
+
commonIcons: [],
|
|
60
|
+
flags: [],
|
|
61
|
+
flagsSquare: [],
|
|
62
|
+
all: [],
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const currentTab = ref(1)
|
|
66
|
+
|
|
67
|
+
const tabs = [
|
|
68
|
+
{ label: 'All', badge: { color: 'secondary', content: all.length, roundedSize: 'full' } },
|
|
69
|
+
{ label: 'Icons', badge: { color: 'secondary', content: commonIcons.length, roundedSize: 'full' } },
|
|
70
|
+
{ label: 'Flags', badge: { color: 'secondary', content: flags.length, roundedSize: 'full' } },
|
|
71
|
+
{ label: 'Flags Square', badge: { color: 'secondary', content: flagsSquare.length, roundedSize: 'full' } },
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
const { success } = useToast()
|
|
75
|
+
|
|
46
76
|
const search = ref()
|
|
47
77
|
|
|
48
78
|
const filteredIcons = computed(() => {
|
|
79
|
+
const _currentTab = currentTab.value
|
|
80
|
+
|
|
81
|
+
const baseIcons = _currentTab === 1 ? all : _currentTab === 2 ? commonIcons : _currentTab === 3 ? flags : _currentTab === 4 ? flagsSquare : all
|
|
82
|
+
|
|
49
83
|
const _search = search.value?.toLowerCase().replace(/\s/g, '')
|
|
50
|
-
if (!_search) return
|
|
84
|
+
if (!_search) return baseIcons
|
|
51
85
|
|
|
52
|
-
return
|
|
86
|
+
return baseIcons.filter(icon => icon.name.toLowerCase().includes(_search) || _search.includes(icon.name.toLowerCase()))
|
|
53
87
|
})
|
|
54
88
|
|
|
55
89
|
const copyIcon = (icon) => {
|
package/docs/src/guide/icons.md
CHANGED
|
@@ -4,7 +4,7 @@ A comprehensive collection of **328 beautiful SVG icons** ready for use in your
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
7
|
+
- **840+ icons** - All icons are available [in the icon set page](./icon-set.md)
|
|
8
8
|
- **Multiple usage patterns** - Direct SVG files, Vue components, or auto-import
|
|
9
9
|
- **TypeScript support** - Full type definitions included
|
|
10
10
|
- **Tree-shakeable** - Import only the icons you need
|
|
@@ -73,7 +73,7 @@ import { MazCheck, MazHeart, MazUser } from '@maz-ui/icons'
|
|
|
73
73
|
|
|
74
74
|
- ✅ Tree-shaking - Only bundled icons are included
|
|
75
75
|
- ✅ TypeScript support with full IntelliSense
|
|
76
|
-
- ✅ Vue
|
|
76
|
+
- ✅ Vue optimized with `defineAsyncComponent`
|
|
77
77
|
- ✅ Easy to style with CSS classes
|
|
78
78
|
|
|
79
79
|
### Method 2: Auto-import with Resolver
|
|
@@ -270,7 +270,7 @@ All icons support CSS custom properties for advanced styling:
|
|
|
270
270
|
|
|
271
271
|
## Available Icons
|
|
272
272
|
|
|
273
|
-
The library includes **
|
|
273
|
+
The library includes **840+ carefully** covering all common use cases:
|
|
274
274
|
|
|
275
275
|
### Icon Naming Convention
|
|
276
276
|
|