diff --git a/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartComp.tsx b/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartComp.tsx index 3d1750d9ce..2d17a36f9c 100644 --- a/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartComp.tsx +++ b/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartComp.tsx @@ -144,7 +144,8 @@ CandleStickChartTmpComp = withViewFn(CandleStickChartTmpComp, (comp) => { const option = useMemo(() => { return getEchartsConfig( childrenToProps(echartsConfigChildren) as ToViewReturn, - chartSize + chartSize, + theme?.theme?.components?.candleStickChart || {}, ); }, [chartSize, ...Object.values(echartsConfigChildren)]); diff --git a/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartUtils.ts b/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartUtils.ts index 00dcb0d2d6..3c6611ba9a 100644 --- a/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartUtils.ts +++ b/client/packages/lowcoder-comps/src/comps/candleStickChartComp/candleStickChartUtils.ts @@ -12,6 +12,7 @@ import { chartColorPalette, isNumeric, JSONObject, loadScript } from "lowcoder-s import { calcXYConfig } from "comps/chartComp/chartConfigs/cartesianAxisConfig"; import Big from "big.js"; import { googleMapsApiUrl } from "../chartComp/chartConfigs/chartUrls"; +import { useContext } from "react"; export function transformData( originData: JSONObject[], @@ -128,7 +129,11 @@ export function getSeriesConfig(props: EchartsConfigProps) { } // https://echarts.apache.org/en/option.html -export function getEchartsConfig(props: EchartsConfigProps, chartSize?: ChartSize): EChartsOptionWithMap { +export function getEchartsConfig( + props: EchartsConfigProps, + chartSize?: ChartSize, + theme?: any, +): EChartsOptionWithMap { if (props.mode === "json") { let opt={ "title": { @@ -136,7 +141,7 @@ export function getEchartsConfig(props: EchartsConfigProps, chartSize?: ChartSiz 'top': props.echartsLegendConfig.top === 'bottom' ?'top':'bottom', "left":"center" }, - "backgroundColor": props?.style?.background, + "backgroundColor": props?.style?.background || theme.background, "color": props.echartsOption.data?.map(data => data.color), "tooltip": props.tooltip&&{ "trigger": "axis", diff --git a/client/packages/lowcoder-design/src/components/colorSelect/index.tsx b/client/packages/lowcoder-design/src/components/colorSelect/index.tsx index 7249ff3303..24c0912561 100644 --- a/client/packages/lowcoder-design/src/components/colorSelect/index.tsx +++ b/client/packages/lowcoder-design/src/components/colorSelect/index.tsx @@ -29,7 +29,7 @@ export const ColorSelect = (props: ColorSelectProps) => { dispatch && dispatch(changeValueAction(toHex(rgbaColor), true)); changeColor && changeColor(toHex(rgbaColor)); }, 200), - [dispatch] + [dispatch,changeColor] ); return ( ; } export function getThemeDetailName(key: keyof ThemeDetail) { switch (key) { - case "primary": - return trans("themeDetail.primary"); - case "textDark": - return trans("themeDetail.textDark"); - case "textLight": - return trans("themeDetail.textLight"); - case "canvas": - return trans("themeDetail.canvas"); - case "primarySurface": - return trans("themeDetail.primarySurface"); - case "borderRadius": - return trans("themeDetail.borderRadius"); - case "margin": - return trans("style.margin"); - case "padding": - return trans("style.padding"); - //Added By Aqib Mirza - case "gridColumns": - return trans("themeDetail.gridColumns"); - case "textSize": - return trans("style.textSize"); + case "primary": return trans("themeDetail.primary"); + case "textDark": return trans("themeDetail.textDark"); + case "textLight": return trans("themeDetail.textLight"); + case "canvas": return trans("themeDetail.canvas"); + case "primarySurface": return trans("themeDetail.primarySurface"); + case "borderRadius": return trans("themeDetail.borderRadius"); + case "borderColor": return trans("themeDetail.borderColor"); + case "borderWidth": return trans("themeDetail.borderWidth"); + case "borderStyle": return trans("themeDetail.borderStyle"); + case "fontFamily": return trans("themeDetail.fontFamily"); + case "margin": return trans("style.margin"); + case "padding": return trans("style.padding"); + case "gridColumns": return trans("themeDetail.gridColumns"); + case "textSize": return trans("style.textSize"); } return ""; } export function isThemeColorKey(key: string) { + console.log("key", key) switch (key as keyof ThemeDetail) { case "primary": case "textDark": case "textLight": case "canvas": case "primarySurface": - case "margin": - case "padding": - case "gridColumns": //Added By Aqib Mirza - case "textSize": + case "accent": + case "validate": + // case "borderRadius": + case "borderColor": + // case "borderWidth": + // case "borderStyle": + // case "fontFamily": + // case "margin": + // case "padding": + // case "gridColumns": + // case "textSize": + case "background" : + case "border": return true; } return false; diff --git a/client/packages/lowcoder/src/components/ColorPicker.tsx b/client/packages/lowcoder/src/components/ColorPicker.tsx deleted file mode 100644 index b461672e26..0000000000 --- a/client/packages/lowcoder/src/components/ColorPicker.tsx +++ /dev/null @@ -1,254 +0,0 @@ -import _ from "lodash"; -import { useEffect, useState } from "react"; -import { ConfigItem, Radius, Margin, Padding, GridColumns } from "../pages/setting/theme/styledComponents"; -import { isValidColor, toHex } from "components/colorSelect/colorUtils"; -import { ColorSelect } from "components/colorSelect"; -import { TacoInput } from "components/tacoInput"; -import { TableCellsIcon as GridIcon } from "lowcoder-design/src/icons"; //Added By Aqib Mirza - -import { ExpandIcon, CompressIcon } from "lowcoder-design/src/icons"; - -export type configChangeParams = { - colorKey: string; - color?: string; - radius?: string; - chart?: string; - margin?: string; - padding?: string; - gridColumns?: string; //Added By Aqib Mirza -}; - -type ColorConfigProps = { - className?: string; - colorKey: string; - name?: string; - desc?: string; - color?: string; - radius?: string; - configChange: (params: configChangeParams) => void; - showVarName?: boolean; - margin?: string; - padding?: string; - gridColumns?: string; //Added By Aqib Mirza -}; - -export default function ColorPicker(props: ColorConfigProps) { - const { - colorKey, - name, - desc, - color: defaultColor, - radius: defaultRadius, - configChange, - showVarName = true, - margin: defaultMargin, - padding: defaultPadding, - gridColumns: defaultGridColumns, //Added By Aqib Mirza - } = props; - const configChangeWithDebounce = _.debounce(configChange, 0); - const [color, setColor] = useState(defaultColor); - const [radius, setRadius] = useState(defaultRadius); - - const [margin, setMargin] = useState(defaultMargin); - const [padding, setPadding] = useState(defaultPadding); - const [gridColumns, setGridColumns] = useState(defaultGridColumns); //Added By Aqib Mirza - - const varName = `(${colorKey})`; - - const colorInputBlur = () => { - if (!color || !isValidColor(color)) { - setColor(defaultColor); - } else { - setColor(toHex(color)); - configChange({ colorKey, color: toHex(color) }); - } - }; - - const radiusInputBlur = (radius: string) => { - let result = ""; - if (!radius || Number(radius) === 0) { - result = "0"; - } else if (/^[0-9]+$/.test(radius)) { - result = Number(radius) + "px"; - } else if (/^[0-9]+(px|%)$/.test(radius)) { - result = radius; - } else { - result = "0"; - } - setRadius(result); - configChange({ colorKey, radius: result }); - }; - - const marginInputBlur = (margin: string) => { - let result = ""; - if (!margin || Number(margin) === 0) { - result = "0"; - } else if (/^[0-9]+$/.test(margin)) { - result = Number(margin) + "px"; - } else if (/^[0-9]+(px|%)$/.test(margin)) { - result = margin; - } else { - result = "3px"; - } - setMargin(result); - configChange({ colorKey, margin: result }); - }; - const paddingInputBlur = (padding: string) => { - let result = ""; - if (!padding || Number(padding) === 0) { - result = "0"; - } else if (/^[0-9]+$/.test(padding)) { - result = Number(padding) + "px"; - } else if (/^[0-9]+(px|%)$/.test(padding)) { - result = padding; - } else { - result = "3px"; - } - setPadding(result); - configChange({ colorKey, padding: result }); - }; - - //Added By Aqib Mirza - - const gridColumnsInputBlur = (gridColumns: string) => { - let result = ""; - if (!gridColumns) { - result = "0"; - } else { - result = gridColumns; - } - setGridColumns(result); - configChange({ colorKey, gridColumns: result }); - }; - - ///////////////////// - - useEffect(() => { - if (color && isValidColor(color)) { - configChangeWithDebounce({ colorKey, color }); - } - }, [color]); - - // reset - useEffect(() => { - setColor(defaultColor); - }, [defaultColor]); - - useEffect(() => { - setRadius(defaultRadius); - }, [defaultRadius]); - - useEffect(() => { - setMargin(defaultMargin); - }, [defaultMargin]); - - useEffect(() => { - setPadding(defaultPadding); - }, [defaultPadding]); - // Added By Aqib Mirza - useEffect(() => { - setGridColumns(defaultGridColumns); - }, [defaultGridColumns]); - ////////////////////// - - return ( - -
-
- {name} {showVarName && {varName}} -
-
{desc}
-
- {colorKey !== "borderRadius" && - colorKey !== "margin" && - colorKey !== "padding" && - colorKey !== "gridColumns" && ( -
- - setColor(e.target.value)} - onBlur={colorInputBlur} - onKeyUp={(e) => e.nativeEvent.key === "Enter" && colorInputBlur()} - /> -
- )} - {colorKey === "borderRadius" && ( -
- -
-
-
- - setRadius(e.target.value)} - onBlur={(e) => radiusInputBlur(e.target.value)} - onKeyUp={(e) => e.nativeEvent.key === "Enter" && radiusInputBlur(e.currentTarget.value)} - /> -
- )} - {colorKey === "margin" && ( -
- -
- -
-
- setMargin(e.target.value)} - onBlur={(e) => marginInputBlur(e.target.value)} - onKeyUp={(e) => - e.nativeEvent.key === "Enter" && - marginInputBlur(e.currentTarget.value) - } - /> -
- )} - {colorKey === "padding" && ( -
- -
- -
-
- setPadding(e.target.value)} - onBlur={(e) => paddingInputBlur(e.target.value)} - onKeyUp={(e) => - e.nativeEvent.key === "Enter" && - paddingInputBlur(e.currentTarget.value) - } - /> -
- )} - {colorKey === "gridColumns" && ( -
- -
- -
-
- setGridColumns(e.target.value)} - onBlur={(e) => gridColumnsInputBlur(e.target.value)} - onKeyUp={(e) => - e.nativeEvent.key === "Enter" && - gridColumnsInputBlur(e.currentTarget.value) - } - /> -
- )} - - ); -} diff --git a/client/packages/lowcoder/src/components/PreviewApp.tsx b/client/packages/lowcoder/src/components/PreviewApp.tsx index df700f75d9..1f5a71f0a7 100644 --- a/client/packages/lowcoder/src/components/PreviewApp.tsx +++ b/client/packages/lowcoder/src/components/PreviewApp.tsx @@ -56,7 +56,9 @@ export default function PreviewApp(props: { return ( - {view} + + {view} + ); } diff --git a/client/packages/lowcoder/src/components/ThemeSettingsCompStyles.tsx b/client/packages/lowcoder/src/components/ThemeSettingsCompStyles.tsx new file mode 100644 index 0000000000..ca8c295e8a --- /dev/null +++ b/client/packages/lowcoder/src/components/ThemeSettingsCompStyles.tsx @@ -0,0 +1,447 @@ +import { useEffect, useMemo, useState } from "react"; +import { ConfigItem, Radius, Margin, Padding, GridColumns, BorderWidth, BorderStyle } from "../pages/setting/theme/styledComponents"; +import { isValidColor, toHex } from "components/colorSelect/colorUtils"; +import { ColorSelect } from "components/colorSelect"; +import { TacoInput } from "components/tacoInput"; +import { Slider } from "antd"; +import { + ExpandIcon, + CompressIcon, + BorderRadiusIcon, + BorderWidthIcon, + BorderStyleIcon, + TableCellsIcon, + RefreshLineIcon, + OpacityIcon, + ShadowIcon, + StarSmileIcon, + TimerFlashIcon, + Timer2Icon, + TextSizeIcon, + TextWeightIcon, + FontFamilyIcon, + TextTransformationIcon, + TextDecorationIcon, + TextStyleIcon, + ImageCompIconSmall, + RotationIcon, + } from "lowcoder-design/src/icons"; +import { trans } from "i18n"; +import { debounce } from "lodash"; + +export type configChangeParams = { + themeSettingKey: string; + color?: string; + radius?: string; + chart?: string; + margin?: string; + padding?: string; + gridColumns?: string; // Added By Aqib Mirza + borderStyle?: string; + borderColor?: string; + borderWidth?: string; + fontFamily?: string; +}; + +type ColorConfigProps = { + className?: string; + themeSettingKey: string; + name?: string; + desc?: string; + color?: string; + + configChange: (params: configChangeParams) => void; + showVarName?: boolean; + radius?: string; + borderStyle?: string; + borderWidth?: string; + borderColor?: string; + fontFamily?: string; + margin?: string; + padding?: string; + gridColumns?: string; // Added By Aqib Mirza +}; + +const isColorStyle = (styleKey: string) => { + return styleKey !== 'radius' && + styleKey !== 'borderWidth' && + styleKey !== 'boxShadow' && + styleKey !== 'animationIterationCount' && + styleKey !== 'opacity' && + styleKey !== 'animation' && + styleKey !== 'animationDelay' && + styleKey !== 'animationDuration' && + styleKey !== 'rotation' && + styleKey !== 'cardRadius' && + styleKey !== 'textSize' && + styleKey !== 'textWeight' && + styleKey !== 'textTransform' && + styleKey !== 'textDecoration' && + styleKey !== 'fontFamily' && + styleKey !== 'borderStyle' && + styleKey !== 'fontStyle' && + styleKey !== 'backgroundImage' && + styleKey !== 'backgroundImageRepeat' && + styleKey !== 'backgroundImageSize' && + styleKey !== 'backgroundImagePosition' && + styleKey !== 'backgroundImageOrigin' && + styleKey !== 'headerBackgroundImage' && + styleKey !== 'headerBackgroundImageRepeat' && + styleKey !== 'headerBackgroundImageSize' && + styleKey !== 'headerBackgroundImagePosition' && + styleKey !== 'headerBackgroundImageOrigin' && + styleKey !== 'footerBackgroundImage' && + styleKey !== 'footerBackgroundImageRepeat' && + styleKey !== 'footerBackgroundImageSize' && + styleKey !== 'footerBackgroundImagePosition' && + styleKey !== 'footerBackgroundImageOrigin' && + styleKey !== 'margin' && + styleKey !== 'padding' && + styleKey !== 'containerHeaderPadding' && + styleKey !== 'containerSiderPadding' && + styleKey !== 'containerFooterPadding' && + styleKey !== 'containerBodyPadding'; +} + + +type CompStyleProps = { + styleOptions: string[]; + defaultStyle: Record; + configChange: (params: any) => void; +} + +export default function ThemeSettingsCompStyles(props: CompStyleProps) { + const { defaultStyle, styleOptions, configChange } = props; + const [compStyle, setCompStyle] = useState({...defaultStyle}); + + const updateThemeWithDebounce = useMemo(() => { + return debounce((updateStyles) => { + configChange(updateStyles); + }, 500); + }, [configChange]); + + const handleChange = (styleKey: string, styleValue: string) => { + const updateStyles = { + ...compStyle, + [styleKey]: styleValue, + }; + setCompStyle(updateStyles); + updateThemeWithDebounce(updateStyles); + } + + const getLabelByStyle = (styleKey: string) => { + let label = styleKey; + switch(styleKey) { + case 'radius': + case 'cardRadius': + case 'gap': { + label = trans("style.borderRadius"); + break; + } + // case 'borderWidth': + // case 'borderStyle': + // case 'margin': + // case 'padding': + // case 'containerHeaderPadding': + // case 'containerSiderPadding': + // case 'containerFooterPadding': + // case 'containerBodyPadding': + // case 'opacity': + // case 'boxShadowColor': + // case 'boxShadow': + // case 'animationIterationCount': + // case 'animation': + // case 'animationDelay': + // case 'animationDuration': + // case 'textSize': + // case 'textWeight': + // case 'fontFamily': + // case 'textDecoration': + // case 'textTransform': + // case 'fontStyle': + // case 'backgroundImage': + // case 'headerBackgroundImage': + // case 'footerBackgroundImage': + // case 'backgroundImageRepeat': + // case 'headerBackgroundImageRepeat': + // case 'footerBackgroundImageRepeat': + // case 'rotation': { + // label = trans(`style.${styleKey}`); + // break; + // } + default: { + label = trans(`style.${styleKey}`); + break; + } + } + return label; + } + + const getPlaceholderByStyle = (styleKey: string) => { + let placeholder = ''; + switch(styleKey) { + case 'radius': + case 'cardRadius': + case 'gap': { + placeholder = '2px'; + break; + } + case 'borderWidth': { + placeholder = '1px'; + break; + } + case 'borderStyle': { + placeholder = 'solid'; + break; + } + case 'margin': { + placeholder = '3px'; + break; + } + case 'padding': + case 'containerHeaderPadding': + case 'containerSiderPadding': + case 'containerFooterPadding': + case 'containerBodyPadding': { + placeholder = '3px'; + break; + } + case 'opacity': { + placeholder = '1'; + break; + } + case 'boxShadowColor': { + placeholder = '#FFFFFF'; + break; + } + case 'boxShadow': { + placeholder = '0px 0px 0px'; + break; + } + case 'animationIterationCount': { + placeholder = '0'; + break; + } + case 'animation': { + placeholder = 'none'; + break; + } + case 'animationDelay': { + placeholder = '0s'; + break; + } + case 'animationDuration': { + placeholder = '0s'; + break; + } + case 'textSize': { + placeholder = '14px'; + break; + } + case 'textWeight': { + placeholder = 'normal'; + break; + } + case 'fontFamily': { + placeholder = 'sans-serif'; + break; + } + case 'textDecoration': { + placeholder = 'none'; + break; + } + case 'textTransform': { + placeholder = 'none'; + break; + } + case 'fontStyle': { + placeholder = 'normal'; + break; + } + case 'backgroundImage': + case 'headerBackgroundImage': + case 'footerBackgroundImage': { + placeholder = ''; + break; + } + case 'backgroundImageRepeat': + case 'headerBackgroundImageRepeat': + case 'footerBackgroundImageRepeat': { + placeholder = 'no-repeat'; + break; + } + case 'rotation': { + placeholder = '0deg'; + break; + } + } + return placeholder; + } + + const getIconByStyle = (styleKey: string) => { + let icon = null; + switch(styleKey) { + case 'radius': + case 'cardRadius': + case 'gap': { + icon = ; + break; + } + case 'borderWidth': { + icon = ; + break; + } + case 'borderStyle': { + icon = ; + break; + } + case 'margin': { + icon = ; + break; + } + case 'padding': + case 'containerHeaderPadding': + case 'containerSiderPadding': + case 'containerFooterPadding': + case 'containerBodyPadding': { + icon = ; + break; + } + case 'opacity': { + icon = ; + break; + } + case 'boxShadowColor': { + icon = ; + break; + } + case 'boxShadow': { + icon = ; + break; + } + case 'animationIterationCount': { + icon = ; + break; + } + case 'animation': { + icon = ; + break; + } + case 'animationDelay': { + icon = ; + break; + } + case 'animationDuration': { + icon = ; + break; + } + case 'textSize': { + icon = ; + break; + } + case 'textWeight': { + icon = ; + break; + } + case 'fontFamily': { + icon = ; + break; + } + case 'textDecoration': { + icon = ; + break; + } + case 'textTransform': { + icon = ; + break; + } + case 'fontStyle': { + icon = ; + break; + } + case 'backgroundImage': + case 'headerBackgroundImage': + case 'footerBackgroundImage': { + icon = ; + break; + } + case 'backgroundImageRepeat': + case 'headerBackgroundImageRepeat': + case 'footerBackgroundImageRepeat': { + icon = ; + break; + } + case 'rotation': { + icon = ; + break; + } + } + return icon; + } + + return ( +
+ {styleOptions.map((styleKey: string) => ( + +
+
+ { getLabelByStyle(styleKey) } +
+
+ { isColorStyle(styleKey) ? ( +
+ handleChange(styleKey, value)} + color={compStyle[styleKey]!} + trigger="hover" + /> + handleChange(styleKey, e.target.value)} + // onChange={(e) => setColor(e.target.value)} + // onBlur={colorInputBlur} + // onKeyUp={(e) => e.nativeEvent.key === "Enter" && colorInputBlur()} + /> +
+ ): ( +
+ {/* */} +
+ {getIconByStyle(styleKey)} +
+ {/*
*/} + handleChange(styleKey, e.target.value)} + // onBlur={(e) => radiusInputBlur(e.target.value)} + // onKeyUp={(e) => e.nativeEvent.key === "Enter" && radiusInputBlur(e.currentTarget.value)} + /> +
+ )} +
+ ))} +
+ ) +} diff --git a/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx b/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx new file mode 100644 index 0000000000..4ac7cbd3ff --- /dev/null +++ b/client/packages/lowcoder/src/components/ThemeSettingsSelector.tsx @@ -0,0 +1,403 @@ +import _ from "lodash"; +import { useEffect, useState } from "react"; +import { ConfigItem, Radius, Margin, Padding, GridColumns, BorderWidth, BorderStyle } from "../pages/setting/theme/styledComponents"; +import { isValidColor, toHex } from "components/colorSelect/colorUtils"; +import { ColorSelect } from "components/colorSelect"; +import { TacoInput } from "components/tacoInput"; +import { Slider } from "antd"; +import { + ExpandIcon, + CompressIcon, + BorderRadiusIcon, + BorderWidthIcon, + BorderStyleIcon, + TableCellsIcon, + } from "lowcoder-design/src/icons"; + +export type configChangeParams = { + themeSettingKey: string; + color?: string; + radius?: string; + chart?: string; + margin?: string; + padding?: string; + gridColumns?: string; // Added By Aqib Mirza + borderStyle?: string; + borderColor?: string; + borderWidth?: string; + fontFamily?: string; + components?: Record, +}; + +type ColorConfigProps = { + className?: string; + themeSettingKey: string; + name?: string; + desc?: string; + color?: string; + + configChange: (params: configChangeParams) => void; + showVarName?: boolean; + radius?: string; + borderStyle?: string; + borderWidth?: string; + borderColor?: string; + fontFamily?: string; + margin?: string; + padding?: string; + gridColumns?: string; // Added By Aqib Mirza +}; + +export default function ThemeSettingsSelector(props: ColorConfigProps) { + const { + themeSettingKey, + name, + desc, + color: defaultColor, + radius: defaultRadius, + configChange, + showVarName = true, + margin: defaultMargin, + padding: defaultPadding, + gridColumns: defaultGridColumns, + borderStyle: defaultBorderStyle, + borderWidth: defaultBorderWidth, + borderColor: defaultBorderColor, + fontFamily: defaultFontFamily + } = props; + + const configChangeWithDebounce = _.debounce(configChange, 0); + const [color, setColor] = useState(defaultColor); + const [radius, setRadius] = useState(defaultRadius); + const [margin, setMargin] = useState(defaultMargin); + const [padding, setPadding] = useState(defaultPadding); + const [gridColumns, setGridColumns] = useState(defaultGridColumns); + const [borderStyle, setBorderStyle] = useState(defaultBorderStyle); + const [borderWidth, setBorderWidth] = useState(defaultBorderWidth); + const [borderColor, setBorderColor] = useState(defaultBorderColor); + const [fontFamily, setFontFamily] = useState(defaultFontFamily); + + const varName = `(${themeSettingKey})`; + + const colorInputBlur = () => { + if (!color || !isValidColor(color)) { + setColor(defaultColor); + } else { + setColor(toHex(color)); + configChange({ themeSettingKey, color: toHex(color) }); + } + }; + + const radiusInputBlur = (radius: string) => { + let result = ""; + if (!radius || Number(radius) === 0) { + result = "0"; + } else if (/^[0-9]+$/.test(radius)) { + result = Number(radius) + "px"; + } else if (/^[0-9]+(px|%)$/.test(radius)) { + result = radius; + } else { + result = "0"; + } + setRadius(result); + configChange({ themeSettingKey, radius: result }); + }; + + const marginInputBlur = (margin: string) => { + let result = ""; + if (!margin || Number(margin) === 0) { + result = "0"; + } else if (/^[0-9]+$/.test(margin)) { + result = Number(margin) + "px"; + } else if (/^[0-9]+(px|%)$/.test(margin)) { + result = margin; + } else { + result = "3px"; + } + setMargin(result); + configChange({ themeSettingKey, margin: result }); + }; + + const paddingInputBlur = (padding: string) => { + let result = ""; + if (!padding || Number(padding) === 0) { + result = "0"; + } else if (/^[0-9]+$/.test(padding)) { + result = Number(padding) + "px"; + } else if (/^[0-9]+(px|%)$/.test(padding)) { + result = padding; + } else { + result = "3px"; + } + setPadding(result); + configChange({ themeSettingKey, padding: result }); + }; + + const gridColumnsInputBlur = (gridColumns: string) => { + let result = ""; + if (!gridColumns) { + result = "24"; + } else { + result = gridColumns; + } + setGridColumns(result); + configChange({ themeSettingKey, gridColumns: result }); + }; + + const borderStyleInputBlur = (borderStyle: string) => { + let result = ""; + if (!borderStyle) { + result = "solid"; + } else { + result = borderStyle; + } + setBorderStyle(result); + configChange({ themeSettingKey, borderStyle: result }); + }; + + const borderWidthInputBlur = (borderWidth: string) => { + let result = ""; + if (!borderWidth || Number(borderWidth) === 0) { + result = "0"; + } else if (/^[0-9]+$/.test(borderWidth)) { + result = Number(borderWidth) + "px"; + } else if (/^[0-9]+(px|%)$/.test(borderWidth)) { + result = borderWidth; + } else { + result = "1px"; + } + setBorderWidth(borderWidth); + configChange({ themeSettingKey, borderWidth: result }); + }; + + const borderColorInputBlur = (borderColor: string) => { + setBorderColor(borderColor); + configChange({ themeSettingKey, borderColor }); + }; + + const fontFamilyInputBlur = (fontFamily: string) => { + let result = ""; + if (!fontFamily) { + result = "Roboto, sans-serif"; + } else { + result = fontFamily; + } + setFontFamily(result); + configChange({ themeSettingKey, fontFamily: result }); + }; + + + useEffect(() => { + if (color && isValidColor(color)) { + configChangeWithDebounce({ themeSettingKey, color }); + } + }, [color]); + + useEffect(() => { + setColor(defaultColor); + }, [defaultColor]); + + useEffect(() => { + setRadius(defaultRadius); + }, [defaultRadius]); + + useEffect(() => { + setMargin(defaultMargin); + }, [defaultMargin]); + + useEffect(() => { + setPadding(defaultPadding); + }, [defaultPadding]); + + useEffect(() => { + setGridColumns(defaultGridColumns); + }, [defaultGridColumns]); + + useEffect(() => { + setBorderStyle(defaultBorderStyle); + }, [defaultBorderStyle]); + + useEffect(() => { + setBorderWidth(defaultBorderWidth); + }, [defaultBorderWidth]); + + useEffect(() => { + setBorderColor(defaultBorderColor); + }, [defaultBorderColor]); + + useEffect(() => { + setFontFamily(defaultFontFamily); + }, [defaultFontFamily]); + + return ( + +
+
+ {name} {showVarName && {varName}} +
+
{desc}
+
+ + {themeSettingKey !== "borderRadius" && + themeSettingKey !== "margin" && + themeSettingKey !== "padding" && + themeSettingKey !== "gridColumns" && + themeSettingKey !== "borderStyle" && + themeSettingKey !== "borderWidth" && + themeSettingKey !== "fontFamily" && ( +
+ + setColor(e.target.value)} + onBlur={colorInputBlur} + onKeyUp={(e) => e.nativeEvent.key === "Enter" && colorInputBlur()} + /> +
+ )} + + {/* // border Styles */} + + {/* {themeSettingKey === "borderColor" && ( +
+ + setBorderColor(e.target.value)} + onBlur={(e) => borderColorInputBlur(e.target.value)} + onKeyUp={(e) => e.nativeEvent.key === "Enter" && borderColorInputBlur(e.currentTarget.value)} + /> +
+ )} */} + {themeSettingKey === "borderRadius" && ( +
+ +
+ +
+
+ setRadius(e.target.value)} + onBlur={(e) => radiusInputBlur(e.target.value)} + onKeyUp={(e) => e.nativeEvent.key === "Enter" && radiusInputBlur(e.currentTarget.value)} + /> +
+ )} + {themeSettingKey === "borderStyle" && ( +
+ +
+ +
+
+ setBorderStyle(e.target.value)} + onBlur={(e) => borderStyleInputBlur(e.target.value)} + onKeyUp={(e) => e.nativeEvent.key === "Enter" && borderStyleInputBlur(e.currentTarget.value)} + /> +
+ )} + {themeSettingKey === "borderWidth" && ( +
+ +
+ +
+
+ setBorderWidth(e.target.value)} + onBlur={(e) => borderWidthInputBlur(e.target.value)} + onKeyUp={(e) => e.nativeEvent.key === "Enter" && borderWidthInputBlur(e.currentTarget.value)} + /> +
+ )} + + {themeSettingKey === "margin" && ( +
+ +
+ +
+
+ setMargin(e.target.value)} + onBlur={(e) => marginInputBlur(e.target.value)} + onKeyUp={(e) => + e.nativeEvent.key === "Enter" && + marginInputBlur(e.currentTarget.value) + } + /> +
+ )} + + {themeSettingKey === "padding" && ( +
+ +
+ +
+
+ setPadding(e.target.value)} + onBlur={(e) => paddingInputBlur(e.target.value)} + onKeyUp={(e) => + e.nativeEvent.key === "Enter" && + paddingInputBlur(e.currentTarget.value) + } + /> +
+ )} + + {themeSettingKey === "gridColumns" && ( +
+ +
+ +
+
+ + setGridColumns(value.toString())} + onAfterChange={(value) => gridColumnsInputBlur(value.toString())} + /> +
+ )} + + + + {themeSettingKey === "fontFamily" && ( +
+ setFontFamily(e.target.value)} + onBlur={(e) => fontFamilyInputBlur(e.target.value)} + onKeyUp={(e) => e.nativeEvent.key === "Enter" && fontFamilyInputBlur(e.currentTarget.value)} + /> +
+ )} +
+ ); +} diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx index b9e1a7031f..5be5c5aa23 100644 --- a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx @@ -21,7 +21,10 @@ import { hasIcon } from "comps/utils"; import { RefControl } from "comps/controls/refControl"; import { EditorContext } from "comps/editorState"; -import React, { useContext } from "react"; +import React, { useContext, useEffect } from "react"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const Link = styled(Button)<{ $style: LinkStyleType; @@ -85,13 +88,28 @@ const LinkTmpComp = (function () { onEvent: ButtonEventHandlerControl, disabled: BoolCodeControl, loading: BoolCodeControl, - style: migrateOldData(styleControl(LinkStyle), fixOldData), - animationStyle:styleControl(AnimationStyle), + style: migrateOldData(styleControl(LinkStyle,'style'), fixOldData), + animationStyle:styleControl(AnimationStyle,'animationStyle'), prefixIcon: IconControl, suffixIcon: IconControl, viewRef: RefControl, }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); // chrome86 bug: button children should not contain only empty span const hasChildren = hasIcon(props.prefixIcon) || !!props.text || hasIcon(props.suffixIcon); return ( diff --git a/client/packages/lowcoder/src/comps/comps/carouselComp.tsx b/client/packages/lowcoder/src/comps/comps/carouselComp.tsx index 6ad2edf60e..ba9195a936 100644 --- a/client/packages/lowcoder/src/comps/comps/carouselComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/carouselComp.tsx @@ -9,7 +9,7 @@ import { trans } from "i18n"; import { ChangeEventHandlerControl } from "comps/controls/eventHandlerControl"; import { formDataChildren, FormDataPropertyView } from "./formComp/formDataConstants"; import { PositionControl } from "comps/controls/dropdownControl"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import ReactResizeDetector from "react-resize-detector"; import { ArrayStringControl } from "comps/controls/codeControl"; import { styleControl } from "comps/controls/styleControl"; @@ -17,6 +17,9 @@ import { AnimationStyle, AnimationStyleType, CarouselStyle } from "comps/control import { useContext } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { setInitialCompStyles } from "../utils/themeUtil"; // TODO: dots at top position needs proper margin (should be the same as bottom position) @@ -44,13 +47,30 @@ let CarouselBasicComp = (function () { onEvent: ChangeEventHandlerControl, showDots: withDefault(BoolControl, true), dotPosition: withDefault(PositionControl, "bottom"), - style: styleControl(CarouselStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(CarouselStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), ...formDataChildren, }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { const containerRef = useRef(null); const [height, setHeight] = useState(0); + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); const onResize = () => { if (containerRef.current) { setHeight(containerRef.current.clientHeight); diff --git a/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx b/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx index d927b67955..cd5aa7aa93 100644 --- a/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/commentComp/commentComp.tsx @@ -66,6 +66,9 @@ import dayjs from "dayjs"; // import "dayjs/locale/zh-cn"; import { getInitialsAndColorCode } from "util/stringUtils"; import { default as CloseOutlined } from "@ant-design/icons/CloseOutlined"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; dayjs.extend(relativeTime); // dayjs.locale("zh-cn"); @@ -100,8 +103,8 @@ const childrenMap = { "#": ["123", "456", "789"], }), onEvent: eventHandlerControl(EventOptions), - style: styleControl(CommentStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(CommentStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), commentList: jsonValueExposingStateControl("commentList", []), deletedItem: jsonValueExposingStateControl("deletedItem", []), submitedItem: jsonValueExposingStateControl("submitedItem", []), @@ -370,9 +373,24 @@ const CommentCompBase = ( }; let CommentBasicComp = (function () { - return new UICompBuilder(childrenMap, (props, dispatch) => ( - - )) + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); + return + }) .setPropertyViewFn((children) => ( <>
diff --git a/client/packages/lowcoder/src/comps/comps/dividerComp.tsx b/client/packages/lowcoder/src/comps/comps/dividerComp.tsx index 3baf6b53dd..80a1ab58f3 100644 --- a/client/packages/lowcoder/src/comps/comps/dividerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/dividerComp.tsx @@ -13,8 +13,11 @@ import { migrateOldData } from "comps/generators/simpleGenerators"; import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { setInitialCompStyles } from "../utils/themeUtil"; type IProps = DividerProps & { $style: DividerStyleType; @@ -70,8 +73,8 @@ const childrenMap = { title: StringControl, dashed: BoolControl, align: alignControl(), - style: styleControl(DividerStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(DividerStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), }; function fixOldStyleData(oldData: any) { @@ -91,7 +94,22 @@ function fixOldStyleData(oldData: any) { // Compatible with historical style data 2022-8-26 export const DividerComp = migrateOldData( - new UICompBuilder(childrenMap, (props) => { + new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ( ; const FormBaseComp = (function () { return new ContainerCompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ( diff --git a/client/packages/lowcoder/src/comps/comps/gridItemComp.tsx b/client/packages/lowcoder/src/comps/comps/gridItemComp.tsx index 4fb4eb9612..2ac4e82eb9 100644 --- a/client/packages/lowcoder/src/comps/comps/gridItemComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/gridItemComp.tsx @@ -39,7 +39,6 @@ const TmpComp = withTypeAndChildren< >( (type) => { const compInfo = parseCompType(type); - if (compInfo.isRemote) { return remoteComp(compInfo); } diff --git a/client/packages/lowcoder/src/comps/comps/iframeComp.tsx b/client/packages/lowcoder/src/comps/comps/iframeComp.tsx index b0e7dd64f4..beb84ccf65 100644 --- a/client/packages/lowcoder/src/comps/comps/iframeComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/iframeComp.tsx @@ -10,8 +10,11 @@ import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; import log from "loglevel"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { setInitialCompStyles } from "../utils/themeUtil"; const Wrapper = styled.div<{$style: IframeStyleType; $animationStyle:AnimationStyleType}>` width: 100%; @@ -43,10 +46,27 @@ let IFrameCompBase = new UICompBuilder( allowMicrophone: BoolControl, allowCamera: BoolControl, allowPopup: BoolControl, - style: styleControl(IframeStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(IframeStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), }, - (props) => { + (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); const sandbox = ["allow-scripts", "allow-same-origin"]; props.allowSubmitForm && sandbox.push("allow-forms"); props.allowDownload && sandbox.push("allow-downloads"); diff --git a/client/packages/lowcoder/src/comps/comps/imageComp.tsx b/client/packages/lowcoder/src/comps/comps/imageComp.tsx index 4b571764ce..d72032a465 100644 --- a/client/packages/lowcoder/src/comps/comps/imageComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/imageComp.tsx @@ -34,6 +34,9 @@ import { DEFAULT_IMG_URL } from "util/stringUtils"; import { useContext } from "react"; import { EditorContext } from "comps/editorState"; import { StringControl } from "../controls/codeControl"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { setInitialCompStyles } from "../utils/themeUtil"; const Container = styled.div<{ $style: ImageStyleType | undefined,$animationStyle:AnimationStyleType }>` height: 100%; @@ -166,14 +169,31 @@ const ContainerImg = (props: RecordConstructorToView) => { const childrenMap = { src: withDefault(StringStateControl, "https://temp.im/350x400"), onEvent: eventHandlerControl(EventOptions), - style: styleControl(ImageStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(ImageStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), autoHeight: withDefault(AutoHeightControl, "fixed"), supportPreview: BoolControl, restrictPaddingOnRotation:withDefault(StringControl, 'image') }; -let ImageBasicComp = new UICompBuilder(childrenMap, (props) => { +let ImageBasicComp = new UICompBuilder(childrenMap, (props,dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ; }) .setPropertyViewFn((children) => { diff --git a/client/packages/lowcoder/src/comps/comps/jsonComp/jsonEditorComp.tsx b/client/packages/lowcoder/src/comps/comps/jsonComp/jsonEditorComp.tsx index 9583c449a2..dd4b01d336 100644 --- a/client/packages/lowcoder/src/comps/comps/jsonComp/jsonEditorComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/jsonComp/jsonEditorComp.tsx @@ -20,6 +20,9 @@ import { } from "base/codeEditor/codeMirror"; import { useExtensions } from "base/codeEditor/extensions"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; /** * JsonEditor Comp @@ -65,14 +68,29 @@ const childrenMap = { value: jsonValueExposingStateControl("value", defaultData), onEvent: ChangeEventHandlerControl, label: withDefault(LabelControl, { position: "column" }), - style: styleControl(JsonEditorStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(JsonEditorStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), ...formDataChildren, }; let JsonEditorTmpComp = (function () { - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); const wrapperRef = useRef(null); const view = useRef(null); const editContent = useRef(); diff --git a/client/packages/lowcoder/src/comps/comps/jsonComp/jsonExplorerComp.tsx b/client/packages/lowcoder/src/comps/comps/jsonComp/jsonExplorerComp.tsx index da9514c799..9d0269a4d7 100644 --- a/client/packages/lowcoder/src/comps/comps/jsonComp/jsonExplorerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/jsonComp/jsonExplorerComp.tsx @@ -10,8 +10,10 @@ import { ArrayOrJSONObjectControl, NumberControl } from "comps/controls/codeCont import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; import { EditorContext } from "comps/editorState"; -import { useContext } from "react"; -import { AnimationStyle, AnimationStyleType, styleControl } from "@lowcoder-ee/index.sdk"; +import { useContext, useEffect } from "react"; +import { AnimationStyle, AnimationStyleType, styleControl, ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; /** * JsonExplorer Comp @@ -54,10 +56,27 @@ let JsonExplorerTmpComp = (function () { indent: withDefault(NumberControl, 4), expandToggle: BoolControl.DEFAULT_TRUE, theme: dropdownControl(themeOptions, 'shapeshifter:inverted'), - animationStyle:styleControl(AnimationStyle), + animationStyle:styleControl(AnimationStyle,'animationStyle'), }; - return new UICompBuilder(childrenMap, (props) => ( - { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); + return @@ -70,7 +89,7 @@ let JsonExplorerTmpComp = (function () { indentWidth={props.indent} /> - )) + }) .setPropertyViewFn((children) => { return ( <> diff --git a/client/packages/lowcoder/src/comps/comps/jsonComp/jsonLottieComp.tsx b/client/packages/lowcoder/src/comps/comps/jsonComp/jsonLottieComp.tsx index 078228642b..74f17df57d 100644 --- a/client/packages/lowcoder/src/comps/comps/jsonComp/jsonLottieComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/jsonComp/jsonLottieComp.tsx @@ -9,7 +9,7 @@ import { styleControl } from "comps/controls/styleControl"; import { AnimationStyle, LottieStyle } from "comps/controls/styleControlConstants"; import { trans } from "i18n"; import { Section, sectionNames } from "lowcoder-design"; -import { useContext, lazy } from "react"; +import { useContext, lazy, useEffect } from "react"; import { UICompBuilder, withDefault } from "../../generators"; import { NameConfig, @@ -18,6 +18,9 @@ import { } from "../../generators/withExposing"; import { defaultLottie } from "./jsonConstants"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const Player = lazy( () => import('@lottiefiles/react-lottie-player') @@ -94,12 +97,29 @@ let JsonLottieTmpComp = (function () { width: withDefault(NumberControl, 100), height: withDefault(NumberControl, 100), container: styleControl(LottieStyle), - animationStyle: styleControl(AnimationStyle), + animationStyle: styleControl(AnimationStyle,'animationStyle'), animationStart: dropdownControl(animationStartOptions, "auto"), loop: dropdownControl(loopOptions, "single"), keepLastFrame: BoolControl.DEFAULT_TRUE, }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return (
{ + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); // rjsf 4.20 supports ui:submitButtonOptions, but if the button is customized, it will not take effect. Here we implement it ourselves const buttonOptions = props?.uiSchema?.[ "ui:submitButtonOptions" diff --git a/client/packages/lowcoder/src/comps/comps/mediaComp/audioComp.tsx b/client/packages/lowcoder/src/comps/comps/mediaComp/audioComp.tsx index 9ed3084934..c4dd01bfc3 100644 --- a/client/packages/lowcoder/src/comps/comps/mediaComp/audioComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/mediaComp/audioComp.tsx @@ -13,8 +13,11 @@ import { withDefault } from "../../generators/simpleGenerators"; import { trans } from "i18n"; import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { mediaCommonChildren, mediaMethods } from "./mediaUtils"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const Container = styled.div<{ $style: any; $animationStyle: AnimationStyleType }>` ${props => props.$style}; @@ -66,15 +69,32 @@ const ContainerAudio = (props: RecordConstructorToView) => { const childrenMap = { src: withDefault(StringStateControl, trans("audio.defaultSrcUrl")), onEvent: eventHandlerControl(EventOptions), - style: styleControl(AudioStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(AudioStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), autoPlay: BoolControl, loop: BoolControl, ...mediaCommonChildren, }; let AudioBasicComp = (function () { - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style','animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ; }) .setPropertyViewFn((children) => { diff --git a/client/packages/lowcoder/src/comps/comps/mediaComp/videoComp.tsx b/client/packages/lowcoder/src/comps/comps/mediaComp/videoComp.tsx index 7130c84e01..9e5961b456 100644 --- a/client/packages/lowcoder/src/comps/comps/mediaComp/videoComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/mediaComp/videoComp.tsx @@ -4,7 +4,7 @@ import { StringStateControl, numberExposingStateControl } from "../../controls/c import { UICompBuilder } from "../../generators"; import { NameConfig, NameConfigHidden, withExposingConfigs } from "../../generators/withExposing"; import { RecordConstructorToView } from "lowcoder-core"; -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { styleControl } from "comps/controls/styleControl"; import { AnimationStyle, @@ -24,6 +24,9 @@ import { mediaCommonChildren, mediaMethods } from "./mediaUtils"; import { useContext } from "react"; import { EditorContext } from "comps/editorState"; import styled, { css } from "styled-components"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const EventOptions = [ { label: trans("video.play"), value: "play", description: trans("video.playDesc") }, @@ -115,8 +118,8 @@ const childrenMap = { src: withDefault(StringStateControl, trans('video.defaultSrcUrl')), poster: withDefault(StringStateControl, trans('video.defaultPosterUrl')), onEvent: eventHandlerControl(EventOptions), - style: styleControl(VideoStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(VideoStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), autoPlay: BoolControl, loop: BoolControl, controls: BoolControl, @@ -128,7 +131,24 @@ const childrenMap = { }; let VideoBasicComp = (function () { - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ; }) .setPropertyViewFn((children) => { diff --git a/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx b/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx index 124829fb24..6a092d25e9 100644 --- a/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/navComp/navComp.tsx @@ -20,8 +20,11 @@ import { import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; type IProps = { $justify: boolean; @@ -134,8 +137,8 @@ const childrenMap = { logoUrl: StringControl, logoEvent: withDefault(eventHandlerControl(logoEventHandlers), [{ name: "click" }]), horizontalAlignment: alignWithJustifyControl(), - style: migrateOldData(styleControl(NavigationStyle), fixOldStyleData), - animationStyle: styleControl(AnimationStyle), + style: migrateOldData(styleControl(NavigationStyle,'style'), fixOldStyleData), + animationStyle: styleControl(AnimationStyle,'animationStyle'), items: withDefault(navListComp(), [ { label: trans("menuItem") + " 1", @@ -143,7 +146,22 @@ const childrenMap = { ]), }; -const NavCompBase = new UICompBuilder(childrenMap, (props) => { +const NavCompBase = new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); const data = props.items; const items = ( <> diff --git a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx index a001c7bd23..38e89595c4 100644 --- a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx @@ -9,8 +9,11 @@ import { NameConfig, NameConfigHidden, withExposingConfigs } from "../generators import { hiddenPropertyView } from "comps/utils/propertyUtils"; import { trans } from "i18n"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { setInitialCompStyles } from "../utils/themeUtil"; // TODO: after Update of ANTd, introduce Size attribute to ProgressCircle @@ -69,10 +72,27 @@ let ProgressCircleTmpComp = (function () { const childrenMap = { value: numberExposingStateControl("value", 60), // borderRadius property hidden as it's not valid for progress circle - style: styleControl(CircleProgressStyle), + style: styleControl(CircleProgressStyle,'style'), animationStyle: styleControl(AnimationStyle), }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ( { return css` @@ -53,10 +56,27 @@ const ProgressBasicComp = (function () { const childrenMap = { value: numberExposingStateControl('value', 60), showInfo: BoolControl, - style: styleControl(ProgressStyle), + style: styleControl(ProgressStyle,'style'), animationStyle: styleControl(AnimationStyle), }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return ( { +const RichTextEditorCompBase = new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); const handleChange = (v: string) => { props.value.onChange(v); props.onEvent("change"); diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx index 095e85f742..4cccee7922 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderComp.tsx @@ -7,6 +7,10 @@ import { UICompBuilder, withDefault } from "../../generators"; import { CommonNameConfig, NameConfig, withExposingConfigs } from "../../generators/withExposing"; import { CascaderChildren, CascaderPropertyView, defaultDataSource } from "./cascaderContants"; import { refMethods } from "comps/generators/withMethodExposing"; +import { useContext, useEffect } from "react"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const CascaderStyle = styled(Cascader)<{ $style: CascaderStyleType,$childrenInputFieldStyle:ChildrenMultiSelectStyleType }>` width: 100%; @@ -37,7 +41,22 @@ const DropdownRenderStyle = styled.div<{ $childrenInputFieldStyle: ChildrenMulti let CascaderBasicComp = (function () { const childrenMap = CascaderChildren; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'labelStyle', 'inputFieldStyle','childrenInputFieldStyle', 'animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return props.label({ style: props.style, labelStyle: props.labelStyle, diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx index ac3eb7999e..1465f77f1d 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx @@ -24,6 +24,10 @@ import { trans } from "i18n"; import { RefControl } from "comps/controls/refControl"; import { migrateOldData } from "comps/generators/simpleGenerators"; import { fixOldInputCompData } from "../textInputComp/textInputConstants"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { useContext, useEffect } from "react"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; export const getStyle = (style: CheckboxStyleType) => { return css` @@ -136,20 +140,37 @@ let CheckboxBasicComp = (function () { disabled: BoolCodeControl, onEvent: ChangeEventHandlerControl, options: SelectInputOptionControl, - style: styleControl(InputFieldStyle), - labelStyle: styleControl(LabelStyle.filter((style) => ['accent', 'validate'].includes(style.name) === false)), + style: styleControl(InputFieldStyle,'style'), + labelStyle: styleControl(LabelStyle.filter((style) => ['accent', 'validate'].includes(style.name) === false),'labelStyle'), layout: dropdownControl(RadioLayoutOptions, "horizontal"), viewRef: RefControl, - inputFieldStyle:styleControl(CheckboxStyle), - animationStyle:styleControl(AnimationStyle), + inputFieldStyle:styleControl(CheckboxStyle,'inputFieldStyle'), + animationStyle:styleControl(AnimationStyle,'animationStyle'), ...SelectInputValidationChildren, ...formDataChildren, }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { const [ validateState, handleChange, ] = useSelectInputValidate(props); + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'labelStyle', 'inputFieldStyle', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return props.label({ required: props.required, style: props.style, diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx index d1a2a2daa9..aca506eab1 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx @@ -13,6 +13,10 @@ import { EllipsisTextCss, ValueFromOption } from "lowcoder-design"; import { trans } from "i18n"; import { fixOldInputCompData } from "../textInputComp/textInputConstants"; import { migrateOldData } from "comps/generators/simpleGenerators"; +import { useContext, useEffect } from "react"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const getStyle = (style: RadioStyleType, inputFieldStyle?:RadioStyleType ) => { return css` @@ -97,11 +101,28 @@ const Radio = styled(AntdRadioGroup)<{ `; let RadioBasicComp = (function () { - return new UICompBuilder(RadioChildrenMap, (props) => { + return new UICompBuilder(RadioChildrenMap, (props,dispatch) => { const [ validateState, handleChange, ] = useSelectInputValidate(props); + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'labelStyle', 'inputFieldStyle', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return props.label({ required: props.required, style: props.style, diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx index 5e3989f6f6..a0655443a2 100644 --- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx +++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioCompConstants.tsx @@ -37,12 +37,12 @@ export const RadioChildrenMap = { disabled: BoolCodeControl, onEvent: ChangeEventHandlerControl, options: SelectInputOptionControl, - style: styleControl(InputFieldStyle), - labelStyle:styleControl(LabelStyle), + style: styleControl(InputFieldStyle,'style'), + labelStyle:styleControl(LabelStyle,'labelStyle'), layout: dropdownControl(RadioLayoutOptions, "horizontal"), viewRef: RefControl, - inputFieldStyle:withDefault(styleControl(RadioStyle),{borderWidth: '1px'}), - animationStyle: styleControl(AnimationStyle), + inputFieldStyle:withDefault(styleControl(RadioStyle,'inputFieldStyle'),{borderWidth: '1px'}), + animationStyle: styleControl(AnimationStyle,'animationStyle'), ...SelectInputValidationChildren, ...formDataChildren, }; diff --git a/client/packages/lowcoder/src/comps/comps/switchComp.tsx b/client/packages/lowcoder/src/comps/comps/switchComp.tsx index 687cde5c0e..1232420f59 100644 --- a/client/packages/lowcoder/src/comps/comps/switchComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/switchComp.tsx @@ -17,8 +17,11 @@ import { RefControl } from "comps/controls/refControl"; import { refMethods } from "comps/generators/withMethodExposing"; import { blurMethod, clickMethod, focusWithOptions } from "comps/utils/methodUtils"; -import { useContext } from "react"; +import { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { setInitialCompStyles } from "../utils/themeUtil"; const EventOptions = [ changeEvent, @@ -89,18 +92,35 @@ let SwitchTmpComp = (function () { label: LabelControl, onEvent: eventHandlerControl(EventOptions), disabled: BoolCodeControl, - style: styleControl(InputFieldStyle), - animationStyle: styleControl(AnimationStyle), + style: styleControl(InputFieldStyle,'style'), + animationStyle: styleControl(AnimationStyle,'animationStyle'), labelStyle: styleControl( LabelStyle.filter( (style) => ['accent', 'validate'].includes(style.name) === false - ) + ),'labelStyle' ), viewRef: RefControl, - inputFieldStyle:migrateOldData(styleControl(SwitchStyle), fixOldData), + inputFieldStyle:migrateOldData(styleControl(SwitchStyle,'inputFieldStyle'), fixOldData), ...formDataChildren, }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props,dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'labelStyle', 'inputFieldStyle', 'animationStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return props.label({ style: props.style, labelStyle: props.labelStyle, diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx index 49838b2942..7419643932 100644 --- a/client/packages/lowcoder/src/comps/comps/textComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/textComp.tsx @@ -6,7 +6,7 @@ import styled, { css } from "styled-components"; import { AlignCenter } from "lowcoder-design"; import { AlignLeft } from "lowcoder-design"; import { AlignRight } from "lowcoder-design"; -import { UICompBuilder } from "../generators"; +import { UICompBuilder, withDefault } from "../generators"; import { NameConfig, NameConfigHidden, withExposingConfigs } from "../generators/withExposing"; import { markdownCompCss, TacoMarkDown } from "lowcoder-design"; import { styleControl } from "comps/controls/styleControl"; @@ -18,8 +18,12 @@ import { alignWithJustifyControl } from "comps/controls/alignControl"; import { MarginControl } from "../controls/marginControl"; import { PaddingControl } from "../controls/paddingControl"; -import React, { useContext } from "react"; +import React, { useContext, useEffect } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "../utils/themeContext"; +import { CompTypeContext } from "../utils/compTypeContext"; +import { changeChildAction } from "lowcoder-core"; +import { setInitialCompStyles } from "../utils/themeUtil"; const getStyle = (style: TextStyleType) => { return css` @@ -112,15 +116,14 @@ const typeOptions = [ value: "text", }, ] as const; + const VerticalAlignmentOptions = [ { label: , value: "flex-start" }, { label: , value: "center" }, { label: , value: "flex-end" }, ] as const; - let TextTmpComp = (function () { - const childrenMap = { text: stringExposingStateControl( "text", @@ -130,13 +133,29 @@ let TextTmpComp = (function () { type: dropdownControl(typeOptions, "markdown"), horizontalAlignment: alignWithJustifyControl(), verticalAlignment: dropdownControl(VerticalAlignmentOptions, "center"), - style: styleControl(TextStyle), + style: styleControl(TextStyle, 'style'), animationStyle: styleControl(AnimationStyle), margin: MarginControl, padding: PaddingControl, }; - return new UICompBuilder(childrenMap, (props) => { + return new UICompBuilder(childrenMap, (props, dispatch) => { const value = props.text.value; + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); + return ( , showCount: BoolControl, allowClear: BoolControl, - style: withDefault(styleControl(InputFieldStyle),{background:'transparent'}) , - labelStyle:styleControl(LabelStyle), + style: withDefault(styleControl(InputFieldStyle,'style'),{background:'transparent'}) , + labelStyle:styleControl(LabelStyle,'labelStyle'), prefixIcon: IconControl, suffixIcon: IconControl, - inputFieldStyle:withDefault(styleControl(InputLikeStyle),{borderWidth: '1px'}) , - animationStyle: styleControl(AnimationStyle), + inputFieldStyle:withDefault(styleControl(InputLikeStyle,'inputFieldStyle'),{borderWidth: '1px'}) , + animationStyle: styleControl(AnimationStyle,'animationStyle'), }; -let InputBasicComp = new UICompBuilder(childrenMap, (props) => { +let InputBasicComp = new UICompBuilder(childrenMap, (props, dispatch) => { const [inputProps, validateState] = useTextInputProps(props); + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style','labelStyle','inputFieldStyle','animationStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); return props.label({ required: props.required, children: ( @@ -87,13 +105,13 @@ let InputBasicComp = new UICompBuilder(childrenMap, (props) => { - {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && ( + {["layout", "both"].includes(useContext(EditorContext).editorModeStatus) && ( children.label.getPropertyView() )} - {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && ( + {["logic", "both"].includes(useContext(EditorContext).editorModeStatus) && ( <> -
{hiddenPropertyView(children)}
+
{hiddenPropertyView(children)}
{children.prefixIcon.propertyView({ label: trans("button.prefixIcon") })} {children.suffixIcon.propertyView({ label: trans("button.suffixIcon") })} @@ -108,7 +126,7 @@ let InputBasicComp = new UICompBuilder(childrenMap, (props) => { <>
{children.style.getPropertyView()}
{children.labelStyle.getPropertyView()}
-
{children.inputFieldStyle.getPropertyView()}
+
{children.inputFieldStyle.getPropertyView()}
{children.animationStyle.getPropertyView()}
)} @@ -117,7 +135,7 @@ let InputBasicComp = new UICompBuilder(childrenMap, (props) => { }) .setExposeMethodConfigs(inputRefMethods) .setExposeStateConfigs([ - new NameConfig("value", trans("export.inputValueDesc")), + new NameConfig("value", trans("export.inputValueDesc")), NameConfigPlaceHolder, NameConfigRequired, ...TextInputConfigs, diff --git a/client/packages/lowcoder/src/comps/comps/treeComp/treeComp.tsx b/client/packages/lowcoder/src/comps/comps/treeComp/treeComp.tsx index d6063652f9..66842127af 100644 --- a/client/packages/lowcoder/src/comps/comps/treeComp/treeComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/treeComp/treeComp.tsx @@ -33,6 +33,9 @@ import { SelectEventHandlerControl } from "comps/controls/eventHandlerControl"; import { trans } from "i18n"; import { useContext } from "react"; import { EditorContext } from "comps/editorState"; +import { ThemeContext } from "@lowcoder-ee/index.sdk"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; type TreeStyleType = StyleConfigType; @@ -76,9 +79,9 @@ const childrenMap = { label: withDefault(LabelControl, { position: "column" }), // TODO: more event onEvent: SelectEventHandlerControl, - style: styleControl(InputFieldStyle), - labelStyle: styleControl(LabelStyle.filter((style) => ['accent', 'validate'].includes(style.name) === false)), - inputFieldStyle:styleControl(TreeStyle) + style: styleControl(InputFieldStyle,'style'), + labelStyle: styleControl(LabelStyle.filter((style) => ['accent', 'validate'].includes(style.name) === false),'labelStyle'), + inputFieldStyle:styleControl(TreeStyle,'inputFieldStyle') }; const TreeCompView = (props: RecordConstructorToView) => { @@ -150,7 +153,26 @@ const TreeCompView = (props: RecordConstructorToView) => { }; let TreeBasicComp = (function () { - return new UICompBuilder(childrenMap, (props) => ) + return new UICompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + const styleProps: Record = {}; + ['style', 'labelStyle', 'inputFieldStyle'].forEach( + (key: string) => { + styleProps[key] = (props as any)[key]; + } + ); + + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); + return + }) .setPropertyViewFn((children) => ( <>
diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx index b1cedc8cc3..965fed4548 100644 --- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx +++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx @@ -35,11 +35,21 @@ const Wrapper = styled.div<{$style: ContainerStyleType; $animationStyle?:Animati `; const HeaderInnerGrid = styled(InnerGrid)<{ - $backgroundColor: string + $backgroundColor: string, + $headerBackgroundImage: string; + $headerBackgroundImageRepeat: string; + $headerBackgroundImageSize: string; + $headerBackgroundImagePosition: string; + $headerBackgroundImageOrigin: string; }>` overflow: visible; ${(props) => props.$backgroundColor && `background-color: ${props.$backgroundColor};`} border-radius: 0; + ${(props) => props.$headerBackgroundImage && `background-image: url(${props.$headerBackgroundImage});`} + ${(props) => props.$headerBackgroundImageRepeat && `background-repeat: ${props.$headerBackgroundImageRepeat};`} + ${(props) => props.$headerBackgroundImageSize && `background-size: ${props.$headerBackgroundImageSize};`} + ${(props) => props.$headerBackgroundImagePosition && `background-position: ${props.$headerBackgroundImagePosition};`} + ${(props) => props.$headerBackgroundImageOrigin && `background-origin: ${props.$headerBackgroundImageOrigin};`} `; const BodyInnerGrid = styled(InnerGrid)<{ @@ -47,11 +57,21 @@ const BodyInnerGrid = styled(InnerGrid)<{ $backgroundColor: string; $borderColor: string; $borderWidth: string; + $backgroundImage: string; + $backgroundImageRepeat: string; + $backgroundImageSize: string; + $backgroundImagePosition: string; + $backgroundImageOrigin: string; }>` border-top: ${(props) => `${props.$showBorder ? props.$borderWidth : 0} solid ${props.$borderColor}`}; flex: 1; ${(props) => props.$backgroundColor && `background-color: ${props.$backgroundColor};`} border-radius: 0; + ${(props) => props.$backgroundImage && `background-image: url(${props.$backgroundImage});`} + ${(props) => props.$backgroundImageRepeat && `background-repeat: ${props.$backgroundImageRepeat};`} + ${(props) => props.$backgroundImageSize && `background-size: ${props.$backgroundImageSize};`} + ${(props) => props.$backgroundImagePosition && `background-position: ${props.$backgroundImagePosition};`} + ${(props) => props.$backgroundImageOrigin && `background-origin: ${props.$backgroundImageOrigin};`} `; const FooterInnerGrid = styled(InnerGrid)<{ @@ -117,6 +137,11 @@ export function TriContainer(props: TriContainerProps) { containerPadding={[paddingWidth, 3]} showName={{ bottom: showBody || showFooter ? 20 : 0 }} $backgroundColor={headerStyle?.headerBackground || 'transparent'} + $headerBackgroundImage={headerStyle?.headerBackgroundImage} + $headerBackgroundImageRepeat={headerStyle?.headerBackgroundImageRepeat} + $headerBackgroundImageSize={headerStyle?.headerBackgroundImageSize} + $headerBackgroundImagePosition={headerStyle?.headerBackgroundImagePosition} + $headerBackgroundImageOrigin={headerStyle?.headerBackgroundImageOrigin} style={{padding: headerStyle.containerHeaderPadding}} /> @@ -139,6 +164,11 @@ export function TriContainer(props: TriContainerProps) { $backgroundColor={bodyStyle?.background || 'transparent'} $borderColor={style?.border} $borderWidth={style?.borderWidth} + $backgroundImage={bodyStyle?.backgroundImage} + $backgroundImageRepeat={bodyStyle?.backgroundImageRepeat} + $backgroundImageSize={bodyStyle?.backgroundImageSize} + $backgroundImagePosition={bodyStyle?.backgroundImagePosition} + $backgroundImageOrigin={bodyStyle?.backgroundImageOrigin} style={{padding: bodyStyle.containerBodyPadding}} /> diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx index b93e018b45..4b293c335d 100644 --- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx @@ -11,10 +11,10 @@ import { import { MultiCompBuilder, sameTypeMap, withDefault } from "comps/generators"; import { migrateOldData } from "comps/generators/simpleGenerators"; import { NameGenerator } from "comps/utils"; -import { fromRecord, Node } from "lowcoder-core"; +import { changeValueAction, fromRecord, multiChangeAction, Node } from "lowcoder-core"; import { nodeIsRecord } from "lowcoder-core"; import _ from "lodash"; -import { ReactNode } from "react"; +import { ReactNode, useContext, useEffect } from "react"; import { lastValueIfEqual } from "util/objectUtils"; import { CompTree, @@ -27,6 +27,9 @@ import { SimpleContainerComp } from "../containerBase/simpleContainerComp"; import { ContainerBodyChildComp } from "./containerBodyChildComp"; import { trans } from "i18n"; import { ControlNode } from "lowcoder-design"; +import { ThemeContext } from "@lowcoder-ee/comps/utils/themeContext"; +import { CompTypeContext } from "@lowcoder-ee/comps/utils/compTypeContext"; +import { setInitialCompStyles } from "@lowcoder-ee/comps/utils/themeUtil"; const childrenMap = { header: SimpleContainerComp, @@ -40,15 +43,32 @@ const childrenMap = { showFooter: BoolControl, autoHeight: AutoHeightControl, scrollbars: withDefault(BoolControl, false), - style: withDefault(styleControl(ContainerStyle),{borderWidth:'1px'}), - headerStyle: styleControl(ContainerHeaderStyle), - bodyStyle: styleControl(ContainerBodyStyle), - footerStyle: styleControl(ContainerFooterStyle), + style: withDefault(styleControl(ContainerStyle, 'style'),{borderWidth:'1px'}), + headerStyle: styleControl(ContainerHeaderStyle, 'headerStyle'), + bodyStyle: styleControl(ContainerBodyStyle, 'bodyStyle'), + footerStyle: styleControl(ContainerFooterStyle, 'footerStyle'), }; // Compatible with old style data 2022-8-15 const TriContainerBaseComp = migrateOldData( new MultiCompBuilder(childrenMap, (props, dispatch) => { + const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const compTheme = theme?.theme?.components?.[compType]; + // Filter style props from children props + const styleProps: Record = {}; + ['style', 'headerStyle', 'bodyStyle', 'footerStyle'].forEach((key: string) => { + styleProps[key] = (props as any)[key]; + }); + // Update comp styles with combination of default style and comp theme style + useEffect(() => { + setInitialCompStyles({ + dispatch, + compTheme, + styleProps, + }); + }, []); + return { ...props, dispatch }; }).build(), fixOldStyleData diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx index fd10c74865..1200bc1d19 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx @@ -5,7 +5,7 @@ import { childrenToProps, ToConstructor } from "comps/generators/multi"; import { BackgroundColorContext } from "comps/utils/backgroundColorContext"; import { ThemeContext } from "comps/utils/themeContext"; import { trans } from "i18n"; -import _ from "lodash"; +import _, { values } from "lodash"; import { controlItem, IconReset, @@ -75,16 +75,28 @@ import { AnimationConfig, AnimationDelayConfig, AnimationDurationConfig, + BackgroundConfig, + BorderConfig, } from "./styleControlConstants"; import { faTextWidth } from "@fortawesome/free-solid-svg-icons"; import appSelectControl from "./appSelectControl"; +import { JSONObject, JSONValue } from "@lowcoder-ee/util/jsonTypes"; +import { CompTypeContext } from "../utils/compTypeContext"; function isSimpleColorConfig(config: SingleColorConfig): config is SimpleColorConfig { return config.hasOwnProperty("color"); } +function isBackgroundColorConfig(config: SingleColorConfig): config is BackgroundConfig { + return config.hasOwnProperty("background"); +} + +function isBorderConfig(config: SingleColorConfig): config is BorderConfig { + return config.hasOwnProperty("border"); +} + function isDepColorConfig(config: SingleColorConfig): config is DepColorConfig { return config.hasOwnProperty("depName") || config.hasOwnProperty("depTheme"); } @@ -350,9 +362,47 @@ function calcColors>( props: ColorMap, colorConfigs: readonly SingleColorConfig[], theme?: ThemeDetail, - bgColor?: string + bgColor?: string, + compTheme?: Record, ) { - const themeWithDefault = (theme || defaultTheme) as unknown as Record; + console.log("🚀 ~ props:", props) + console.log("🚀 ~ compTheme:", compTheme) + console.log("🚀 ~ theme:", theme) + console.log("🚀 ~ defaultTheme:", defaultTheme) + let themeWithDefault = {...(theme || defaultTheme)} as unknown as Record; + themeWithDefault = { ...themeWithDefault, ...(compTheme || {})}; + console.log("🚀 ~ themeWithDefault:", themeWithDefault) + let canvas; + let textLight; + let borderColor; + +// if (compTheme && compTheme.background) { +// console.log('1st ifffffffffffffff', compTheme.background); +// canvas = compTheme.background; +// textLight = compTheme.text; +// borderColor = compTheme.border; +// } else if (theme && theme.canvas) { +// console.log('2nd else ifffffffffffffff', theme.canvas); + +// canvas = theme.canvas; +// textLight = theme.textLight; +// borderColor = theme.canvas; +// } else { +// console.log('3rd else ifffffffffffffff', defaultTheme.canvas); + +// canvas = defaultTheme.canvas; +// textLight = defaultTheme.textLight; +// borderColor = defaultTheme.canvas; +// } +// themeWithDefault = { +// ...themeWithDefault, +// ...compTheme, +// canvas, +// textLight, +// border:borderColor||canvas +// }; +// console.log("🚀 ~ themeWithDefaultUpdated:", themeWithDefault) + // Cover what is not there for the first pass let res: Record = {}; colorConfigs.forEach((config) => { @@ -501,69 +551,68 @@ function calcColors>( return; } if (!isEmptyColor(props[name])) { - if (isThemeColorKey(props[name])) { - res[name] = themeWithDefault[props[name]]; - } else { + if (isThemeColorKey(name)) { res[name] = props[name]; - } + } return; } - if (isSimpleColorConfig(config)) { - res[name] = config.color; - } + // if (isSimpleColorConfig(config) && name === 'validate') { + // res[name] = config.color; + // } + if (isRadiusConfig(config)) { res[name] = themeWithDefault[config.radius]; } if (isBorderWidthConfig(config)) { - res[name] = '0px'; + res[name] = themeWithDefault[config.borderWidth] || '0px'; } if (isRotationConfig(config)) { - res[name] = '0deg'; + res[name] = themeWithDefault[config.rotation] || '0deg'; } if (isBackgroundImageConfig(config)) { - res[name] = ''; + res[name] = themeWithDefault[config.backgroundImage] || ''; } if (isBackgroundImageRepeatConfig(config)) { - res[name] = 'no-repeat'; + res[name] = themeWithDefault[config.backgroundImageRepeat] || 'no-repeat'; } if (isBackgroundImageSizeConfig(config)) { - res[name] = 'cover'; + res[name] = themeWithDefault[config.backgroundImageSize] || 'cover'; } if (isBackgroundImagePositionConfig(config)) { - res[name] = 'center'; + res[name] = themeWithDefault[config.backgroundImagePosition] || 'center'; } if (isBackgroundImageOriginConfig(config)) { - res[name] = 'padding-box'; + res[name] = themeWithDefault[config.backgroundImageOrigin] || 'padding-box'; } if (isHeaderBackgroundImageConfig(config)) { - res[name] = ''; + res[name] = themeWithDefault[config.headerBackgroundImage] || ''; } if (isHeaderBackgroundImageRepeatConfig(config)) { - res[name] = 'no-repeat'; + res[name] = themeWithDefault[config.headerBackgroundImageRepeat] || 'no-repeat'; } if (isHeaderBackgroundImageSizeConfig(config)) { - res[name] = 'cover'; + res[name] = themeWithDefault[config.headerBackgroundImageSize] || 'cover'; } if (isHeaderBackgroundImagePositionConfig(config)) { - res[name] = 'center'; + res[name] = themeWithDefault[config.headerBackgroundImagePosition] || 'center'; } if (isHeaderBackgroundImageOriginConfig(config)) { - res[name] = 'padding-box'; + res[name] = themeWithDefault[config.headerBackgroundImageOrigin] || 'padding-box'; } if (isFooterBackgroundImageConfig(config)) { - res[name] = ''; + res[name] = themeWithDefault[config.footerBackgroundImage] || ''; } if (isFooterBackgroundImageRepeatConfig(config)) { - res[name] = 'no-repeat'; + res[name] = themeWithDefault[config.footerBackgroundImageRepeat] || 'no-repeat'; } if (isFooterBackgroundImageSizeConfig(config)) { - res[name] = 'cover'; + res[name] = themeWithDefault[config.footerBackgroundImageSize] || 'cover'; } if (isFooterBackgroundImagePositionConfig(config)) { - res[name] = 'center'; + res[name] = themeWithDefault[config.footerBackgroundImagePosition] || 'center'; } if (isFooterBackgroundImageOriginConfig(config)) { - res[name] = 'padding-box'; + res[name] = themeWithDefault[config.footerBackgroundImageOrigin] || 'padding-box'; } if (isTextSizeConfig(config)) { // TODO: remove default textSize after added in theme in backend. @@ -615,6 +664,21 @@ function calcColors>( if (isAnimationDurationConfig(config)) { res[name] = themeWithDefault[config.animationDuration] || '0s'; } + // if (isBackgroundColorConfig(config)) { + // console.log("isBackgroundColorConfig",themeWithDefault[config.background]) + // res[name] = themeWithDefault[config.background] ; + // } + // if (isBorderConfig(config)) { + // console.log("isBorderConfig",themeWithDefault[config.border]) + + // res[name] = themeWithDefault[config.border] ; + // } + if (isEmptyColor(props[name])) { + if (isThemeColorKey(name)) { + res[name] = themeWithDefault[config.name]; + } + return; + } }); // The second pass calculates dep colorConfigs.forEach((config) => { @@ -639,7 +703,7 @@ function calcColors>( } else { const rest = []; config.depName && rest.push(res[config.depName]); - config.depTheme && rest.push(themeWithDefault[config.depTheme]); + config.depTheme && rest.push(themeWithDefault[config.depTheme]); res[name] = config.transformer(rest[0], rest[1]); } } @@ -781,7 +845,10 @@ const ResetIcon = styled(IconReset)` } `; -export function styleControl(colorConfigs: T) { +export function styleControl( + colorConfigs: T, + styleKey: string = '', +) { type ColorMap = { [K in Names]: string }; const childrenMap: any = {}; colorConfigs.map((config) => { @@ -836,23 +903,38 @@ export function styleControl(colorConfig return new ControlItemCompBuilder( childrenMap as ToConstructor<{ [K in Names]: ColorControl }>, (props) => { - // const x = useContext(CompNameContext); - const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); + const theme = useContext(ThemeContext); const bgColor = useContext(BackgroundColorContext); - return calcColors(props as ColorMap, colorConfigs, theme?.theme, bgColor); + const compTheme = compType + ? theme?.theme?.components?.[compType]?.[styleKey] + : undefined; + + return calcColors( + props as ColorMap, + colorConfigs, + theme?.theme, + bgColor, + compTheme as Record | undefined, + ); } ) .setControlItemData({ filterText: label, searchChild: true }) .setPropertyViewFn((children) => { const theme = useContext(ThemeContext); + const compType = useContext(CompTypeContext); const bgColor = useContext(BackgroundColorContext); const isMobile = useIsMobile(); + const compTheme = compType + ? theme?.theme?.components?.[compType]?.[styleKey] + : undefined; const props = calcColors( childrenToProps(children) as ColorMap, colorConfigs, theme?.theme, - bgColor + bgColor, + compTheme as Record | undefined, ); const showReset = Object.values(childrenToProps(children)).findIndex((item) => item) > -1; return ( diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index e96702f53e..f5c3f04e90 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx @@ -54,7 +54,9 @@ export type AnimationDelayConfig = CommonColorConfig & { export type AnimationDurationConfig = CommonColorConfig & { readonly animationDuration: string; }; - +export type BackgroundConfig = CommonColorConfig & { + readonly background: string; +}; export type BackgroundImageConfig = CommonColorConfig & { readonly backgroundImage: string; }; @@ -138,6 +140,9 @@ export type FontStyleConfig = CommonColorConfig & { export type borderStyleConfig = CommonColorConfig & { readonly borderStyle: string; }; +export type BorderConfig = CommonColorConfig & { + readonly border: string; +}; export type ContainerHeaderPaddingConfig = CommonColorConfig & { readonly containerHeaderPadding: string; @@ -223,7 +228,9 @@ export type SingleColorConfig = | OpacityConfig | BoxShadowConfig | BoxShadowColorConfig - | AnimationIterationCountConfig; + | AnimationIterationCountConfig + | BackgroundConfig + | BorderConfig; export const defaultTheme: ThemeDetail = { primary: "#3377FF", @@ -231,7 +238,10 @@ export const defaultTheme: ThemeDetail = { textLight: "#FFFFFF", canvas: "#F5F5F6", primarySurface: "#FFFFFF", + borderColor: "#D7D9E0", borderRadius: "4px", + borderWidth: "1px", + borderStyle: "solid", margin: "3px", padding: "3px", gridColumns: "24", @@ -243,6 +253,7 @@ export const defaultTheme: ThemeDetail = { boxShadow: "", boxShadowColor: "", animationIterationCount: "", + components: {}, }; export const SURFACE_COLOR = "#FFFFFF"; @@ -489,14 +500,13 @@ const ANIMATIONDURATION = { const BORDER = { name: "border", label: trans("style.border"), - depName: "background", transformer: backgroundToBorder, } as const; const RADIUS = { name: "radius", label: trans("style.borderRadius"), - radius: "borderRadius", + radius: "radius", } as const; const BORDER_WIDTH = { @@ -1133,7 +1143,7 @@ export const LabelStyle = [ ]; export const InputFieldStyle = [ - getBackground(), + getBackground('canvas'), getStaticBorder(), ...STYLING_FIELDS_CONTAINER_SEQUENCE.filter( (style) => ["border"].includes(style.name) === false diff --git a/client/packages/lowcoder/src/comps/generators/simpleGenerators.tsx b/client/packages/lowcoder/src/comps/generators/simpleGenerators.tsx index 430b1a55a1..60291e98c7 100644 --- a/client/packages/lowcoder/src/comps/generators/simpleGenerators.tsx +++ b/client/packages/lowcoder/src/comps/generators/simpleGenerators.tsx @@ -96,6 +96,9 @@ export function withDefault( constructor(params: CompParams) { const newParams = { value: defaultValue, ...params }; super(newParams); + console.log("🚀 ~ TEMP_CLASS ~ constructor ~ defaultValue:", defaultValue) + console.log("🚀 ~ TEMP_CLASS ~ constructor ~ newParams:", newParams) + console.log("🚀 ~ TEMP_CLASS ~ constructor ~ params:", params) } readonly IGNORABLE_DEFAULT_VALUE = undefined; } diff --git a/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx b/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx index da84424dea..2d0fa3e4bd 100644 --- a/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx +++ b/client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx @@ -235,6 +235,7 @@ function UIView(props: { } //END ADD BY FRED + // render condition for modal and drawer as we are not getting compType here if (comp.children.hasOwnProperty('showMask') && comp.children.hasOwnProperty('maskClosable')) { return (