UNPKG

react-native-reanimated

Version:

More powerful alternative to Animated library for React Native.

123 lines (122 loc) 3.94 kB
'use strict'; import { hasProp, hasSuffix, isConfigPropertyAlias, isDefined, isRecord, kebabizeCamelCase } from '../../utils'; const hasValueProcessor = configValue => typeof configValue === 'object' && configValue !== null && 'process' in configValue; class BuilderBase { processedProps = {}; constructor(config) { this.config = config; } add(property, value) { const configValue = this.config[property]; if (!configValue || !isDefined(value) || configValue === false) { return; } if (configValue === true) { this.maybeAssignProp(property, String(value)); } else if (typeof configValue === 'string') { this.maybeAssignProp(property, hasSuffix(value) ? value : `${String(value)}${configValue}`); } else if (isConfigPropertyAlias(configValue)) { this.add(configValue.as, value); } else { this.customProcess(property, value); } } maybeAssignProp(property, value) { this.processedProps[property] ??= value; } maybeAssignProps(properties) { Object.entries(properties).forEach(([key, value]) => this.maybeAssignProp(key, value)); } handleProcess(property, value, process) { const processedValue = process ? process(value) : String(value); if (!isDefined(processedValue)) { return; } if (isRecord(processedValue)) { this.maybeAssignProps(processedValue); } else { this.maybeAssignProp(property, processedValue); } } } class StyleBuilderImpl extends BuilderBase { ruleBuildersSet = new Set(); nameAliases = {}; constructor(config, buildHandler) { super(config); this.buildHandler = buildHandler; } buildFrom(props) { Object.entries(props).forEach(([key, value]) => this.add(key, value)); return this.build(); } build() { this.buildRuleBuilders(); const result = this.buildHandler(this.processedProps, this.nameAliases); this.cleanup(); return result; } customProcess(property, value) { const configValue = this.config[property]; if (typeof configValue !== 'object') { return; } if (isRuleBuilder(configValue)) { this.ruleBuildersSet.add(configValue); configValue.add(property, value); } else { if (hasValueProcessor(configValue)) { this.handleProcess(property, value, configValue.process); } else { this.maybeAssignProp(property, String(value)); } if (hasProp(configValue, 'name')) { this.nameAliases[property] = configValue.name; } } } buildRuleBuilders() { // Build props which are created from other style properties this.ruleBuildersSet.forEach(builder => this.maybeAssignProps(builder.build())); this.ruleBuildersSet.clear(); } cleanup() { this.processedProps = {}; this.nameAliases = {}; } } class RuleBuilderImpl extends BuilderBase { constructor(config, buildHandler) { super(config); this.buildHandler = buildHandler; } build() { const result = this.buildHandler(this.processedProps); this.cleanup(); return result; } customProcess(property, value) { const configValue = this.config[property]; if (hasValueProcessor(configValue)) { this.handleProcess(property, value, configValue.process); } } cleanup() { this.processedProps = {}; } } const isRuleBuilder = value => value instanceof RuleBuilderImpl; const defaultStyleBuildHandler = (props, nameAliases) => { const entries = Object.entries(props); if (entries.length === 0) { return null; } return entries.map(([key, value]) => `${nameAliases[key] ?? kebabizeCamelCase(key)}: ${value}`).join('; '); }; export function createStyleBuilder(config, buildHandler = defaultStyleBuildHandler) { return new StyleBuilderImpl(config, buildHandler); } export function createRuleBuilder(config, buildHandler) { return new RuleBuilderImpl(config, buildHandler); } //# sourceMappingURL=builderFactories.js.map