import { cloneDeep, isEqual } from 'lodash'; import type { PageDSL7, PageDSL8, WidgetProps7, WidgetProps8 } from '../../types/index.js'; // if these properties have been cleared by the user, // set them to a value that will match the existing behavior const WIDGET_TYPE_TO_DEFAULT_STYLES = { CONTAINER_WIDGET: { backgroundColor: 'none' }, FORM_WIDGET: { backgroundColor: 'none' }, IMAGE_WIDGET: { borderRadius: '0px' }, CANVAS_WIDGET: { backgroundColor: 'none', padding: { top: { value: 0, mode: 'px' }, bottom: { value: 0, mode: 'px' }, left: { value: 0, mode: 'px' }, right: { value: 0, mode: 'px' } } }, GRID_WIDGET: { backgroundColor: 'none' } }; // white -> "DEFAULT" // '' -> none // what components get the padding ? // canvas const WHITES = new Set(['#ffffff', 'white', 'rgb(255, 255, 255)']); const BORDER_RADII = new Set(['4px']); // if these properties have not been set by the user, clear them so that // they will be themable const WIDGET_TYPE_TO_CLEARED_STYLES = { CONTAINER_WIDGET: { backgroundColor: WHITES }, FORM_WIDGET: { backgroundColor: WHITES }, IMAGE_WIDGET: { borderRadius: BORDER_RADII }, CANVAS_WIDGET: { padding: { top: { value: 12, mode: 'px' }, bottom: { value: 12, mode: 'px' }, right: { value: 16, mode: 'px' }, left: { value: 16, mode: 'px' } } }, GRID_WIDGET: { backgroundColor: WHITES } }; const adjustStyles = (oldWidget: WidgetProps7): WidgetProps8 => { // Don't clone children for performance reasons const { children: oldChildren, ..._widget } = Object.freeze(oldWidget); const newWidget = cloneDeep(_widget) as unknown as WidgetProps7; if (WIDGET_TYPE_TO_DEFAULT_STYLES[newWidget.type]) { Object.keys(WIDGET_TYPE_TO_DEFAULT_STYLES[newWidget.type]).forEach((key) => { if (!newWidget[key]) { newWidget[key] = WIDGET_TYPE_TO_DEFAULT_STYLES[newWidget.type][key]; } }); } // clear out styles that have not been set by the user if (WIDGET_TYPE_TO_CLEARED_STYLES[newWidget.type]) { Object.keys(WIDGET_TYPE_TO_CLEARED_STYLES[newWidget.type]).forEach((key) => { if ( typeof newWidget[key] === 'string' && WIDGET_TYPE_TO_CLEARED_STYLES[newWidget.type][key].has((newWidget[key] as string).toLowerCase()) ) { newWidget[key] = undefined; } else if (isEqual(newWidget[key], WIDGET_TYPE_TO_CLEARED_STYLES[newWidget.type][key])) { newWidget[key] = undefined; } }); } // recurse over children if (oldChildren) { newWidget.children = oldChildren.map((child) => adjustStyles(child)); } return newWidget; }; export const migrate7to8 = (dsl: PageDSL7): PageDSL8 => { const updatedDsl = adjustStyles(dsl); updatedDsl.version = 8; return updatedDsl as PageDSL8; };