UNPKG

edgerender

Version:
102 lines (90 loc) 2.63 kB
import type {Properties} from 'csstype' export function render_styles(styles: Properties): string | null { let serialized = '' let delimiter = '' for (const [name, value] of Object.entries(styles)) { const is_custom_property = name.indexOf('--') == 0 if (value != null) { serialized += delimiter + (is_custom_property ? name : get_style_name(name)) + ':' + get_style_value(name, value, is_custom_property) delimiter = ';' } } return serialized || null } const uppercase_pattern = /([A-Z])/g const ms_pattern = /^ms-/ const style_name_cache: Record<string, string> = {} export const hyphenate = (name: string): string => name.replace(uppercase_pattern, '-$1').toLowerCase() function get_style_name(name: string): string { // from https://github.com/facebook/react/blob/master/packages/react-dom/src/server/ReactPartialRenderer.js // (processStyleName) and // https://github.com/facebook/react/blob/master/packages/react-dom/src/shared/hyphenateStyleName.js const cached_value = style_name_cache[name] as string | undefined if (typeof cached_value == 'string') { return cached_value } else { return (style_name_cache[name] = hyphenate(name).replace(ms_pattern, '-ms-')) } } function get_style_value(name: string, value: string | number | null | boolean, is_custom_property: boolean): string { // from https://github.com/facebook/react/blob/master/packages/react-dom/src/shared/dangerousStyleValue.js const is_empty = value == null || typeof value === 'boolean' || value === '' if (is_empty) { return '' } if (!is_custom_property && typeof value === 'number' && value !== 0 && !unitless_numbers.has(name)) { // Presumes implicit 'px' suffix for unitless numbers return value + 'px' } return ('' + value).trim() } const unitless_numbers = new Set([ 'animationIterationCount', 'aspectRatio', 'borderImageOutset', 'borderImageSlice', 'borderImageWidth', 'boxFlex', 'boxFlexGroup', 'boxOrdinalGroup', 'columnCount', 'columns', 'flex', 'flexGrow', 'flexPositive', 'flexShrink', 'flexNegative', 'flexOrder', 'gridArea', 'gridRow', 'gridRowEnd', 'gridRowSpan', 'gridRowStart', 'gridColumn', 'gridColumnEnd', 'gridColumnSpan', 'gridColumnStart', 'fontWeight', 'lineClamp', 'lineHeight', 'opacity', 'order', 'orphans', 'tabSize', 'widows', 'zIndex', 'zoom', // SVG-related properties 'fillOpacity', 'floodOpacity', 'stopOpacity', 'strokeDasharray', 'strokeDashoffset', 'strokeMiterlimit', 'strokeOpacity', 'strokeWidth', ])