From 81e8540dd7842f817278ca9244b3ff7a76033b07 Mon Sep 17 00:00:00 2001 From: Yauheni Date: Tue, 16 May 2023 15:14:18 +0200 Subject: [PATCH 01/13] add @propery support --- packages/css/src/index.ts | 1 + packages/css/src/properties.ts | 46 ++++++++++++++++++++++++++++++++ packages/css/src/transformCss.ts | 15 +++++++++++ packages/css/src/types.ts | 28 ++++++++++++++++++- packages/css/src/vars.ts | 10 ++++--- 5 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 packages/css/src/properties.ts diff --git a/packages/css/src/index.ts b/packages/css/src/index.ts index 28937df8c..824099e8b 100644 --- a/packages/css/src/index.ts +++ b/packages/css/src/index.ts @@ -14,3 +14,4 @@ export * from './style'; export * from './vars'; export { createContainer } from './container'; export * from './layer'; +export * from './properties'; diff --git a/packages/css/src/properties.ts b/packages/css/src/properties.ts new file mode 100644 index 000000000..482648905 --- /dev/null +++ b/packages/css/src/properties.ts @@ -0,0 +1,46 @@ +import type { AtRule } from 'csstype'; + +import { appendCss } from './adapter'; +import { PropertySyntax } from './types'; +import { getFileScope } from './fileScope'; +import { generateIdentifier } from './identifier'; +import cssesc from 'cssesc'; +import {assertVarName} from './vars' + +type PropertyOptions = { + syntax: PropertySyntax | Array; + inherits: boolean; + initialValue?: string +}; + +const buildPropertyRule = ({ syntax, inherits, initialValue }: PropertyOptions): AtRule.Property => ({ + syntax: `"${Array.isArray(syntax) ? syntax.join(' | ') : syntax}"`, + inherits: inherits ? 'true' : 'false', + initialValue, +}) + +export function createProperty(options: PropertyOptions, debugId?: string): string { + const cssPropertyName = cssesc( + generateIdentifier({ + debugId, + debugFileName: false, + }), + { isIdentifier: true }, + ); + + appendCss({ type: 'property', name: `--${cssPropertyName}`, rule: buildPropertyRule(options) }, getFileScope()); + + return `var(--${cssPropertyName})`; +} + +export function createGlobalProperty(name: string, options: PropertyOptions): string { + appendCss({ type: 'property', name: `--${name}`, rule: buildPropertyRule(options) }, getFileScope()); + + return `var(--${name})`; +} + +export function property(varName: string): string { + assertVarName(varName); + + return varName.replace(/^var\((--.*)\)$/, '$1'); +} diff --git a/packages/css/src/transformCss.ts b/packages/css/src/transformCss.ts index 43baf90c6..cedd45cd3 100644 --- a/packages/css/src/transformCss.ts +++ b/packages/css/src/transformCss.ts @@ -13,6 +13,7 @@ import type { CSSSelectorBlock, Composition, WithQueries, + CSSPropertyBlock, } from './types'; import { markCompositionUsed } from './adapter'; import { forEach, omit, mapKeys } from './utils'; @@ -119,6 +120,7 @@ class Stylesheet { localClassNamesSearch: AhoCorasick; composedClassLists: Array<{ identifier: string; regex: RegExp }>; layers: Map>; + propertyRules: Array; constructor( localClassNames: Array, @@ -128,6 +130,7 @@ class Stylesheet { this.conditionalRulesets = [new ConditionalRuleset()]; this.fontFaceRules = []; this.keyframesRules = []; + this.propertyRules = []; this.localClassNamesMap = new Map( localClassNames.map((localClassName) => [localClassName, localClassName]), ); @@ -150,6 +153,13 @@ class Stylesheet { return; } + + if (root.type === 'property') { + this.propertyRules.push(root) + + return; + } + if (root.type === 'keyframes') { root.rule = Object.fromEntries( Object.entries(root.rule).map(([keyframe, rule]) => { @@ -573,6 +583,11 @@ class Stylesheet { css.push(renderCss({ '@font-face': fontFaceRule })); } + // Render property rules + for (const property of this.propertyRules) { + css.push(renderCss({ [`@property ${property.name}`]: property.rule })); + } + // Render keyframes for (const keyframe of this.keyframesRules) { css.push(renderCss({ [`@keyframes ${keyframe.name}`]: keyframe.rule })); diff --git a/packages/css/src/types.ts b/packages/css/src/types.ts index 7d89d3ced..ea1d42b6a 100644 --- a/packages/css/src/types.ts +++ b/packages/css/src/types.ts @@ -103,12 +103,19 @@ export type CSSLayerDeclaration = { name: string; }; +export type CSSPropertyBlock = { + type: 'property'; + name: string; + rule: AtRule.Property +}; + export type CSS = | CSSStyleBlock | CSSFontFaceBlock | CSSKeyframesBlock | CSSSelectorBlock - | CSSLayerDeclaration; + | CSSLayerDeclaration + | CSSPropertyBlock; export type FileScope = { packageName?: string; @@ -147,3 +154,22 @@ export type ThemeVars = MapLeafNodes< export type ClassNames = string | Array; export type ComplexStyleRule = StyleRule | Array; + +export type PropertySyntax = + | '' + | '' + | '' + | '' + | '' + | '' + | '' + | '' + | '' + | '