Skip to content

Commit

Permalink
feat!: make utils configurable for v1 release
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisrzhou committed Dec 30, 2021
1 parent d0692c9 commit 90db661
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 325 deletions.
9 changes: 2 additions & 7 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
/**
* @typedef {import('./lib/types.js').Theme} Theme
* @typedef {import('./lib/types.js').ThemeMapping} ThemeMapping
*/

export {createTheme} from './lib/create-theme.js';
export {themeMapping} from './lib/theme-mapping.js';
export * as types from './lib/types.js';
export {defaultThemeSpec} from './lib/default-theme-spec.js';
export * from './lib/types.js';
33 changes: 17 additions & 16 deletions lib/create-theme.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
import {merge} from 'uinix-fp-merge';

import {themeMapping} from './theme-mapping.js';
import {defaultThemeSpec} from './default-theme-spec.js';

export {createTheme};

/**
* @typedef {import('./types.js').Theme} Theme
* @typedef {import('./types.js').ThemeSpec} ThemeSpec
*/

/**
* Creates a uinix `Theme` object.
*
* The theme is a mapping of `ThemeProperty` to `ThemePropertyDefinition` (arbitarily nested), which eventually resolves to valid `ThemePropertyValue`s.
* Creates a theme based on the provided theme spec and override theme.
* Theme properties not specified in the theme spec are not included in the
* resolved theme.
*
* Supports deep-merging and overriding with a partial theme.
*
* @param {Partial<Theme>} theme
* @returns {Theme}
* @template {Theme} T
* @template {ThemeSpec} S
* @param {T} [theme]
* @param {S} [themeSpec]
* @returns {T & Record<keyof S, {}>}
*/
const createTheme = (theme = {}) => {
const defaultTheme = Object.fromEntries(
Object.keys(themeMapping).map((themeProperty) => [themeProperty, {}]),
const createTheme = (theme, themeSpec) =>
// @ts-ignore (insufficient TS-inference)
Object.fromEntries(
Object.keys(themeSpec || defaultThemeSpec).map((themeProperty) => [
themeProperty,
theme?.[themeProperty] || {},
]),
);

return merge(defaultTheme)(theme);
};
29 changes: 10 additions & 19 deletions lib/theme-mapping.js → lib/default-theme-spec.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
export {themeMapping};

/**
* @typedef {import('./types.js').ThemeMapping} ThemeMapping
*/

/**
* A mapping of `ThemeProperty` to one or more `CssProperty`.
*
* @type {ThemeMapping}
*/
const themeMapping = {
export const defaultThemeSpec = {
animations: ['animation'],
backgrounds: ['background'],
borders: [
'border',
'borderBlock',
Expand Down Expand Up @@ -64,6 +54,7 @@ const themeMapping = {
'outlineColor',
'stroke',
],
filters: ['filter'],
fontFamilies: ['fontFamily'],
fontSizes: ['fontSize'],
fontWeights: ['fontWeight'],
Expand All @@ -80,19 +71,19 @@ const themeMapping = {
],
shadows: ['boxShadow', 'textShadow'],
sizes: [
'width',
'minWidth',
'maxWidth',
'height',
'minHeight',
'maxHeight',
'flexBasis',
'blockSize',
'flexBasis',
'height',
'inlineSize',
'maxBlockSize',
'maxHeight',
'maxInlineSize',
'maxWidth',
'minBlockSize',
'minHeight',
'minInlineSize',
'minWidth',
'width',
],
spacings: [
'bottom',
Expand Down
97 changes: 17 additions & 80 deletions lib/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,92 +4,29 @@

export {};

// Aliases
/**
* @typedef {string} CssProperty
* A valid JS-named CSS property (e.g. color, marginBottom, alignItems).
* A valid CSS property e.g. "backgroundColor", "paddingLeft"
*
* @typedef {string | number} CssPropertyValue
* A valid `CssProperty` value (e.g. "center", "10px", 10).
* @typedef {string | number} CssValue
* A valid CSS value e.g. "4px", 4, "red".
*
* @typedef {object} CssKeyframesRuleValue
* A valid CSS keyframes rule value expressed as a JS object.
* e.g. {from: {...}, to: {...}}
*
* @typedef {CssPropertyValue | CssKeyframesRuleValue} ThemePropertyValue
* The possible value types a theme property vale can assume.
* @typedef {string} ThemeProperty
* A string key in the Theme object.
*/

// Theme
/**
* @typedef {Record<ThemeProperty, CssProperty[]>} ThemeSpec
* A theme spec relates theme properties with CSS properties.
*
* @typedef {{
* [key: string]: ThemePropertyValue | ThemePropertyDefinition
* [key: string]: ThemePropertyDefinition | CssValue
* }} ThemePropertyDefinition
* A `ThemePropertyDefinition` can be recursively nested to organize
* evenutally-resolved `ThemePropertyValue`s.
* A recursively nested definition for a `ThemeProperty` that eventually
* resolves to a `ThemePropertyValue`.
*
* @typedef {(
* 'animations'
* | 'borders'
* | 'borderStyles'
* | 'borderWidths'
* | 'colors'
* | 'fontFamilies'
* | 'fontSizes'
* | 'fontWeights'
* | 'keyframes'
* | 'letterSpacings'
* | 'lineHeights'
* | 'opacities'
* | 'radii'
* | 'shadows'
* | 'sizes'
* | 'spacings'
* | 'transforms'
* | 'transitions'
* | 'zIndices'
* )} ThemeProperty
* Theme property values
*
* @typedef Theme
* A mapping of `ThemeProperty` to `ThemePropertyDefinition`.
* @property {ThemePropertyDefinition} animations
* @property {ThemePropertyDefinition} borders
* @property {ThemePropertyDefinition} borderStyles
* @property {ThemePropertyDefinition} borderWidths
* @property {ThemePropertyDefinition} colors
* @property {ThemePropertyDefinition} fontFamilies
* @property {ThemePropertyDefinition} fontSizes
* @property {ThemePropertyDefinition} fontWeights
* @property {ThemePropertyDefinition} keyframes
* @property {ThemePropertyDefinition} letterSpacings
* @property {ThemePropertyDefinition} lineHeights
* @property {ThemePropertyDefinition} opacities
* @property {ThemePropertyDefinition} radii
* @property {ThemePropertyDefinition} shadows
* @property {ThemePropertyDefinition} sizes
* @property {ThemePropertyDefinition} spacings
* @property {ThemePropertyDefinition} transforms
* @property {ThemePropertyDefinition} transitions
* @property {ThemePropertyDefinition} zIndices
* A theme property definition is an arbitrarily nested interface that
* organizes resolved CSS values.
*
* @typedef ThemeMapping
* A mapping of `ThemeProperty` to one or more `CssProperty`.
* @property {CssProperty[]} animations
* @property {CssProperty[]} borders
* @property {CssProperty[]} borderStyles
* @property {CssProperty[]} borderWidths
* @property {CssProperty[]} colors
* @property {CssProperty[]} fontFamilies
* @property {CssProperty[]} fontSizes
* @property {CssProperty[]} fontWeights
* @property {CssProperty[]} keyframes
* @property {CssProperty[]} letterSpacings
* @property {CssProperty[]} lineHeights
* @property {CssProperty[]} opacities
* @property {CssProperty[]} radii
* @property {CssProperty[]} shadows
* @property {CssProperty[]} sizes
* @property {CssProperty[]} spacings
* @property {CssProperty[]} transforms
* @property {CssProperty[]} transitions
* @property {CssProperty[]} zIndices
* @typedef {Record<ThemeProperty, ThemePropertyDefinition>} Theme
* A theme relates theme properties with theme property definitions.
*/
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "uinix-theme",
"version": "0.2.3",
"description": "uinix theme spec and utilties",
"description": "Configurable theme spec and utilties",
"license": "MIT",
"keywords": [
"uinix",
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![Downloads][downloads-badge]][downloads]
[![Size][bundle-size-badge]][bundle-size]

[uinix][uinix-js] theme spec and utilties.
Configurable theme spec and utilties.

---

Expand Down Expand Up @@ -45,7 +45,7 @@ npm install uinix-theme

This package has no default export and exports the following identifiers:
- `createTheme`
- `createThemeSpec`
- `defaultThemeSpec`

APIs are explorable via [JSDoc]-based [Typescript] typings accompanying the source code.

Expand Down
Loading

0 comments on commit 90db661

Please sign in to comment.