diff --git a/apps/web-sandbox/src/theme.ts b/apps/web-sandbox/src/theme.ts index 07ed8297..2e1bab75 100644 --- a/apps/web-sandbox/src/theme.ts +++ b/apps/web-sandbox/src/theme.ts @@ -9,14 +9,10 @@ export const components = { transition: 'slow', height: 'xxl', width: 'xxl', - bg: { - md: 'primary', - lg: 'primary', - }, + bg: 'primary', color: 'white', borderRadius: 'm', - borderStyle: 'solid', - borderColor: 'primary', + border: 'primary', '&:hover': { bg: 'transparent', color: 'primary', diff --git a/packages/core/src/parsers/borders.ts b/packages/core/src/parsers/borders.ts new file mode 100644 index 00000000..9a19fd8d --- /dev/null +++ b/packages/core/src/parsers/borders.ts @@ -0,0 +1,49 @@ +import { bordersProperties, Border, BorderConfig } from '@morfeo/spec'; +import { theme } from '../theme'; +import { SliceParsers, ParserParams } from '../types'; +import { baseParser } from './baseParser'; + +type BorderProperties = SliceParsers< + typeof bordersProperties, + keyof typeof bordersProperties +>; + +function makeBorder({ color, style, width }: BorderConfig) { + const { borderColor } = baseParser({ + property: 'borderColor', + scale: 'colors', + value: color, + }); + + const { borderWidth } = baseParser({ + property: 'borderWidth', + scale: 'borderWidths', + value: width, + }); + + const { borderStyle } = baseParser({ + property: 'borderStyle', + scale: 'borderStyles', + value: style, + }); + + return [borderWidth, borderStyle, borderColor].filter(Boolean).join(' '); +} + +function borderParser({ value }: ParserParams<'border'>) { + const config = theme.getValue('borders', value as Border); + + return { + border: !config ? value : makeBorder(config), + }; +} + +export const bordersParsers = Object.keys(bordersProperties).reduce( + (acc, curr) => { + return { + ...acc, + [curr]: borderParser, + }; + }, + {}, +) as BorderProperties; diff --git a/packages/core/src/parsers/createParsers.ts b/packages/core/src/parsers/createParsers.ts index e303ce71..95ae5913 100644 --- a/packages/core/src/parsers/createParsers.ts +++ b/packages/core/src/parsers/createParsers.ts @@ -17,6 +17,7 @@ import { sizeParsers } from './sizes'; import { radiiParsers } from './radii'; import { colorsParsers } from './colors'; import { shadowsParsers } from './shadows'; +import { bordersParsers } from './borders'; import { spacingsParsers } from './spacings'; import { componentsParses } from './components'; import { deepMerge } from '../utils'; @@ -43,6 +44,7 @@ const ADDITIONAL_PARSERS = { ...radiiParsers, ...colorsParsers, ...shadowsParsers, + ...bordersParsers, ...spacingsParsers, ...componentsParses, }; diff --git a/packages/core/tests/parsers/borders.test.ts b/packages/core/tests/parsers/borders.test.ts index 879ee80f..fd6619dd 100644 --- a/packages/core/tests/parsers/borders.test.ts +++ b/packages/core/tests/parsers/borders.test.ts @@ -3,7 +3,18 @@ import { parsers, theme } from '../../src'; const THEME: Theme = { borders: { - primary: '1px solid red', + primary: { + width: 'm', + style: 'solid', + color: 'primary', + }, + secondary: { + width: 'l', + color: 'primary', + }, + }, + colors: { + primary: 'red', }, borderWidths: { m: '3px', @@ -26,7 +37,21 @@ describe('borders', () => { test('should generate a style with border property', () => { const result = parsers.resolve({ border: 'primary' }); expect(result).toEqual({ - border: '1px solid red', + border: '3px solid red', + }); + }); + + test('should generate a border style without borderStyle', () => { + const result = parsers.resolve({ border: 'secondary' } as any); + expect(result).toEqual({ + border: '5px red', + }); + }); + + test('should generate a border style from a regular css string', () => { + const result = parsers.resolve({ border: '4px dotted blue' } as any); + expect(result).toEqual({ + border: '4px dotted blue', }); }); }); diff --git a/packages/preset-default/src/base/borders.ts b/packages/preset-default/src/base/borders.ts index 44ff91bd..695affeb 100644 --- a/packages/preset-default/src/base/borders.ts +++ b/packages/preset-default/src/base/borders.ts @@ -1,6 +1,6 @@ import { Borders } from '@morfeo/spec'; export const borders: Borders = { - primary: '1px solid dark', - secondary: '3px solid light', + primary: { width: 'm', style: 'solid', color: 'invertedBackground' }, + secondary: { width: 's', style: 'solid', color: 'invertedBackground' }, }; diff --git a/packages/preset-default/src/base/colors.ts b/packages/preset-default/src/base/colors.ts index 8c041c13..ce020728 100644 --- a/packages/preset-default/src/base/colors.ts +++ b/packages/preset-default/src/base/colors.ts @@ -1,5 +1,3 @@ -import { Colors } from '@morfeo/spec'; - export const baseColors = { dark: '#2f2f2f', error: '#d10343', diff --git a/packages/spec/src/types/borders.ts b/packages/spec/src/types/borders.ts index 1fdff074..149c1c1c 100644 --- a/packages/spec/src/types/borders.ts +++ b/packages/spec/src/types/borders.ts @@ -1,19 +1,5 @@ import { bordersMap, borderStylesMap, borderWidthsMap } from '../properties'; - -export interface Borders { - primary: string; - secondary: string; -} - -export type Border = keyof Borders; - -type BaseBorderProps = { - [K in typeof bordersMap[number]]: Border; -}; - -export interface BorderProps extends BaseBorderProps {} - -export type BorderProperty = keyof BorderProps; +import { Color } from './colors'; export interface BorderWidths { xxs: string; @@ -55,3 +41,24 @@ type BaseBorderStyleProps = { export interface BorderStyleProps extends BaseBorderStyleProps {} export type BorderStyleProperty = keyof BorderStyleProps; + +export type BorderConfig = { + width?: BorderWidth; + color?: Color; + style?: BorderStyle; +}; + +export interface Borders { + primary: BorderConfig; + secondary: BorderConfig; +} + +export type Border = keyof Borders; + +type BaseBorderProps = { + [K in typeof bordersMap[number]]: Border; +}; + +export interface BorderProps extends BaseBorderProps {} + +export type BorderProperty = keyof BorderProps;