'use strict';
import { createPropsBuilder } from '../../style';
import type { PlainStyle, UnknownRecord } from '../../types';
import {
hasValueProcessor,
isConfigPropertyAlias,
isDefined,
kebabizeCamelCase,
maybeAddSuffix,
} from '../../utils';
import { isRuleBuilder } from '../utils';
import { PROPERTIES_CONFIG } from './config';
import type { PropsBuilderConfig, RuleBuilder } from './types';
type WebPropsBuilderConfig
=
PropsBuilderConfig
;
export function createWebPropsBuilder(
config: WebPropsBuilderConfig
) {
const usedRuleBuilders = new Set>();
const propsBuilder = createPropsBuilder({
config,
processConfigValue(configValue, propertyKey) {
// Handle true - include unchanged
if (configValue === true) {
return true;
}
// Handle false - exclude property
if (configValue === false) {
return;
}
// Handle suffix (e.g., 'px')
if (typeof configValue === 'string') {
return (value) => maybeAddSuffix(value, configValue);
}
// Handle property alias
if (isConfigPropertyAlias(configValue)) {
return config[configValue.as];
}
// Handle rule builders - store reference and return marker
if (isRuleBuilder(configValue)) {
// Return a processor that feeds values to the rule builder and returns undefined
// so the property doesn't appear in the regular processed props (only the result
// of the rule builder will appear in the final style)
return (value) => {
usedRuleBuilders.add(configValue);
configValue.add(propertyKey, value as TProps[keyof TProps]);
return;
};
}
// Handle value processor
if (hasValueProcessor(configValue)) {
return configValue.process;
}
},
});
return {
build(props: Partial): string | null {
usedRuleBuilders.clear();
// Build props - rule builders are fed during processing
const processedProps = propsBuilder.build(props);
// Build only used rule builders and merge their results
for (const builder of usedRuleBuilders) {
Object.assign(processedProps, builder.build());
}
// Convert to CSS string
const cssString = Object.entries(processedProps)
.reduce((acc, [key, value]) => {
if (isDefined(value)) {
acc.push(`${kebabizeCamelCase(key)}: ${value as string}`);
}
return acc;
}, [])
.join('; ');
return cssString || null; // Return null if cssString is empty
},
};
}
export const webPropsBuilder =
createWebPropsBuilder(PROPERTIES_CONFIG);