@@ -91,7 +124,13 @@ export function TriContainer(props: TriContainerProps) {
containerPadding={[paddingWidth, 3]}
showName={{ bottom: showBody || showFooter ? 20 : 0 }}
$backgroundColor={style?.headerBackground}
+ $headerBackgroundImage={style?.headerBackgroundImage}
+ $headerBackgroundImageRepeat={style?.headerBackgroundImageRepeat}
+ $headerBackgroundImageSize={style?.headerBackgroundImageSize}
+ $headerBackgroundImagePosition={style?.headerBackgroundImagePosition}
+ $headerBackgroundImageOrigin={style?.headerBackgroundImageOrigin}
style={{padding: style.containerheaderpadding}}
+
/>
)}
@@ -110,6 +149,11 @@ export function TriContainer(props: TriContainerProps) {
hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
$backgroundColor={style?.background}
$borderColor={style?.border}
+ $backgroundImage={style?.backgroundImage}
+ $backgroundImageRepeat={style?.backgroundImageRepeat}
+ $backgroundImageSize={style?.backgroundImageSize}
+ $backgroundImagePosition={style?.backgroundImagePosition}
+ $backgroundImageOrigin={style?.backgroundImageOrigin}
style={{padding: style.containerbodypadding}}
/>
@@ -126,6 +170,11 @@ export function TriContainer(props: TriContainerProps) {
containerPadding={showBody || showHeader ? [paddingWidth, 3.5] : [paddingWidth, 3]}
showName={{ top: showHeader || showBody ? 20 : 0 }}
$backgroundColor={style?.footerBackground}
+ $footerBackgroundImage={style?.footerBackgroundImage}
+ $footerBackgroundImageRepeat={style?.footerBackgroundImageRepeat}
+ $footerBackgroundImageSize={style?.footerBackgroundImageSize}
+ $footerBackgroundImagePosition={style?.footerBackgroundImagePosition}
+ $footerBackgroundImageOrigin={style?.footerBackgroundImageOrigin}
$borderColor={style?.border}
style={{padding: style.containerfooterpadding}}
/>
diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
index bf0373188..b76095ea5 100644
--- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainerComp.tsx
@@ -30,7 +30,6 @@ const childrenMap = {
0: { view: { layout: {}, items: {} } },
}),
footer: SimpleContainerComp,
-
showHeader: BoolControl.DEFAULT_TRUE,
showBody: BoolControl.DEFAULT_TRUE,
showFooter: BoolControl,
@@ -108,7 +107,7 @@ export class TriContainerComp extends TriContainerBaseComp implements IContainer
return lastValueIfEqual(this, "exposing_node", fromRecord(allNodes), checkEquals);
}
- getPropertyView(): ControlNode {
+ getPropertyView(): ControlNode {
return [this.areaPropertyView(), this.heightPropertyView()];
}
@@ -127,6 +126,7 @@ export class TriContainerComp extends TriContainerBaseComp implements IContainer
stylePropertyView() {
return this.children.style.getPropertyView();
}
+
}
function checkEquals(node1: Node
, node2: Node): boolean {
diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
index a91429492..fb97e3f2a 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
@@ -13,11 +13,14 @@ import {
ExpandIcon,
CompressIcon,
TextSizeIcon,
+ TypographyIcon,
+ ShowBorderIcon,
+ ImageCompIcon,
} from "lowcoder-design";
import { useContext } from "react";
import styled from "styled-components";
import { useIsMobile } from "util/hooks";
-import { RadiusControl, StringControl } from "./codeControl";
+import { CSSCodeControl, ObjectControl, RadiusControl, StringControl } from "./codeControl";
import { ColorControl } from "./colorControl";
import {
defaultTheme,
@@ -29,8 +32,27 @@ import {
MarginConfig,
PaddingConfig,
TextSizeConfig,
+ TextWeightConfig,
BorderWidthConfig,
+ BackgroundImageConfig,
+ BackgroundImageRepeatConfig,
+ BackgroundImageSizeConfig,
+ BackgroundImagePositionConfig,
+ BackgroundImageOriginConfig,
+ HeaderBackgroundImageConfig,
+ HeaderBackgroundImageRepeatConfig,
+ HeaderBackgroundImageSizeConfig,
+ HeaderBackgroundImagePositionConfig,
+ HeaderBackgroundImageOriginConfig,
+ FooterBackgroundImageConfig,
+ FooterBackgroundImageRepeatConfig,
+ FooterBackgroundImageSizeConfig,
+ FooterBackgroundImagePositionConfig,
+ FooterBackgroundImageOriginConfig,
+
} from "./styleControlConstants";
+import { faTextWidth } from "@fortawesome/free-solid-svg-icons";
+import appSelectControl from "./appSelectControl";
function isSimpleColorConfig(config: SingleColorConfig): config is SimpleColorConfig {
return config.hasOwnProperty("color");
@@ -48,10 +70,65 @@ function isBorderWidthConfig(config: SingleColorConfig): config is BorderWidthCo
return config.hasOwnProperty("borderWidth");
}
+function isBackgroundImageConfig(config: SingleColorConfig): config is BackgroundImageConfig {
+ return config.hasOwnProperty("backgroundImage");
+}
+
+function isBackgroundImageRepeatConfig(config: SingleColorConfig): config is BackgroundImageRepeatConfig {
+ return config.hasOwnProperty("backgroundImageRepeat");
+}
+
+function isBackgroundImageSizeConfig(config: SingleColorConfig): config is BackgroundImageSizeConfig {
+ return config.hasOwnProperty("backgroundImageSize");
+}
+
+function isBackgroundImagePositionConfig(config: SingleColorConfig): config is BackgroundImagePositionConfig {
+ return config.hasOwnProperty("backgroundImagePosition");
+}
+
+function isBackgroundImageOriginConfig(config: SingleColorConfig): config is BackgroundImageOriginConfig {
+ return config.hasOwnProperty("backgroundImageOrigin");
+}
+
+function isHeaderBackgroundImageConfig(config: SingleColorConfig): config is HeaderBackgroundImageConfig {
+ return config.hasOwnProperty("headerBackgroundImage");
+}
+function isHeaderBackgroundImageRepeatConfig(config: SingleColorConfig): config is HeaderBackgroundImageRepeatConfig {
+ return config.hasOwnProperty("headerBackgroundImageRepeat");
+}
+function isHeaderBackgroundImageSizeConfig(config: SingleColorConfig): config is HeaderBackgroundImageSizeConfig {
+ return config.hasOwnProperty("headerBackgroundImageSize");
+}
+function isHeaderBackgroundImagePositionConfig(config: SingleColorConfig): config is HeaderBackgroundImagePositionConfig {
+ return config.hasOwnProperty("headerBackgroundImagePosition");
+}
+function isHeaderBackgroundImageOriginConfig(config: SingleColorConfig): config is HeaderBackgroundImageOriginConfig {
+ return config.hasOwnProperty("headerBackgroundImageOrigin");
+}
+function isFooterBackgroundImageConfig(config: SingleColorConfig): config is FooterBackgroundImageConfig {
+ return config.hasOwnProperty("footerBackgroundImage");
+}
+function isFooterBackgroundImageRepeatConfig(config: SingleColorConfig): config is FooterBackgroundImageRepeatConfig {
+ return config.hasOwnProperty("footerBackgroundImageRepeat");
+}
+function isFooterBackgroundImageSizeConfig(config: SingleColorConfig): config is FooterBackgroundImageSizeConfig {
+ return config.hasOwnProperty("footerBackgroundImageSize");
+}
+function isFooterBackgroundImagePositionConfig(config: SingleColorConfig): config is FooterBackgroundImagePositionConfig {
+ return config.hasOwnProperty("footerBackgroundImagePosition");
+}
+function isFooterBackgroundImageOriginConfig(config: SingleColorConfig): config is FooterBackgroundImageOriginConfig {
+ return config.hasOwnProperty("footerBackgroundImageOrigin");
+}
+
function isTextSizeConfig(config: SingleColorConfig): config is TextSizeConfig {
return config.hasOwnProperty("textSize");
}
+function isTextWeightConfig(config: SingleColorConfig): config is TextWeightConfig {
+ return config.hasOwnProperty("textWeight");
+}
+
function isMarginConfig(config: SingleColorConfig): config is MarginConfig {
return config.hasOwnProperty("margin");
}
@@ -75,9 +152,58 @@ function isEmptyRadius(radius: string) {
function isEmptyBorderWidth(borderWidth: string) {
return _.isEmpty(borderWidth);
}
+function isEmptyBackgroundImageConfig(backgroundImage: string) {
+ return _.isEmpty(backgroundImage);
+}
+function isEmptyBackgroundImageRepeatConfig(backgroundImageRepeat: string) {
+ return _.isEmpty(backgroundImageRepeat);
+}
+function isEmptyBackgroundImageSizeConfig(backgroundImageSize: string) {
+ return _.isEmpty(backgroundImageSize);
+}
+function isEmptyBackgroundImagePositionConfig(backgroundImagePosition: string) {
+ return _.isEmpty(backgroundImagePosition);
+}
+function isEmptyBackgroundImageOriginConfig(backgroundImageOrigin: string) {
+ return _.isEmpty(backgroundImageOrigin);
+}
+function isEmptyHeaderBackgroundImageConfig(headerBackgroundImage: string) {
+ return _.isEmpty(headerBackgroundImage);
+}
+function isEmptyHeaderBackgroundImageRepeatConfig(headerBackgroundImageRepeat: string) {
+ return _.isEmpty(headerBackgroundImageRepeat);
+}
+function isEmptyHeaderBackgroundImageSizeConfig(headerBackgroundImageSize: string) {
+ return _.isEmpty(headerBackgroundImageSize);
+}
+function isEmptyHeaderBackgroundImagePositionConfig(headerBackgroundImagePosition: string) {
+ return _.isEmpty(headerBackgroundImagePosition);
+}
+function isEmptyHeaderBackgroundImageOriginConfig(headerBackgroundImageOrigin: string) {
+ return _.isEmpty(headerBackgroundImageOrigin);
+}
+function isEmptyFooterBackgroundImageConfig(footerBackgroundImage: string) {
+ return _.isEmpty(footerBackgroundImage);
+}
+function isEmptyFooterBackgroundImageRepeatConfig(footerBackgroundImageRepeat: string) {
+ return _.isEmpty(footerBackgroundImageRepeat);
+}
+function isEmptyFooterBackgroundImageSizeConfig(footerBackgroundImageSize: string) {
+ return _.isEmpty(footerBackgroundImageSize);
+}
+function isEmptyFooterBackgroundImagePositionConfig(footerBackgroundImagePosition: string) {
+ return _.isEmpty(footerBackgroundImagePosition);
+}
+function isEmptyFooterBackgroundImageOriginConfig(footerBackgroundImageOrigin: string) {
+ return _.isEmpty(footerBackgroundImageOrigin);
+}
+
function isEmptyTextSize(textSize: string) {
return _.isEmpty(textSize);
}
+function isEmptyTextWeight(textWeight: string) {
+ return _.isEmpty(textWeight);
+}
function isEmptyMargin(margin: string) {
return _.isEmpty(margin);
@@ -108,10 +234,74 @@ function calcColors>(
res[name] = props[name];
return;
}
+ if (!isEmptyBackgroundImageConfig(props[name]) && isBackgroundImageConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyBackgroundImageRepeatConfig(props[name]) && isBackgroundImageRepeatConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyBackgroundImageSizeConfig(props[name]) && isBackgroundImageSizeConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyBackgroundImagePositionConfig(props[name]) && isBackgroundImagePositionConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyBackgroundImageOriginConfig(props[name]) && isBackgroundImageOriginConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyHeaderBackgroundImageConfig(props[name]) && isHeaderBackgroundImageConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyHeaderBackgroundImageRepeatConfig(props[name]) && isHeaderBackgroundImageRepeatConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyHeaderBackgroundImageSizeConfig(props[name]) && isHeaderBackgroundImageSizeConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyHeaderBackgroundImagePositionConfig(props[name]) && isHeaderBackgroundImagePositionConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyHeaderBackgroundImageOriginConfig(props[name]) && isHeaderBackgroundImageOriginConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyFooterBackgroundImageConfig(props[name]) && isFooterBackgroundImageConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyFooterBackgroundImageRepeatConfig(props[name]) && isFooterBackgroundImageRepeatConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyFooterBackgroundImageSizeConfig(props[name]) && isFooterBackgroundImageSizeConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyFooterBackgroundImagePositionConfig(props[name]) && isFooterBackgroundImagePositionConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyFooterBackgroundImageOriginConfig(props[name]) && isFooterBackgroundImageOriginConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
if (!isEmptyTextSize(props[name]) && isTextSizeConfig(config)) {
res[name] = props[name];
return;
}
+ if (!isEmptyTextWeight(props[name]) && isTextWeightConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
if (!isEmptyMargin(props[name]) && isMarginConfig(config)) {
res[name] = props[name];
return;
@@ -137,10 +327,59 @@ function calcColors>(
if (isBorderWidthConfig(config)) {
res[name] = '0px';
}
+ if (isBackgroundImageConfig(config)) {
+ res[name] = '';
+ }
+ if (isBackgroundImageRepeatConfig(config)) {
+ res[name] = 'no-repeat';
+ }
+ if (isBackgroundImageSizeConfig(config)) {
+ res[name] = 'cover';
+ }
+ if (isBackgroundImagePositionConfig(config)) {
+ res[name] = 'center';
+ }
+ if (isBackgroundImageOriginConfig(config)) {
+ res[name] = 'padding-box';
+ }
+ if (isHeaderBackgroundImageConfig(config)) {
+ res[name] = '';
+ }
+ if (isHeaderBackgroundImageRepeatConfig(config)) {
+ res[name] = 'no-repeat';
+ }
+ if (isHeaderBackgroundImageSizeConfig(config)) {
+ res[name] = 'cover';
+ }
+ if (isHeaderBackgroundImagePositionConfig(config)) {
+ res[name] = 'center';
+ }
+ if (isHeaderBackgroundImageOriginConfig(config)) {
+ res[name] = 'padding-box';
+ }
+ if (isFooterBackgroundImageConfig(config)) {
+ res[name] = '';
+ }
+ if (isFooterBackgroundImageRepeatConfig(config)) {
+ res[name] = 'no-repeat';
+ }
+ if (isFooterBackgroundImageSizeConfig(config)) {
+ res[name] = 'cover';
+ }
+ if (isFooterBackgroundImagePositionConfig(config)) {
+ res[name] = 'center';
+ }
+ if (isFooterBackgroundImageOriginConfig(config)) {
+ res[name] = 'padding-box';
+ }
if (isTextSizeConfig(config)) {
// TODO: remove default textSize after added in theme in backend.
res[name] = themeWithDefault[config.textSize] || '14px';
}
+ if (isTextWeightConfig(config)) {
+ // TODO: remove default textWeight after added in theme in backend.
+ res[name] = themeWithDefault[config.textWeight] || 'regular';
+ }
if (isMarginConfig(config)) {
res[name] = themeWithDefault[config.margin];
}
@@ -250,19 +489,14 @@ const StyleContent = styled.div`
}
`;
-const RadiusIcon = styled(IconRadius)`
- margin: 0 8px 0 -2px;
-`;
+const RadiusIcon = styled(IconRadius)` margin: 0 8px 0 -2px;`;
+const BorderIcon = styled(ShowBorderIcon)` margin: 0px 10px 0 3px;`;
+const MarginIcon = styled(ExpandIcon)` margin: 0 8px 0 2px;`;
+const PaddingIcon = styled(CompressIcon)` margin: 0 8px 0 2px;`;
+const StyledTextSizeIcon = styled(TextSizeIcon)` margin: 0 8px 0 0px;`;
+const StyledTextWeightIcon = styled(TypographyIcon)` margin: 0 8px 0 0px;`;
+const StyledBackgroundImageIcon = styled(ImageCompIcon)` margin: 0 0px 0 -12px;`;
-const MarginIcon = styled(ExpandIcon)`
-margin: 0 8px 0 -2px;
-`;
-const PaddingIcon = styled(CompressIcon)`
-margin: 0 8px 0 -2px;
-`;
-const StyledTextSizeIcon = styled(TextSizeIcon)`
-margin: 0 8px 0 -2px;
-`;
const ResetIcon = styled(IconReset)`
&:hover g g {
stroke: #315efb;
@@ -278,12 +512,31 @@ export function styleControl(colorConfig
name === "radius" ||
name === "borderWidth" ||
name === "cardRadius" ||
- name === "textSize"
+ name === "textSize" ||
+ name === "textWeight" ||
+ name === "backgroundImage" ||
+ name === "backgroundImageRepeat" ||
+ name === "backgroundImageSize" ||
+ name === "backgroundImagePosition" ||
+ name === "backgroundImageOrigin" ||
+ name === "headerBackgroundImage" ||
+ name === "headerBackgroundImageRepeat" ||
+ name === "headerBackgroundImageSize" ||
+ name === "headerBackgroundImagePosition" ||
+ name === "headerBackgroundImageOrigin" ||
+ name === "footerBackgroundImage" ||
+ name === "footerBackgroundImageRepeat" ||
+ name === "footerBackgroundImageSize" ||
+ name === "footerBackgroundImagePosition" ||
+ name === "footerBackgroundImageOrigin" ||
+ name === "margin" ||
+ name === "padding" ||
+ name === "containerheaderpadding" ||
+ name === "containerfooterpadding" ||
+ name === "containerbodypadding"
) {
childrenMap[name] = StringControl;
- } else if (name === "margin" || name === "padding" || name==="containerheaderpadding" || name==="containerfooterpadding" || name==="containerbodypadding") {
- childrenMap[name] = StringControl;
- } else {
+ } else {
childrenMap[name] = ColorControl;
}
});
@@ -324,9 +577,25 @@ export function styleControl(colorConfig
name === "radius" ||
name === "margin" ||
name === "padding" ||
- name==="containerheaderpadding" ||
- name==="containerfooterpadding" ||
- name==="containerbodypadding"
+ name === "containerheaderpadding" ||
+ name === "containerfooterpadding" ||
+ name === "containerbodypadding" ||
+ name === "borderWidth" ||
+ name === "backgroundImage" ||
+ name === "backgroundImageRepeat" ||
+ name === "backgroundImageSize" ||
+ name === "backgroundImagePosition" ||
+ name === "backgroundImageOrigin" ||
+ name === "headerBackgroundImage" ||
+ name === "headerBackgroundImageRepeat" ||
+ name === "headerBackgroundImageSize" ||
+ name === "headerBackgroundImagePosition" ||
+ name === "headerBackgroundImageOrigin" ||
+ name === "footerBackgroundImage" ||
+ name === "footerBackgroundImageRepeat" ||
+ name === "footerBackgroundImageSize" ||
+ name === "footerBackgroundImagePosition" ||
+ name === "footerBackgroundImageOrigin"
) {
children[name]?.dispatchChangeValueAction("");
} else {
@@ -366,22 +635,29 @@ export function styleControl(colorConfig
{ filterText: config.label },
{(name === "radius" ||
- name === "borderWidth" ||
name === "gap" ||
name === "cardRadius")
? (
children[name] as InstanceType
).propertyView({
label: config.label,
- preInputNode: ,
+ preInputNode: ,
placeholder: props[name],
- })
+ })
+ : name === "borderWidth"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
: name === "margin"
? (
children[name] as InstanceType
).propertyView({
label: config.label,
- preInputNode: ,
+ preInputNode: ,
placeholder: props[name],
})
: (name === "padding" ||
@@ -392,7 +668,7 @@ export function styleControl(colorConfig
children[name] as InstanceType
).propertyView({
label: config.label,
- preInputNode: ,
+ preInputNode: ,
placeholder: props[name],
})
: name === "textSize"
@@ -400,7 +676,55 @@ export function styleControl(colorConfig
children[name] as InstanceType
).propertyView({
label: config.label,
- preInputNode: ,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "textWeight"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "backgroundImage" || name === "headerBackgroundImage" || name === "footerBackgroundImage"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "backgroundImageRepeat" || name === "headerBackgroundImageRepeat" || name === "footerBackgroundImageRepeat"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "backgroundImageSize" || name === "headerBackgroundImageSize" || name === "footerBackgroundImageSize"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "backgroundImagePosition" || name === "headerBackgroundImagePosition" || name === "footerBackgroundImagePosition"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "backgroundImageOrigin" || name === "headerBackgroundImageOrigin" || name === "footerBackgroundImageOrigin"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
placeholder: props[name],
})
: children[name].propertyView({
@@ -429,4 +753,4 @@ export function useStyle(colorConfigs: T
props[config.name as Names] = "";
});
return calcColors(props, colorConfigs, theme?.theme, bgColor);
-}
+}
\ No newline at end of file
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index cd39479fe..b12c8569e 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -1,7 +1,7 @@
import { ThemeDetail } from "api/commonSettingApi";
import { darkenColor, isDarkColor, lightenColor, toHex } from "lowcoder-design";
import { trans } from "i18n";
-import { StyleConfigType } from "./styleControl";
+import { StyleConfigType } from "./styleControl";
type SupportPlatform = "pc" | "mobile";
@@ -21,10 +21,32 @@ export type BorderWidthConfig = CommonColorConfig & {
readonly borderWidth: string;
};
+export type BackgroundImageConfig = CommonColorConfig & { readonly backgroundImage: string; };
+export type BackgroundImageRepeatConfig = CommonColorConfig & { readonly backgroundImageRepeat: string; };
+export type BackgroundImageSizeConfig = CommonColorConfig & { readonly backgroundImageSize: string;};
+export type BackgroundImagePositionConfig = CommonColorConfig & { readonly backgroundImagePosition: string; };
+export type BackgroundImageOriginConfig = CommonColorConfig & { readonly backgroundImageOrigin: string;};
+
+export type HeaderBackgroundImageConfig = CommonColorConfig & { readonly headerBackgroundImage: string; };
+export type HeaderBackgroundImageRepeatConfig = CommonColorConfig & { readonly headerBackgroundImageRepeat: string; };
+export type HeaderBackgroundImageSizeConfig = CommonColorConfig & { readonly headerBackgroundImageSize: string;};
+export type HeaderBackgroundImagePositionConfig = CommonColorConfig & { readonly headerBackgroundImagePosition: string; };
+export type HeaderBackgroundImageOriginConfig = CommonColorConfig & { readonly headerBackgroundImageOrigin: string;};
+
+export type FooterBackgroundImageConfig = CommonColorConfig & { readonly footerBackgroundImage: string; };
+export type FooterBackgroundImageRepeatConfig = CommonColorConfig & { readonly footerBackgroundImageRepeat: string; };
+export type FooterBackgroundImageSizeConfig = CommonColorConfig & { readonly footerBackgroundImageSize: string;};
+export type FooterBackgroundImagePositionConfig = CommonColorConfig & { readonly footerBackgroundImagePosition: string; };
+export type FooterBackgroundImageOriginConfig = CommonColorConfig & { readonly footerBackgroundImageOrigin: string;};
+
export type TextSizeConfig = CommonColorConfig & {
readonly textSize: string;
};
+export type TextWeightConfig = CommonColorConfig & {
+ readonly textWeight: string;
+};
+
export type ContainerHeaderPaddigConfig = CommonColorConfig & {
readonly containerheaderpadding: string;
};
@@ -50,7 +72,7 @@ export type DepColorConfig = CommonColorConfig & {
readonly depType?: DEP_TYPE;
transformer: (color: string, ...rest: string[]) => string;
};
-export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | BorderWidthConfig | TextSizeConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig;
+export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | BorderWidthConfig | BackgroundImageConfig | BackgroundImageRepeatConfig | BackgroundImageSizeConfig | BackgroundImagePositionConfig | BackgroundImageOriginConfig | TextSizeConfig | TextWeightConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig | HeaderBackgroundImageConfig | HeaderBackgroundImageRepeatConfig | HeaderBackgroundImageSizeConfig | HeaderBackgroundImagePositionConfig | HeaderBackgroundImageOriginConfig | FooterBackgroundImageConfig | FooterBackgroundImageRepeatConfig | FooterBackgroundImageSizeConfig | FooterBackgroundImagePositionConfig | FooterBackgroundImageOriginConfig;
export const defaultTheme: ThemeDetail = {
primary: "#3377FF",
@@ -266,6 +288,36 @@ const BORDER_WIDTH = {
borderWidth: "borderWidth",
} as const;
+const BACKGROUND_IMAGE = {
+ name: "backgroundImage",
+ label: trans("style.backgroundImage"),
+ backgroundImage: "backgroundImage",
+} as const;
+
+const BACKGROUND_IMAGE_REPEAT = {
+ name: "backgroundImageRepeat",
+ label: trans("style.backgroundImageRepeat"),
+ backgroundImageRepeat: "backgroundImageRepeat",
+} as const;
+
+const BACKGROUND_IMAGE_SIZE = {
+ name: "backgroundImageSize",
+ label: trans("style.backgroundImageSize"),
+ backgroundImageSize: "backgroundImageSize",
+} as const;
+
+const BACKGROUND_IMAGE_POSITION = {
+ name: "backgroundImagePosition",
+ label: trans("style.backgroundImagePosition"),
+ backgroundImagePosition: "backgroundImagePosition",
+} as const;
+
+const BACKGROUND_IMAGE_ORIGIN = {
+ name: "backgroundImageOrigin",
+ label: trans("style.backgroundImageOrigin"),
+ backgroundImageOrigin: "backgroundImageOrigin",
+} as const;
+
const MARGIN = {
name: "margin",
label: trans("style.margin"),
@@ -284,6 +336,12 @@ const TEXT_SIZE = {
textSize: "textSize",
} as const;
+const TEXT_WEIGHT = {
+ name: "textWeight",
+ label: trans("style.textWeight"),
+ textWeight: "textWeight",
+} as const;
+
const CONTAINERHEADERPADDING = {
name: "containerheaderpadding",
label: trans("style.containerheaderpadding"),
@@ -370,11 +428,20 @@ function getStaticBackground(color: string) {
} as const;
}
-export const ButtonStyle = [...getBgBorderRadiusByBg("primary"), TEXT, MARGIN, PADDING] as const;
+export const ButtonStyle = [
+ ...getBgBorderRadiusByBg("primary"),
+ TEXT,
+ TEXT_SIZE,
+ TEXT_WEIGHT,
+ MARGIN,
+ PADDING
+] as const;
export const ToggleButtonStyle = [
getBackground("canvas"),
TEXT,
+ TEXT_SIZE,
+ TEXT_WEIGHT,
{
name: "border",
label: trans("style.border"),
@@ -396,6 +463,8 @@ export const TextStyle = [
transformer: toSelf,
},
TEXT,
+ TEXT_SIZE,
+ TEXT_WEIGHT,
BORDER,
MARGIN,
PADDING,
@@ -421,6 +490,7 @@ export const MarginStyle = [
export const ContainerStyle = [
...BG_STATIC_BORDER_RADIUS,
+ BORDER_WIDTH,
HEADER_BACKGROUND,
{
name: "footerBackground",
@@ -433,7 +503,82 @@ export const ContainerStyle = [
PADDING,
CONTAINERHEADERPADDING,
CONTAINERFOOTERPADDING,
- CONTAINERBODYPADDING
+ CONTAINERBODYPADDING,
+ {
+ name: "headerBackgroundImage",
+ label: trans("style.headerBackgroundImage"),
+ headerBackgroundImage: "headerBackgroundImage",
+ },
+ {
+ name: "headerBackgroundImageRepeat",
+ label: trans("style.headerBackgroundImageRepeat"),
+ headerBackgroundImageRepeat: "headerBackgroundImageRepeat",
+ },
+ {
+ name: "headerBackgroundImageSize",
+ label: trans("style.headerBackgroundImageSize"),
+ headerBackgroundImageSize: "headerBackgroundImageSize",
+ },
+ {
+ name: "headerBackgroundImagePosition",
+ label: trans("style.headerBackgroundImagePosition"),
+ headerBackgroundImagePosition: "headerBackgroundImagePosition",
+ }
+ ,{
+ name: "headerBackgroundImageOrigin",
+ label: trans("style.headerBackgroundImageOrigin"),
+ headerBackgroundImageOrigin: "headerBackgroundImageOrigin",
+ },
+ {
+ name: "backgroundImage",
+ label: trans("style.backgroundImage"),
+ backgroundImage: "backgroundImage",
+ },
+ {
+ name: "backgroundImageRepeat",
+ label: trans("style.backgroundImageRepeat"),
+ backgroundImageRepeat: "backgroundImageRepeat",
+ },
+ {
+ name: "backgroundImageSize",
+ label: trans("style.backgroundImageSize"),
+ backgroundImageSize: "backgroundImageSize",
+ },
+ {
+ name: "backgroundImagePosition",
+ label: trans("style.backgroundImagePosition"),
+ backgroundImagePosition: "backgroundImagePosition",
+ },
+ {
+ name: "backgroundImageOrigin",
+ label: trans("style.backgroundImageOrigin"),
+ backgroundImageOrigin: "backgroundImageOrigin",
+ },
+ {
+ name: "footerBackgroundImage",
+ label: trans("style.footerBackgroundImage"),
+ footerBackgroundImage: "footerBackgroundImage",
+ },
+ {
+ name: "footerBackgroundImageRepeat",
+ label: trans("style.footerBackgroundImageRepeat"),
+ footerBackgroundImageRepeat: "footerBackgroundImageRepeat",
+ },
+ {
+ name: "footerBackgroundImageSize",
+ label: trans("style.footerBackgroundImageSize"),
+ footerBackgroundImageSize: "footerBackgroundImageSize",
+ },
+ {
+ name: "footerBackgroundImagePosition",
+ label: trans("style.footerBackgroundImagePosition"),
+ footerBackgroundImagePosition: "footerBackgroundImagePosition",
+ }
+ ,{
+ name: "footerBackgroundImageOrigin",
+ label: trans("style.footerBackgroundImageOrigin"),
+ footerBackgroundImageOrigin: "footerBackgroundImageOrigin",
+ }
] as const;
export const SliderStyle = [
@@ -551,6 +696,7 @@ export const MultiSelectStyle = [
export const TabContainerStyle = [
...BG_STATIC_BORDER_RADIUS,
+ BORDER_WIDTH,
HEADER_BACKGROUND,
{
name: "tabText",
@@ -568,9 +714,94 @@ export const TabContainerStyle = [
},
MARGIN,
PADDING,
+ {
+ name: "headerBackgroundImage",
+ label: trans("style.headerBackgroundImage"),
+ headerBackgroundImage: "headerBackgroundImage",
+ },
+ {
+ name: "headerBackgroundImageRepeat",
+ label: trans("style.headerBackgroundImageRepeat"),
+ headerBackgroundImageRepeat: "headerBackgroundImageRepeat",
+ },
+ {
+ name: "headerBackgroundImageSize",
+ label: trans("style.headerBackgroundImageSize"),
+ headerBackgroundImageSize: "headerBackgroundImageSize",
+ },
+ {
+ name: "headerBackgroundImagePosition",
+ label: trans("style.headerBackgroundImagePosition"),
+ headerBackgroundImagePosition: "headerBackgroundImagePosition",
+ }
+ ,{
+ name: "headerBackgroundImageOrigin",
+ label: trans("style.headerBackgroundImageOrigin"),
+ headerBackgroundImageOrigin: "headerBackgroundImageOrigin",
+ },
+ {
+ name: "backgroundImage",
+ label: trans("style.backgroundImage"),
+ backgroundImage: "backgroundImage",
+ },
+ {
+ name: "backgroundImageRepeat",
+ label: trans("style.backgroundImageRepeat"),
+ backgroundImageRepeat: "backgroundImageRepeat",
+ },
+ {
+ name: "backgroundImageSize",
+ label: trans("style.backgroundImageSize"),
+ backgroundImageSize: "backgroundImageSize",
+ },
+ {
+ name: "backgroundImagePosition",
+ label: trans("style.backgroundImagePosition"),
+ backgroundImagePosition: "backgroundImagePosition",
+ },
+ {
+ name: "backgroundImageOrigin",
+ label: trans("style.backgroundImageOrigin"),
+ backgroundImageOrigin: "backgroundImageOrigin",
+ },
+ {
+ name: "footerBackgroundImage",
+ label: trans("style.footerBackgroundImage"),
+ footerBackgroundImage: "footerBackgroundImage",
+ },
+ {
+ name: "footerBackgroundImageRepeat",
+ label: trans("style.footerBackgroundImageRepeat"),
+ footerBackgroundImageRepeat: "footerBackgroundImageRepeat",
+ },
+ {
+ name: "footerBackgroundImageSize",
+ label: trans("style.footerBackgroundImageSize"),
+ footerBackgroundImageSize: "footerBackgroundImageSize",
+ },
+ {
+ name: "footerBackgroundImagePosition",
+ label: trans("style.footerBackgroundImagePosition"),
+ footerBackgroundImagePosition: "footerBackgroundImagePosition",
+ }
+ ,{
+ name: "footerBackgroundImageOrigin",
+ label: trans("style.footerBackgroundImageOrigin"),
+ footerBackgroundImageOrigin: "footerBackgroundImageOrigin",
+ }
] as const;
-export const ModalStyle = getBgBorderRadiusByBg();
+export const ModalStyle = [
+ ...getBgBorderRadiusByBg(),
+ BORDER_WIDTH,
+ MARGIN,
+ PADDING,
+ BACKGROUND_IMAGE,
+ BACKGROUND_IMAGE_REPEAT,
+ BACKGROUND_IMAGE_SIZE,
+ BACKGROUND_IMAGE_POSITION,
+ BACKGROUND_IMAGE_ORIGIN
+] as const;
export const CascaderStyle = [
LABEL,
diff --git a/client/packages/lowcoder/src/comps/hooks/modalComp.tsx b/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
index 92af6fb6d..49139eb39 100644
--- a/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
+++ b/client/packages/lowcoder/src/comps/hooks/modalComp.tsx
@@ -26,25 +26,45 @@ const EventOptions = [
{ label: trans("modalComp.close"), value: "close", description: trans("modalComp.closeDesc") },
] as const;
-const DEFAULT_WIDTH = "60%";
-const DEFAULT_HEIGHT = 222;
-const DEFAULT_PADDING = 16;
-
const getStyle = (style: ModalStyleType) => {
return css`
.ant-modal-content {
border-radius: ${style.radius};
- border: 1px solid ${style.border};
+ border: ${style.borderWidth} solid ${style.border};
overflow: hidden;
background-color: ${style.background};
-
+ ${style.backgroundImage ? `background-image: ${style.backgroundImage} !important; ` : ';'}
+ ${style.backgroundImageRepeat ? `background-repeat: ${style.backgroundImageRepeat};` : 'no-repeat;'}
+ ${style.backgroundImageSize ? `background-size: ${style.backgroundImageSize};` : 'cover'}
+ ${style.backgroundImagePosition ? `background-position: ${style.backgroundImagePosition};` : 'center;'}
+ ${style.backgroundImageOrigin ? `background-origin: ${style.backgroundImageOrigin};` : 'padding-box;'}
+ margin: ${style.margin};
.ant-modal-body > .react-resizable > .react-grid-layout {
background-color: ${style.background};
}
+ > .ant-modal-body {
+ background-color: ${style.background};
+ }
}
`;
};
+const DEFAULT_WIDTH = "60%";
+const DEFAULT_HEIGHT = 222;
+
+function extractMarginValues(style: ModalStyleType) {
+ // Regular expression to match numeric values with units (like px, em, etc.)
+ const regex = /\d+px|\d+em|\d+%|\d+vh|\d+vw/g;
+ // Extract the values using the regular expression
+ let values = style.padding.match(regex);
+ // If only one value is found, duplicate it to simulate uniform margin
+ if (values && values.length === 1) {
+ values = [values[0], values[0]];
+ }
+ // Return the array of values
+ return values;
+}
+
const ModalStyled = styled.div<{ $style: ModalStyleType }>`
${(props) => props.$style && getStyle(props.$style)}
`;
@@ -101,6 +121,7 @@ let TmpModalComp = (function () {
},
[dispatch]
);
+ let paddingValues = extractMarginValues(props.style);
return (
@@ -129,8 +150,8 @@ let TmpModalComp = (function () {
{...otherContainerProps}
items={gridItemCompToGridItems(items)}
autoHeight={props.autoHeight}
- minHeight={DEFAULT_HEIGHT - DEFAULT_PADDING * 2 + "px"}
- containerPadding={[DEFAULT_PADDING, DEFAULT_PADDING]}
+ minHeight={paddingValues ? DEFAULT_HEIGHT - parseInt(paddingValues[0]) * 2 + "px" : ""}
+ containerPadding={paddingValues ? [parseInt(paddingValues[0]), parseInt(paddingValues[1])] : [24,24]}
hintPlaceholder={HintPlaceHolder}
/>
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index c4f32115a..49cbef022 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -358,7 +358,23 @@ export const en = {
"containerbodypadding": "Body Padding",
"minWidth": "Minimum Width",
"aspectRatio": "Aspect Ratio",
- "textSize": "Text Size"
+ "textSize": "Text Size",
+ "textWeight": "Text Weight",
+ "backgroundImage": "BgImage",
+ "backgroundImageRepeat": "BgImage Repeat",
+ "backgroundImageSize": "BgImage Size",
+ "backgroundImagePosition": "BgImage Position",
+ "backgroundImageOrigin": "BgImage Origin",
+ "headerBackgroundImage": "Header BgImage",
+ "headerBackgroundImageRepeat": "Header BgImage Repeat",
+ "headerBackgroundImageSize": "Header BgImage Size",
+ "headerBackgroundImagePosition": "Header BgImage Position",
+ "headerBackgroundImageOrigin": "Header BgImage Origin",
+ "footerBackgroundImage": "Footer BgImage",
+ "footerBackgroundImageRepeat": "Footer BgImage Repeat",
+ "footerBackgroundImageSize": "Footer BgImage Size",
+ "footerBackgroundImagePosition": "Footer BgImage Position",
+ "footerBackgroundImageOrigin": "Footer BgImage Origin",
},
"export": {
"hiddenDesc": "If true, the component is hidden",
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index 44e245746..1c1d1b760 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -349,6 +349,22 @@ style: {
containerbodypadding: "内边距",
minWidth: "最小宽度",
textSize: "字体大小",
+ textWeight: "字体粗细",
+ "backgroundImage": "背景图片",
+ "backgroundImageRepeat" : "背景图片重复",
+ "backgroundImageSize" : "背景图片大小",
+ "backgroundImagePosition" : "背景图片位置",
+ "backgroundImageOrigin": "背景图片原点",
+ "headerBackgroundImage": "头部背景图片",
+ "headerBackgroundImageRepeat" : "头部背景图片重复",
+ "headerBackgroundImageSize" : "头部背景图片大小",
+ "headerBackgroundImagePosition" : "头部背景图片位置",
+ "headerBackgroundImageOrigin": "头部背景图片原点",
+ "footerBackgroundImage": "底部背景图片",
+ "footerBackgroundImageRepeat" : "底部背景图片重复",
+ "footerBackgroundImageSize" : "底部背景图片大小",
+ "footerBackgroundImagePosition" : "底部背景图片位置",
+ "footerBackgroundImageOrigin": "底部背景图片原点",
},
export: {
hiddenDesc: "如果为true,则隐藏组件",