Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/docs/src/pages/en/features/sass-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,18 @@ Your own styles will always<sup>*</sup> override vuetify's if you don't use `@la

\* Layers invert `!important`, so anything trying to override an important vuetify style must also be in a layer. { class="text-caption" }

You can also enable a layer for the vuetify theme by setting the `layer` option in your theme config:

```ts { resource="src/plugins/vuetify.ts" }
import { createVuetify } from 'vuetify'

export default createVuetify({
theme: {
layer: true,
},
})
```

## Caveats

When using sass variables, there are a few considerations to be aware of.
Expand Down
32 changes: 32 additions & 0 deletions packages/docs/src/pages/en/features/theme.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,38 @@ export default createVuetify({
})
```

## Theme layers

The layer option can be used to enable a [css cascade layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer) for the theme:

```ts { resource="src/plugins/vuetify.ts" }
import { createVuetify } from 'vuetify'

export default createVuetify({
theme: {
layer: true,
},
})
```

which generates the theme layer with two sub-layers (background and foreground):

```css
@layer vuetify.theme {
:root {
/* ... */
}

@layer background {
/* ... */
}

@layer foreground {
/* ... */
}
}
```

## Theme object structure

```ts
Expand Down
23 changes: 23 additions & 0 deletions packages/vuetify/src/composables/__tests__/theme.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,27 @@ describe('createTheme', () => {
expect(css).not.toContain('.text-primary')
expect(css).not.toContain('.border-primary')
})

it('should generate layer with default name if layer option is provided', async () => {
const theme = createTheme({ layer: true })

theme.install(app)

const stylesheet = document.getElementById('vuetify-theme-stylesheet')
const css = stylesheet!.innerHTML

expect(css).toContain('@layer vuetify.theme {')
expect(css).toContain('}')
})

it('should not generate a layer if disabled', async () => {
const theme = createTheme({ layer: false })

theme.install(app)

const stylesheet = document.getElementById('vuetify-theme-stylesheet')
const css = stylesheet!.innerHTML

expect(css).not.toMatch(/@layer vuetify-theme {/)
})
})
25 changes: 23 additions & 2 deletions packages/vuetify/src/composables/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export type ThemeOptions = false | {
stylesheetId?: string
scope?: string
unimportant?: boolean
layer?: boolean
}
export type ThemeDefinition = DeepPartial<InternalThemeDefinition>

Expand All @@ -58,6 +59,7 @@ interface InternalThemeOptions {
scoped: boolean
unimportant: boolean
utilities: boolean
layer?: boolean | string
}

interface VariationsOptions {
Expand Down Expand Up @@ -419,10 +421,29 @@ export function createTheme (options?: ThemeOptions): ThemeInstance & { install:
}
}

lines.push(...bgLines, ...fgLines)
if (parsedOptions.layer) {
lines.push(
'@layer background {\n',
...bgLines.map(v => ` ${v}`),
'}\n',
'@layer foreground {\n',
...fgLines.map(v => ` ${v}`),
'}\n',
)
} else {
lines.push(...bgLines, ...fgLines)
}
}

let final = lines.map((str, i) => (i === 0 ? str : ` ${str}`)).join('')
if (parsedOptions.layer) {
final =
'@layer vuetify.theme {\n' +
lines.map(v => ` ${v}`).join('') +
'\n}'
}

return lines.map((str, i) => i === 0 ? str : ` ${str}`).join('')
return final
})

const themeClasses = toRef(() => parsedOptions.isDisabled ? undefined : `${parsedOptions.prefix}theme--${name.value}`)
Expand Down