UNPKG

@mapcss/preset-tw

Version:

Tailwind CSS preset for MapCSS

248 lines (247 loc) 9.55 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveModifierMap = exports.mergeCSSMap = exports.resolveConfig = exports.resolvePreset = exports.resolveSyntax = exports.resolvePreProcessor = exports.$resolveTheme = exports.resolveTheme = exports.resolveDeepMapIdentifier = void 0; const deps_js_1 = require("../deps.js"); const deps_js_2 = require("../deps.js"); const assert_js_1 = require("./utils/assert.js"); function firstSplit(value, separator) { const arr = new RegExp(`(.+?)${separator}(.+)`).exec(value); if (!arr) return; const [_, ...rest] = arr; return rest; } function leftSplit(value, separator) { const _value = (0, deps_js_1.isString)(value) ? [value] : value; const _last = (0, deps_js_1.last)(_value); if (!_last) return [_value]; const result = firstSplit(_last, separator); if (!result) return [_value]; return [_value, ...leftSplit([...(0, deps_js_1.init)(_value), ...result], separator)]; } class MockRegExpExecArray extends Array { constructor(input = "") { super(); Object.defineProperty(this, "input", { enumerable: true, configurable: true, writable: true, value: input }); Object.defineProperty(this, "index", { enumerable: true, configurable: true, writable: true, value: 0 }); } } function resolveDeepMapIdentifier(value, deepMapCSS, context) { const paths = leftSplit(value, context.separator); for (const path of paths) { const first = (0, deps_js_1.head)(path) ?? "DEFAULT"; const rest = (0, deps_js_1.tail)(path); const identifierContext = { ...context, parentKey: context.key, key: first, path, }; const has = deepMapCSS.has(first); if (has) { const definition = deepMapCSS.get(first); if ((0, deps_js_1.isFunction)(definition)) { if (!(0, deps_js_1.isLength0)(rest)) continue; const result = definition(new MockRegExpExecArray(), identifierContext); if ((0, deps_js_1.isUndefined)(result)) continue; return handleCSSObject(result, identifierContext.className); } if (definition instanceof Map) { return resolveDeepMapIdentifier(rest, definition, identifierContext); } if ((0, deps_js_1.isEmptyObject)(definition)) return; return handleCSSObject(definition, identifierContext.className); } for (const [key, m] of deepMapCSS) { if ((0, deps_js_1.isRegExp)(key)) { const regExpExecResult = key.exec(first); if (!regExpExecResult) continue; if ((0, deps_js_1.isFunction)(m)) { const result = m(regExpExecResult, identifierContext); if ((0, deps_js_1.isUndefined)(result)) continue; return handleCSSObject(result, identifierContext.className); } if (m instanceof Map) { return resolveDeepMapIdentifier(rest, m, identifierContext); } if ((0, deps_js_1.isEmptyObject)(m)) return; return handleCSSObject(m, identifierContext.className); } } } } exports.resolveDeepMapIdentifier = resolveDeepMapIdentifier; function handleCSSObject(cssObject, selector) { if (cssObject instanceof deps_js_1.Root) { return cssObject; } else if ((0, assert_js_1.isCSSDefinition)(cssObject)) { return (0, deps_js_2.toAST)(cssObject.value); } else { return new deps_js_1.Root({ nodes: [new deps_js_1.Rule({ selector, nodes: (0, deps_js_2.toAST)(cssObject).nodes })], }); } } /** resolve theme via propPath safety */ function resolveTheme(identifier, themeRoot, { separator, theme }) { const paths = leftSplit(identifier, separator); for (const path of paths) { const result = (0, deps_js_1.propPath)([themeRoot, ...path], theme); if ((0, deps_js_1.isString)(result)) { return result; } } } exports.resolveTheme = resolveTheme; /** new version for theme resolver */ function $resolveTheme(identifier, themeRoot, { separator, theme }) { const recursive = (path, theme) => { const first = (0, deps_js_1.head)(path); if ((0, deps_js_1.isUndefined)(first)) return theme; const result = (0, deps_js_1.prop)(first, theme); if ((0, deps_js_1.isString)(result) || (0, deps_js_1.isUndefined)(result)) return result; return recursive((0, deps_js_1.tail)(path), result); }; const paths = leftSplit(identifier, separator); for (const path of paths) { const rootResult = (0, deps_js_1.prop)(themeRoot, theme); if ((0, deps_js_1.isUndefined)(rootResult)) continue; if ((0, deps_js_1.isString)(rootResult)) return rootResult; const result = recursive(path, rootResult); if (!(0, deps_js_1.isUndefined)(result)) { return result; } } } exports.$resolveTheme = $resolveTheme; function pickByName({ name }) { return name; } function resolvePreProcessor(...postProcessors) { return (0, deps_js_1.distinctBy)(postProcessors, pickByName); } exports.resolvePreProcessor = resolvePreProcessor; function resolveSyntax(...syntaxes) { return (0, deps_js_1.distinctBy)(syntaxes, pickByName); } exports.resolveSyntax = resolveSyntax; function resolvePreset(preset, context) { return (0, deps_js_1.distinctBy)(preset, pickByName).map(({ fn }) => { const { syntax = [], cssMap = {}, modifierMap = {}, theme = {}, preProcess = [], postcssPlugin = [], css = {}, } = fn(context); return { syntax, cssMap, modifierMap, theme, preProcess, postcssPlugin, css, }; }); } exports.resolvePreset = resolvePreset; /** resolve config to deep merge */ function resolveConfig({ syntax: _syntax = [], preset = [], cssMap: _cssMap = {}, theme: _theme = {}, preProcess: _postProcess = [], modifierMap: _modifierMap = {}, postcssPlugin: _postcssPlugin = [], css: _css = {}, }, context) { const _presets = resolvePreset(preset, context); const modifierMap = _presets.map(({ modifierMap }) => modifierMap) .reduce((acc, cur) => { return (0, deps_js_1.deepMerge)(acc, cur); }, _modifierMap); const theme = _presets.map(({ theme }) => theme).reduce((acc, cur) => { return (0, deps_js_1.deepMerge)(acc, cur); }, _theme); const syntax = resolveSyntax(..._syntax, ..._presets.map(({ syntax }) => syntax).flat()); const deepMapCSS = mergeCSSMap([..._presets.map(({ cssMap }) => cssMap), _cssMap]); const preProcess = resolvePreProcessor(..._postProcess, ..._presets.map(({ preProcess }) => preProcess).flat()); const css = [..._presets.map(({ css }) => css), _css].reduce((acc, cur) => (0, deps_js_1.deepMerge)(acc, cur), {}); const postcssPlugin = [ ..._postcssPlugin, ..._presets.map(({ postcssPlugin }) => postcssPlugin).flat(), ]; return { deepMapCSS, theme, modifierMap, syntax, preProcess, css, postcssPlugin, }; } exports.resolveConfig = resolveConfig; function mergeCSSMap(cssMaps) { const recursive = (id, map) => { const entries = Array.isArray(id) ? id : Object.entries(id); entries.forEach(([key, value]) => { const _key = (0, deps_js_1.isRegExp)(key) ? key : String(key); if ((0, deps_js_1.isFunction)(value) || (0, assert_js_1.isCSSObject)(value)) { map.set(_key, value); } else { map.set(_key, recursive(value, new Map())); } }); return map; }; return cssMaps.reduce((acc, cur) => recursive(cur, acc), new Map()); } exports.mergeCSSMap = mergeCSSMap; function resolveModifierMap(modifier, modifierMap, parentNode, context) { const { separator } = context; const paths = leftSplit(modifier, separator); for (const path of paths) { const _head = (0, deps_js_1.head)(path); const first = _head ?? "DEFAULT"; if ((0, deps_js_1.isUndefined)(first)) continue; if (!context.path) { context.path = path; } const ctx = context.path ? context : { ...context, path }; const modifier = (0, deps_js_1.prop)(first, modifierMap); if ((0, deps_js_1.isUndefined)(modifier)) { context.path = undefined; continue; } if ((0, deps_js_1.isFunction)(modifier)) { const maybeRoot = modifier(parentNode, ctx); context.path = undefined; if ((0, deps_js_1.isUndefined)(maybeRoot)) continue; return maybeRoot; } const rest = (0, deps_js_1.tail)(path); const result = resolveModifierMap(rest, modifier, parentNode, ctx); if (result) { return result; } context.path = undefined; } } exports.resolveModifierMap = resolveModifierMap;