@maz-ui/mcp 4.0.0-beta.26
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/LICENSE +21 -0
- package/README.md +264 -0
- package/bin/maz-ui-mcp.mjs +7 -0
- package/dist/mcp.d.mts +13 -0
- package/dist/mcp.d.ts +13 -0
- package/dist/mcp.mjs +586 -0
- package/docs/generated-docs/maz-accordion.doc.md +21 -0
- package/docs/generated-docs/maz-animated-counter.doc.md +17 -0
- package/docs/generated-docs/maz-animated-element.doc.md +14 -0
- package/docs/generated-docs/maz-animated-text.doc.md +14 -0
- package/docs/generated-docs/maz-avatar.doc.md +44 -0
- package/docs/generated-docs/maz-backdrop.doc.md +61 -0
- package/docs/generated-docs/maz-badge.doc.md +16 -0
- package/docs/generated-docs/maz-bottom-sheet.doc.md +21 -0
- package/docs/generated-docs/maz-btn.doc.md +30 -0
- package/docs/generated-docs/maz-card-spotlight.doc.md +16 -0
- package/docs/generated-docs/maz-card.doc.md +39 -0
- package/docs/generated-docs/maz-carousel.doc.md +16 -0
- package/docs/generated-docs/maz-chart.doc.md +10 -0
- package/docs/generated-docs/maz-checkbox.doc.md +34 -0
- package/docs/generated-docs/maz-checklist.doc.md +30 -0
- package/docs/generated-docs/maz-circular-progress-bar.doc.md +27 -0
- package/docs/generated-docs/maz-date-picker.doc.md +52 -0
- package/docs/generated-docs/maz-dialog-confirm.doc.md +24 -0
- package/docs/generated-docs/maz-dialog.doc.md +22 -0
- package/docs/generated-docs/maz-drawer.doc.md +26 -0
- package/docs/generated-docs/maz-dropdown.doc.md +42 -0
- package/docs/generated-docs/maz-dropzone.doc.md +82 -0
- package/docs/generated-docs/maz-expand-animation.doc.md +12 -0
- package/docs/generated-docs/maz-fullscreen-loader.doc.md +13 -0
- package/docs/generated-docs/maz-gallery.doc.md +17 -0
- package/docs/generated-docs/maz-icon.doc.md +18 -0
- package/docs/generated-docs/maz-input-code.doc.md +25 -0
- package/docs/generated-docs/maz-input-number.doc.md +31 -0
- package/docs/generated-docs/maz-input-phone-number.doc.md +56 -0
- package/docs/generated-docs/maz-input-price.doc.md +26 -0
- package/docs/generated-docs/maz-input-tags.doc.md +24 -0
- package/docs/generated-docs/maz-input.doc.md +54 -0
- package/docs/generated-docs/maz-lazy-img.doc.md +31 -0
- package/docs/generated-docs/maz-link.doc.md +31 -0
- package/docs/generated-docs/maz-loading-bar.doc.md +6 -0
- package/docs/generated-docs/maz-pagination.doc.md +22 -0
- package/docs/generated-docs/maz-popover.doc.md +70 -0
- package/docs/generated-docs/maz-pull-to-refresh.doc.md +31 -0
- package/docs/generated-docs/maz-radio-buttons.doc.md +33 -0
- package/docs/generated-docs/maz-radio.doc.md +33 -0
- package/docs/generated-docs/maz-reading-progress-bar.doc.md +18 -0
- package/docs/generated-docs/maz-select-country.doc.md +44 -0
- package/docs/generated-docs/maz-select.doc.md +65 -0
- package/docs/generated-docs/maz-slider.doc.md +20 -0
- package/docs/generated-docs/maz-spinner.doc.md +6 -0
- package/docs/generated-docs/maz-stepper.doc.md +29 -0
- package/docs/generated-docs/maz-switch.doc.md +31 -0
- package/docs/generated-docs/maz-table-cell.doc.md +5 -0
- package/docs/generated-docs/maz-table-row.doc.md +11 -0
- package/docs/generated-docs/maz-table-title.doc.md +5 -0
- package/docs/generated-docs/maz-table.doc.md +66 -0
- package/docs/generated-docs/maz-tabs-bar.doc.md +18 -0
- package/docs/generated-docs/maz-tabs-content-item.doc.md +11 -0
- package/docs/generated-docs/maz-tabs-content.doc.md +5 -0
- package/docs/generated-docs/maz-tabs.doc.md +17 -0
- package/docs/generated-docs/maz-textarea.doc.md +41 -0
- package/docs/src/components/index.md +8 -0
- package/docs/src/components/maz-accordion.md +80 -0
- package/docs/src/components/maz-animated-counter.md +124 -0
- package/docs/src/components/maz-animated-element.md +36 -0
- package/docs/src/components/maz-animated-text.md +36 -0
- package/docs/src/components/maz-avatar.md +179 -0
- package/docs/src/components/maz-backdrop.md +16 -0
- package/docs/src/components/maz-badge.md +222 -0
- package/docs/src/components/maz-bottom-sheet.md +398 -0
- package/docs/src/components/maz-btn.md +526 -0
- package/docs/src/components/maz-card-spotlight.md +163 -0
- package/docs/src/components/maz-card.md +447 -0
- package/docs/src/components/maz-carousel.md +127 -0
- package/docs/src/components/maz-chart.md +346 -0
- package/docs/src/components/maz-checkbox.md +168 -0
- package/docs/src/components/maz-checklist.md +414 -0
- package/docs/src/components/maz-circular-progress-bar.md +147 -0
- package/docs/src/components/maz-date-picker.md +1078 -0
- package/docs/src/components/maz-dialog-confirm.md +240 -0
- package/docs/src/components/maz-dialog.md +208 -0
- package/docs/src/components/maz-drawer.md +177 -0
- package/docs/src/components/maz-dropdown.md +650 -0
- package/docs/src/components/maz-dropzone.md +442 -0
- package/docs/src/components/maz-expand-animation.md +99 -0
- package/docs/src/components/maz-fullscreen-loader.md +58 -0
- package/docs/src/components/maz-gallery.md +85 -0
- package/docs/src/components/maz-icon.md +85 -0
- package/docs/src/components/maz-input-code.md +61 -0
- package/docs/src/components/maz-input-number.md +81 -0
- package/docs/src/components/maz-input-phone-number.md +867 -0
- package/docs/src/components/maz-input-price.md +58 -0
- package/docs/src/components/maz-input-tags.md +114 -0
- package/docs/src/components/maz-input.md +453 -0
- package/docs/src/components/maz-lazy-img.md +24 -0
- package/docs/src/components/maz-link.md +156 -0
- package/docs/src/components/maz-loading-bar.md +26 -0
- package/docs/src/components/maz-pagination.md +81 -0
- package/docs/src/components/maz-popover.md +1414 -0
- package/docs/src/components/maz-pull-to-refresh.md +49 -0
- package/docs/src/components/maz-radio-buttons.md +456 -0
- package/docs/src/components/maz-radio.md +141 -0
- package/docs/src/components/maz-reading-progress-bar.md +74 -0
- package/docs/src/components/maz-select-country.md +636 -0
- package/docs/src/components/maz-select.md +439 -0
- package/docs/src/components/maz-slider.md +191 -0
- package/docs/src/components/maz-spinner.md +93 -0
- package/docs/src/components/maz-stepper.md +418 -0
- package/docs/src/components/maz-switch.md +92 -0
- package/docs/src/components/maz-table.md +571 -0
- package/docs/src/components/maz-tabs.md +231 -0
- package/docs/src/components/maz-textarea.md +218 -0
- package/docs/src/composables/use-aos.md +34 -0
- package/docs/src/composables/use-breakpoints.md +35 -0
- package/docs/src/composables/use-dialog.md +88 -0
- package/docs/src/composables/use-display-names.md +174 -0
- package/docs/src/composables/use-form-validator.md +1149 -0
- package/docs/src/composables/use-idle-timeout.md +256 -0
- package/docs/src/composables/use-reading-time.md +168 -0
- package/docs/src/composables/use-string-matching.md +63 -0
- package/docs/src/composables/use-swipe.md +223 -0
- package/docs/src/composables/use-timer.md +130 -0
- package/docs/src/composables/use-toast.md +71 -0
- package/docs/src/composables/use-user-visibility.md +169 -0
- package/docs/src/composables/use-wait.md +62 -0
- package/docs/src/composables/use-window-size.md +18 -0
- package/docs/src/demo/DemoAuthPage.vue +178 -0
- package/docs/src/demo/DemoDashboardPage.vue +298 -0
- package/docs/src/demo/DemoProductPage.vue +135 -0
- package/docs/src/directives/click-outside.md +275 -0
- package/docs/src/directives/fullscreen-img.md +101 -0
- package/docs/src/directives/lazy-img.md +184 -0
- package/docs/src/directives/tooltip.md +458 -0
- package/docs/src/directives/zoom-img.md +127 -0
- package/docs/src/guide/cli.md +144 -0
- package/docs/src/guide/getting-started.md +284 -0
- package/docs/src/guide/icon-set.md +60 -0
- package/docs/src/guide/icons.md +481 -0
- package/docs/src/guide/mcp.md +210 -0
- package/docs/src/guide/migration-v4.md +898 -0
- package/docs/src/guide/nuxt.md +411 -0
- package/docs/src/guide/resolvers.md +697 -0
- package/docs/src/guide/themes.md +789 -0
- package/docs/src/guide/translations.md +1173 -0
- package/docs/src/guide/vue.md +243 -0
- package/docs/src/helpers/camel-case.md +14 -0
- package/docs/src/helpers/capitalize.md +51 -0
- package/docs/src/helpers/check-availability.md +14 -0
- package/docs/src/helpers/country-code-to-unicode-flag.md +213 -0
- package/docs/src/helpers/currency.md +67 -0
- package/docs/src/helpers/date.md +67 -0
- package/docs/src/helpers/debounce-callback.md +14 -0
- package/docs/src/helpers/debounce-id.md +14 -0
- package/docs/src/helpers/debounce.md +14 -0
- package/docs/src/helpers/get-country-flag-url.md +156 -0
- package/docs/src/helpers/is-client.md +14 -0
- package/docs/src/helpers/is-equal.md +14 -0
- package/docs/src/helpers/is-standalone-mode.md +14 -0
- package/docs/src/helpers/kebab-case.md +14 -0
- package/docs/src/helpers/normalize-string.md +14 -0
- package/docs/src/helpers/number.md +65 -0
- package/docs/src/helpers/pascal-case.md +14 -0
- package/docs/src/helpers/script-loader.md +14 -0
- package/docs/src/helpers/sleep.md +14 -0
- package/docs/src/helpers/snake-case.md +14 -0
- package/docs/src/helpers/throttle-id.md +14 -0
- package/docs/src/helpers/throttle.md +14 -0
- package/docs/src/index.md +555 -0
- package/docs/src/made-with-maz-ui.md +58 -0
- package/docs/src/plugins/aos.md +347 -0
- package/docs/src/plugins/dialog.md +411 -0
- package/docs/src/plugins/toast.md +349 -0
- package/docs/src/plugins/wait.md +109 -0
- package/package.json +84 -0
|
@@ -0,0 +1,789 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Theming
|
|
3
|
+
description: Modern and performant theme system for Maz-UI with TypeScript, HSL CSS variables and flexible strategies.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# {{ $frontmatter.title }}
|
|
7
|
+
|
|
8
|
+
{{ $frontmatter.description }}
|
|
9
|
+
|
|
10
|
+
<NpmBadge package="@maz-ui/themes"></NpmBadge>
|
|
11
|
+
|
|
12
|
+
## ✨ Features
|
|
13
|
+
|
|
14
|
+
- 🎨 **Modern HSL CSS Variables** - Maximum flexibility with colors
|
|
15
|
+
- 🌓 **Smart Dark Mode** - Automatic support with `prefers-color-scheme`
|
|
16
|
+
- 🚀 **Automatic Generation** - Color scales (50-950) created automatically
|
|
17
|
+
- ⚡ **Performance Strategies** - Runtime, build-time or hybrid according to your needs
|
|
18
|
+
- 🛡️ **Strict TypeScript** - Complete types for perfect DX
|
|
19
|
+
- 🎯 **Zero FOUC** - Critical CSS injected inline to avoid flashes
|
|
20
|
+
- 🔧 **Flexible Presets** - Ready-to-use and customizable configurations
|
|
21
|
+
|
|
22
|
+
## Quick Usage
|
|
23
|
+
|
|
24
|
+
### 1. Plugin Configuration with `MazUi` plugin
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// main.ts
|
|
28
|
+
import { MazUi } from 'maz-ui/plugins/maz-ui'
|
|
29
|
+
import { mazUi } from '@maz-ui/themes/presets/mazUi'
|
|
30
|
+
import { createApp } from 'vue'
|
|
31
|
+
|
|
32
|
+
const app = createApp(App)
|
|
33
|
+
|
|
34
|
+
app.use(MazUi, {
|
|
35
|
+
theme: {
|
|
36
|
+
preset: mazUi, // pristine | ocean | obsidian
|
|
37
|
+
strategy: 'hybrid', // 'runtime' | 'buildtime' | 'hybrid'
|
|
38
|
+
darkModeStrategy: 'class', // 'class' | 'media' (only if mode is `both`)
|
|
39
|
+
mode: 'both', // 'light' | 'dark' | 'both' (supported color modes)
|
|
40
|
+
colorMode: 'auto', // 'auto' | 'light' | 'dark' (initial color mode, only if mode is 'both')
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. Setup your CSS to support theme foundation and dark mode
|
|
46
|
+
|
|
47
|
+
```css
|
|
48
|
+
html {
|
|
49
|
+
font-size: var(--maz-base-font-size);
|
|
50
|
+
font-family: var(--maz-font-family);
|
|
51
|
+
background-color: hsl(var(--maz-background));
|
|
52
|
+
color: hsl(var(--maz-foreground));
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. Using in your components
|
|
57
|
+
|
|
58
|
+
```vue
|
|
59
|
+
<script setup>
|
|
60
|
+
import { useTheme } from '@maz-ui/themes'
|
|
61
|
+
|
|
62
|
+
const { toggleDarkMode, isDark, updateTheme } = useTheme()
|
|
63
|
+
</script>
|
|
64
|
+
|
|
65
|
+
<template>
|
|
66
|
+
<div class="maz-bg-background maz-text-foreground">
|
|
67
|
+
<button
|
|
68
|
+
class="maz-rounded maz-bg-primary maz-text-primary-foreground"
|
|
69
|
+
@click="toggleDarkMode"
|
|
70
|
+
>
|
|
71
|
+
{{ isDark ? '☀️' : '🌙' }} Toggle theme
|
|
72
|
+
</button>
|
|
73
|
+
</div>
|
|
74
|
+
</template>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Configuration
|
|
78
|
+
|
|
79
|
+
- `preset`: The theme preset to use
|
|
80
|
+
- `overrides` (optional): Override specific parts of the theme
|
|
81
|
+
- `strategy` (optional): The rendering strategy to use
|
|
82
|
+
- `darkModeStrategy` (optional): The dark mode strategy to use, only if you use mode `both`
|
|
83
|
+
- `mode` (optional): The supported color modes to use (light, dark, both)
|
|
84
|
+
- `colorMode` (optional): The initial color mode to use (only if mode is 'both')
|
|
85
|
+
|
|
86
|
+
## Interactive Demo
|
|
87
|
+
|
|
88
|
+
<ComponentDemo title="Real-time theme control">
|
|
89
|
+
<div class="demo-theme-controls">
|
|
90
|
+
<div class="maz-space-y-4">
|
|
91
|
+
<div class="maz-grid maz-grid-cols-1 md:maz-grid-cols-2 maz-gap-4">
|
|
92
|
+
<MazBtn color="primary">Primary Button</MazBtn>
|
|
93
|
+
<MazBtn color="secondary">Secondary Button</MazBtn>
|
|
94
|
+
<MazBtn color="success">Success Button</MazBtn>
|
|
95
|
+
<MazBtn color="warning">Warning Button</MazBtn>
|
|
96
|
+
</div>
|
|
97
|
+
<div class="theme-controls maz-space-y-4">
|
|
98
|
+
<div class="maz-flex maz-flex-col maz-gap-4">
|
|
99
|
+
<label class="maz-text-sm maz-font-medium">Color Mode: {{ colorMode }}</label>
|
|
100
|
+
<div class="maz-flex maz-gap-2">
|
|
101
|
+
<MazBtn
|
|
102
|
+
size="sm"
|
|
103
|
+
:color="colorMode === 'light' ? 'primary' : 'contrast'"
|
|
104
|
+
@click="setColorMode('light')"
|
|
105
|
+
>
|
|
106
|
+
☀️ Light
|
|
107
|
+
</MazBtn>
|
|
108
|
+
<MazBtn
|
|
109
|
+
size="sm"
|
|
110
|
+
:color="colorMode === 'dark' ? 'primary' : 'contrast'"
|
|
111
|
+
@click="setColorMode('dark')"
|
|
112
|
+
>
|
|
113
|
+
🌙 Dark
|
|
114
|
+
</MazBtn>
|
|
115
|
+
<MazBtn
|
|
116
|
+
size="sm"
|
|
117
|
+
:color="colorMode === 'auto' ? 'primary' : 'contrast'"
|
|
118
|
+
@click="setColorMode('auto')"
|
|
119
|
+
>
|
|
120
|
+
🔄 Auto
|
|
121
|
+
</MazBtn>
|
|
122
|
+
</div>
|
|
123
|
+
</div>
|
|
124
|
+
<div class="maz-space-y-2">
|
|
125
|
+
<label class="maz-text-sm maz-font-medium">Preset:</label>
|
|
126
|
+
<div class="maz-flex maz-gap-2">
|
|
127
|
+
<MazBtn
|
|
128
|
+
size="sm"
|
|
129
|
+
:color="presetName === 'maz-ui' ? 'primary' : 'contrast'"
|
|
130
|
+
@click="updateTheme('maz-ui')"
|
|
131
|
+
>
|
|
132
|
+
Maz-UI
|
|
133
|
+
</MazBtn>
|
|
134
|
+
<MazBtn
|
|
135
|
+
size="sm"
|
|
136
|
+
:color="presetName === 'ocean' ? 'primary' : 'contrast'"
|
|
137
|
+
@click="updateTheme('ocean')"
|
|
138
|
+
>
|
|
139
|
+
Ocean
|
|
140
|
+
</MazBtn>
|
|
141
|
+
<MazBtn
|
|
142
|
+
size="sm"
|
|
143
|
+
:color="presetName === 'pristine' ? 'primary' : 'contrast'"
|
|
144
|
+
@click="updateTheme('pristine')"
|
|
145
|
+
>
|
|
146
|
+
Pristine
|
|
147
|
+
</MazBtn>
|
|
148
|
+
<MazBtn
|
|
149
|
+
size="sm"
|
|
150
|
+
:color="presetName === 'obsidian' ? 'primary' : 'contrast'"
|
|
151
|
+
@click="updateTheme('obsidian')"
|
|
152
|
+
>
|
|
153
|
+
Obsidian
|
|
154
|
+
</MazBtn>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
<template #code>
|
|
162
|
+
|
|
163
|
+
```vue
|
|
164
|
+
<script setup>
|
|
165
|
+
import { useTheme } from '@maz-ui/themes'
|
|
166
|
+
|
|
167
|
+
const { presetName, updateTheme, colorMode, setColorMode } = useTheme()
|
|
168
|
+
</script>
|
|
169
|
+
|
|
170
|
+
<template>
|
|
171
|
+
<div class="demo-theme-controls">
|
|
172
|
+
<div class="maz-space-y-4">
|
|
173
|
+
<div class="maz-grid maz-grid-cols-1 md:maz-grid-cols-2 maz-gap-4">
|
|
174
|
+
<MazBtn color="primary">Primary Button</MazBtn>
|
|
175
|
+
<MazBtn color="secondary">Secondary Button</MazBtn>
|
|
176
|
+
<MazBtn color="success">Success Button</MazBtn>
|
|
177
|
+
<MazBtn color="warning">Warning Button</MazBtn>
|
|
178
|
+
</div>
|
|
179
|
+
<div class="theme-controls maz-space-y-4">
|
|
180
|
+
<div class="maz-flex maz-items-center maz-gap-4">
|
|
181
|
+
<label class="maz-text-sm maz-font-medium">Mode:</label>
|
|
182
|
+
<MazBtn
|
|
183
|
+
size="sm"
|
|
184
|
+
:color="colorMode === 'light' ? 'primary' : 'secondary'"
|
|
185
|
+
@click="setColorMode('light')"
|
|
186
|
+
>
|
|
187
|
+
☀️ Light
|
|
188
|
+
</MazBtn>
|
|
189
|
+
<MazBtn
|
|
190
|
+
size="sm"
|
|
191
|
+
:color="colorMode === 'dark' ? 'primary' : 'secondary'"
|
|
192
|
+
@click="setColorMode('dark')"
|
|
193
|
+
>
|
|
194
|
+
🌙 Dark
|
|
195
|
+
</MazBtn>
|
|
196
|
+
<MazBtn
|
|
197
|
+
size="sm"
|
|
198
|
+
:color="colorMode === 'auto' ? 'primary' : 'secondary'"
|
|
199
|
+
@click="setColorMode('auto')"
|
|
200
|
+
>
|
|
201
|
+
🔄 Auto
|
|
202
|
+
</MazBtn>
|
|
203
|
+
</div>
|
|
204
|
+
<div class="maz-space-y-2">
|
|
205
|
+
<label class="maz-text-sm maz-font-medium">Preset:</label>
|
|
206
|
+
<div class="maz-flex maz-gap-2">
|
|
207
|
+
<MazBtn
|
|
208
|
+
size="sm"
|
|
209
|
+
:color="presetName === 'maz-ui' ? 'primary' : 'secondary'"
|
|
210
|
+
@click="updateTheme('mazUi')"
|
|
211
|
+
>
|
|
212
|
+
Maz-UI
|
|
213
|
+
</MazBtn>
|
|
214
|
+
<MazBtn
|
|
215
|
+
size="sm"
|
|
216
|
+
:color="presetName === 'ocean' ? 'primary' : 'secondary'"
|
|
217
|
+
@click="updateTheme('ocean')"
|
|
218
|
+
>
|
|
219
|
+
Ocean
|
|
220
|
+
</MazBtn>
|
|
221
|
+
<MazBtn
|
|
222
|
+
size="sm"
|
|
223
|
+
:color="presetName === 'pristine' ? 'primary' : 'secondary'"
|
|
224
|
+
@click="updateTheme('pristine')"
|
|
225
|
+
>
|
|
226
|
+
Pristine
|
|
227
|
+
</MazBtn>
|
|
228
|
+
<MazBtn
|
|
229
|
+
size="sm"
|
|
230
|
+
:color="presetName === 'obsidian' ? 'primary' : 'secondary'"
|
|
231
|
+
@click="updateTheme('obsidian')"
|
|
232
|
+
>
|
|
233
|
+
Obsidian
|
|
234
|
+
</MazBtn>
|
|
235
|
+
</div>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
</div>
|
|
239
|
+
</div>
|
|
240
|
+
</template>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
</template>
|
|
244
|
+
</ComponentDemo>
|
|
245
|
+
|
|
246
|
+
## Available Presets
|
|
247
|
+
|
|
248
|
+
### Maz-UI (Default)
|
|
249
|
+
|
|
250
|
+
The default theme inspired by Maz-UI identity with vibrant and modern colors.
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
import { mazUi } from '@maz-ui/themes/presets'
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Pristine
|
|
257
|
+
|
|
258
|
+
A minimalist and elegant theme inspired by Apple design with pure black and white aesthetics.
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
import { pristine } from '@maz-ui/themes/presets'
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### Ocean
|
|
265
|
+
|
|
266
|
+
A vibrant ocean-inspired theme with deep blues, aquatic greens, and coral accents. Features rounded borders and Poppins font for a fresh, modern look.
|
|
267
|
+
|
|
268
|
+
```typescript
|
|
269
|
+
import { ocean } from '@maz-ui/themes/presets'
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Obsidian
|
|
273
|
+
|
|
274
|
+
A dark and elegant theme with a focus on readability and minimalism.
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { obsidian } from '@maz-ui/themes/presets'
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Rendering Strategies
|
|
281
|
+
|
|
282
|
+
### 🚀 Hybrid (Recommended)
|
|
283
|
+
|
|
284
|
+
The hybrid strategy combines the best of both worlds:
|
|
285
|
+
|
|
286
|
+
- **Critical CSS injected immediately** - Prevents FOUC (Flash of Unstyled Content)
|
|
287
|
+
- **Full CSS loaded asynchronously** - Uses `requestIdleCallback` to avoid blocking the main thread
|
|
288
|
+
- **Optimal performance** - Balance between display speed and interface fluidity
|
|
289
|
+
|
|
290
|
+
The full CSS is injected via `requestIdleCallback` with a 100ms timeout, allowing the browser to prioritize critical tasks while ensuring fast loading of complete styling.
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
app.use(MazUi, {
|
|
294
|
+
theme: {
|
|
295
|
+
preset: 'maz-ui',
|
|
296
|
+
strategy: 'hybrid'
|
|
297
|
+
}
|
|
298
|
+
})
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### ⚡ Runtime
|
|
302
|
+
|
|
303
|
+
CSS generated (critical and full) injected immediately.
|
|
304
|
+
|
|
305
|
+
**⚠️ Potential risks:**
|
|
306
|
+
- **Main thread blocking** - Immediate injection can impact performance
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
app.use(MazUi, {
|
|
310
|
+
theme: {
|
|
311
|
+
preset: 'maz-ui',
|
|
312
|
+
strategy: 'runtime'
|
|
313
|
+
}
|
|
314
|
+
})
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### 🏗️ Buildtime
|
|
318
|
+
|
|
319
|
+
CSS generated at build-time and included in the bundle.
|
|
320
|
+
Optimal for static sites without theme changes.
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
app.use(MazUi, {
|
|
324
|
+
theme: {
|
|
325
|
+
preset: 'maz-ui',
|
|
326
|
+
strategy: 'buildtime'
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Creating Custom Themes
|
|
332
|
+
|
|
333
|
+
### Basic Theme
|
|
334
|
+
|
|
335
|
+
<br />
|
|
336
|
+
|
|
337
|
+
<ComponentDemo title="Create your own theme">
|
|
338
|
+
<MazBtn @click="applyCustomTheme" color="info">
|
|
339
|
+
Apply Custom Theme
|
|
340
|
+
</MazBtn>
|
|
341
|
+
<MazBtn @click="resetTheme" color="secondary" class="maz-ml-2">
|
|
342
|
+
Reset
|
|
343
|
+
</MazBtn>
|
|
344
|
+
|
|
345
|
+
<div class="maz-mt-4 maz-p-4 maz-bg-primary/10 maz-rounded-[var(--maz-radius)]">
|
|
346
|
+
<p v-if="presetName === 'custom-purple'" class="maz-text-primary maz-font-medium">
|
|
347
|
+
Custom theme applied with purple colors!
|
|
348
|
+
</p>
|
|
349
|
+
<p v-else class="maz-text-primary maz-font-medium">
|
|
350
|
+
Default theme
|
|
351
|
+
</p>
|
|
352
|
+
</div>
|
|
353
|
+
|
|
354
|
+
<template #code>
|
|
355
|
+
|
|
356
|
+
```typescript
|
|
357
|
+
import { definePreset, MazUiTheme, type ThemePresetOverrides, ocean } from '@maz-ui/themes'
|
|
358
|
+
|
|
359
|
+
const customTheme = await definePreset({
|
|
360
|
+
base: 'ocean',
|
|
361
|
+
overrides: {
|
|
362
|
+
name: 'custom-purple',
|
|
363
|
+
foundation: {
|
|
364
|
+
radius: '1rem'
|
|
365
|
+
'font-family': 'Inter, sans-serif'
|
|
366
|
+
},
|
|
367
|
+
colors: {
|
|
368
|
+
light: {
|
|
369
|
+
primary: '280 100% 60%',
|
|
370
|
+
secondary: '300 50% 90%',
|
|
371
|
+
accent: '260 100% 70%'
|
|
372
|
+
},
|
|
373
|
+
dark: {
|
|
374
|
+
primary: '280 100% 70%',
|
|
375
|
+
secondary: '300 30% 20%',
|
|
376
|
+
accent: '260 100% 80%'
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
})
|
|
381
|
+
/**
|
|
382
|
+
* or with preset object
|
|
383
|
+
* The function is synchronous when using a preset object
|
|
384
|
+
*/
|
|
385
|
+
const customTheme = definePreset({
|
|
386
|
+
base: ocean,
|
|
387
|
+
overrides,
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
// Usage
|
|
391
|
+
|
|
392
|
+
// with plugin
|
|
393
|
+
app.use(MazUiTheme, {
|
|
394
|
+
preset: customTheme,
|
|
395
|
+
})
|
|
396
|
+
|
|
397
|
+
// or with composable
|
|
398
|
+
const { updateTheme } = useTheme()
|
|
399
|
+
updateTheme(customTheme)
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
</template>
|
|
403
|
+
</ComponentDemo>
|
|
404
|
+
|
|
405
|
+
### Advanced Theme with Overrides
|
|
406
|
+
|
|
407
|
+
```typescript
|
|
408
|
+
import { definePreset } from '@maz-ui/themes'
|
|
409
|
+
|
|
410
|
+
const brandTheme = await definePreset({
|
|
411
|
+
base: 'maz-ui',
|
|
412
|
+
overrides: {
|
|
413
|
+
name: 'brand',
|
|
414
|
+
foundation: {
|
|
415
|
+
'radius': '0.75rem',
|
|
416
|
+
'border-width': '2px',
|
|
417
|
+
'font-family': 'Inter, sans-serif'
|
|
418
|
+
},
|
|
419
|
+
colors: {
|
|
420
|
+
light: {
|
|
421
|
+
primary: '210 100% 50%',
|
|
422
|
+
secondary: '210 40% 96%',
|
|
423
|
+
background: '210 20% 98%',
|
|
424
|
+
accent: '280 100% 70%'
|
|
425
|
+
},
|
|
426
|
+
dark: {
|
|
427
|
+
primary: '210 100% 60%',
|
|
428
|
+
secondary: '210 40% 15%',
|
|
429
|
+
background: '210 20% 8%',
|
|
430
|
+
accent: '280 100% 80%'
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
})
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## useTheme Composable API
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
const {
|
|
441
|
+
// Reactive state
|
|
442
|
+
presetName, // ComputedRef<string>
|
|
443
|
+
colorMode, // ComputedRef<'light' | 'dark' | 'auto'>
|
|
444
|
+
isDark, // ComputedRef<boolean>
|
|
445
|
+
strategy, // ComputedRef<'runtime' | 'buildtime' | 'hybrid'>
|
|
446
|
+
|
|
447
|
+
// Actions
|
|
448
|
+
updateTheme, // (preset: ThemePreset | ThemePresetOverrides) => void
|
|
449
|
+
setColorMode, // (mode: 'light' | 'dark' | 'auto') => void
|
|
450
|
+
toggleDarkMode // () => void
|
|
451
|
+
} = useTheme()
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
### Advanced Usage Examples
|
|
455
|
+
|
|
456
|
+
```vue
|
|
457
|
+
<script setup>
|
|
458
|
+
import { useTheme } from '@maz-ui/themes'
|
|
459
|
+
import { computed } from 'vue'
|
|
460
|
+
|
|
461
|
+
const { presetName, isDark, updateTheme, setColorMode } = useTheme()
|
|
462
|
+
|
|
463
|
+
// Computed for interface
|
|
464
|
+
const themeIcon = computed(() => isDark.value ? '☀️' : '🌙')
|
|
465
|
+
|
|
466
|
+
// Function to apply a temporary custom theme
|
|
467
|
+
function previewColor(color: string) {
|
|
468
|
+
updateTheme({
|
|
469
|
+
colors: {
|
|
470
|
+
light: { primary: color },
|
|
471
|
+
dark: { primary: color }
|
|
472
|
+
}
|
|
473
|
+
})
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
// Auto mode with system detection
|
|
477
|
+
function enableAutoMode() {
|
|
478
|
+
setColorMode('auto')
|
|
479
|
+
}
|
|
480
|
+
</script>
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
## Build-time Strategy: Complete Guide
|
|
484
|
+
|
|
485
|
+
The build-time strategy allows you to generate your theme CSS files at compile time, offering the best performance in production.
|
|
486
|
+
|
|
487
|
+
### Step-by-step configuration
|
|
488
|
+
|
|
489
|
+
#### 1. Create a generation script
|
|
490
|
+
|
|
491
|
+
Create `scripts/build-themes.ts`:
|
|
492
|
+
|
|
493
|
+
```typescript
|
|
494
|
+
import { mkdirSync, writeFileSync } from 'node:fs'
|
|
495
|
+
import { join } from 'node:path'
|
|
496
|
+
import {
|
|
497
|
+
buildThemeCSS,
|
|
498
|
+
generateThemeBundle,
|
|
499
|
+
buildSeparateThemeFiles,
|
|
500
|
+
createThemeStylesheet,
|
|
501
|
+
definePreset,
|
|
502
|
+
mazUi,
|
|
503
|
+
} from '@maz-ui/themes'
|
|
504
|
+
|
|
505
|
+
// Custom theme
|
|
506
|
+
const customPreset = definePreset({
|
|
507
|
+
base: mazUi,
|
|
508
|
+
overrides: {
|
|
509
|
+
name: 'custom',
|
|
510
|
+
colors: {
|
|
511
|
+
light: { primary: '221.2 83.2% 53.3%' },
|
|
512
|
+
dark: { primary: '217.2 91.2% 59.8%' },
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
})
|
|
516
|
+
|
|
517
|
+
// Create destination folder
|
|
518
|
+
mkdirSync(join(process.cwd(), 'public/themes'), { recursive: true })
|
|
519
|
+
|
|
520
|
+
// Generate complete CSS
|
|
521
|
+
const customCSS = buildThemeCSS({
|
|
522
|
+
preset: customPreset,
|
|
523
|
+
mode: 'both',
|
|
524
|
+
criticalOnly: false,
|
|
525
|
+
})
|
|
526
|
+
|
|
527
|
+
writeFileSync(join(process.cwd(), 'public/themes/custom.css'), customCSS)
|
|
528
|
+
|
|
529
|
+
// Generate bundle for multiple themes
|
|
530
|
+
const themeBundle = generateThemeBundle([customPreset, mazUi], {
|
|
531
|
+
mode: 'both',
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
Object.entries(themeBundle).forEach(([name, css]) => {
|
|
535
|
+
writeFileSync(join(process.cwd(), `public/themes/${name}.css`), css)
|
|
536
|
+
})
|
|
537
|
+
|
|
538
|
+
console.log('✅ Themes generated in public/themes/')
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
#### 2. Add script to package.json
|
|
542
|
+
|
|
543
|
+
```json
|
|
544
|
+
{
|
|
545
|
+
"scripts": {
|
|
546
|
+
"build:themes": "tsx scripts/build-themes.ts",
|
|
547
|
+
"build": "npm run build:themes && vite build"
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
#### 3. Include in your HTML
|
|
553
|
+
|
|
554
|
+
```html
|
|
555
|
+
<!-- Critical CSS first -->
|
|
556
|
+
<link rel="stylesheet" href="/themes/custom-critical.css">
|
|
557
|
+
|
|
558
|
+
<!-- Full CSS deferred -->
|
|
559
|
+
<link rel="stylesheet" href="/themes/custom-full.css" media="print" onload="this.media='all'">
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
#### 4. Plugin configuration
|
|
563
|
+
|
|
564
|
+
```typescript
|
|
565
|
+
app.use(MazThemePlugin, {
|
|
566
|
+
strategy: 'buildtime', // Important!
|
|
567
|
+
darkModeStrategy: 'class',
|
|
568
|
+
})
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### Utility functions
|
|
572
|
+
|
|
573
|
+
#### `buildThemeCSS(options)`
|
|
574
|
+
|
|
575
|
+
Generates complete CSS for a theme.
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
const css = buildThemeCSS({
|
|
579
|
+
preset: customPreset,
|
|
580
|
+
mode: 'both', // 'light' | 'dark' | 'both'
|
|
581
|
+
darkSelector: 'class', // 'class' | 'media'
|
|
582
|
+
criticalOnly: false, // true for critical CSS only
|
|
583
|
+
})
|
|
584
|
+
```
|
|
585
|
+
|
|
586
|
+
#### `generateThemeBundle(presets, options)`
|
|
587
|
+
|
|
588
|
+
Generates a bundle containing multiple themes.
|
|
589
|
+
|
|
590
|
+
```typescript
|
|
591
|
+
const bundle = generateThemeBundle([theme1, theme2], {
|
|
592
|
+
mode: 'both',
|
|
593
|
+
darkSelector: 'class',
|
|
594
|
+
})
|
|
595
|
+
// Result: { 'theme1': 'css...', 'theme2': 'css...' }
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
#### `buildSeparateThemeFiles(preset, options)`
|
|
599
|
+
|
|
600
|
+
Generates separate files for different use cases.
|
|
601
|
+
|
|
602
|
+
```typescript
|
|
603
|
+
const files = buildSeparateThemeFiles(preset)
|
|
604
|
+
// Result: { critical, full, lightOnly, darkOnly }
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
#### `createThemeStylesheet(css, options)`
|
|
608
|
+
|
|
609
|
+
Creates a `<style>` tag with the provided CSS.
|
|
610
|
+
|
|
611
|
+
```typescript
|
|
612
|
+
const styleTag = createThemeStylesheet(css, {
|
|
613
|
+
id: 'my-theme',
|
|
614
|
+
media: 'screen', // optional
|
|
615
|
+
})
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### Build-time strategy advantages
|
|
619
|
+
|
|
620
|
+
- **Optimal performance** - No client-side CSS generation
|
|
621
|
+
- **Efficient caching** - CSS files cached by CDN
|
|
622
|
+
- **Reduced bundle** - Generation utilities excluded from client
|
|
623
|
+
- **Full compatibility** - Works even with JavaScript disabled
|
|
624
|
+
|
|
625
|
+
### Recommended use cases
|
|
626
|
+
|
|
627
|
+
- Production applications with static themes
|
|
628
|
+
- Sites with critical performance requirements
|
|
629
|
+
- Projects with multiple predefined themes
|
|
630
|
+
- Applications requiring fine control over CSS loading
|
|
631
|
+
|
|
632
|
+
## Generated CSS Variables
|
|
633
|
+
|
|
634
|
+
The system automatically generates all necessary variables:
|
|
635
|
+
|
|
636
|
+
### Base Variables
|
|
637
|
+
|
|
638
|
+
```css
|
|
639
|
+
:root {
|
|
640
|
+
/* Main colors */
|
|
641
|
+
--maz-primary: 210 100% 56%;
|
|
642
|
+
--maz-primary-foreground: 0 0% 100%;
|
|
643
|
+
--maz-secondary: 164 76% 46%;
|
|
644
|
+
--maz-background: 0 0% 100%;
|
|
645
|
+
--maz-foreground: 210 8% 14%;
|
|
646
|
+
|
|
647
|
+
/* Design tokens */
|
|
648
|
+
--maz-radius: 0.7rem;
|
|
649
|
+
--maz-border-width: 0.063rem;
|
|
650
|
+
--maz-font-family: Manrope, sans-serif;
|
|
651
|
+
}
|
|
652
|
+
```
|
|
653
|
+
|
|
654
|
+
### Automatic Color Scales
|
|
655
|
+
|
|
656
|
+
```css
|
|
657
|
+
:root {
|
|
658
|
+
/* Primary scale generated automatically */
|
|
659
|
+
--maz-primary-50: 210 100% 95%;
|
|
660
|
+
--maz-primary-100: 210 100% 87%;
|
|
661
|
+
--maz-primary-200: 210 100% 79%;
|
|
662
|
+
/* ... up to 900 */
|
|
663
|
+
--maz-primary-900: 210 79% 17%;
|
|
664
|
+
}
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
### Dark Mode
|
|
668
|
+
|
|
669
|
+
```css
|
|
670
|
+
.dark {
|
|
671
|
+
--maz-background: 235 16% 15%;
|
|
672
|
+
--maz-foreground: 0 0% 85%;
|
|
673
|
+
/* Variables automatically adapted */
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/* Or with media query */
|
|
677
|
+
@media (prefers-color-scheme: dark) {
|
|
678
|
+
:root {
|
|
679
|
+
--maz-background: 235 16% 15%;
|
|
680
|
+
--maz-foreground: 0 0% 85%;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
```
|
|
684
|
+
|
|
685
|
+
## Usage with Nuxt
|
|
686
|
+
|
|
687
|
+
For Nuxt users, check the [dedicated Nuxt documentation](/guide/nuxt) which covers installation and framework-specific configuration.
|
|
688
|
+
|
|
689
|
+
## Migration from Legacy System
|
|
690
|
+
|
|
691
|
+
If you're using the legacy theme system with CLI:
|
|
692
|
+
|
|
693
|
+
::: code-group
|
|
694
|
+
|
|
695
|
+
```typescript [Before (CLI)]
|
|
696
|
+
// maz-ui.config.ts
|
|
697
|
+
export default defineConfig({
|
|
698
|
+
theme: {
|
|
699
|
+
colors: {
|
|
700
|
+
primary: 'hsl(210, 100%, 56%)',
|
|
701
|
+
secondary: 'hsl(164, 76%, 46%)'
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
})
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
```typescript [After (@maz-ui/themes)]
|
|
708
|
+
// main.ts
|
|
709
|
+
import { definePreset, mazUi } from '@maz-ui/themes'
|
|
710
|
+
|
|
711
|
+
const myTheme = definePreset({
|
|
712
|
+
base: mazUi,
|
|
713
|
+
overrides: {
|
|
714
|
+
colors: {
|
|
715
|
+
light: {
|
|
716
|
+
primary: '210 100% 56%',
|
|
717
|
+
secondary: '164 76% 46%'
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
})
|
|
722
|
+
|
|
723
|
+
app.use(MazThemePlugin, { preset: myTheme })
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
:::
|
|
727
|
+
|
|
728
|
+
The new system offers much more flexibility and performance!
|
|
729
|
+
|
|
730
|
+
<script setup>
|
|
731
|
+
import { useTheme } from '@maz-ui/themes/src/composables/useTheme.js'
|
|
732
|
+
import { definePreset } from '@maz-ui/themes/src/define-preset.js'
|
|
733
|
+
import { ref } from 'vue'
|
|
734
|
+
|
|
735
|
+
const {
|
|
736
|
+
isDark,
|
|
737
|
+
colorMode,
|
|
738
|
+
currentPreset,
|
|
739
|
+
setColorMode,
|
|
740
|
+
updateTheme,
|
|
741
|
+
presetName
|
|
742
|
+
} = useTheme()
|
|
743
|
+
|
|
744
|
+
const originalPresetName = ref(null)
|
|
745
|
+
|
|
746
|
+
const customPreset = await definePreset({
|
|
747
|
+
base: 'pristine',
|
|
748
|
+
overrides: {
|
|
749
|
+
name: 'custom-purple',
|
|
750
|
+
colors: {
|
|
751
|
+
light: {
|
|
752
|
+
'primary': '280 100% 60%',
|
|
753
|
+
'secondary': '300 50% 90%',
|
|
754
|
+
'accent': '260 100% 70%'
|
|
755
|
+
},
|
|
756
|
+
dark: {
|
|
757
|
+
'primary': '280 100% 70%',
|
|
758
|
+
'secondary': '300 30% 20%',
|
|
759
|
+
'accent': '260 100% 80%'
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
})
|
|
764
|
+
|
|
765
|
+
function applyCustomTheme() {
|
|
766
|
+
if (!originalPresetName.value) {
|
|
767
|
+
originalPresetName.value = presetName.value
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
updateTheme(customPreset)
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
function resetTheme() {
|
|
774
|
+
if (originalPresetName.value) {
|
|
775
|
+
updateTheme(originalPresetName.value)
|
|
776
|
+
originalPresetName.value = null
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
</script>
|
|
780
|
+
|
|
781
|
+
<style scoped>
|
|
782
|
+
.demo-theme-controls {
|
|
783
|
+
@apply maz-w-full;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.theme-controls {
|
|
787
|
+
@apply maz-border-t maz-border-divider maz-pt-4;
|
|
788
|
+
}
|
|
789
|
+
</style>
|