Skip to content

Commit 94e7dec

Browse files
committed
refactor: improve types (use csstypes) and type-coverage
1 parent 880d3e6 commit 94e7dec

File tree

5 files changed

+75
-48
lines changed

5 files changed

+75
-48
lines changed

lib/create-theme-renderer.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {isUnitlessProperty} from 'css-in-js-utils';
22
import {createRenderer} from 'fela';
33
import {render as renderToDom} from 'fela-dom';
4-
import enforceLonghands from 'fela-enforce-longhands';
4+
import enforceLonghands from 'fela-enforce-longhands'; // type-coverage:ignore-line
55
import monolithic from 'fela-monolithic';
66
import {createWebPreset} from 'fela-preset-web';
77
import {isPlainObject, merge} from 'uinix-fp';
@@ -14,7 +14,6 @@ import {validateNamespacePrefix} from './utils/validate-namespace-prefix.js';
1414

1515
/**
1616
* @typedef {import('./types.js').StyleObject} StyleObject
17-
* @typedef {import('./types.js').StyleProps} StyleProps
1817
* @typedef {import('./types.js').StyleRule} StyleRule
1918
* @typedef {import('./types.js').Theme} Theme
2019
* @typedef {import('./types.js').ThemeSpec} ThemeSpec
@@ -94,7 +93,6 @@ export const createThemeRenderer = (options = {}) => {
9493
? merge({':root': cssVariables})(initialGlobalStyles)
9594
: initialGlobalStyles;
9695
for (const [selector, style] of Object.entries(globalStyles)) {
97-
/** @type {StyleObject} */
9896
const processedStyle = plugins.reduce(
9997
(_acc, plugin) => plugin(style, 'STATIC', renderer, {theme}),
10098
style,
@@ -106,14 +104,14 @@ export const createThemeRenderer = (options = {}) => {
106104
/**
107105
* Renders style (themed or responsive).
108106
*
107+
* @template P
109108
* @param {StyleObject} style
110-
* @param {StyleProps} styleProps
109+
* @param {P} [styleProps]
111110
* @returns {string} Rendered CSS classname
112111
*/
113112
const renderStyle = (style, styleProps) => {
114-
const styleRule = /** @type {StyleRule} */ (
115-
isPlainObject(style) ? () => style : style
116-
);
113+
const styleRule = isPlainObject(style) ? () => style : style;
114+
// @ts-ignore mask vendor internals
117115
return renderer.renderRule(styleRule, {...styleProps, theme});
118116
};
119117

lib/types.js

+43-30
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,65 @@
1-
// Imports
21
/**
3-
* @typedef {import('fela').IStyle} IStyle
4-
* @typedef {import('fela').TRule} TRule
2+
* @typedef {import('csstype').Properties} CssTypeProperties
53
*/
64

7-
// Aliases
85
/**
9-
* @typedef {string} CssProperty
10-
* A valid CSS property e.g. "backgroundColor", "paddingLeft"
11-
*
6+
* This module exports nothing. It contains JSDoc typedefs.
7+
*/
8+
export {};
9+
10+
// CSS
11+
/**
1212
* @typedef {string | number} CssValue
13-
* A valid CSS value e.g. "4px", 4, "red".
13+
* A valid base CSS value e.g. "4px", 4, "red".
1414
*
15-
* @typedef {string} ThemeProperty
16-
* A string key in the Theme object.
15+
* @typedef {keyof CssTypeProperties} CssProperty
16+
* A valid CSS property e.g. "backgroundColor", "paddingLeft".
17+
*
18+
* @typedef {Record<string, CssValue>} CssVariables
19+
* Map of CSS variables to CSS values.
1720
*/
1821

1922
// Theme
2023
/**
21-
* @typedef {Record<ThemeProperty, CssProperty[]>} ThemeSpec
24+
* @typedef {string} ThemeProperty
25+
* A theme property.
26+
*
27+
* @typedef {Record<ThemeProperty, Array<CssProperty>>} ThemeSpec
2228
* A theme spec relates theme properties with CSS properties.
2329
*
2430
* @typedef {{
25-
* [key: string]: ThemePropertyDefinition | CssValue
26-
* }} ThemePropertyDefinition
27-
* A theme property definition is an arbitrarily nested interface that
28-
* organizes resolved CSS values.
31+
* [key: string]: ThemeRecursive | CssValue
32+
* }} ThemeRecursive
33+
* Recursive helper type.
2934
*
30-
* @typedef {Record<ThemeProperty, ThemePropertyDefinition>} Theme
31-
* A theme relates theme properties with theme property definitions.
35+
* @typedef {Record<ThemeProperty, ThemeRecursive>} Theme
36+
* A theme relates theme properties with CSS values (recursive).
3237
*/
3338

3439
// Style
3540
/**
36-
* @typedef {Record<string, any>} StyleObject
37-
* A style object
41+
* @typedef {CssValue | Array<CssValue>} StyleValue
42+
* Style values can be specified as either singleton or array of CSS values.
3843
*
39-
* @typedef {TRule} StyleRule
40-
* A style rule (function)
44+
* @typedef {CssTypeProperties & Record<string, StyleValue>} StyleCssProperties
45+
* Mapping of CSS properties to style values.
4146
*
42-
* @typedef {StyleObject | StyleRule} Style
43-
* Either a style object or rule
47+
* @typedef {{
48+
* [key: string]: StyleRecursiveAny | StyleRecursivePseudo | StyleCssProperties | StyleValue;
49+
* }} StyleRecursiveAny;
50+
* Recursive helper type.
4451
*
45-
* @typedef {Object} StyleProps
46-
* Generic object for style props
47-
*/
48-
49-
/**
50-
* This module exports nothing. It contains JSDoc typedefs.
52+
* @typedef {{
53+
* [key: string]: StyleRecursivePseudo | StyleRecursiveAny | StyleCssProperties | StyleValue;
54+
* }} StyleRecursivePseudo;
55+
* Recursive helper type.
56+
*
57+
* @typedef {StyleCssProperties | StyleRecursivePseudo | StyleRecursiveAny} StyleObject
58+
* A style object.
59+
*
60+
* @typedef {<P>(props?: P) => StyleObject | null} StyleRule
61+
* A style rule is a function returning a style object or null.
62+
*
63+
* @typedef {StyleObject | StyleRule} Style
64+
* A style can be either a style object or a style rule.
5165
*/
52-
export {};

lib/utils/coerce-esm.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
* @param {X} x
66
* @returns {X}
77
*/
8-
// @ts-ignore
8+
// @ts-ignore TODO: tighten
99
export const coerceEsm = (x) => (x && x.default ? x.default : x);

lib/utils/plugin-responsive-value.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import felaResponsiveValue from 'fela-plugin-responsive-value';
1+
import felaResponsiveValue from 'fela-plugin-responsive-value'; // type-coverage:ignore-line
22

33
import {coerceEsm} from './coerce-esm.js';
44

lib/utils/plugin-theme-value.js

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
import {isPlainObject, props} from 'uinix-fp';
2+
23
import {createCssVariable} from './create-css-variable.js';
34

45
/**
56
* @typedef {import('fela').TPlugin} FelaPlugin
7+
* @typedef {import('../types.js').CssValue} CssValue
8+
* @typedef {import('../types.js').CssVariables} CssVariables
69
* @typedef {import('../types.js').StyleObject} StyleObject
710
* @typedef {import('../types.js').Theme} Theme
11+
* @typedef {import('../types.js').ThemeProperty} ThemeProperty
812
* @typedef {import('../types.js').ThemeSpec} ThemeSpec
913
*/
1014

1115
/**
1216
* Customized Fela theme value plugin.
1317
* @param {Object} params
14-
* @param {Object} [params.cssVariables]
18+
* @param {CssVariables} [params.cssVariables]
1519
* @param {string} [params.namespace]
1620
* @param {ThemeSpec} params.themeSpec
1721
* @returns {FelaPlugin}
@@ -22,16 +26,17 @@ export const themeValue =
2226
resolveThemeValues({
2327
cssVariables,
2428
namespace,
25-
style,
26-
// @ts-ignore
29+
// @ts-ignore mask vendor internals
30+
/** @type {StyleObject} */ style,
31+
// @ts-ignore TODO: tighten
2732
theme: props.theme,
2833
themeSpec,
2934
});
3035

3136
/**
3237
* Recursively resolve theme value
3338
* @param {Object} params
34-
* @param {Object} [params.cssVariables]
39+
* @param {CssVariables} [params.cssVariables]
3540
* @param {string} [params.namespace='']
3641
* @param {StyleObject} params.style
3742
* @param {Theme} params.theme
@@ -57,6 +62,7 @@ const resolveThemeValues = ({
5762
if (cssVariable in cssVariables) {
5863
style[cssProperty] = `var(${cssVariable})`;
5964
} else {
65+
// @ts-ignore TODO: tighten
6066
const isNegative = NEGATIVE_REGEXP.test(styleValue);
6167
if (isNegative) {
6268
styleValue = String(styleValue).split(NEGATIVE_REGEXP)[1].trim();
@@ -75,6 +81,7 @@ const resolveThemeValues = ({
7581
style[cssProperty] = resolveThemeValues({
7682
cssVariables,
7783
namespace,
84+
// @ts-ignore TODO: tighten
7885
style: style[cssProperty],
7986
theme,
8087
themeSpec,
@@ -86,14 +93,23 @@ const resolveThemeValues = ({
8693
};
8794

8895
/**
89-
* Creates a theme themeMapping from a theme spec
96+
* Creates a theme mapping of theme property resolvers from a theme spec.
97+
*
98+
* @typedef ThemePropertyResolver
99+
* A map storing the themeProperty and resolve method.
100+
* @property {(theme: Theme) => CssValue} resolve
101+
* Resolves CSS value given a theme.
102+
* @property {ThemeProperty} themeProperty
103+
* A theme property.
104+
*
105+
* @typedef {Partial<Record<string, ThemePropertyResolver>>} ThemeMapping;
90106
*
91107
* @param {ThemeSpec} themeSpec
92-
* @returns {Object.<string, any>}
108+
* @returns {ThemeMapping}
93109
*/
94110
const createThemeMapping = (themeSpec) => {
95-
/** @type {Object.<string, any>} */
96-
const initialAcc = {};
111+
/** @type {ThemeMapping} */
112+
const themeMapping = {};
97113
return Object.entries(themeSpec).reduce(
98114
(acc, [themeProperty, cssProperties]) => {
99115
for (const cssProperty of cssProperties) {
@@ -105,6 +121,6 @@ const createThemeMapping = (themeSpec) => {
105121

106122
return acc;
107123
},
108-
initialAcc,
124+
themeMapping,
109125
);
110126
};

0 commit comments

Comments
 (0)