Skip to content

Commit

Permalink
feat: create border plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
bre97-web committed Aug 30, 2024
1 parent 4de16cd commit 0252947
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/tokens/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@
* provide*()
*/
export * from './provide-all'
export * from './provide-border'
export * from './provide-color'
export * from './provide-elevation'
export * from './provide-motion'
export * from './provide-shape'
export * from './provide-typography'

export * from './internal/border'
export * from './internal/color'
export * from './internal/elevation'
export * from './internal/motion'
Expand Down
148 changes: 148 additions & 0 deletions src/tokens/internal/border.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import plugin from "tailwindcss/plugin"
import type { IProvider } from "../../declaration/provider.interface"
import { Strings } from "../../utils/strings"
import { Validates } from "../../utils/validates"

export type TBorderProviderConstructorParams = {

/**
* @description
* For managed or public CSS variables.
*
* @default 'md-sys-color'
*
* @example If the value of prefix is 'your-prefix'.
* ```css
* .border-outline {
* border-color: var(--your-prefix-outline, #727785);
* }
* ```
*/
readonly prefix: string

/**
* @description
* This option can customize the CSS value corresponding to certain tokens.
* Note that this option ignores [hardcodeDefaultValue] and [prefix].
*
* @default []
*
* @example
* ```typescript
* const color = provideBorder({
* customTokens: {
* // .border-outline { border-color: red; }
* 'outline': 'red'
* },
* })
* ```
*/
readonly customTokens: IBorderTokens | Record<string, string>

/**
* @description
* When set to true, each token contains a default value.
*
* @default true
*
* @example
* ```typescript
* const color = provideBorder({
* // .border-outline { border-color: var(--md-sys-color-outline, #727785); }
* hardcodeDefaultValue: true,
*
* // .border-outline { border-color: var(--md-sys-color-outline, ); }
* hardcodeDefaultValue: false,
* })
* ```
*/
readonly hardcodeDefaultValue: boolean

/**
* @description
* Exclude some unnecessary tokens.
*
* @default []
*
* @example
* ```typescript
* const color = provideBorder({
* excludedTokens: [
* // remove .border-outline-variant and .outline-outline-variant
* 'outlineVariant',
* ],
* })
* ```
*/
readonly excludedTokens: Array<(keyof IBorderTokens) | {}>

}

interface IBorderTokens {
outline: string
outlineVariant: string
}

class DefaultBorderTokens implements IBorderTokens {
/**
* Colors
*/
outline = '#727785'
outlineVariant = '#c2c6d6'

public get defaultTokenRecord() {
return {
outline: this.outline,
outlineVariant: this.outlineVariant,
}
}
}

export class BorderProvider extends DefaultBorderTokens implements IProvider {
private prefix
private tokens
private customTokens
private excludedTokens
private hardcodeDefaultValue

constructor(params: Partial<TBorderProviderConstructorParams>) {
super()
this.prefix = params.prefix ?? 'md-sys-color'
this.hardcodeDefaultValue = params.hardcodeDefaultValue ?? true
this.customTokens = params.customTokens ?? {}
this.excludedTokens = params.excludedTokens ?? []
this.tokens = this.validate([this.customTokens as Record<string, string>, this.defaultTokenRecord, this.excludedTokens])
}

private validate(params: Parameters<typeof Validates.validate>) {
return Validates.validate(...params)
}

protected transformTokensToCssRuleObject(prefix: string, tokens: Record<string, string>, hardcodeDefaultValue: boolean) {
const cssPropertyComputed = (name: string, value: string) => !Object.hasOwn(this.customTokens, name) ? `var(--${prefix}-${Strings.toKebabCase(name)}, ${hardcodeDefaultValue ? value : ''})` : `${value}`

const borderTokens = Validates.transformTokenRecordToCssRuleObject(
tokens,
(name) => `.border-${Strings.toKebabCase(name)}`,
(name, value) => ({
'border-color': cssPropertyComputed(name, value)
})
)
const outlineTokens = Validates.transformTokenRecordToCssRuleObject(
tokens,
(name) => `.outline-${Strings.toKebabCase(name)}`,
(name, value) => ({
'outline-color': cssPropertyComputed(name, value)
})
)
return Object.assign({}, borderTokens, outlineTokens)
}

getPlugin() {
const tokens = this.transformTokensToCssRuleObject(this.prefix, this.tokens, this.hardcodeDefaultValue)
return plugin(({ addUtilities }) => {
addUtilities(tokens)
})
}

}
5 changes: 5 additions & 0 deletions src/tokens/provide-all.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { TBorderProviderConstructorParams } from "./internal/border";
import type { TColorProviderConstructorParams } from "./internal/color";
import type { TElevationProviderConstructorParams } from "./internal/elevation";
import type { TMotionProviderConstructorParams } from "./internal/motion";
import type { TShapeProviderConstructorParams } from "./internal/shape";
import type { TTypographyProviderConstructorParams } from "./internal/typography";
import { provideBorder } from "./provide-border";
import { provideColor } from "./provide-color";
import { provideElevation } from "./provide-elevation";
import { provideMotion } from "./provide-motion";
Expand All @@ -15,20 +17,23 @@ export function provideAll(params: {
motion?: TMotionProviderConstructorParams,
shape?: TShapeProviderConstructorParams,
typography?: TTypographyProviderConstructorParams,
border?: Partial<TBorderProviderConstructorParams>,
}) {
return ({
color: provideColor(params.color),
elevation: provideElevation(params.elevation),
motion: provideMotion(params.motion),
shape: provideShape(params.shape),
typography: provideTypography(params.typography),
border: provideBorder(params.border),
allPlugins() {
return ([
this.color.getPlugin(),
this.elevation.getPlugin(),
this.motion.getPlugin(),
this.shape.getPlugin(),
this.typography.getPlugin(),
this.border.getPlugin(),
])
}
})
Expand Down
15 changes: 15 additions & 0 deletions src/tokens/provide-border.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { BorderProvider, type TBorderProviderConstructorParams } from './internal/border'

/**
* @example
* ```typescript
* const border = provideBorder()
*
* export default {
* plugins: [
* border.getPlugin()
* ]
* }
* ```
*/
export const provideBorder = (param?: Partial<TBorderProviderConstructorParams>) => new BorderProvider(param ?? {})

0 comments on commit 0252947

Please sign in to comment.