From 59d075a4adf249b90e140bfb2335958e53e11521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sigui=20Kess=C3=A9=20Emmanuel?= Date: Sat, 6 Jul 2024 23:59:07 +0100 Subject: [PATCH] :truck: Move plugin to another file --- packages/colorwind/package.json | 4 + packages/colorwind/src/index.ts | 297 +------------------------------ packages/colorwind/src/plugin.ts | 295 ++++++++++++++++++++++++++++++ tailwind.config.ts | 2 +- website/tailwind.config.ts | 2 +- 5 files changed, 302 insertions(+), 298 deletions(-) create mode 100644 packages/colorwind/src/plugin.ts diff --git a/packages/colorwind/package.json b/packages/colorwind/package.json index ef19f6e..e8b8b60 100644 --- a/packages/colorwind/package.json +++ b/packages/colorwind/package.json @@ -26,6 +26,10 @@ "default": "./js/colors.js", "types": "./ts/colors.d.ts" }, + "./plugin": { + "default": "./js/plugin.js", + "types": "./ts/plugin.d.ts" + }, "./utils": { "default": "./js/utils.js", "types": "./ts/utils.d.ts" diff --git a/packages/colorwind/src/index.ts b/packages/colorwind/src/index.ts index 93f1276..c961961 100644 --- a/packages/colorwind/src/index.ts +++ b/packages/colorwind/src/index.ts @@ -1,297 +1,2 @@ -import { - type DeclarationBlock, - PluginWithOptions as Plugin, - type StyleCallback, - type TailwindPluginWithOptions, -} from 'plugwind.js'; -import { - stylizeProperties, - stylizePropertiesCallback, - stylizeProperty, - stylizePropertyCallback, -} from 'plugwind.js/utils'; -import plugin from 'tailwindcss/plugin'; -import type { PluginAPI } from 'tailwindcss/types/config'; -import DEFAULT_COLORS, { type ColorsConfig, type ColorOption } from './colors'; -import { isArray, isObject, isString } from './utils'; - export * as config from './config'; - -export type UtilityList = string[]; -export type UtilityMap = Record; - -export type ComponentValue = string | UtilityList; -export type ComponentVariant = Record; -export type ComponentOption = ComponentValue | ComponentVariant; - -export type ComponentList = Record; - -export function isUtilityList(utilities: unknown): utilities is UtilityList { - return isArray(utilities, isString); -} - -export function isUtilityMap(utilities: unknown): utilities is UtilityMap { - return isObject(utilities, isString, isString); -} - -export function isComponentValue(value: unknown): value is ComponentValue { - return isString(value) || isUtilityList(value); -} - -export function isComponentVariant( - variant: unknown, -): variant is ComponentVariant { - return isObject(variant, isString, isComponentValue); -} - -export function isComponentOption(option: unknown): option is ComponentOption { - return isComponentValue(option) || isComponentVariant(option); -} - -export interface ColorwindConfig { - utilities: UtilityMap; - components: ComponentList; - colors: ColorsConfig; -} - -export type ColorwindOptions = Partial; - -export const DEFAULT_UTILITIES: UtilityMap = { - text: 'color', - bg: 'background-color', - decoration: 'text-decoration-color', - border: 'border-color', - outline: 'outline-color', - accent: 'accent-color', - caret: 'caret-color', - divide: 'border-color', - fill: 'fill', - stroke: 'stroke', - shadow: '--tw-shadow-color', - ring: '--tw-ring-color', -}; - -export const DEFAULT_COMPONENTS: ComponentList = { - link: ['text', 'decoration'], - - entry: ['text', 'caret', 'border'], - - choice: ['accent'], - - button: { - DEFAULT: ['bg'], - link: ['text', 'decoration'], - ring: ['text', 'ring'], - bordered: ['text', 'border'], - outlined: ['text', 'outline'], - }, -}; - -export const DEFAULT_OPTIONS: ColorwindConfig = { - colors: DEFAULT_COLORS, - utilities: DEFAULT_UTILITIES, - components: DEFAULT_COMPONENTS, -}; - -export class Colorwind extends Plugin { - public constructor(api: PluginAPI, options: ColorwindConfig) { - super(api, options); - this.addColors(); - } - - protected getPropertyOf(utility: string): string { - return this.options.utilities[utility]; - } - - protected getPropertiesOf(utilities: UtilityList): string[] { - const properties: string[] = []; - for (const utility of utilities) { - properties.push(this.getPropertyOf(utility)); - } - return properties; - } - - protected stylizeUtility( - utilityName: string, - propertyValue: string, - ): DeclarationBlock { - return stylizeProperty(this.getPropertyOf(utilityName), propertyValue); - } - - protected stylizeUtilityCallback(utilityName: string): StyleCallback { - return stylizePropertyCallback(this.getPropertyOf(utilityName)); - } - - protected stylizeUtilities( - utilityList: UtilityList, - propertyValue: string, - ): DeclarationBlock { - return stylizeProperties(this.getPropertiesOf(utilityList), propertyValue); - } - - protected stylizeUtilitiesCallback(utilityList: UtilityList): StyleCallback { - return stylizePropertiesCallback(this.getPropertiesOf(utilityList)); - } - - public addColors(): this { - for (const [colorName, colorOption] of Object.entries( - this.options.colors, - )) { - this.addColor(colorName, colorOption); - } - return this; - } - - public addColor(name: string, option: ColorOption): this { - return this.addColorComponents( - name, - option, - this.options.components, - ).addColorUtilities(name, option, this.options.utilities); - } - - public addColorComponents( - colorName: string, - colorOption: ColorOption, - componentList: ComponentList, - ): this { - for (const [componentName, componentOption] of Object.entries( - componentList, - )) { - this.addColorComponent( - componentName, - componentOption, - colorName, - colorOption, - ); - } - return this; - } - - public addColorComponent( - componentName: string, - componentOption: ComponentOption, - colorName: string, - colorOption: ColorOption, - ): this { - if (isString(componentOption)) { - return this.addColorComponentUtility( - componentName, - componentOption, - colorName, - colorOption, - ); - } - - if (isUtilityList(componentOption)) { - return this.addColorComponentUtilityList( - componentName, - componentOption, - colorName, - colorOption, - ); - } - - return this.addColorComponentVariant( - componentName, - componentOption, - colorName, - colorOption, - ); - } - - public addColorComponentUtility( - componentName: string, - utilityName: string, - colorName: string, - colorOption: ColorOption, - ): this { - const className = `${componentName}-${utilityName}-${colorName}`; - return isString(colorOption) - ? this.addUtility( - className, - this.stylizeUtility(utilityName, colorOption), - ) - : this.addDark( - className, - this.stylizeUtility(utilityName, colorOption.light), - this.stylizeUtility(utilityName, colorOption.dark), - ); - } - - public addColorComponentUtilityList( - componentName: string, - utilityList: UtilityList, - colorName: string, - colorOption: ColorOption, - ): this { - const className = `${componentName}-${colorName}`; - return isString(colorOption) - ? this.addComponent( - className, - this.stylizeUtilities(utilityList, colorOption), - ) - : this.addDark( - className, - this.stylizeUtilities(utilityList, colorOption.light), - this.stylizeUtilities(utilityList, colorOption.dark), - ); - } - - public addColorComponentVariant( - componentName: string, - componentVariant: ComponentVariant, - colorName: string, - colorOption: ColorOption, - ): this { - for (const [variantName, utilities] of Object.entries(componentVariant)) { - this.addColorComponent( - variantName === 'DEFAULT' - ? componentName - : `${componentName}-${variantName}`, - utilities, - colorName, - colorOption, - ); - } - return this; - } - - public addColorUtilities( - colorName: string, - colorOption: ColorOption, - utilityMap: UtilityMap, - ): this { - for (const [utilityName, propertyName] of Object.entries(utilityMap)) { - this.addColorUtility(utilityName, propertyName, colorName, colorOption); - } - return this; - } - - public addColorUtility( - utilityName: string, - propertyName: string, - colorName: string, - colorOption: ColorOption, - ): this { - const className = `${utilityName}-${colorName}`; - return isString(colorOption) - ? this.addUtility(className, stylizeProperty(propertyName, colorOption)) - : this.addDark( - className, - stylizeProperty(propertyName, colorOption.light), - stylizeProperty(propertyName, colorOption.dark), - ); - } -} - -const colorwind: TailwindPluginWithOptions = - plugin.withOptions((options?: ColorwindOptions) => (api: PluginAPI) => { - const opts = options ?? DEFAULT_OPTIONS; - opts.colors = opts.colors ?? DEFAULT_COLORS; - opts.utilities = opts.utilities ?? DEFAULT_UTILITIES; - opts.components = opts.components ?? DEFAULT_COMPONENTS; - new Colorwind(api, opts as ColorwindConfig); - }); - -export default colorwind; +export { default as plugin } from './plugin'; diff --git a/packages/colorwind/src/plugin.ts b/packages/colorwind/src/plugin.ts new file mode 100644 index 0000000..41f10d5 --- /dev/null +++ b/packages/colorwind/src/plugin.ts @@ -0,0 +1,295 @@ +import { + type DeclarationBlock, + PluginWithOptions as Plugin, + type StyleCallback, + type TailwindPluginWithOptions, +} from 'plugwind.js'; +import { + stylizeProperties, + stylizePropertiesCallback, + stylizeProperty, + stylizePropertyCallback, +} from 'plugwind.js/utils'; +import plugin from 'tailwindcss/plugin'; +import type { PluginAPI } from 'tailwindcss/types/config'; +import DEFAULT_COLORS, { type ColorsConfig, type ColorOption } from './colors'; +import { isArray, isObject, isString } from './utils'; + +export type UtilityList = string[]; +export type UtilityMap = Record; + +export type ComponentValue = string | UtilityList; +export type ComponentVariant = Record; +export type ComponentOption = ComponentValue | ComponentVariant; + +export type ComponentList = Record; + +export function isUtilityList(utilities: unknown): utilities is UtilityList { + return isArray(utilities, isString); +} + +export function isUtilityMap(utilities: unknown): utilities is UtilityMap { + return isObject(utilities, isString, isString); +} + +export function isComponentValue(value: unknown): value is ComponentValue { + return isString(value) || isUtilityList(value); +} + +export function isComponentVariant( + variant: unknown, +): variant is ComponentVariant { + return isObject(variant, isString, isComponentValue); +} + +export function isComponentOption(option: unknown): option is ComponentOption { + return isComponentValue(option) || isComponentVariant(option); +} + +export interface ColorwindConfig { + utilities: UtilityMap; + components: ComponentList; + colors: ColorsConfig; +} + +export type ColorwindOptions = Partial; + +export const DEFAULT_UTILITIES: UtilityMap = { + text: 'color', + bg: 'background-color', + decoration: 'text-decoration-color', + border: 'border-color', + outline: 'outline-color', + accent: 'accent-color', + caret: 'caret-color', + divide: 'border-color', + fill: 'fill', + stroke: 'stroke', + shadow: '--tw-shadow-color', + ring: '--tw-ring-color', +}; + +export const DEFAULT_COMPONENTS: ComponentList = { + link: ['text', 'decoration'], + + entry: ['text', 'caret', 'border'], + + choice: ['accent'], + + button: { + DEFAULT: ['bg'], + link: ['text', 'decoration'], + ring: ['text', 'ring'], + bordered: ['text', 'border'], + outlined: ['text', 'outline'], + }, +}; + +export const DEFAULT_OPTIONS: ColorwindConfig = { + colors: DEFAULT_COLORS, + utilities: DEFAULT_UTILITIES, + components: DEFAULT_COMPONENTS, +}; + +export class Colorwind extends Plugin { + public constructor(api: PluginAPI, options: ColorwindConfig) { + super(api, options); + this.addColors(); + } + + protected getPropertyOf(utility: string): string { + return this.options.utilities[utility]; + } + + protected getPropertiesOf(utilities: UtilityList): string[] { + const properties: string[] = []; + for (const utility of utilities) { + properties.push(this.getPropertyOf(utility)); + } + return properties; + } + + protected stylizeUtility( + utilityName: string, + propertyValue: string, + ): DeclarationBlock { + return stylizeProperty(this.getPropertyOf(utilityName), propertyValue); + } + + protected stylizeUtilityCallback(utilityName: string): StyleCallback { + return stylizePropertyCallback(this.getPropertyOf(utilityName)); + } + + protected stylizeUtilities( + utilityList: UtilityList, + propertyValue: string, + ): DeclarationBlock { + return stylizeProperties(this.getPropertiesOf(utilityList), propertyValue); + } + + protected stylizeUtilitiesCallback(utilityList: UtilityList): StyleCallback { + return stylizePropertiesCallback(this.getPropertiesOf(utilityList)); + } + + public addColors(): this { + for (const [colorName, colorOption] of Object.entries( + this.options.colors, + )) { + this.addColor(colorName, colorOption); + } + return this; + } + + public addColor(name: string, option: ColorOption): this { + return this.addColorComponents( + name, + option, + this.options.components, + ).addColorUtilities(name, option, this.options.utilities); + } + + public addColorComponents( + colorName: string, + colorOption: ColorOption, + componentList: ComponentList, + ): this { + for (const [componentName, componentOption] of Object.entries( + componentList, + )) { + this.addColorComponent( + componentName, + componentOption, + colorName, + colorOption, + ); + } + return this; + } + + public addColorComponent( + componentName: string, + componentOption: ComponentOption, + colorName: string, + colorOption: ColorOption, + ): this { + if (isString(componentOption)) { + return this.addColorComponentUtility( + componentName, + componentOption, + colorName, + colorOption, + ); + } + + if (isUtilityList(componentOption)) { + return this.addColorComponentUtilityList( + componentName, + componentOption, + colorName, + colorOption, + ); + } + + return this.addColorComponentVariant( + componentName, + componentOption, + colorName, + colorOption, + ); + } + + public addColorComponentUtility( + componentName: string, + utilityName: string, + colorName: string, + colorOption: ColorOption, + ): this { + const className = `${componentName}-${utilityName}-${colorName}`; + return isString(colorOption) + ? this.addUtility( + className, + this.stylizeUtility(utilityName, colorOption), + ) + : this.addDark( + className, + this.stylizeUtility(utilityName, colorOption.light), + this.stylizeUtility(utilityName, colorOption.dark), + ); + } + + public addColorComponentUtilityList( + componentName: string, + utilityList: UtilityList, + colorName: string, + colorOption: ColorOption, + ): this { + const className = `${componentName}-${colorName}`; + return isString(colorOption) + ? this.addComponent( + className, + this.stylizeUtilities(utilityList, colorOption), + ) + : this.addDark( + className, + this.stylizeUtilities(utilityList, colorOption.light), + this.stylizeUtilities(utilityList, colorOption.dark), + ); + } + + public addColorComponentVariant( + componentName: string, + componentVariant: ComponentVariant, + colorName: string, + colorOption: ColorOption, + ): this { + for (const [variantName, utilities] of Object.entries(componentVariant)) { + this.addColorComponent( + variantName === 'DEFAULT' + ? componentName + : `${componentName}-${variantName}`, + utilities, + colorName, + colorOption, + ); + } + return this; + } + + public addColorUtilities( + colorName: string, + colorOption: ColorOption, + utilityMap: UtilityMap, + ): this { + for (const [utilityName, propertyName] of Object.entries(utilityMap)) { + this.addColorUtility(utilityName, propertyName, colorName, colorOption); + } + return this; + } + + public addColorUtility( + utilityName: string, + propertyName: string, + colorName: string, + colorOption: ColorOption, + ): this { + const className = `${utilityName}-${colorName}`; + return isString(colorOption) + ? this.addUtility(className, stylizeProperty(propertyName, colorOption)) + : this.addDark( + className, + stylizeProperty(propertyName, colorOption.light), + stylizeProperty(propertyName, colorOption.dark), + ); + } +} + +const colorwind: TailwindPluginWithOptions = + plugin.withOptions((options?: ColorwindOptions) => (api: PluginAPI) => { + const opts = options ?? DEFAULT_OPTIONS; + opts.colors = opts.colors ?? DEFAULT_COLORS; + opts.utilities = opts.utilities ?? DEFAULT_UTILITIES; + opts.components = opts.components ?? DEFAULT_COMPONENTS; + new Colorwind(api, opts as ColorwindConfig); + }); + +export default colorwind; diff --git a/tailwind.config.ts b/tailwind.config.ts index a7218d3..dd675bb 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -1,4 +1,4 @@ -import colorwind from 'colorwind'; +import colorwind from 'colorwind/plugin'; export default { plugins: [colorwind], diff --git a/website/tailwind.config.ts b/website/tailwind.config.ts index 72bcd70..29e140c 100644 --- a/website/tailwind.config.ts +++ b/website/tailwind.config.ts @@ -1,5 +1,5 @@ import starlight from '@astrojs/starlight-tailwind'; -import colorwind from 'colorwind'; +import colorwind from 'colorwind/plugin'; export default { content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],