[Bug Report][3.4.1] Automatic color variations override manually defined colors
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 41k
- Forks
- 7.1k
- Avg merge
- 1d 21h
- Merged PRs (30d)
- 11
Description
Environment
Vuetify Version: 3.4.1
Vue Version: 3.3.8
Browsers: Chrome 119.0.0.0
OS: Mac OS 10.15.7
Steps to reproduce
- Define a custom theme:
const customTheme = {
dark: false,
colors: {
primary: '#00456c',
secondary: '#c8c8c8',
'primary-darken-1': '#f00',
},
}
- Use the custom theme and let vuetify create color variations:
export const vuetify = createVuetify({
theme: {
defaultTheme: 'customTheme',
themes: {
customTheme,
},
variations: {
colors: ['primary', 'secondary'],
darken: 2,
lighten: 2,
},
},
})
- Use the color variant
primary-darken-1on, for example, a button:
<v-btn color="primary-darken-1" class="mt-3">Hello world primary-darken-1!</v-btn><br />
The button will use the darkened primary color and not the manually defined primary-darken-1 color.
Expected Behavior
The manually defined color should be used. In the example the button background should be red.
Actual Behavior
The automatic color variation overrides the manually provided color. In the example the button background is a darker variant of the primary blue.
Reproduction Link (updated)
https://play.vuetifyjs.com/#...
Other comments
The cause of this is probably because there is no check if a color already exists in that line: https://github.com/vuetifyjs/vuetify/blob/master/packages/vuetify/src/composables/theme.ts#L228
for (const variation of (['lighten', 'darken'] as const)) {
const fn = variation === 'lighten' ? lighten : darken
for (const amount of createRange(parsedOptions.variations[variation], 1)) {
theme.colors[`${name}-${variation}-${amount}`] = RGBtoHex(fn(parseColor(color), amount))
}
}
This could be prevented by checking if the key already exists and only adding it if it isn't there already:
for (const variation of (['lighten', 'darken'] as const)) {
const fn = variation === 'lighten' ? lighten : darken
for (const amount of createRange(parsedOptions.variations[variation], 1)) {
const colorkey = `${name}-${variation}-${amount}`
if(!(colorkey in theme.colors)){
theme.colors[colorkey] = RGBtoHex(fn(parseColor(color), amount))
}
}
}
My use-case for that is using the color variations as a default but also being able to override some variations with colors from a user customizable theme.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/vuetify/src/composables/theme.ts around line 228 and reproduce the issue with the customTheme and variations configuration from the report. Verify that an explicitly defined primary-darken-1 color is preserved instead of being replaced by the generated variation, using the linked reproduction to confirm the button background.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- design, frontend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100