diff --git a/shesha-reactjs/src/components/panel/index.tsx b/shesha-reactjs/src/components/panel/index.tsx index a0097945c..77c163917 100644 --- a/shesha-reactjs/src/components/panel/index.tsx +++ b/shesha-reactjs/src/components/panel/index.tsx @@ -1,20 +1,17 @@ import React, { FC } from 'react'; -import { Collapse, Skeleton, theme } from 'antd'; +import { Collapse, Skeleton } from 'antd'; import { CollapseProps } from 'antd/lib/collapse'; import classNames from 'classnames'; -import styled from 'styled-components'; +import { IStyleType } from '@/index'; import { useStyles } from './styles/styles'; -const { useToken } = theme; - export type headerType = 'parent' | 'child' | 'default'; -export interface ICollapsiblePanelProps extends CollapseProps { +export interface ICollapsiblePanelProps extends CollapseProps, Omit { isActive?: boolean; header?: React.ReactNode; className?: string; extraClassName?: string; - style?: React.CSSProperties; showArrow?: boolean; forceRender?: boolean; extra?: React.ReactNode; @@ -30,6 +27,9 @@ export interface ICollapsiblePanelProps extends CollapseProps { primaryColor?: string; dynamicBorderRadius?: number; panelHeadType?: headerType; + headerStyles?: IStyleType; + bodyStyle?: React.CSSProperties; + headerStyle?: React.CSSProperties; } /** @@ -41,70 +41,42 @@ export interface ICollapsiblePanelProps extends CollapseProps { * */ -const StyledCollapse: any = styled(Collapse) < - Omit ->` - .ant-collapse-header { - visibility: ${({ hideCollapseContent }) => (hideCollapseContent ? 'hidden' : 'visible')}; - border-top: ${({ primaryColor, panelHeadType }) => (panelHeadType === 'parent' ? `3px solid ${primaryColor}` : 'none')}; - border-left: ${({ primaryColor, panelHeadType }) => (panelHeadType === 'child' ? `3px solid ${primaryColor}` : 'none')}; - font-size: ${({ panelHeadType }) => (panelHeadType === 'parent' ? '13px' : '16px')}; - font-weight: 'bold'; - background-color: ${({ headerColor }) => headerColor} !important; - - } - .ant-collapse-content { - .ant-collapse-content-box > .sha-components-container { - background-color: ${({ bodyColor }) => bodyColor}; - } - } -`; - export const CollapsiblePanel: FC> = ({ expandIconPosition = 'end', onChange, header, extra, children, - noContentPadding, loading, className, extraClassName, - style, collapsedByDefault = false, showArrow, collapsible, ghost, - bodyColor = 'unset', - headerColor = 'unset', + bodyStyle = { borderRadius: '8px 8px 8px 8px', }, + headerStyle = { + borderRadius: '8px 8px 8px 8px' + }, isSimpleDesign, - hideCollapseContent, - hideWhenEmpty = false, - panelHeadType = 'default', - dynamicBorderRadius, - + panelHeadType, + noContentPadding, + hideWhenEmpty, + hideCollapseContent }) => { // Prevent the CollapsiblePanel from collapsing every time you click anywhere on the extra and header const onContainerClick = (event: React.MouseEvent) => event?.stopPropagation(); - const { styles } = useStyles({ borderRadius: dynamicBorderRadius }); - const { token } = useToken(); - - const shaCollapsiblePanelStyle = isSimpleDesign ? {} : styles.shaCollapsiblePanel; + const { styles } = useStyles({ bodyStyle, headerStyles: headerStyle, panelHeadType, ghost, noContentPadding, hideWhenEmpty, hideCollapseContent }); + const shaCollapsiblePanelStyle = isSimpleDesign ? styles.shaSimpleDesign : styles.shaCollapsiblePanel; return ( - { - const extraMargin = "28px"; - +export const useStyles = createStyles(({ css, cx, token, prefixCls }, { headerStyles, panelHeadType, bodyStyle, hideCollapseContent }) => { const noContentPadding = "no-content-padding"; const hideWhenEmpty = "hide-empty"; - const shaCollapsiblePanel = cx("sha-collapsible-panel", css` - &.${hideWhenEmpty}:not(:has(.${prefixCls}-collapse-content .${prefixCls}-form-item:not(.${prefixCls}-form-item-hidden))) { + const { + borderWidth, + borderStyle, + borderColor, + borderTopWidth, + borderTopStyle, + borderTopColor, + borderBottomWidth, + borderBottomStyle, + borderBottomColor, + borderRightWidth, + borderRightStyle, + borderRightColor, + borderLeftWidth, + borderLeftStyle, + borderLeftColor, + backgroundColor, + backgroundImage, + boxShadow, + width, + height, + minWidth, + minHeight, + maxWidth, + maxHeight, + borderRadius, + marginBottom, + marginTop, + marginLeft, + marginRight, + paddingTop, + paddingBottom, + paddingLeft, + paddingRight, + ...rest + } = bodyStyle; + + const { + backgroundImage: headerBgImage, + backgroundColor: headerBgColor, + height: headerHeight, + minHeight: headerMinHeight, + maxHeight: headerMaxHeight, + color: headerColor = token.colorTextLabel, + fontFamily, + textAlign, + fontSize, + fontWeight, + borderWidth: headerBorderWidth, + borderStyle: headerBorderStyle, + borderColor: headerBorderColor, + borderTopWidth: headerBorderTopWidth = panelHeadType === 'parent' ? '3px' : '', + borderTopStyle: headerBorderTopStyle, + borderTopColor: headerBorderTopColor = panelHeadType === 'parent' ? token.colorPrimary : '', + borderBottomWidth: headerBorderBottomWidth, + borderBottomStyle: headerBorderBottomStyle, + borderBottomColor: headerBorderBottomColor, + borderRightWidth: headerBorderRightWidth, + borderRightStyle: headerBorderRightStyle, + borderRightColor: headerBorderRightColor, + borderLeftWidth: headerBorderLeftWidth = panelHeadType === 'child' ? '3px' : '', + borderLeftStyle: headerBorderLeftStyle, + borderLeftColor: headerBorderLeftColor = panelHeadType === 'child' ? token.colorPrimary : '', + borderRadius: headerBorderRadius, + ...headerRest + } = headerStyles; + + const borderTopLeftRadius = borderRadius?.split(' ')[0] || 0; + const borderTopRightRadius = borderRadius?.split(' ')[1] || 0; + const borderBottomLeftRadius = borderRadius?.split(' ')[2] || 0; + const borderBottomRightRadius = borderRadius?.split(' ')[3] || 0; + + const shaCollapsiblePanel = cx("ant-collapse-component", css` + &.${hideWhenEmpty}:not(:has(.${prefixCls}-collapse-content .${prefixCls}-form-item:not(.${prefixCls}-form-item-hidden))) { display: none; } + ${borderWidth && '--ant-line-width: 0px !important;'} + --primary-color: ${token.colorPrimary}; + --ant-collapse-content-padding: ${paddingTop} ${paddingRight} ${paddingBottom} ${paddingLeft}; + width: ${width}; + min-width: ${minWidth}; + max-width: ${maxWidth}; + height: max-content; + min-height: ${minHeight}; + max-height: ${maxHeight}; + border-radius: ${borderTopLeftRadius} ${borderTopRightRadius} ${borderBottomLeftRadius} ${borderBottomRightRadius} !important; + margin-bottom: ${marginBottom}; + margin-top: ${marginTop}; + margin-left: ${marginLeft}; + margin-right: ${marginRight}; - &.${prefixCls}-collapse-icon-position-left { - .${prefixCls}-collapse-header-text { - margin-left: ${extraMargin}; - } - } - - &.${prefixCls}-collapse-icon-position-right { - .${prefixCls}-collapse-extra { - margin-right: ${extraMargin}; - } + + .ant-collapse-item { + display: flex; + flex-direction: column; + box-shadow: ${boxShadow}; + ${rest} + border-radius: ${borderTopLeftRadius} ${borderTopRightRadius} ${borderBottomLeftRadius} ${borderBottomRightRadius} !important; + } + + .ant-collapse-content-box { + width: ${width}; + min-width: ${minWidth}; + max-width: ${maxWidth}; + height: ${height}; + min-height: ${minHeight}; + max-height: ${maxHeight}; + background: ${backgroundImage || backgroundColor}; + position: relative; + padding-top: ${paddingTop} !important; + padding-bottom: ${paddingBottom} !important; + padding-left: ${paddingLeft} !important; + padding-right: ${paddingRight} !important; + border-radius : 0 0 ${borderBottomLeftRadius} ${borderBottomRightRadius} !important; + border-top: ${borderTopWidth || borderWidth} ${borderTopStyle || borderStyle} ${borderTopColor || borderColor}; + border-right: ${borderRightWidth || borderWidth} ${borderRightStyle || borderStyle} ${borderRightColor || borderColor}; + border-left: ${borderLeftWidth || borderWidth} ${borderLeftStyle || borderStyle} ${borderLeftColor || borderColor}; + border-bottom: ${borderBottomWidth || borderWidth} ${borderBottomStyle || borderStyle} ${borderBottomColor || borderColor}; + } + + .ant-collapse-header { + position: relative; + visibility: ${hideCollapseContent ? 'hidden' : 'visible'}; + border-radius : ${borderTopLeftRadius} ${borderTopRightRadius} 0 0 !important; + background: ${headerBgImage || headerBgColor}; + height: ${headerHeight}; + min-height: ${headerMinHeight}; + max-height: ${headerMaxHeight}; + border-top: ${headerBorderTopWidth || headerBorderWidth} ${headerBorderTopStyle || headerBorderStyle} ${headerBorderTopColor || headerBorderColor}; + border-right: ${headerBorderRightWidth || headerBorderWidth} ${headerBorderRightStyle || headerBorderStyle} ${headerBorderRightColor || headerBorderColor}; + border-left: ${headerBorderLeftWidth || headerBorderWidth} ${headerBorderLeftStyle || headerBorderStyle} ${headerBorderLeftColor || headerBorderColor}; + border-bottom: ${headerBorderBottomWidth || headerBorderWidth} ${headerBorderBottomStyle || headerBorderStyle} ${headerBorderBottomColor || headerBorderColor}; + ${headerRest} + + .ant-collapse-header-text { + color: ${headerColor}; + font-family: ${fontFamily}; + text-align: ${textAlign}; + font-size: ${fontSize}; + font-weight: ${fontWeight}; + align-self: center; + margin-left: 10px; } - - &.${noContentPadding} { - .${prefixCls}-collapse-content-box { - padding: unset; - padding-top: 16px; - } + + .ant-collapse-extra { + align-self: center; + margin-right: 10px; } - - &:not(.${prefixCls}-collapse-ghost) { - > .${prefixCls}-collapse-item { - > .${prefixCls}-collapse-header { - border-top-left-radius: ${borderRadius ?? token.borderRadiusLG}px; - border-top-right-radius: ${borderRadius ?? token.borderRadiusLG}px; - background-color: #f0f0f0; - margin:'auto 0px'; - min-height: 50px; - height: auto; - width: auto; - padding: 0; - padding-left:10px; - padding-top:5px; - } - } + + .ant-collapse-expand-icon { + align-self: center; } - - &.${prefixCls}-collapse-ghost { + + } + + &.${prefixCls}-collapse-ghost { > .${prefixCls}-collapse-item { > .${prefixCls}-collapse-header { - padding: 4px 0px; border-bottom: 2px solid ${token.colorPrimary}; border-bottom-left-radius: unset; border-bottom-right-radius: unset; + border-top: ${panelHeadType === 'parent' ? `${headerBorderTopWidth} solid var(--primary-color)` : 'none'}; + border-left: ${panelHeadType === 'child' ? `${headerBorderTopWidth} solid var(--primary-color)` : 'none'}; + font-weight: ${fontWeight || 'bold'}; } > .${prefixCls}-collapse-content { > .${prefixCls}-collapse-content-box { @@ -62,66 +176,43 @@ export const useStyles = createStyles(({ css, cx, token, prefixCls }, { borderRa } } } - - .${prefixCls}-collapse-item { - &.${prefixCls}-collapse-item-active { - } - - .${prefixCls}-collapse-header { - min-height: 25px; - font-size: 15px; - font-weight: 500; - position: relative; - display: flex; - justify-content: space-between; - align-items: center; - .${prefixCls}-collapse-extra { - float: unset; - } - - .${prefixCls}-collapse-header-text { - flex-grow: 1; - margin: auto 0; - margin-left: -5px; - } - } - - .${prefixCls}-collapse-content { - border-top: unset; - background: white; - - &.${noContentPadding} { - padding: unset; + + `); + + const shaSimpleDesign = cx(css` + &.${hideWhenEmpty}:not(:has(.${prefixCls}-collapse-content .${prefixCls}-form-item:not(.${prefixCls}-form-item-hidden))) { + display: none; + } + --ant-line-width: 0px !important; + --primary-color: ${token.colorPrimary}; + &.${prefixCls}-collapse-ghost { + > .${prefixCls}-collapse-item { + > .${prefixCls}-collapse-header { + padding: 12px 16px !important; + border-top: ${panelHeadType === 'parent' ? `3px solid var(--primary-color)` : 'none'}; + border-left: ${panelHeadType === 'child' ? `3px solid var(--primary-color)` : 'none'}; + font-size: ${panelHeadType === 'parent' ? '13px' : '16px'}; + font-weight: 'bold'; } - - &.${prefixCls}-collapse-content-active { + > .${prefixCls}-collapse-content { + > .${prefixCls}-collapse-content-box { + padding: 5px 0; + } } } } - - .${prefixCls}-collapse-header-text { - font-size: 14px; - min-height: 30px; - line-height: 2; - } - - .${prefixCls}-blend-btn { - border: none; - height: 24px; - } - - .${prefixCls}-collapse-arrow { - padding-top: 3px !important; - margin-top: -3px !important; - } - .ant-collapse-expand-icon{ - margin-right:10px; - } - `); + + .ant-collapse-header { + border-top: ${panelHeadType === 'parent' ? `3px solid var(--primary-color)` : 'none'}; + border-left: ${panelHeadType === 'child' ? `3px solid var(--primary-color)` : 'none'}; + font-size: ${panelHeadType === 'parent' ? '13px' : '16px'}; + font-weight: 'bold'; + `); return { shaCollapsiblePanel, noContentPadding, hideWhenEmpty, + shaSimpleDesign }; }); \ No newline at end of file diff --git a/shesha-reactjs/src/designer-components/_common-migrations/migrateStyles.ts b/shesha-reactjs/src/designer-components/_common-migrations/migrateStyles.ts index 05e742ca6..98d2e70c2 100644 --- a/shesha-reactjs/src/designer-components/_common-migrations/migrateStyles.ts +++ b/shesha-reactjs/src/designer-components/_common-migrations/migrateStyles.ts @@ -37,7 +37,13 @@ export const migratePrevStyles = (prev: T, defaults?: Om left: border('left'), right: border('right'), }, - radius: { all: prevStyles?.borderRadius || defaults?.border?.radius?.all || 8 }, + radius: { + all: defaults?.border?.radius?.all || 8, + topLeft: defaults?.border?.radius?.topLeft || 8, + topRight: defaults?.border?.radius?.topRight || 8, + bottomLeft: defaults?.border?.radius?.bottomLeft || 8, + bottomRight: defaults?.border?.radius?.bottomRight || 8 + }, }, background: { type: defaults?.background?.type || 'color', diff --git a/shesha-reactjs/src/designer-components/_settings/utils/border/utils.tsx b/shesha-reactjs/src/designer-components/_settings/utils/border/utils.tsx index 9ab13fe1b..80da8db50 100644 --- a/shesha-reactjs/src/designer-components/_settings/utils/border/utils.tsx +++ b/shesha-reactjs/src/designer-components/_settings/utils/border/utils.tsx @@ -14,6 +14,7 @@ import { } from "@ant-design/icons"; import { IDropdownOption } from "../background/interfaces"; import { addPx } from "../../utils"; +import { nanoid } from "@/utils/uuid"; export const getBorderStyle = (input: IBorderValue, jsStyle: React.CSSProperties): React.CSSProperties => { if (!input || jsStyle?.border) return {}; @@ -24,7 +25,7 @@ export const getBorderStyle = (input: IBorderValue, jsStyle: React.CSSProperties const { all, top, right, bottom, left } = input?.border; const handleBorderPart = (part, prefix: string) => { - if (part?.width && !jsStyle?.[prefix] && !jsStyle?.[`${prefix}Width`]) style[`${prefix}Width`] = input?.hideBorder ? 0 : addPx(part.width); + if (part?.width && !jsStyle?.[prefix] && !jsStyle?.[`${prefix}Width`]) style[`${prefix}Width`] = input?.hideBorder ? 0 : addPx(part.width) || 0; if (part?.style && !jsStyle?.[prefix] && !jsStyle?.[`${prefix}Style`]) style[`${prefix}Style`] = part.style || 'solid'; if (part?.color && !jsStyle?.[prefix] && !jsStyle?.[`${prefix}Color`]) style[`${prefix}Color`] = part.color || 'black'; }; @@ -116,23 +117,24 @@ export const borderCorners = [ } ]; -export const getBorderInputs = (isResponsive: boolean = true) => borderSides.map(value => { +export const getBorderInputs = (isResponsive: boolean = true, path = '') => borderSides.map(value => { const side = value.value; - const code = isResponsive ? 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.border?.selectedSide)' + `!== "${side}"` + ' || getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.border?.hideBorder);' - : 'return getSettingValue(data?.border?.selectedSide)' + `!== "${side}"` + ' || getSettingValue(data?.border?.hideBorder);'; + const code = isResponsive ? 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]' + `${path ? '?.' + path : ''}` + '?.border?.selectedSide)' + `!== "${side}"` + + ' || getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]' + `${path ? '?.' + path : ''}` + '?.border?.hideBorder);' + : 'return getSettingValue(data?' + `${path ? '.' + path : ''}` + '.border?.selectedSide)' + `!== "${side}"` + ' || getSettingValue(data' + `${path ? '?.' + path : ''}` + '?.border?.hideBorder);'; return { - id: `borderStyleRow-${side}`, + id: nanoid(), parentId: 'borderStylePnl', inline: true, - readOnly: { _code: 'return getSettingValue(data?.border?.hideBorder);', _mode: 'code', _value: false } as any, + readOnly: false, hidden: { _code: code, _mode: 'code', _value: false } as any, inputs: [ { label: "Border", hideLabel: true, type: "button", - propertyName: "border.hideBorder", + propertyName: path ? `${path}.border.hideBorder` : "border.hideBorder", icon: "EyeOutlined", iconAlt: "EyeInvisibleOutlined", tooltip: "Select a border side to which the style will be applied", @@ -140,7 +142,7 @@ export const getBorderInputs = (isResponsive: boolean = true) => borderSides.map { label: "Select Side", hideLabel: true, - propertyName: "border.selectedSide", + propertyName: path ? `${path}.border.selectedSide` : "border.selectedSide", type: "radio", readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, buttonGroupOptions: borderSides @@ -149,11 +151,11 @@ export const getBorderInputs = (isResponsive: boolean = true) => borderSides.map type: 'text', label: "Width", hideLabel: true, - propertyName: `border.border.${side}.width`, + propertyName: path ? `${path}.border.border.${side}.width` : `border.border.${side}.width`, }, { label: "Style", - propertyName: `border.border.${side}.style`, + propertyName: path ? `${path}.border.border.${side}.style` : `border.border.${side}.style`, type: "dropdown", hideLabel: true, width: 60, @@ -162,7 +164,7 @@ export const getBorderInputs = (isResponsive: boolean = true) => borderSides.map }, { label: `Color ${side}`, - propertyName: `border.border.${side}.color`, + propertyName: path ? `${path}.border.border.${side}.color` : `border.border.${side}.color`, type: "color", readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, hideLabel: true, @@ -171,21 +173,22 @@ export const getBorderInputs = (isResponsive: boolean = true) => borderSides.map }; }); -export const getCornerInputs = (isResponsive: boolean = true) => radiusCorners.map(value => { +export const getCornerInputs = (isResponsive: boolean = true, path = '') => radiusCorners.map(value => { const corner = value.value; - const code = isResponsive ? 'return getSettingValue(data?.border?.selectedCorner)' + `!== "${corner}";` : 'return getSettingValue(data?.border?.selectedCorner)' + `!== "${corner}";`; + const code = isResponsive ? 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]' + `${path ? '?.' + path : ''}` + '?.border?.selectedCorner)' + `!== "${corner}"` + : 'return getSettingValue(data?' + `${path ? '.' + path : ''}` + '.border?.seclectedCorner)' + `!== "${corner}"`; return { - id: `borderStyleRow-${corner}`, + id: nanoid(), parentId: 'borderStylePnl', inline: true, - readOnly: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.border?.hideBorder);', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]' + `${path ? '?.' + path : ''}` + '?.border?.hideBorder);', _mode: 'code', _value: false } as any, hidden: { _code: code, _mode: 'code', _value: false } as any, inputs: [ { id: "corner-selector", label: "Corner Radius", - propertyName: "border.selectedCorner", + propertyName: path ? `${path}.border.selectedCorner` : "border.selectedCorner", type: "radio", defaultValue: "all", tooltip: "Select a corner to which the radius will be applied", @@ -200,7 +203,7 @@ export const getCornerInputs = (isResponsive: boolean = true) => radiusCorners.m defaultValue: 0, inputType: 'number', tooltip: "Select a corner to which the radius will be applied", - propertyName: `border.radius.${corner}` + propertyName: path ? `${path}.border.radius.${corner}` : `border.radius.${corner}`, }] }; -}); +}); \ No newline at end of file diff --git a/shesha-reactjs/src/designer-components/_settings/utils/position/utils.tsx b/shesha-reactjs/src/designer-components/_settings/utils/position/utils.tsx index 49c16ff06..ff98be3bb 100644 --- a/shesha-reactjs/src/designer-components/_settings/utils/position/utils.tsx +++ b/shesha-reactjs/src/designer-components/_settings/utils/position/utils.tsx @@ -24,6 +24,7 @@ export const getPositionStyle = (input?: IStyleType['position']): React.CSSPrope return style; }; + export const getPositionInputs = () => positions.map(value => { const label = value.value; const code = 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.position.offset)' + `!== "${label}"` + ' || getSettingValue(data[`${ contexts.canvasContext?.designerDevice || "desktop"}`]?.position.value) === "static";'; diff --git a/shesha-reactjs/src/designer-components/collapsiblePanel/collapsiblePanelComponent.tsx b/shesha-reactjs/src/designer-components/collapsiblePanel/collapsiblePanelComponent.tsx index 0509ae322..b4d9b5901 100644 --- a/shesha-reactjs/src/designer-components/collapsiblePanel/collapsiblePanelComponent.tsx +++ b/shesha-reactjs/src/designer-components/collapsiblePanel/collapsiblePanelComponent.tsx @@ -3,22 +3,25 @@ import { CollapsiblePanel, headerType } from '@/components/panel'; import { migrateCustomFunctions, migratePropertyName } from '@/designer-components/_common-migrations/migrateSettings'; import { migrateVisibility } from '@/designer-components/_common-migrations/migrateVisibility'; import { IToolboxComponent } from '@/interfaces'; -import { useFormData, useGlobalState } from '@/providers'; +import { useFormData, useGlobalState, useSheshaApplication } from '@/providers'; import { useForm } from '@/providers/form'; -import { FormMarkup } from '@/providers/form/models'; -import { evaluateString, pickStyleFromModel, validateConfigurableComponentSettings } from '@/providers/form/utils'; +import { evaluateString, getStyle, pickStyleFromModel, validateConfigurableComponentSettings } from '@/providers/form/utils'; import { GroupOutlined } from '@ant-design/icons'; import { ExpandIconPosition } from 'antd/lib/collapse/Collapse'; import { nanoid } from '@/utils/uuid'; -import React, { createContext, useContext } from 'react'; +import React, { createContext, useContext, useEffect, useState, useMemo } from 'react'; import { ICollapsiblePanelComponentProps, ICollapsiblePanelComponentPropsV0 } from './interfaces'; -import settingsFormJson from './settingsForm.json'; -import { executeFunction } from '@/utils'; import ParentProvider from '@/providers/parentProvider/index'; import { migrateFormApi } from '../_common-migrations/migrateFormApi1'; import { removeComponents } from '../_common-migrations/removeComponents'; - -const settingsForm = settingsFormJson as FormMarkup; +import { getSettings } from './settingsForm'; +import { getBackgroundImageUrl, getBackgroundStyle } from '../_settings/utils/background/utils'; +import { getSizeStyle } from '../_settings/utils/dimensions/utils'; +import { getBorderStyle } from '../_settings/utils/border/utils'; +import { getFontStyle } from '../_settings/utils/font/utils'; +import { getShadowStyle } from '../_settings/utils/shadow/utils'; +import { migratePrevStyles } from '../_common-migrations/migrateStyles'; +import { defaultHeaderStyles, defaultStyles } from './utils'; type PanelContextType = 'parent' | 'child' | undefined; @@ -33,46 +36,95 @@ const CollapsiblePanelComponent: IToolboxComponent({}); + const [headerFinalStyle, setCardFinalStyle] = useState({}); const { label, expandIconPosition, collapsedByDefault, collapsible, + isSimpleDesign, ghost, bodyColor, - headerColor, - isSimpleDesign, hideCollapseContent, hideWhenEmpty, + dimensions, + border, + font, + shadow, + headerStyles, + hasCustomHeader, + isDynamic, + customHeader, + content, + className, + hidden, + stylingBox } = model; const panelContextState = useContext(PanelContext); - const evaluatedLabel = typeof label === 'string' ? evaluateString(label, data) : label; - - if (model.hidden) return null; + const evaluatedLabel = useMemo(() => ( + typeof label === 'string' ? evaluateString(label, data) : label + ), [label, data]); - const styling = JSON.parse(model.stylingBox || '{}'); + const styling = useMemo(() => JSON.parse(stylingBox || '{}'), [stylingBox]); - const getPanelStyle = { + const getBodyStyle = useMemo(() => ({ ...pickStyleFromModel(styling), - ...(executeFunction(model?.style, { data, globalState }) || {}), - }; + ...(getStyle(model?.style, { data, globalState }) || {}), + }), [styling, model?.style, data, globalState]); + + const getHeaderStyle = useMemo(() => ({ + ...(getStyle(model?.headerStyles?.style, { data, globalState }) || {}), + }), [model?.headerStyles?.style, data, globalState]); + + const style = useMemo(() => ({ + ...getSizeStyle(dimensions), + ...(!ghost && getBorderStyle(border, getBodyStyle)), + ...getFontStyle(font), + ...(!ghost && getShadowStyle(shadow)), + ...getBodyStyle + }), [dimensions, border, font, shadow, getBodyStyle, ghost]); + + const headerStyle = useMemo(() => ({ + ...getSizeStyle(headerStyles?.dimensions), + ...(!ghost && getBorderStyle(headerStyles?.border, getHeaderStyle)), + ...getFontStyle(headerStyles?.font), + ...getShadowStyle(headerStyles?.shadow), + ...getHeaderStyle + }), [headerStyles, getHeaderStyle, ghost]); + + useEffect(() => { + const fetchTabStyles = async () => { + const background = model?.background; + const headerBackground = headerStyles?.background; + + const storedImageUrl = await getBackgroundImageUrl(background, backendUrl, httpHeaders); + const headerStoredImageUrl = await getBackgroundImageUrl(headerBackground, backendUrl, httpHeaders); + + const backgroundStyle = await getBackgroundStyle(background, getBodyStyle, storedImageUrl); + const headerBackgroundStyle = await getBackgroundStyle(headerBackground, getHeaderStyle, headerStoredImageUrl); + + setCardFinalStyle({ ...headerBackgroundStyle, ...headerStyle }); + setFinalStyle({ ...backgroundStyle, ...style }); + }; - const headerComponents = model?.header?.components ?? []; + fetchTabStyles(); + }, [model.background, headerStyles?.background, backendUrl, httpHeaders, getBodyStyle, getHeaderStyle, style, headerStyle]); - const hasCustomHeader = model?.hasCustomHeader; + const headerComponents = model?.header?.components ?? []; - const extra = - ((headerComponents?.length > 0 || formMode === 'designer') && !hasCustomHeader) ? ( - - ) : null; + const extra = ((headerComponents?.length > 0 || formMode === 'designer') && !hasCustomHeader) ? ( + + ) : null; const panelPosition = !!panelContextState ? 'child' : 'parent'; @@ -88,48 +140,44 @@ const CollapsiblePanelComponent: IToolboxComponent : - evaluatedLabel - } + containerId={customHeader.id} + dynamicComponents={isDynamic ? customHeader?.components : []} + /> + ) : evaluatedLabel} expandIconPosition={expandIconPosition !== 'hide' ? (expandIconPosition as ExpandIconPosition) : 'start'} collapsedByDefault={collapsedByDefault} extra={extra} collapsible={collapsible === 'header' ? 'header' : 'icon'} showArrow={collapsible !== 'disabled' && expandIconPosition !== 'hide'} ghost={ghost} - dynamicBorderRadius={model?.borderRadius} - style={{ ...getPanelStyle }} - className={model.className} + bodyStyle={finalStyle} + headerStyle={headerFinalStyle} + className={className} bodyColor={bodyColor} - headerColor={headerColor} isSimpleDesign={isSimpleDesign} panelHeadType={headType} hideCollapseContent={hideCollapseContent} hideWhenEmpty={hideWhenEmpty} > ); }, - initModel: (model) => ({ - ...model, - stylingBox: "{\"marginBottom\":\"5\"}" - }), - settingsFormMarkup: settingsForm, - validateSettings: (model) => validateConfigurableComponentSettings(settingsForm, model), + settingsFormMarkup: () => getSettings(), + validateSettings: (model) => validateConfigurableComponentSettings(getSettings(), model), migrator: (m) => m .add(0, (prev) => { @@ -176,8 +224,13 @@ const CollapsiblePanelComponent: IToolboxComponent(8, (prev) => ({ ...prev, stylingBox: '{"marginBottom":"5","paddingLeft":"16","paddingBottom":"16","paddingTop":"16","paddingRight":"16"}' })) + .add(9, (prev) => { + const newModel = migratePrevStyles(prev, defaultStyles(prev)); + const defaultHeaderStyle = defaultHeaderStyles(prev); - , + return { ...newModel, desktop: { ...newModel.desktop, headerStyles: defaultHeaderStyle }, tablet: { ...newModel.tablet, headerStyles: defaultHeaderStyle }, mobile: { ...newModel.mobile, headerStyles: defaultHeaderStyle } }; + }), customContainerNames: ['header', 'content', 'customHeader'], }; diff --git a/shesha-reactjs/src/designer-components/collapsiblePanel/interfaces.ts b/shesha-reactjs/src/designer-components/collapsiblePanel/interfaces.ts index 558a24df4..c120bb9e3 100644 --- a/shesha-reactjs/src/designer-components/collapsiblePanel/interfaces.ts +++ b/shesha-reactjs/src/designer-components/collapsiblePanel/interfaces.ts @@ -1,5 +1,5 @@ import { headerType } from './../../components/panel/index'; -import { IConfigurableFormComponent } from '@/providers/form/models'; +import { IConfigurableFormComponent, IStyleType } from '@/providers/form/models'; import { ExpandIconPosition } from 'antd/lib/collapse/Collapse'; import { CollapsibleType } from 'antd/lib/collapse/CollapsePanel'; @@ -8,7 +8,7 @@ export interface ICollapsiblePanelContent { components?: IConfigurableFormComponent[]; } -export interface ICollapsiblePanelComponentProps extends IConfigurableFormComponent { +export interface ICollapsiblePanelComponentProps extends IConfigurableFormComponent, IStyleType { collapsedByDefault?: boolean; expandIconPosition?: ExpandIconPosition | 'hide'; header?: ICollapsiblePanelContent; @@ -27,7 +27,11 @@ export interface ICollapsiblePanelComponentProps extends IConfigurableFormCompon hasCustomHeader?: boolean; customHeader?: ICollapsiblePanelContent; panelHeadType?: headerType; -} + headerStyles?: IStyleType; + desktop?: IStyleType; + mobile?: IStyleType; + tablet?: IStyleType; +}; export interface ICollapsiblePanelComponentPropsV0 extends IConfigurableFormComponent { collapsedByDefault?: boolean; diff --git a/shesha-reactjs/src/designer-components/collapsiblePanel/settingsForm.json b/shesha-reactjs/src/designer-components/collapsiblePanel/settingsForm.json deleted file mode 100644 index 75cc6a97c..000000000 --- a/shesha-reactjs/src/designer-components/collapsiblePanel/settingsForm.json +++ /dev/null @@ -1,385 +0,0 @@ -{ - "components": [ - { - "id": "bbbb4bf6-f76d-4139-a850-c99bf06c8b69", - "type": "collapsiblePanel", - "propertyName": "pnlDisplay", - "label": "Display", - "labelAlign": "right", - "parentId": "root", - "hidden": false, - "isDynamic": false, - "version": 4, - "expandIconPosition": "start", - "collapsible": "header", - "ghost": true, - "header": { - "id": "FizvoIoyeq1cZMqAgbDLL", - "components": [] - }, - "content": { - "id": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "components": [ - { - "id": "5c813b1a-04c5-4658-ac0f-cbcbae6b3bd4", - "type": "textField", - "propertyName": "componentName", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "label": "Component name", - "validate": { - "required": true - }, - "version": 2, - "textType": "text", - "jsSetting": false - }, - { - "id": "46d07439-4c18-468c-89e1-60c002ce96c5", - "type": "textField", - "propertyName": "label", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "label": "Label", - "version": 2, - "textType": "text" - }, - { - "id": "cfd7d45e-c7e3-4a27-987b-dc525c412558", - "type": "checkbox", - "propertyName": "hasCustomHeader", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "label": "Custom Header", - "version": 1 - }, - { - "id": "57a40a33-7e08-4ce4-9f08-a34d24a83338", - "type": "dropdown", - "propertyName": "expandIconPosition", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "label": "Icon position", - "values": [ - { - "label": "Hide", - "value": "hide", - "id": "f01e54aa-a1a4-4bd6-ba73-c395e48af8ce" - }, - { - "label": "Start", - "value": "start", - "id": "f01e54aa-a1a4-4bd6-ba73-c395e48af8ce" - }, - { - "label": "End", - "value": "end", - "id": "b920ef96-ae27-4a01-bfad-b5b7d07218da" - } - ], - "dataSourceType": "values", - "validate": {}, - "version": 3, - "referenceListId": null - }, - { - "id": "-wshDLo-lK468vwxVVBDMh", - "type": "dropdown", - "propertyName": "collapsible", - "label": "Collapsible", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "values": [ - { - "label": "Header", - "value": "header", - "id": "111e54aa-a1a4-4bd6-ba73-c395e48af8ce" - }, - { - "label": "Icon", - "value": "icon", - "id": "2220ef96-ae27-4a01-bfad-b5b7d07218da" - }, - { - "label": "Disabled", - "value": "disabled", - "id": "3330ef96-ae27-4a01-bfad-b5b7d07218da" - } - ], - "dataSourceType": "values", - "validate": {}, - "version": 3, - "referenceListId": null - }, - { - "id": "-wYzLo-lK468vwxVVBDMh", - "type": "checkbox", - "propertyName": "collapsedByDefault", - "label": "Collapsed by default", - "labelAlign": "right", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "hidden": false, - "isDynamic": false, - "description": "", - "validate": {}, - "settingsValidationErrors": [], - "version": 1 - }, - { - "id": "cfd7d45e-c7e3-4a27-987b-dc525c412448", - "type": "checkbox", - "propertyName": "hidden", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "label": "Hidden", - "version": 1 - }, - { - "id": "41924074-296C-4E4D-820A-DC29EC2C7B92", - "type": "checkbox", - "propertyName": "ghost", - "label": "Ghost", - "labelAlign": "right", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "hidden": false, - "isDynamic": false, - "description": "Make the collapse borderless and its background transparent", - "validate": {}, - "settingsValidationErrors": [], - "version": 1 - }, - { - "id": "7e5fc1c1-a804-4f0a-8327-1a92e963e5e1", - "type": "checkbox", - "propertyName": "hideCollapseContent", - "label": "Hide Top Bar", - "labelAlign": "right", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "hidden": false, - "isDynamic": false, - "description": "Hides the collapsible panel", - "validate": {}, - "settingsValidationErrors": [], - "version": 1 - }, - { - "id": "cd7d29fe-63d4-4c43-96c3-d4456f9ef237", - "type": "checkbox", - "propertyName": "isSimpleDesign", - "label": "Simple Design", - "labelAlign": "right", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "hidden": false, - "isDynamic": false, - "description": "Make the collapse borderless, background transparent and simple design", - "validate": {}, - "settingsValidationErrors": [], - "version": 1 - }, - { - "id": "6bac1a1f-67a2-48b5-a11e-b474e30d282e", - "type": "numberField", - "propertyName": "borderRadius", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "label": "Border Radius", - "defaultValue": 8, - "version": 2, - "textType": "number", - "max": 40, - "jsSetting": false - }, - { - "id": "d95693e6-f8dc-4f77-9ec4-68a14612cf34", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "type": "colorPicker", - "propertyName": "headerColor", - "componentName": "headerColor", - "label": "Header Background Color", - "labelAlign": "right", - "hidden": false, - "isDynamic": false, - "version": 2, - "settingsValidationErrors": [], - "title": "", - "fontSize": "", - "allowClear": true, - "showText": true - }, - { - "id": "09f31142-4053-45e6-ab3d-e9b063acbfa7", - "parentId": "b8954bf6-f76d-4139-a850-c99bf06c8b69", - "type": "colorPicker", - "propertyName": "bodyColor", - "componentName": "bodyColor", - "label": "Body Background Color", - "labelAlign": "right", - "hidden": false, - "isDynamic": false, - "version": 2, - "settingsValidationErrors": [], - "title": "", - "fontSize": "", - "allowClear": true, - "showText": true - } - ] - } - }, - { - "id": "038adb3d-6fae-450b-afb5-0855e6a30d06", - "type": "collapsiblePanel", - "propertyName": "pnlStyle", - "label": "Style", - "labelAlign": "right", - "parentId": "root", - "hidden": false, - "isDynamic": false, - "version": 4, - "expandIconPosition": "start", - "collapsible": "header", - "ghost": true, - "header": { - "id": "FizvoIoyeq1cZMqAgbDLL", - "components": [] - }, - "content": { - "id": "f47668c1-e424-4d18-850e-6d712e48211d", - "components": [ - { - "textType": "text", - "id": "b1M4TO4K1t3pl8pyM2mOK", - "type": "textField", - "propertyName": "className", - "componentName": "className", - "label": "Custom CSS Class", - "labelAlign": "right", - "parentId": "f47668c1-e424-4d18-850e-6d712e48211d", - "hidden": false, - "isDynamic": false, - "version": 2, - "description": "Custom CSS Class to add to this component", - "validate": {}, - "settingsValidationErrors": [] - }, - { - "id": "e029c4ed-6415-412f-be9e-73dddff4037c", - "type": "codeEditor", - "propertyName": "style", - "label": "Style", - "labelAlign": "right", - "parentId": "f47668c1-e424-4d18-850e-6d712e48211d", - "hidden": false, - "autoSize": false, - "showCount": false, - "allowClear": false, - "validate": {}, - "exposedVariables": [ - { - "id": "6034ec34-2b5d-4320-90cd-6ed6a61a0481", - "name": "data", - "description": "Selected form values", - "type": "object" - }, - { - "id": "4008f09b-c4dc-41cd-981c-4b0101d005c3", - "name": "globalState", - "description": "The global state of the application", - "type": "object" - } - ], - "version": 1 - }, - { - "id": "8473d32d-ef70-4310-abef-28c887b940b0", - "type": "styleBox", - "propertyName": "stylingBox", - "parentId": "f47668c1-e424-4d18-850e-6d712e48211d", - "validate": {}, - "settingsValidationErrors": [], - "jsSetting": false - } - ] - } - }, - { - "id": "bbbb960e-77e3-40f2-89cc-f18f94678cce", - "type": "collapsiblePanel", - "propertyName": "pnlVisibility", - "label": "Visibility", - "labelAlign": "right", - "parentId": "root", - "hidden": false, - "isDynamic": false, - "version": 4, - "expandIconPosition": "start", - "collapsible": "header", - "ghost": true, - "header": { - "id": "FizvoIoyeq1cZMqAgbDLL", - "components": [] - }, - "content": { - "id": "bc67960e-77e3-40f2-89cc-f18f94678cce", - "components": [ - { - "id": "BC7507ED-ADB6-4D2E-BD37-F5DD51EFF45D", - "type": "checkbox", - "propertyName": "hideWhenEmpty", - "label": "Hide when empty", - "labelAlign": "right", - "parentId": "bc67960e-77e3-40f2-89cc-f18f94678cce", - "hidden": false, - "isDynamic": false, - "description": "Allows to hide the panel when all components are hidden due to some conditions", - "validate": {}, - "settingsValidationErrors": [], - "version": 1 - } - ] - } - }, - { - "id": "6Vw9iiDw9d0MD_Rh5cbIn", - "type": "collapsiblePanel", - "propertyName": "pnlSecurity", - "label": "Security", - "labelAlign": "right", - "parentId": "root", - "isDynamic": false, - "version": 4, - "expandIconPosition": "start", - "header": { - "id": "mbzE03mJnv_89oUvkmjPs", - "components": [] - }, - "content": { - "id": "SsWPpiJfTbgl4iHlFA_or", - "components": [ - { - "id": "1adea529-1f0c-4def-bd41-ee166a5dfcd7", - "type": "permissionAutocomplete", - "propertyName": "permissions", - "parentId": "SsWPpiJfTbgl4iHlFA_or", - "label": "Permissions", - "validate": {}, - "version": 1 - } - ] - }, - "collapsible": "header", - "ghost": true, - "hideWhenEmpty": true, - "settingsValidationErrors": [] - } - ], - "formSettings": { - "layout": "horizontal", - "colon": true, - "labelCol": { - "span": 5 - }, - "wrapperCol": { - "span": 13 - }, - "displayName": "DEFAULT_FORM_SETTINGS", - "__docgenInfo": { - "description": "Default form settings", - "displayName": "DEFAULT_FORM_SETTINGS", - "props": {} - } - } -} \ No newline at end of file diff --git a/shesha-reactjs/src/designer-components/collapsiblePanel/settingsForm.ts b/shesha-reactjs/src/designer-components/collapsiblePanel/settingsForm.ts new file mode 100644 index 000000000..9b0c99390 --- /dev/null +++ b/shesha-reactjs/src/designer-components/collapsiblePanel/settingsForm.ts @@ -0,0 +1,1039 @@ +import { DesignerToolbarSettings } from '@/interfaces/toolbarSettings'; +import { FormLayout } from 'antd/lib/form/Form'; +import { getBorderInputs, getCornerInputs } from '../_settings/utils/border/utils'; +import { positionOptions, repeatOptions, sizeOptions } from '../_settings/utils/background/utils'; +import { fontTypes, fontWeights, textAlign } from '../_settings/utils/font/utils'; +import { nanoid } from '@/utils/uuid'; + +export const getSettings = () => { + return { + components: new DesignerToolbarSettings() + .addSearchableTabs({ + id: 'panelpanel-W_m7doMyCpCYwAYDfRh6I', + propertyName: 'settingsTabs', + parentId: 'root', + label: 'Settings', + hideLabel: true, + labelAlign: 'right', + size: 'small', + tabs: [ + { + id: 'panels4gmBg31azZC0UjZjpfTm', + key: '1', + title: 'Common', + components: [...new DesignerToolbarSettings() + .addSettingsInput({ + id: 'panel5c813b1a-04c5-4658-ac0f-cbcbae6b3bd4', + propertyName: 'componentName', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + label: 'Component name', + validate: { + required: true + }, + jsSetting: false + }) + .addSettingsInput({ + id: 'panel46d07439-4c18-468c-89e1-60c002ce96c5', + propertyName: 'label', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + label: 'Label' + }) + .addSettingsInput({ + id: 'panelcfd7d45e-c7e3-4a27-987b-dc525c412558', + propertyName: 'hasCustomHeader', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + label: 'Custom Header', + inputType: 'switch' + }) + .addSettingsInput({ + id: 'panel57a40a33-7e08-4ce4-9f08-a34d24a83338', + propertyName: 'expandIconPosition', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + label: 'Icon position', + inputType: 'dropdown', + dropdownOptions: [ + { + label: 'Hide', + value: 'hide', + }, + { + label: 'Start', + value: 'start', + }, + { + label: 'End', + value: 'end', + } + ], + validate: {}, + }) + .addSettingsInput({ + id: 'panel-wshDLo-lK468vwxVVBDMh', + propertyName: 'collapsible', + label: 'Collapsible', + inputType: 'dropdown', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + dropdownOptions: [ + { + label: 'Header', + value: 'header', + }, + { + label: 'Icon', + value: 'icon', + }, + { + label: 'Disabled', + value: 'disabled', + } + ], + validate: {}, + version: 3 + }) + .addSettingsInput({ + id: 'panel-wYzLo-lK468vwxVVBDMh', + propertyName: 'collapsedByDefault', + label: 'Collapsed by default', + labelAlign: 'right', + inputType: 'switch', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + hidden: false, + isDynamic: false, + description: '', + validate: {}, + }) + .addSettingsInput({ + id: 'panel-wYzLo-lK468vwxVVBDMh', + label: 'Ghost', + propertyName: 'ghost', + inputType: 'switch', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + }) + .addSettingsInput({ + id: 'panelcfd7d45e-smpl-4a27-987b-dc525c412448', + propertyName: 'isSimpleDesign', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + label: 'Simple Design', + inputType: 'switch', + jsSetting: true + }) + .addSettingsInput({ + id: 'panelcfd7d45e-c7e3-4a27-987b-dc525c412448', + propertyName: 'hidden', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + label: 'Hidden', + inputType: 'switch', + jsSetting: true + }) + .addSettingsInput({ + id: 'panel7e5fc1c1-a804-4f0a-8327-1a92e963e5e1', + propertyName: 'hideCollapseContent', + label: 'Hide Top Bar', + labelAlign: 'right', + inputType: 'switch', + parentId: 'b8954bf6-f76d-4139-a850-c99bf06c8b69', + description: 'Hides the collapsible panel', + }) + .addSettingsInput({ + id: 'panelBC7507ED-ADB6-4D2E-BD37-F5DD51EFF45D', + propertyName: 'hideWhenEmpty', + label: 'Hide when empty', + labelAlign: 'right', + parentId: 'bc67960e-77e3-40f2-89cc-f18f94678cce', + inputType: 'switch', + description: 'Allows to hide the panel when all components are hidden due to some conditions', + }) + .toJson()] + }, + { + key: '2', + title: 'Appearance', + id: 'panelelgrlievlfwehhh848r8hsdnflsdnclurbd', + components: [...new DesignerToolbarSettings() + .addPropertyRouter({ + id: 'panelstyleRouter', + propertyName: 'propertyRouter1', + componentName: 'propertyRouter', + label: 'Property router1', + labelAlign: 'right', + parentId: 'elgrlievlfwehhh848r8hsdnflsdnclurbd', + hidden: false, + propertyRouteName: { + _mode: "code", + _code: " return contexts.canvasContext?.designerDevice || 'desktop';", + _value: "" + }, + components: [ + ...new DesignerToolbarSettings() + .addCollapsiblePanel({ + id: 'paneldimensionsStyleCollapsiblePanel', + propertyName: 'pnlDimensions', + label: 'Dimensions', + parentId: 'styleRouter', + labelAlign: 'right', + ghost: true, + collapsible: 'header', + content: { + id: 'paneldimensionsStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInputRow({ + id: 'paneldimensionsStyleRowWidth', + parentId: 'dimensionsStylePnl', + inline: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'text', + id: 'panelwidth-s4gmBg31azZC0UjZjpfTm', + label: "Width", + width: 85, + propertyName: "dimensions.width", + icon: "widthIcon", + tooltip: "You can use any unit (%, px, em, etc). px by default if without unit" + }, + { + type: 'text', + id: 'panelminWidth-s4gmBg31azZC0UjZjpfTm', + label: "Min Width", + width: 85, + hideLabel: true, + propertyName: "dimensions.minWidth", + icon: "minWidthIcon", + }, + { + type: 'text', + id: 'panelmaxWidth-s4gmBg31azZC0UjZjpfTm', + label: "Max Width", + width: 85, + hideLabel: true, + propertyName: "dimensions.maxWidth", + icon: "maxWidthIcon", + } + ] + }) + .addSettingsInputRow({ + id: 'paneldimensionsStyleRowHeight', + parentId: 'dimensionsStylePnl', + inline: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'text', + id: 'panelheight-s4gmBg31azZC0UjZjpfTm', + label: "Height", + width: 85, + propertyName: "dimensions.height", + icon: "heightIcon", + tooltip: "You can use any unit (%, px, em, etc). px by default if without unit" + }, + { + type: 'text', + id: 'panelminHeight-s4gmBg31azZC0UjZjpfTm', + label: "Min Height", + width: 85, + hideLabel: true, + propertyName: "dimensions.minHeight", + icon: "minHeightIcon", + }, + { + type: 'text', + id: 'panelmaxHeight-s4gmBg31azZC0UjZjpfTm', + label: "Max Height", + width: 85, + hideLabel: true, + propertyName: "dimensions.maxHeight", + icon: "maxHeightIcon", + } + ] + }) + .addSettingsInput({ + id: 'panelpredefinedSizes', + inputType: 'dropdown', + propertyName: 'size', + label: 'Size', + width: '150px', + hidden: { _code: 'return getSettingValue(data?.dimensions?.width) || getSettingValue(data?.dimensions?.height);', _mode: 'code', _value: false } as any, + dropdownOptions: [ + { value: 'small', label: 'Small' }, + { value: 'medium', label: 'Medium' }, + { value: 'large', label: 'Large' }, + ] + }) + .toJson() + ] + } + }) + .addCollapsiblePanel({ + id: 'panelborderStyleCollapsiblePanel', + propertyName: 'pnlBorderStyle', + label: 'Border', + labelAlign: 'right', + ghost: true, + parentId: 'styleRouter', + collapsible: 'header', + content: { + id: 'panelborderStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInputRow({ + id: `borderStyleRow`, + parentId: 'borderStylePnl', + hidden: { _code: 'return !getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.border?.hideBorder);', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'button', + id: 'panelborderStyleRow-hideBorder', + label: "Border", + hideLabel: true, + propertyName: "border.hideBorder", + icon: "EyeOutlined", + iconAlt: "EyeInvisibleOutlined" + }, + ] + }) + .addSettingsInputRow( + getBorderInputs()[0] as any + ) + .addSettingsInputRow( + getBorderInputs()[1] as any + ) + .addSettingsInputRow( + getBorderInputs()[2] as any + ) + .addSettingsInputRow( + getBorderInputs()[3] as any + ) + .addSettingsInputRow( + getBorderInputs()[4] as any + ) + .addSettingsInputRow( + getCornerInputs()[0] as any + ) + .addSettingsInputRow( + getCornerInputs()[1] as any + ) + .addSettingsInputRow( + getCornerInputs()[2] as any + ) + .addSettingsInputRow( + getCornerInputs()[3] as any + ) + .addSettingsInputRow( + getCornerInputs()[4] as any + ) + .toJson() + ] + } + }) + .addCollapsiblePanel({ + id: 'panelbackgroundStyleCollapsiblePanel', + propertyName: 'pnlBackgroundStyle', + label: 'Background', + labelAlign: 'right', + ghost: true, + parentId: 'styleRouter', + collapsible: 'header', + content: { + id: 'panelbackgroundStylePnl', + components: [ + ...new DesignerToolbarSettings() + .addSettingsInput({ + id: "backgroundStyleRow-selectType", + parentId: "backgroundStylePnl", + label: "Type", + jsSetting: false, + propertyName: "background.type", + inputType: "radio", + tooltip: "Select a type of background", + buttonGroupOptions: [ + { + value: "color", + icon: "FormatPainterOutlined", + title: "Color" + }, + { + value: "gradient", + icon: "BgColorsOutlined", + title: "Gradient" + }, + { + value: "image", + icon: "PictureOutlined", + title: "Image" + }, + { + value: "url", + icon: "LinkOutlined", + title: "URL" + }, + { + value: "storedFile", + icon: "DatabaseOutlined", + title: "Stored File" + } + ], + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: "backgroundStyleRow-color", + parentId: "backgroundStylePnl", + inputs: [{ + type: 'color', + id: 'panelbackgroundStyleRow-color', + label: "Color", + propertyName: "background.color", + hideLabel: true, + jsSetting: false, + }], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.background?.type) !== "color";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: "backgroundStyle-gradientColors", + parentId: "backgroundStylePnl", + inputs: [{ + type: 'multiColorPicker', + id: 'panelbackgroundStyle-gradientColors', + propertyName: "background.gradient.colors", + label: "Colors", + jsSetting: false, + } + ], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.background?.type) !== "gradient";', _mode: 'code', _value: false } as any, + hideLabel: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: "backgroundStyle-url", + parentId: "backgroundStylePnl", + inputs: [{ + type: 'text', + id: 'panelbackgroundStyle-url', + propertyName: "background.url", + jsSetting: false, + label: "URL", + }], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.background?.type) !== "url";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: "backgroundStyle-image", + parentId: 'backgroundStylePnl', + inputs: [{ + type: 'imageUploader', + id: 'panelbackgroundStyle-image', + propertyName: 'background.uploadFile', + label: "Image", + jsSetting: false, + }], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.background?.type) !== "image";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: "backgroundStyleRow-storedFile", + parentId: 'backgroundStylePnl', + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.background?.type) !== "storedFile";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'text', + id: 'panelbackgroundStyle-storedFile', + jsSetting: false, + propertyName: "background.storedFile.id", + label: "File ID" + } + ] + }) + .addSettingsInputRow({ + id: "backgroundStyleRow-controls", + parentId: 'backgroundStyleRow', + inline: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'customDropdown', + id: 'panelbackgroundStyleRow-size', + label: "Size", + hideLabel: true, + propertyName: "background.size", + dropdownOptions: [ + { + value: "cover", + label: "Cover" + }, + { + value: "contain", + label: "Contain" + }, + { + value: "auto", + label: "Auto" + } + ], + }, + { + type: 'customDropdown', + id: 'panelbackgroundStyleRow-position', + label: "Position", + hideLabel: true, + propertyName: "background.position", + dropdownOptions: [ + { + value: "center", + label: "Center" + }, + { + value: "top", + label: "Top" + }, + { + value: "left", + label: "Left" + }, + { + value: "right", + label: "Right" + }, + { + value: "bottom", + label: "Bottom" + }, + { + value: "top left", + label: "Top Left" + }, + { + value: "top right", + label: "Top Right" + }, + { + value: "bottom left", + label: "Bottom Left" + }, + { + value: "bottom right", + label: "Bottom Right" + } + ], + }, + { + type: 'dropdown', + id: 'panelbackgroundStyleRow-repeat', + label: "Repeat", + hideLabel: true, + propertyName: "background.repeat", + dropdownOptions: repeatOptions, + } + ] + }) + .toJson() + ], + } + }) + .addCollapsiblePanel({ + id: 'panelshadowStyleCollapsiblePanel', + propertyName: 'pnlShadowStyle', + label: 'Shadow', + labelAlign: 'right', + ghost: true, + parentId: 'styleRouter', + collapsible: 'header', + content: { + id: 'panelshadowStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInputRow({ + id: 'panelshadowStyleRow', + parentId: 'shadowStylePnl', + inline: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'number', + id: 'panelshadowStyleRow-offsetX', + label: 'Offset X', + hideLabel: true, + width: 60, + icon: "offsetHorizontalIcon", + propertyName: 'shadow.offsetX', + }, + { + type: 'number', + id: 'panelshadowStyleRow-offsetY', + label: 'Offset Y', + hideLabel: true, + width: 60, + icon: 'offsetVerticalIcon', + propertyName: 'shadow.offsetY', + }, + { + type: 'number', + id: 'panelshadowStyleRow-blurRadius', + label: 'Blur', + hideLabel: true, + width: 60, + icon: 'blurIcon', + propertyName: 'shadow.blurRadius', + }, + { + type: 'number', + id: 'panelshadowStyleRow-spreadRadius', + label: 'Spread', + hideLabel: true, + width: 60, + icon: 'spreadIcon', + propertyName: 'shadow.spreadRadius', + }, + { + type: 'color', + id: 'panelshadowStyleRow-color', + label: 'Color', + hideLabel: true, + propertyName: 'shadow.color', + }, + ], + }) + .toJson() + ] + } + }) + .addCollapsiblePanel({ + id: 'panelstyleCollapsiblePanel', + propertyName: 'stylingBox', + label: 'Margin & Padding', + labelAlign: 'right', + ghost: true, + collapsible: 'header', + content: { + id: 'panelstylePnl-M5-911', + components: [...new DesignerToolbarSettings() + .addStyleBox({ + id: 'panelstyleBoxPnl', + label: 'Margin Padding', + hideLabel: true, + propertyName: 'stylingBox', + }) + .toJson() + ] + } + }) + .addCollapsiblePanel({ + id: 'panelcustomStyleCollapsiblePanel', + propertyName: 'customStyle', + label: 'Custom Styles', + labelAlign: 'right', + ghost: true, + parentId: 'styleRouter', + collapsible: 'header', + content: { + id: 'panelstylePnl-M500-911MFR', + components: [...new DesignerToolbarSettings() + .addSettingsInput({ + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + id: 'panelcustom-css-412c-8461-4c8d55e5c073', + inputType: 'codeEditor', + propertyName: 'style', + hideLabel: false, + label: 'Style', + description: 'A script that returns the style of the element as an object. This should conform to CSSProperties', + }) + .toJson() + ] + } + }) + .addCollapsiblePanel({ + id: 'panel-header-collapsible', + propertyName: 'header', + label: 'Header Style', + labelAlign: 'right', + ghost: true, + collapsible: 'header', + collapsedByDefault: true, + parentId: 'styleRouter', + content: { + id: 'panel-header-styles-pnl', + components: [...new DesignerToolbarSettings() + .addCollapsiblePanel({ + id: 'panelheaderfontStyleCollapsiblePanel', + propertyName: 'pnlFontStyle', + label: 'Font', + labelAlign: 'right', + collapsedByDefault: true, + parentId: 'panel-header-styles-pnl', + collapsible: 'header', + content: { + id: 'panelheaderfontStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInputRow({ + id: 'try26voxhs-HxJ5k5ngYE', + parentId: 'panel-header-styles-pnl', + inline: true, + propertyName: 'font', + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'dropdown', + id: 'fontFamily-s4gmBg31azZC0UjZjpfTm', + label: 'Font', + hideLabel: true, + propertyName: 'headerStyles.font.type', + dropdownOptions: fontTypes, + }, + { + type: 'number', + id: 'fontSize-s4gmBg31azZC0UjZjpfTm', + label: 'Size', + propertyName: 'headerStyles.font.size', + hideLabel: true, + width: 50, + }, + { + type: 'dropdown', + id: 'fontWeight-s4gmBg31azZC0UjZjpfTm', + label: 'Weight', + propertyName: 'headerStyles.font.weight', + hideLabel: true, + tooltip: "Controls text thickness (light, normal, bold, etc.)", + dropdownOptions: fontWeights, + width: 100, + }, + { + type: 'color', + id: 'fontColor-s4gmBg31azZC0UjZjpfTm', + label: 'Color', + hideLabel: true, + propertyName: 'headerStyles.font.color', + }, + { + type: 'dropdown', + id: 'fontAlign-s4gmBg31azZC0UjZjpfTm', + label: 'Align', + propertyName: 'headerStyles.font.align', + hideLabel: true, + width: 60, + dropdownOptions: textAlign, + }, + ], + }) + .toJson()] + } + }) + .addCollapsiblePanel({ + id: 'panelheaderdimensionsStyleCollapsiblePanel', + propertyName: 'pnlDimensionsStyle', + label: 'Dimensions', + labelAlign: 'right', + collapsedByDefault: true, + parentId: 'panel-header-styles-pnl', + collapsible: 'header', + content: { + id: 'panelheaderdimensionsStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInputRow({ + id: 'header-dimensionsStyleRowHeight', + parentId: 'panel-header-styles-pnl', + inline: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'text', + id: 'header-height-s4gmBg31azZC0UjZjpfTm', + label: "Height", + width: 85, + propertyName: "headerStyles.dimensions.height", + icon: "heightIcon", + tooltip: "You can use any unit (%, px, em, etc). px by default if without unit" + }, + { + type: 'text', + id: 'header-minHeight-s4gmBg31azZC0UjZjpfTm', + label: "Min Height", + width: 85, + hideLabel: true, + propertyName: "headerStyles.dimensions.minHeight", + icon: "minHeightIcon", + }, + { + type: 'text', + id: 'header-maxHeight-s4gmBg31azZC0UjZjpfTm', + label: "Max Height", + width: 85, + hideLabel: true, + propertyName: "headerStyles.dimensions.maxHeight", + icon: "maxHeightIcon", + } + ] + }) + .toJson()] + } + }) + .addCollapsiblePanel({ + id: 'panelheaderborderStyleCollapsiblePanel', + propertyName: 'pnlBorderStyle', + label: 'Border', + labelAlign: 'right', + collapsedByDefault: true, + parentId: 'panel-header-styles-pnl', + content: { + id: 'panelheaderborderStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInputRow({ + id: nanoid(), + parentId: 'panelheaderborderStylePnl', + hidden: { _code: 'return !getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.headerStyles?.border?.hideBorder);', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'button', + id: 'panel-header-borderStyleRow-hideBorder', + label: "Border", + hideLabel: true, + propertyName: "headerStyles.border.hideBorder", + icon: "EyeOutlined", + iconAlt: "EyeInvisibleOutlined" + }, + ] + }) + .addSettingsInputRow( + { ...getBorderInputs(true, 'headerStyles')[0] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getBorderInputs(true, 'headerStyles')[1] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getBorderInputs(true, 'headerStyles')[2] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getBorderInputs(true, 'headerStyles')[3] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getBorderInputs(true, 'headerStyles')[4] as any, parentId: 'panelheaderborderStylePnl' } + ) + + .addSettingsInputRow( + { ...getCornerInputs(true, 'headerStyles')[0] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getCornerInputs(true, 'headerStyles')[1] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getCornerInputs(true, 'headerStyles')[2] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getCornerInputs(true, 'headerStyles')[3] as any, parentId: 'panelheaderborderStylePnl' } + ) + .addSettingsInputRow( + { ...getCornerInputs(true, 'headerStyles')[4] as any, parentId: 'panelheaderborderStylePnl' } + ) + .toJson()] + } + }) + .addCollapsiblePanel({ + id: 'panelheaderbackgroundStyleCollapsiblePanel', + propertyName: 'pnlBackgroundStyle', + label: 'Background', + labelAlign: 'right', + collapsedByDefault: true, + parentId: 'panel-header-styles-pnl', + collapsible: 'header', + content: { + id: 'panelheaderbackgroundStylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInput({ + id: "header-backgroundStyleRow-selectType", + parentId: "styleRouter", + label: "Type", + jsSetting: false, + propertyName: "headerStyles.background.type", + inputType: "radio", + tooltip: "Select a type of background", + buttonGroupOptions: [ + { + value: "color", + icon: "FormatPainterOutlined", + title: "Color" + }, + { + value: "gradient", + icon: "BgColorsOutlined", + title: "Gradient" + }, + { + value: "image", + icon: "PictureOutlined", + title: "Image" + }, + { + value: "url", + icon: "LinkOutlined", + title: "URL" + }, + { + value: "storedFile", + icon: "DatabaseOutlined", + title: "Stored File" + } + ], + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: "header-backgroundStyleRow-color", + parentId: "panel-header-styles-pnl", + inputs: [{ + type: 'color', + id: 'backgroundStyleRow-color', + label: "Color", + propertyName: "headerStyles.background.color", + hideLabel: true, + jsSetting: false, + }], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.headerStyles?.background?.type) !== "color";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: nanoid(), + parentId: "panel-header-styles-pnl", + inputs: [{ + type: 'multiColorPicker', + id: 'backgroundStyle-gradientColors', + propertyName: "headerStyles.background.gradient.colors", + label: "Colors", + jsSetting: false, + } + ], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.headerStyles?.background?.type) !== "gradient";', _mode: 'code', _value: false } as any, + hideLabel: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: nanoid(), + parentId: "panel-header-styles-pnl", + inputs: [{ + type: 'text', + id: 'backgroundStyle-url', + propertyName: "headerStyles.background.url", + jsSetting: false, + label: "URL", + }], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.headerStyles?.background?.type) !== "url";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: nanoid(), + parentId: 'panel-header-styles-pnl', + inputs: [{ + type: 'imageUploader', + id: 'backgroundStyle-image', + propertyName: 'headerStyles.background.uploadFile', + label: "Image", + jsSetting: false, + }], + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.headerStyles?.background?.type) !== "image";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + }) + .addSettingsInputRow({ + id: nanoid(), + parentId: 'panel-header-styles-pnl', + hidden: { _code: 'return getSettingValue(data[`${contexts.canvasContext?.designerDevice || "desktop"}`]?.headerStyles?.background?.type) !== "storedFile";', _mode: 'code', _value: false } as any, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'text', + id: 'backgroundStyle-storedFile', + jsSetting: false, + propertyName: "headerStyles.background.storedFile.id", + label: "File ID" + } + ] + }) + .addSettingsInputRow({ + id: "header-backgroundStyleRow-controls", + parentId: 'panel-header-styles-pnl', + inline: true, + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + inputs: [ + { + type: 'customDropdown', + id: nanoid(), + label: "Size", + hideLabel: true, + propertyName: "headerStyles.background.size", + dropdownOptions: sizeOptions + }, + { + type: 'customDropdown', + id: nanoid(), + label: "Position", + hideLabel: true, + propertyName: "headerStyles.background.position", + dropdownOptions: positionOptions, + }, + { + type: 'dropdown', + id: nanoid(), + label: "Repeat", + hideLabel: true, + propertyName: "headerStyles.background.repeat", + dropdownOptions: repeatOptions, + } + ] + }) + .toJson() + ] + } + }) + .addCollapsiblePanel({ + id: 'panelheaderjsstyle', + propertyName: 'customStyle', + label: 'Custom Styles', + labelAlign: 'right', + collapsedByDefault: true, + parentId: 'panel-header-styles-pnl', + collapsible: 'header', + content: { + id: 'panelheaderjsstylePnl', + components: [...new DesignerToolbarSettings() + .addSettingsInput({ + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + id: nanoid(), + inputType: 'codeEditor', + propertyName: 'headerStyles.style', + hideLabel: false, + label: 'Style', + description: 'A script that returns the style of the element as an object. This should conform to CSSProperties', + }) + .toJson()] + } + }) + .toJson()] + } + }) + .toJson()] + }).toJson()] + }, + { + key: '3', + title: 'Security', + id: 'panel6Vw9iiDw9d0MD_Rh5cbIn', + components: [...new DesignerToolbarSettings() + .addSettingsInput({ + readOnly: { _code: 'return getSettingValue(data?.readOnly);', _mode: 'code', _value: false } as any, + id: 'panel1adea529-1f0c-4def-bd41-ee166a5dfcd7', + inputType: 'permissions', + propertyName: 'permissions', + label: 'Permissions', + size: 'small', + parentId: '6Vw9iiDw9d0MD_Rh5cbIn' + }) + .toJson() + ] + } + ] + }).toJson(), + formSettings: { + colon: false, + layout: 'vertical' as FormLayout, + labelCol: { span: 24 }, + wrapperCol: { span: 24 } + } + }; +}; \ No newline at end of file diff --git a/shesha-reactjs/src/designer-components/collapsiblePanel/utils.ts b/shesha-reactjs/src/designer-components/collapsiblePanel/utils.ts new file mode 100644 index 000000000..289c0cc4d --- /dev/null +++ b/shesha-reactjs/src/designer-components/collapsiblePanel/utils.ts @@ -0,0 +1,41 @@ +import { IStyleType } from "@/index"; +import { ICollapsiblePanelComponentProps } from "./interfaces"; + +export const defaultStyles = (prev: ICollapsiblePanelComponentProps): IStyleType => { + const bodyColor = prev.bodyColor || '#fff'; + const { ghost, borderRadius, isSimpleDesign } = prev; + + return { + background: { type: 'color', color: bodyColor }, + dimensions: { width: 'auto', height: 'auto', minHeight: '0px', maxHeight: 'auto', minWidth: '0px', maxWidth: 'auto' }, + border: { + selectedCorner: 'all', selectedSide: 'all', + border: { + ...ghost ? { all: { width: '1px', color: '#d9d9d9', style: 'solid' } } + : { all: { width: '1px', color: '#d9d9d9', style: 'solid' }, bottom: { style: 'none' } }, + }, + radius: { all: borderRadius || 8, topLeft: isSimpleDesign || ghost ? '0' : borderRadius, topRight: isSimpleDesign || ghost ? '0' : borderRadius } + }, + shadow: { blurRadius: 0, color: 'rgba(0, 0, 0, 0.15)', offsetX: 0, offsetY: 0, spreadRadius: 0 }, + position: { value: 'relative', top: 0, right: 0, bottom: 0, left: 0, offset: 'top' }, + }; +}; + +export const defaultHeaderStyles = (prev: ICollapsiblePanelComponentProps): IStyleType => { + const headerBgColor = prev?.headerColor || '#00000005'; + const { isSimpleDesign, ghost, borderRadius } = prev; + + return { + font: { color: '#000', size: 14, weight: isSimpleDesign ? '400' : 'bold', align: 'left', type: 'Arial' }, + background: { type: 'color', color: headerBgColor }, + dimensions: { width: 'auto', height: 'auto', minHeight: '0', maxHeight: 'auto', minWidth: '0', maxWidth: 'auto' }, + border: { + selectedCorner: 'all', selectedSide: 'all', + border: { + ...ghost ? { all: { width: '1px', color: '#d9d9d9', style: 'solid' }, top: { width: '3px', style: 'solid', color: 'var(--primary-color)' }, bottom: { width: ghost ? '2px' : 0, style: 'solid', color: 'var(--primary-color)' } } + : { all: { width: '1px', color: '#d9d9d9', style: 'solid' } }, + }, + radius: { all: borderRadius, bottomLeft: '0', bottomRight: '0', topLeft: isSimpleDesign || ghost ? '0' : borderRadius, topRight: isSimpleDesign || ghost ? '0' : borderRadius } + } + }; +}; \ No newline at end of file diff --git a/shesha-reactjs/src/designer-components/multiColorInput/index.tsx b/shesha-reactjs/src/designer-components/multiColorInput/index.tsx index 125e44051..39fa6f259 100644 --- a/shesha-reactjs/src/designer-components/multiColorInput/index.tsx +++ b/shesha-reactjs/src/designer-components/multiColorInput/index.tsx @@ -21,6 +21,12 @@ export const MultiColorInput = ({ value = {}, onChange, readOnly, propertyName } } }, [value, onChange, theme.application.primaryColor]); + const removeLastWord = (inputString) => { + const words = inputString.split('.'); + words.pop(); + return words.join('.'); + }; + return ( <> @@ -44,7 +50,7 @@ export const MultiColorInput = ({ value = {}, onChange, readOnly, propertyName } })} - +