Skip to content

Commit 35f90b9

Browse files
feat(module): add theme.defaultVariants option (#4400)
1 parent 836f748 commit 35f90b9

File tree

4 files changed

+77
-2
lines changed

4 files changed

+77
-2
lines changed

docs/content/1.getting-started/2.installation/1.nuxt.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,27 @@ export default defineNuxtConfig({
225225
This option adds the `transition-colors` class on components with hover or active states.
226226
::
227227

228+
### `theme.defaultVariants` :badge{label="Soon" class="align-text-top"}
229+
230+
Use the `theme.defaultVariants` option to override the default `color` and `size` variants for components.
231+
232+
- Default: `{ color: 'primary', size: 'md' }`{lang="ts-type"}
233+
234+
```ts [nuxt.config.ts]
235+
export default defineNuxtConfig({
236+
modules: ['@nuxt/ui'],
237+
css: ['~/assets/css/main.css'],
238+
ui: {
239+
theme: {
240+
defaultVariants: {
241+
color: 'neutral',
242+
size: 'sm'
243+
}
244+
}
245+
}
246+
})
247+
```
248+
228249
## Continuous Releases
229250

230251
Nuxt UI uses [pkg.pr.new](https://github.com/stackblitz-labs/pkg.pr.new) for continuous preview releases, providing developers with instant access to the latest features and bug fixes without waiting for official releases.

docs/content/1.getting-started/2.installation/2.vue.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,32 @@ export default defineConfig({
333333
This option adds the `transition-colors` class on components with hover or active states.
334334
::
335335

336+
### `theme.defaultVariants` :badge{label="Soon" class="align-text-top"}
337+
338+
Use the `theme.defaultVariants` option to override the default `color` and `size` variants for components.
339+
340+
- Default: `{ color: 'primary', size: 'md' }`{lang="ts-type"}
341+
342+
```ts [vite.config.ts]
343+
import { defineConfig } from 'vite'
344+
import vue from '@vitejs/plugin-vue'
345+
import ui from '@nuxt/ui/vite'
346+
347+
export default defineConfig({
348+
plugins: [
349+
vue(),
350+
ui({
351+
theme: {
352+
defaultVariants: {
353+
color: 'neutral',
354+
size: 'sm'
355+
}
356+
}
357+
})
358+
]
359+
})
360+
```
361+
336362
### `inertia`
337363

338364
Use the `inertia` option to enable compatibility with [Inertia.js](https://inertiajs.com/).

src/module.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import { name, version } from '../package.json'
66

77
export type * from './runtime/types'
88

9+
type Color = 'primary' | 'secondary' | 'success' | 'info' | 'warning' | 'error' | (string & {})
10+
type Size = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {})
11+
912
export interface ModuleOptions {
1013
/**
1114
* Prefix for components
@@ -38,14 +41,28 @@ export interface ModuleOptions {
3841
* @defaultValue `['primary', 'secondary', 'success', 'info', 'warning', 'error']`
3942
* @link https://ui.nuxt.com/getting-started/installation/nuxt#themecolors
4043
*/
41-
colors?: string[]
44+
colors?: Color[]
4245

4346
/**
4447
* Enable or disable transitions on components
4548
* @defaultValue `true`
4649
* @link https://ui.nuxt.com/getting-started/installation/nuxt#themetransitions
4750
*/
4851
transitions?: boolean
52+
53+
defaultVariants?: {
54+
/**
55+
* The default color variant to use for components
56+
* @defaultValue `'primary'`
57+
*/
58+
color?: Color
59+
60+
/**
61+
* The default size variant to use for components
62+
* @defaultValue `'md'`
63+
*/
64+
size?: Size
65+
}
4966
}
5067
}
5168

src/templates.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
2626
const template = (theme as any)[component]
2727
const result = typeof template === 'function' ? template(options) : template
2828

29+
// Override default variants from nuxt.config.ts
30+
if (result?.defaultVariants?.color && options.theme?.defaultVariants?.color) {
31+
result.defaultVariants.color = options.theme.defaultVariants.color
32+
}
33+
if (result?.defaultVariants?.size && options.theme?.defaultVariants?.size) {
34+
result.defaultVariants.size = options.theme.defaultVariants.size
35+
}
36+
2937
const variants = Object.entries(result.variants || {})
3038
.filter(([_, values]) => {
3139
const keys = Object.keys(values as Record<string, unknown>)
@@ -56,7 +64,10 @@ export function getTemplates(options: ModuleOptions, uiConfig: Record<string, an
5664
return [
5765
`import template from ${JSON.stringify(templatePath)}`,
5866
...generateVariantDeclarations(variants),
59-
`const result = typeof template === 'function' ? (template as Function)(${JSON.stringify(options, null, 2)}) : template`,
67+
`const options = ${JSON.stringify(options, null, 2)}`,
68+
`const result = typeof template === 'function' ? (template as Function)(options) : template`,
69+
`if (result?.defaultVariants?.color && options.theme?.defaultVariants?.color) result.defaultVariants.color = options.theme.defaultVariants.color`,
70+
`if (result?.defaultVariants?.size && options.theme?.defaultVariants?.size) result.defaultVariants.size = options.theme.defaultVariants.size`,
6071
`const theme = ${json}`,
6172
`export default result as typeof theme`
6273
].join('\n\n')

0 commit comments

Comments
 (0)