From 1fcd886619be6646f970b91a9a31754f559936b4 Mon Sep 17 00:00:00 2001 From: bre97-web Date: Wed, 4 Sep 2024 15:05:59 +0800 Subject: [PATCH] refactor: apply new interfaces and abstract classes --- .../material-design-theme-token.interface.ts | 57 ----- src/declaration/token.interface.ts | 4 + src/declaration/window-sizing.interface.ts | 8 - src/deprecated/color.ts | 2 +- src/deprecated/elevation.ts | 2 +- src/deprecated/typography.ts | 2 +- src/tokens/internal/border.ts | 61 ++--- src/tokens/internal/color.ts | 223 +++++++++++------- src/tokens/internal/elevation.ts | 70 +++--- src/tokens/internal/sizing.ts | 68 +++--- 10 files changed, 257 insertions(+), 240 deletions(-) delete mode 100644 src/declaration/material-design-theme-token.interface.ts create mode 100644 src/declaration/token.interface.ts delete mode 100644 src/declaration/window-sizing.interface.ts diff --git a/src/declaration/material-design-theme-token.interface.ts b/src/declaration/material-design-theme-token.interface.ts deleted file mode 100644 index 1dc081d..0000000 --- a/src/declaration/material-design-theme-token.interface.ts +++ /dev/null @@ -1,57 +0,0 @@ - -export interface IMaterialDesignThemeTokens { - primaryPaletteKeyColor: string - secondaryPaletteKeyColor: string - tertiaryPaletteKeyColor: string - neutralPaletteKeyColor: string - neutralVariantPaletteKeyColor: string - background: string - onBackground: string - surface: string - surfaceDim: string - surfaceBright: string - surfaceContainerLowest: string - surfaceContainerLow: string - surfaceContainer: string - surfaceContainerHigh: string - surfaceContainerHighest: string - onSurface: string - surfaceVariant: string - onSurfaceVariant: string - inverseSurface: string - inverseOnSurface: string - outline: string - outlineVariant: string - shadow: string - scrim: string - surfaceTint: string - primary: string - onPrimary: string - primaryContainer: string - onPrimaryContainer: string - inversePrimary: string - secondary: string - onSecondary: string - secondaryContainer: string - onSecondaryContainer: string - tertiary: string - onTertiary: string - tertiaryContainer: string - onTertiaryContainer: string - error: string - onError: string - errorContainer: string - onErrorContainer: string - primaryFixed: string - primaryFixedDim: string - onPrimaryFixed: string - onPrimaryFixedVariant: string - secondaryFixed: string - secondaryFixedDim: string - onSecondaryFixed: string - onSecondaryFixedVariant: string - tertiaryFixed: string - tertiaryFixedDim: string - onTertiaryFixed: string - onTertiaryFixedVariant: string -} diff --git a/src/declaration/token.interface.ts b/src/declaration/token.interface.ts new file mode 100644 index 0000000..23e8a4e --- /dev/null +++ b/src/declaration/token.interface.ts @@ -0,0 +1,4 @@ + +export abstract class Tokens { + public abstract get values(): T +} diff --git a/src/declaration/window-sizing.interface.ts b/src/declaration/window-sizing.interface.ts deleted file mode 100644 index 5df2082..0000000 --- a/src/declaration/window-sizing.interface.ts +++ /dev/null @@ -1,8 +0,0 @@ - -export interface IWindowSizing { - compact: string - medium: string - expanded: string - large: string - extraLarge: string -} diff --git a/src/deprecated/color.ts b/src/deprecated/color.ts index 461f72f..ab9d553 100644 --- a/src/deprecated/color.ts +++ b/src/deprecated/color.ts @@ -1,4 +1,4 @@ -import plugin from 'tailwindcss/plugin.js' +import plugin from 'tailwindcss/plugin' /** * @deprecated diff --git a/src/deprecated/elevation.ts b/src/deprecated/elevation.ts index ca3cdbe..8e5c13a 100644 --- a/src/deprecated/elevation.ts +++ b/src/deprecated/elevation.ts @@ -1,4 +1,4 @@ -import plugin from 'tailwindcss/plugin.js' +import plugin from 'tailwindcss/plugin' /** * @deprecated diff --git a/src/deprecated/typography.ts b/src/deprecated/typography.ts index bd250c4..b83e5dc 100644 --- a/src/deprecated/typography.ts +++ b/src/deprecated/typography.ts @@ -1,4 +1,4 @@ -import plugin from 'tailwindcss/plugin.js' +import plugin from 'tailwindcss/plugin' /** * @deprecated diff --git a/src/tokens/internal/border.ts b/src/tokens/internal/border.ts index 0917141..aa5a2e6 100644 --- a/src/tokens/internal/border.ts +++ b/src/tokens/internal/border.ts @@ -1,5 +1,6 @@ import plugin from "tailwindcss/plugin" import type { IProvider } from "../../declaration/provider.interface" +import { Tokens } from "../../declaration/token.interface" import { Strings } from "../../utils/strings" import { Validates } from "../../utils/validates" @@ -18,7 +19,9 @@ export type TBorderProviderConstructorParams = { * } * ``` */ - readonly prefix: string + readonly classNamePrefix: string + + readonly cssVariableTokenPrefix: string /** * @description @@ -74,23 +77,20 @@ export type TBorderProviderConstructorParams = { * }) * ``` */ - readonly excludedTokens: Array<(keyof IBorderTokens) | {}> + readonly excludedTokens: Array } -interface IBorderTokens { - outline: string - outlineVariant: string +export interface IBorderTokens { + readonly outline: string + readonly outlineVariant: string } -class DefaultBorderTokens implements IBorderTokens { - /** - * Colors - */ - outline = '#727785' - outlineVariant = '#c2c6d6' +class DefaultBorderTokens extends Tokens { + protected outline = '#727785' + protected outlineVariant = '#c2c6d6' - public get defaultTokenRecord() { + public get values() { return { outline: this.outline, outlineVariant: this.outlineVariant, @@ -99,38 +99,36 @@ class DefaultBorderTokens implements IBorderTokens { } export class BorderProvider extends DefaultBorderTokens implements IProvider { - private prefix - private tokens - private customTokens - private excludedTokens - private hardcodeDefaultValue + private readonly cssVariableTokenPrefix + private readonly classNamePrefix + private readonly tokens + private readonly customTokens + private readonly excludedTokens + private readonly hardcodeDefaultValue constructor(params: Partial) { super() - this.prefix = params.prefix ?? 'md-sys-color' + this.classNamePrefix = params.classNamePrefix ?? '' + this.cssVariableTokenPrefix = params.cssVariableTokenPrefix ?? 'md-sys-color' this.hardcodeDefaultValue = params.hardcodeDefaultValue ?? true this.customTokens = params.customTokens ?? {} this.excludedTokens = params.excludedTokens ?? [] - this.tokens = this.validate([this.customTokens as Record, this.defaultTokenRecord, this.excludedTokens]) + this.tokens = Validates.validate(this.customTokens as Record, this.values, this.excludedTokens) } - private validate(params: Parameters) { - return Validates.validate(...params) - } - - protected transformTokensToCssRuleObject(prefix: string, tokens: Record, hardcodeDefaultValue: boolean) { - const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${prefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` + protected transformTokensToCssRuleObject(classNamePrefix: string, cssVariableTokenPrefix: string, tokens: Record, hardcodeDefaultValue: boolean) { + const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${cssVariableTokenPrefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` const borderTokens = Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.border-${Strings.toKebabCase(name)}`, + (name) => Validates.className(['.border', classNamePrefix, name]), (name, value) => ({ 'border-color': cssPropertyComputed(name, value) }) ) const outlineTokens = Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.outline-${Strings.toKebabCase(name)}`, + (name) => Validates.className(['.outline', classNamePrefix, name]), (name, value) => ({ 'outline-color': cssPropertyComputed(name, value) }) @@ -138,10 +136,13 @@ export class BorderProvider extends DefaultBorderTokens implements IProvider { return Object.assign({}, borderTokens, outlineTokens) } - getPlugin() { - const tokens = this.transformTokensToCssRuleObject(this.prefix, this.tokens, this.hardcodeDefaultValue) + public get cssString() { + return this.transformTokensToCssRuleObject(this.classNamePrefix, this.cssVariableTokenPrefix, this.tokens, this.hardcodeDefaultValue) + } + + public getPlugin() { return plugin(({ addUtilities }) => { - addUtilities(tokens) + addUtilities(this.cssString) }) } diff --git a/src/tokens/internal/color.ts b/src/tokens/internal/color.ts index e5a51b0..3afd083 100644 --- a/src/tokens/internal/color.ts +++ b/src/tokens/internal/color.ts @@ -1,6 +1,6 @@ import plugin from "tailwindcss/plugin" -import type { IMaterialDesignThemeTokens } from "../../declaration/material-design-theme-token.interface" import type { IProvider } from "../../declaration/provider.interface" +import { Tokens } from "../../declaration/token.interface" import { Strings } from "../../utils/strings" import { Validates } from "../../utils/validates" @@ -11,14 +11,14 @@ export type TColorProviderConstructorParams = { * * @default 'md-sys-color' * - * @example If the value of prefix is 'your-prefix'. + * @example If the value of cssVariableTokenPrefix is 'your-prefix'. * ```css * .text-on-surface { * color: var(--your-prefix-on-surface, #181c25); * } * ``` */ - readonly prefix: string + readonly cssVariableTokenPrefix: string /** * @description @@ -41,7 +41,7 @@ export type TColorProviderConstructorParams = { * }) * ``` */ - readonly customTokens: IMaterialDesignThemeTokens | Record + readonly customTokens: IColorTokens | Record /** * @description @@ -78,81 +78,143 @@ export type TColorProviderConstructorParams = { * }) * ``` */ - readonly excludedTokens: Array<(keyof IMaterialDesignThemeTokens) | {}> + readonly excludedTokens: Array<(keyof IColorTokens) | {}> + + /** + * @default '' + */ + readonly classNamePrefix: string +} + +export interface IColorTokens { + readonly primaryPaletteKeyColor: string + readonly secondaryPaletteKeyColor: string + readonly tertiaryPaletteKeyColor: string + readonly neutralPaletteKeyColor: string + readonly neutralVariantPaletteKeyColor: string + readonly background: string + readonly onBackground: string + readonly surface: string + readonly surfaceDim: string + readonly surfaceBright: string + readonly surfaceContainerLowest: string + readonly surfaceContainerLow: string + readonly surfaceContainer: string + readonly surfaceContainerHigh: string + readonly surfaceContainerHighest: string + readonly onSurface: string + readonly surfaceVariant: string + readonly onSurfaceVariant: string + readonly inverseSurface: string + readonly inverseOnSurface: string + readonly outline: string + readonly outlineVariant: string + readonly shadow: string + readonly scrim: string + readonly surfaceTint: string + readonly primary: string + readonly onPrimary: string + readonly primaryContainer: string + readonly onPrimaryContainer: string + readonly inversePrimary: string + readonly secondary: string + readonly onSecondary: string + readonly secondaryContainer: string + readonly onSecondaryContainer: string + readonly tertiary: string + readonly onTertiary: string + readonly tertiaryContainer: string + readonly onTertiaryContainer: string + readonly error: string + readonly onError: string + readonly errorContainer: string + readonly onErrorContainer: string + readonly primaryFixed: string + readonly primaryFixedDim: string + readonly onPrimaryFixed: string + readonly onPrimaryFixedVariant: string + readonly secondaryFixed: string + readonly secondaryFixedDim: string + readonly onSecondaryFixed: string + readonly onSecondaryFixedVariant: string + readonly tertiaryFixed: string + readonly tertiaryFixedDim: string + readonly onTertiaryFixed: string + readonly onTertiaryFixedVariant: string } -class DefaultMaterialDesignThemeTokens implements IMaterialDesignThemeTokens { +class DefaultColorTokens extends Tokens { /** * Key colors */ - primaryPaletteKeyColor = '#047aff' - secondaryPaletteKeyColor = '#727598' - tertiaryPaletteKeyColor = '#7b70a3' - neutralPaletteKeyColor = '#737782' - neutralVariantPaletteKeyColor = '#727785' + protected readonly primaryPaletteKeyColor = '#047aff' + protected readonly secondaryPaletteKeyColor = '#727598' + protected readonly tertiaryPaletteKeyColor = '#7b70a3' + protected readonly neutralPaletteKeyColor = '#737782' + protected readonly neutralVariantPaletteKeyColor = '#727785' /** * Base colors */ - background = '#f9f9ff' - onBackground = '#181c25' - surface = '#f9f9ff' - surfaceDim = '#d7d9e6' - surfaceBright = '#f9f9ff' - surfaceContainerLowest = '#ffffff' - surfaceContainerLow = '#f1f3ff' - surfaceContainer = '#ebedfa' - surfaceContainerHigh = '#e5e8f5' - surfaceContainerHighest = '#dfe2ef' - onSurface = '#181c25' - surfaceVariant = '#dee2f2' - onSurfaceVariant = '#424753' - inverseSurface = '#2c303a' - inverseOnSurface = '#eef0fd' - shadow = '#000000' - scrim = '#000000' - surfaceTint = '#005ac1' - primary = '#005ac1' - onPrimary = '#ffffff' - primaryContainer = '#d8e2ff' - onPrimaryContainer = '#001a41' - inversePrimary = '#adc6ff' - secondary = '#595c7e' - onSecondary = '#ffffff' - secondaryContainer = '#dfe0ff' - onSecondaryContainer = '#151937' - tertiary = '#625789' - onTertiary = '#ffffff' - tertiaryContainer = '#e7deff' - onTertiaryContainer = '#1e1341' - error = '#ba1a1a' - onError = '#ffffff' - errorContainer = '#ffdad6' - onErrorContainer = '#410002' + protected readonly background = '#f9f9ff' + protected readonly onBackground = '#181c25' + protected readonly surface = '#f9f9ff' + protected readonly surfaceDim = '#d7d9e6' + protected readonly surfaceBright = '#f9f9ff' + protected readonly surfaceContainerLowest = '#ffffff' + protected readonly surfaceContainerLow = '#f1f3ff' + protected readonly surfaceContainer = '#ebedfa' + protected readonly surfaceContainerHigh = '#e5e8f5' + protected readonly surfaceContainerHighest = '#dfe2ef' + protected readonly onSurface = '#181c25' + protected readonly surfaceVariant = '#dee2f2' + protected readonly onSurfaceVariant = '#424753' + protected readonly inverseSurface = '#2c303a' + protected readonly inverseOnSurface = '#eef0fd' + protected readonly shadow = '#000000' + protected readonly scrim = '#000000' + protected readonly surfaceTint = '#005ac1' + protected readonly primary = '#005ac1' + protected readonly onPrimary = '#ffffff' + protected readonly primaryContainer = '#d8e2ff' + protected readonly onPrimaryContainer = '#001a41' + protected readonly inversePrimary = '#adc6ff' + protected readonly secondary = '#595c7e' + protected readonly onSecondary = '#ffffff' + protected readonly secondaryContainer = '#dfe0ff' + protected readonly onSecondaryContainer = '#151937' + protected readonly tertiary = '#625789' + protected readonly onTertiary = '#ffffff' + protected readonly tertiaryContainer = '#e7deff' + protected readonly onTertiaryContainer = '#1e1341' + protected readonly error = '#ba1a1a' + protected readonly onError = '#ffffff' + protected readonly errorContainer = '#ffdad6' + protected readonly onErrorContainer = '#410002' /** * Border as bg/text */ - outline = '#727785' - outlineVariant = '#c2c6d6' + protected readonly outline = '#727785' + protected readonly outlineVariant = '#c2c6d6' /** * Fixed colors */ - primaryFixed = '#d8e2ff' - primaryFixedDim = '#adc6ff' - onPrimaryFixed = '#001a41' - onPrimaryFixedVariant = '#004494' - secondaryFixed = '#dfe0ff' - secondaryFixedDim = '#c1c4eb' - onSecondaryFixed = '#151937' - onSecondaryFixedVariant = '#414465' - tertiaryFixed = '#e7deff' - tertiaryFixedDim = '#ccbff8' - onTertiaryFixed = '#1e1341' - onTertiaryFixedVariant = '#4a4070' + protected readonly primaryFixed = '#d8e2ff' + protected readonly primaryFixedDim = '#adc6ff' + protected readonly onPrimaryFixed = '#001a41' + protected readonly onPrimaryFixedVariant = '#004494' + protected readonly secondaryFixed = '#dfe0ff' + protected readonly secondaryFixedDim = '#c1c4eb' + protected readonly onSecondaryFixed = '#151937' + protected readonly onSecondaryFixedVariant = '#414465' + protected readonly tertiaryFixed = '#e7deff' + protected readonly tertiaryFixedDim = '#ccbff8' + protected readonly onTertiaryFixed = '#1e1341' + protected readonly onTertiaryFixedVariant = '#4a4070' - public get defaultTokenRecord() { + public get values() { return { primaryPaletteKeyColor: this.primaryPaletteKeyColor, secondaryPaletteKeyColor: this.secondaryPaletteKeyColor, @@ -212,39 +274,37 @@ class DefaultMaterialDesignThemeTokens implements IMaterialDesignThemeTokens { } } -export class ColorProvider extends DefaultMaterialDesignThemeTokens implements IProvider { - public prefix - public tokens - public hardcodeDefaultValue - public excludedTokens - public customTokens +export class ColorProvider extends DefaultColorTokens implements IProvider { + private readonly tokens + private readonly hardcodeDefaultValue + private readonly excludedTokens + private readonly customTokens + private readonly cssVariableTokenPrefix + private readonly classNamePrefix constructor(params: Partial) { super() - this.prefix = params.prefix ?? 'md-sys-color' + this.cssVariableTokenPrefix = params.cssVariableTokenPrefix ?? 'md-sys-color' + this.classNamePrefix = params.classNamePrefix ?? '' this.hardcodeDefaultValue = params.hardcodeDefaultValue ?? true this.excludedTokens = params.excludedTokens ?? [] this.customTokens = params.customTokens ?? {} - this.tokens = this.validate([(this.customTokens) as Record, this.defaultTokenRecord, this.excludedTokens]) + this.tokens = Validates.validate((this.customTokens) as Record, this.values, this.excludedTokens) } - protected validate(params: Parameters) { - return Validates.validate(...params) - } - - protected transformTokensToCssRuleObject(prefix: string, tokens: Record, hardcodeDefaultValue: boolean) { - const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${prefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` + protected transformTokensToCssRuleObject(classNamePrefix: string, cssVariableTokenPrefix: string, tokens: Record, hardcodeDefaultValue: boolean) { + const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${cssVariableTokenPrefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` const textTokens = Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.text-${Strings.toKebabCase(name)}`, + (name) => Validates.className([`.text`, classNamePrefix, name], {}), (name, value) => ({ 'color': cssPropertyComputed(name, value) }) ) const bgTokens = Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.bg-${Strings.toKebabCase(name)}`, + (name) => Validates.className([`.bg`, classNamePrefix, name], {}), (name, value) => ({ 'background-color': cssPropertyComputed(name, value) }) @@ -252,10 +312,13 @@ export class ColorProvider extends DefaultMaterialDesignThemeTokens implements I return Object.assign({}, textTokens, bgTokens) } - getPlugin() { - const tokens = this.transformTokensToCssRuleObject(this.prefix, this.tokens, this.hardcodeDefaultValue) + public get cssString() { + return this.transformTokensToCssRuleObject(this.classNamePrefix, this.cssVariableTokenPrefix, this.tokens, this.hardcodeDefaultValue) + } + + public getPlugin() { return plugin(({ addUtilities }) => { - addUtilities(tokens) + addUtilities(this.cssString) }) } diff --git a/src/tokens/internal/elevation.ts b/src/tokens/internal/elevation.ts index cebfb52..5bb54a9 100644 --- a/src/tokens/internal/elevation.ts +++ b/src/tokens/internal/elevation.ts @@ -1,5 +1,6 @@ import plugin from "tailwindcss/plugin"; import type { IProvider } from "../../declaration/provider.interface"; +import { Tokens } from "../../declaration/token.interface"; import { Strings } from "../../utils/strings"; import { Validates } from "../../utils/validates"; @@ -57,7 +58,9 @@ export type TElevationProviderConstructorParams = { * } * ``` */ - readonly prefix: string + readonly classNamePrefix: string + + readonly cssVariableTokenPrefix: string /** * @description @@ -117,31 +120,31 @@ export type TElevationProviderConstructorParams = { } export interface IElevation { - levelNone: string - level1: string - level2: string - level3: string - level4: string - level5: string + readonly levelNone: string + readonly level1: string + readonly level2: string + readonly level3: string + readonly level4: string + readonly level5: string } -class DefaultElevationTokens implements IElevation { - levelNone = 'none' - level1 - level2 - level3 - level4 - level5 +class DefaultElevationTokens extends Tokens { + protected readonly levelNone = 'none' + protected readonly level1 + protected readonly level2 + protected readonly level3 + protected readonly level4 + protected readonly level5 constructor(shadowColorCssVariableLayer1: string, shadowColorCssVariableLayer2: string, shadowColorCssVariableLayer3: string) { + super() this.level1 = `${shadowColorCssVariableLayer1} 0px 2px 1px -1px, ${shadowColorCssVariableLayer2} 0px 1px 1px 0px, ${shadowColorCssVariableLayer3} 0px 1px 3px 0px` this.level2 = `${shadowColorCssVariableLayer1} 0px 3px 3px -2px, ${shadowColorCssVariableLayer2} 0px 3px 4px 0px, ${shadowColorCssVariableLayer3} 0px 1px 8px 0px` this.level3 = `${shadowColorCssVariableLayer1} 0px 3px 5px -1px, ${shadowColorCssVariableLayer2} 0px 6px 10px 0px, ${shadowColorCssVariableLayer3} 0px 1px 18px 0px` this.level4 = `${shadowColorCssVariableLayer1} 0px 5px 5px -3px, ${shadowColorCssVariableLayer2} 0px 8px 10px 1px, ${shadowColorCssVariableLayer3} 0px 3px 14px 2px` this.level5 = `${shadowColorCssVariableLayer1} 0px 7px 8px -4px, ${shadowColorCssVariableLayer2} 0px 12px 17px 2px, ${shadowColorCssVariableLayer3} 0px 5px 22px 4px` } - - public get defaultTokenRecord() { + public get values() { return { levelNone: this.levelNone, level1: this.level1, @@ -154,11 +157,12 @@ class DefaultElevationTokens implements IElevation { } export class ElevationProvider extends DefaultElevationTokens implements IProvider { - public prefix - public hardcodeDefaultValue - public excludedTokens - public tokens - public customTokens + public readonly classNamePrefix + public readonly cssVariableTokenPrefix + public readonly hardcodeDefaultValue + public readonly excludedTokens + public readonly tokens + public readonly customTokens constructor(params: Partial) { const shadowColorCssVariableLayer1 = params.shadowColorCssVariable?.layer1 ?? `var(--${params.shadowColorTokenPrefix ?? 'md-sys-color'}-shadow, rgba(0, 0, 0, 0.2))` @@ -166,33 +170,35 @@ export class ElevationProvider extends DefaultElevationTokens implements IProvid const shadowColorCssVariableLayer3 = params.shadowColorCssVariable?.layer3 ?? `var(--${params.shadowColorTokenPrefix ?? 'md-sys-color'}-shadow, rgba(0, 0, 0, 0.12))` super(shadowColorCssVariableLayer1, shadowColorCssVariableLayer2, shadowColorCssVariableLayer3) - this.prefix = params.prefix ?? 'md-sys-elevation' + this.classNamePrefix = params.classNamePrefix ?? '' + this.cssVariableTokenPrefix = params.cssVariableTokenPrefix ?? 'md-sys-elevation' this.hardcodeDefaultValue = params.hardcodeDefaultValue ?? true this.excludedTokens = params.excludedTokens ?? [] this.customTokens = params.customTokens ?? {} - this.tokens = this.validate([this.customTokens as Record, this.defaultTokenRecord, this.excludedTokens]) - } - - protected validate(params: Parameters) { - return Validates.validate(...params) + this.tokens = Validates.validate(this.customTokens as Record, this.values, this.excludedTokens) } - protected transformTokensToCssRuleObject(prefix: string, tokens: Record, hardcodeDefaultValue: boolean) { - const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${prefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` + protected transformTokensToCssRuleObject(classNamePrefix: string, cssVariableTokenPrefix: string, tokens: Record, hardcodeDefaultValue: boolean) { + const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${cssVariableTokenPrefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` return Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.${Strings.toKebabCase(name).replace('level', 'elevation')}`, + (name) => Validates.className(['.elevation', classNamePrefix, name], { + preProcessingCallback: (before) => before.replace('level', ''), + }), (name, value) => ({ 'box-shadow': cssPropertyComputed(name, value) }) ) } + public get cssString() { + return this.transformTokensToCssRuleObject(this.classNamePrefix, this.cssVariableTokenPrefix, this.tokens, this.hardcodeDefaultValue) + } + public getPlugin() { - const tokens = this.transformTokensToCssRuleObject(this.prefix, this.tokens, this.hardcodeDefaultValue) return plugin(({ addUtilities }) => { - addUtilities(tokens) + addUtilities(this.cssString) }) } } diff --git a/src/tokens/internal/sizing.ts b/src/tokens/internal/sizing.ts index e02fdc1..b4b914b 100644 --- a/src/tokens/internal/sizing.ts +++ b/src/tokens/internal/sizing.ts @@ -1,6 +1,6 @@ import plugin from "tailwindcss/plugin"; import type { IProvider } from "../../declaration/provider.interface"; -import type { IWindowSizing } from "../../declaration/window-sizing.interface"; +import { Tokens } from "../../declaration/token.interface"; import { Strings } from "../../utils/strings"; import { Validates } from "../../utils/validates"; @@ -19,7 +19,9 @@ export type TSizingProviderConstructorParams = { * } * ``` */ - readonly prefix: string + readonly classNamePrefix: string + + readonly cssVariableTokenPrefix: string /** * @description @@ -78,21 +80,27 @@ export type TSizingProviderConstructorParams = { readonly excludedTokens: Array) | {}> } -abstract class DefaultWindowSizing implements IWindowSizing { - compact = '600px' - medium = '840px' - expanded = '1200px' - large = '1600px' +export interface IWindowSizing { + readonly compact: string + readonly medium: string + readonly expanded: string + readonly large: string + readonly extraLarge: string +} + +class DefaultSizingTokens extends Tokens> { + protected readonly compact = '600px' + protected readonly medium = '840px' + protected readonly expanded = '1200px' + protected readonly large = '1600px' /** * extraLarge: width >= 1600px * @deprecated */ - extraLarge = '1600px' -} + private readonly extraLarge = '1600px' -class DefaultSizingTokens extends DefaultWindowSizing { - public get defaultTokensRecord() { + public get values() { return { compact: this.compact, medium: this.medium, @@ -102,39 +110,38 @@ class DefaultSizingTokens extends DefaultWindowSizing { } } + export class SizingProvider extends DefaultSizingTokens implements IProvider { - public prefix - public tokens - public hardcodeDefaultValue - public excludedTokens - public customTokens + private readonly classNamePrefix + private readonly cssVariableTokenPrefix + private readonly tokens + private readonly hardcodeDefaultValue + private readonly excludedTokens + private readonly customTokens constructor(params: Partial) { super() - this.prefix = params.prefix ?? 'md-sys-sizing' + this.classNamePrefix = params.classNamePrefix ?? '' + this.cssVariableTokenPrefix = params.cssVariableTokenPrefix ?? 'md-sys-sizing' this.hardcodeDefaultValue = params.hardcodeDefaultValue ?? true this.excludedTokens = params.excludedTokens ?? [] this.customTokens = params.customTokens ?? {} - this.tokens = this.validate([this.customTokens, this.defaultTokensRecord, this.excludedTokens]) + this.tokens = Validates.validate(this.customTokens, this.values, this.excludedTokens) } - private validate(params: Parameters) { - return Validates.validate(...params) - } - - protected transformTokensToCssRuleObject(prefix: string, tokens: Record, hardcodeDefaultValue: boolean) { - const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${prefix}-width-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` + protected transformTokensToCssRuleObject(classNamePrefix: string, cssVariableTokenPrefix: string, tokens: Record, hardcodeDefaultValue: boolean) { + const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${cssVariableTokenPrefix}-width-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}` const width = Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.w-${Strings.toKebabCase(name)}`, + (name) => Validates.className(['.w', classNamePrefix, name]), (name, value) => ({ 'width': cssPropertyComputed(name, value) }) ) const maxWidthScreen = Validates.transformTokenRecordToCssRuleObject( tokens, - (name) => `.max-w-screen-${Strings.toKebabCase(name)}`, + (name) => Validates.className(['.max-w-screen', classNamePrefix, name]), (name, value) => ({ 'max-width': cssPropertyComputed(name, value) }) @@ -142,12 +149,13 @@ export class SizingProvider extends DefaultSizingTokens implements IProvider { return Object.assign({}, width, maxWidthScreen) } - getPlugin() { - const tokens = this.transformTokensToCssRuleObject(this.prefix, this.tokens, this.hardcodeDefaultValue) - console.log(tokens); + public get cssString() { + return this.transformTokensToCssRuleObject(this.classNamePrefix, this.cssVariableTokenPrefix, this.tokens, this.hardcodeDefaultValue) + } + getPlugin() { return plugin(({ addUtilities }) => { - addUtilities(tokens) + addUtilities(this.cssString) }) }