Skip to content

Commit

Permalink
🚚 Move plugin to another file
Browse files Browse the repository at this point in the history
  • Loading branch information
siguici committed Jul 6, 2024
1 parent 21eaae8 commit 59d075a
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 298 deletions.
4 changes: 4 additions & 0 deletions packages/colorwind/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
297 changes: 1 addition & 296 deletions packages/colorwind/src/index.ts
Original file line number Diff line number Diff line change
@@ -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<string, string>;

export type ComponentValue = string | UtilityList;
export type ComponentVariant = Record<string, ComponentValue>;
export type ComponentOption = ComponentValue | ComponentVariant;

export type ComponentList = Record<string, ComponentOption>;

export function isUtilityList(utilities: unknown): utilities is UtilityList {
return isArray<string>(utilities, isString);
}

export function isUtilityMap(utilities: unknown): utilities is UtilityMap {
return isObject<string, string>(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<string, ComponentValue>(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<ColorwindConfig>;

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<ColorwindConfig> {
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<ColorwindOptions> =
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';
Loading

0 comments on commit 59d075a

Please sign in to comment.