Upgrade theme calls so merged values from v3 are included
This is done purely for backwards compatability and is intentionally NOT done when requesting a theme value using the CSS property syntax. e.g. `theme(“--accent-color”)`
This commit is contained in:
parent
c763a7799c
commit
b9f618b11c
2 changed files with 126 additions and 4 deletions
|
|
@ -21,10 +21,37 @@ export function buildPluginApi(designSystem: DesignSystem) {
|
|||
// Replace camelCase with dashes
|
||||
.replace(/([a-z])([A-Z])/g, (_, a, b) => `${a}-${b.toLowerCase()}`)
|
||||
|
||||
// Prepend with `--` to match CSS variables
|
||||
original = `--${original}`
|
||||
// Perform an "upgrade" on the path so that, for example, a request for
|
||||
// accentColor merges values from --color-* and --accent-color-*
|
||||
let paths: string[] = []
|
||||
|
||||
let map = designSystem.theme.namespace(original as any)
|
||||
for (let prefix in themeUpgradeMap) {
|
||||
if (!original.startsWith(prefix)) continue
|
||||
|
||||
// This makes sure that:
|
||||
// `accent-color` is turned into `color`; AND
|
||||
// `accent-color-foo` is turned into `color-foo`
|
||||
let suffix = original.slice(prefix.length)
|
||||
|
||||
for (let upgrade of themeUpgradeMap[prefix]) {
|
||||
paths.push(upgrade + suffix)
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the original path is included last because it should take precedence
|
||||
paths.push(original)
|
||||
|
||||
let map = new Map<string | null, string>()
|
||||
|
||||
for (let path of paths) {
|
||||
let ns = designSystem.theme.namespace(`--${path}` as any)
|
||||
|
||||
for (let [key, value] of ns) {
|
||||
map.set(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
// Now we've got the "upgraded" list of theme values let's look for the requested value
|
||||
|
||||
// Does the requested value exist in the theme
|
||||
if (map.has(null)) {
|
||||
|
|
@ -51,3 +78,56 @@ export function buildPluginApi(designSystem: DesignSystem) {
|
|||
}
|
||||
}
|
||||
|
||||
let themeUpgradeMap: Record<string, string[]> = {
|
||||
'accent-color': ['color'],
|
||||
'backdrop-blur': ['blur'],
|
||||
'backdrop-brightness': ['brightness'],
|
||||
'backdrop-contrast': ['contrast'],
|
||||
'backdrop-grayscale': ['grayscale'],
|
||||
'backdrop-hue-rotate': ['hue-rotate'],
|
||||
'backdrop-invert': ['invert'],
|
||||
'backdrop-opacity': ['opacity'],
|
||||
'backdrop-saturate': ['saturate'],
|
||||
'backdrop-sepia': ['sepia'],
|
||||
'background-color': ['color'],
|
||||
'background-opacity': ['opacity'],
|
||||
'border-color': ['color'],
|
||||
'border-opacity': ['opacity'],
|
||||
'border-spacing': ['spacing'],
|
||||
'box-shadow-color': ['color'],
|
||||
'caret-color': ['color'],
|
||||
colors: ['color'],
|
||||
'divide-color': ['border-color', 'color'],
|
||||
'divide-opacity': ['border-opacity', 'opacity'],
|
||||
'divide-width': ['border-width'],
|
||||
fill: ['color'],
|
||||
'flex-basis': ['spacing'],
|
||||
gap: ['spacing'],
|
||||
'gradient-color-stops': ['color'],
|
||||
height: ['spacing'],
|
||||
inset: ['spacing'],
|
||||
margin: ['spacing'],
|
||||
'max-height': ['spacing'],
|
||||
'max-width': ['spacing', 'breakpoint'],
|
||||
'min-height': ['spacing'],
|
||||
'min-width': ['spacing'],
|
||||
'outline-color': ['color'],
|
||||
padding: ['spacing'],
|
||||
'placeholder-color': ['color'],
|
||||
'placeholder-opacity': ['opacity'],
|
||||
'ring-color': ['color'],
|
||||
'ring-offset-color': ['color'],
|
||||
'ring-opacity': ['opacity'],
|
||||
screens: ['breakpoint'],
|
||||
'scroll-margin': ['spacing'],
|
||||
'scroll-padding': ['spacing'],
|
||||
space: ['spacing'],
|
||||
stroke: ['color'],
|
||||
'text-color': ['color'],
|
||||
'text-decoration-color': ['color'],
|
||||
'text-indent': ['spacing'],
|
||||
'text-opacity': ['opacity'],
|
||||
translate: ['spacing'],
|
||||
size: ['spacing'],
|
||||
width: ['spacing'],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15162,7 +15162,7 @@ describe('theme function in plugins', () => {
|
|||
|
||||
--scrollbar-color-light: white;
|
||||
--scrollbar-color-dark: black;
|
||||
},
|
||||
}
|
||||
`
|
||||
|
||||
test('CSS property notation', () => {
|
||||
|
|
@ -15235,4 +15235,46 @@ describe('theme function in plugins', () => {
|
|||
},
|
||||
})
|
||||
})
|
||||
|
||||
test('path upgrades', () => {
|
||||
expect.hasAssertions()
|
||||
|
||||
let input = css`
|
||||
@plugin "my-plugin";
|
||||
@theme reference {
|
||||
--color-100: red;
|
||||
--color-200: green;
|
||||
--color-300: blue;
|
||||
--accent-color-100: cyan;
|
||||
}
|
||||
`
|
||||
|
||||
compile(input, {
|
||||
loadPlugin() {
|
||||
return ({ theme }) => {
|
||||
expect(theme('accentColor')).toEqual({
|
||||
// Values from --color-* and --accent-color-* are merged into one object
|
||||
// with the values from --accent-color-* taking precedence
|
||||
100: 'cyan',
|
||||
200: 'green',
|
||||
300: 'blue',
|
||||
})
|
||||
|
||||
// This one is defined on --accent-color-* so it is found directly
|
||||
expect(theme('accentColor.100')).toEqual('cyan')
|
||||
|
||||
// This one is defined in --color-* so the value is taken from there
|
||||
expect(theme('accentColor.200')).toEqual('green')
|
||||
|
||||
// The CSS property syntax is NOT upgraded
|
||||
expect(theme('--accent-color-*')).toEqual({
|
||||
100: 'cyan',
|
||||
})
|
||||
|
||||
expect(theme('--accent-color-100')).toEqual('cyan')
|
||||
expect(theme('--accent-color-200')).toEqual(null)
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue