diff --git a/client/packages/lowcoder-design/src/icons/icon-compress.svg b/client/packages/lowcoder-design/src/icons/icon-compress.svg
new file mode 100644
index 000000000..7c93fdcb0
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/icon-compress.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/client/packages/lowcoder-design/src/icons/icon-expand.svg b/client/packages/lowcoder-design/src/icons/icon-expand.svg
new file mode 100644
index 000000000..3bd362686
--- /dev/null
+++ b/client/packages/lowcoder-design/src/icons/icon-expand.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts
index 0fd41530e..4d7591df3 100644
--- a/client/packages/lowcoder-design/src/icons/index.ts
+++ b/client/packages/lowcoder-design/src/icons/index.ts
@@ -284,4 +284,6 @@ export { ReactComponent as CalendarDeleteIcon } from "icons/icon-calendar-delete
export { ReactComponent as TableCheckedIcon } from "icons/icon-table-checked.svg";
export { ReactComponent as TableUnCheckedIcon } from "icons/icon-table-boolean-false.svg";
export { ReactComponent as FileFolderIcon } from "icons/icon-editor-folder.svg";
+export { ReactComponent as ExpandIcon } from "icons/icon-expand.svg";
+export { ReactComponent as CompressIcon } from "icons/icon-compress.svg"
export { ReactComponent as TableCellsIcon } from "icons/icon-table-cells.svg" // Added By Aqib Mirza
diff --git a/client/packages/lowcoder/src/api/commonSettingApi.ts b/client/packages/lowcoder/src/api/commonSettingApi.ts
index 62486f358..f1e1ac9f4 100644
--- a/client/packages/lowcoder/src/api/commonSettingApi.ts
+++ b/client/packages/lowcoder/src/api/commonSettingApi.ts
@@ -44,6 +44,8 @@ export interface ThemeDetail {
primarySurface: string; // comp bg-color
borderRadius: string;
chart?: string;
+ margin?: string;
+ padding?: string;
gridColumns?: string; //Added By Aqib Mirza
}
@@ -61,6 +63,10 @@ export function getThemeDetailName(key: keyof ThemeDetail) {
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");
@@ -75,6 +81,8 @@ export function isThemeColorKey(key: string) {
case "textLight":
case "canvas":
case "primarySurface":
+ case "margin":
+ case "padding":
case "gridColumns": //Added By Aqib Mirza
return true;
}
diff --git a/client/packages/lowcoder/src/components/ColorPicker.tsx b/client/packages/lowcoder/src/components/ColorPicker.tsx
index 3fb44215c..6f06b82c3 100644
--- a/client/packages/lowcoder/src/components/ColorPicker.tsx
+++ b/client/packages/lowcoder/src/components/ColorPicker.tsx
@@ -1,16 +1,20 @@
import _ from "lodash";
import { useEffect, useState } from "react";
-import { ConfigItem, Radius, GridColumns } from "../pages/setting/theme/styledComponents";
+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"; //Added By Aqib Mirza
+import { ExpandIcon, CompressIcon } from "lowcoder-design";
+
export type configChangeParams = {
colorKey: string;
color?: string;
radius?: string;
chart?: string;
+ margin?: string;
+ padding?: string;
gridColumns?: string; //Added By Aqib Mirza
};
@@ -23,6 +27,8 @@ type ColorConfigProps = {
radius?: string;
configChange: (params: configChangeParams) => void;
showVarName?: boolean;
+ margin?: string;
+ padding?: string;
gridColumns?: string; //Added By Aqib Mirza
};
@@ -35,12 +41,16 @@ export default function ColorPicker(props: ColorConfigProps) {
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})`;
@@ -69,6 +79,35 @@ export default function ColorPicker(props: ColorConfigProps) {
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) => {
@@ -99,6 +138,13 @@ export default function ColorPicker(props: ColorConfigProps) {
setRadius(defaultRadius);
}, [defaultRadius]);
+ useEffect(() => {
+ setMargin(defaultMargin);
+ }, [defaultMargin]);
+
+ useEffect(() => {
+ setPadding(defaultPadding);
+ }, [defaultPadding]);
// Added By Aqib Mirza
useEffect(() => {
setGridColumns(defaultGridColumns);
@@ -113,7 +159,9 @@ export default function ColorPicker(props: ColorConfigProps) {
{desc}
- {colorKey !== "borderRadius" &&
+ {colorKey !== "borderRadius" &&
+ colorKey !== "margin" &&
+ colorKey !== "padding" &&
colorKey !== "gridColumns" && (
)}
+ {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" && (
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
index 496408803..22fa3463e 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/buttonCompConstants.tsx
@@ -12,6 +12,8 @@ export function getButtonStyle(buttonStyle: ButtonStyleType) {
const activeColor = genActiveColor(buttonStyle.background);
return css`
border-radius: ${buttonStyle.radius};
+ margin: ${buttonStyle.margin};
+ padding: ${buttonStyle.padding};
&:not(:disabled) {
// click animation color
--antd-wave-shadow-color: ${buttonStyle.border};
@@ -19,6 +21,8 @@ export function getButtonStyle(buttonStyle: ButtonStyleType) {
color: ${buttonStyle.text};
background-color: ${buttonStyle.background};
border-radius: ${buttonStyle.radius};
+ margin: ${buttonStyle.margin};
+ padding: ${buttonStyle.padding};
:hover,
:focus {
@@ -37,12 +41,14 @@ export function getButtonStyle(buttonStyle: ButtonStyleType) {
: buttonStyle.border};
}
}
+
`;
}
export const Button100 = styled(Button)<{ $buttonStyle?: ButtonStyleType }>`
${(props) => props.$buttonStyle && getButtonStyle(props.$buttonStyle)}
- width: 100%;
+ width: -webkit-fill-available;
+ height: auto;
display: inline-flex;
justify-content: center;
align-items: center;
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
index a6405d6b5..f8e9e1224 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/dropdownComp.tsx
@@ -29,10 +29,14 @@ const DropdownButton = styled(Dropdown.Button)`
const LeftButtonWrapper = styled.div<{ $buttonStyle: ButtonStyleType }>`
width: calc(100% - 32px);
-
+ ${(props) => `margin: ${props.$buttonStyle.margin};`}
+ margin-right: 0;
.ant-btn {
${(props) => getButtonStyle(props.$buttonStyle)}
+ margin: 0 !important;
+ height: 100%;
&.ant-btn-default {
+ margin: 0 !important;
${(props) => `border-radius: ${props.$buttonStyle.radius} 0 0 ${props.$buttonStyle.radius};`}
}
width: 100%;
@@ -40,12 +44,15 @@ const LeftButtonWrapper = styled.div<{ $buttonStyle: ButtonStyleType }>`
`;
const RightButtonWrapper = styled.div<{ $buttonStyle: ButtonStyleType }>`
- width: 32px;
+ // width: 32px;
+ ${(props) => `margin: ${props.$buttonStyle.margin};`}
margin-left: -1px;
-
.ant-btn {
${(props) => getButtonStyle(props.$buttonStyle)}
+ margin: 0 !important;
+ height: 100%;
&.ant-btn-default {
+ margin: 0 !important;
${(props) => `border-radius: 0 ${props.$buttonStyle.radius} ${props.$buttonStyle.radius} 0;`}
}
width: 100%;
@@ -69,6 +76,7 @@ const DropdownTmpComp = (function () {
.map((option, index) => ({
title: option.label,
label: option.label,
+ style: {padding: props.style.padding},
key: option.label + " - " + index,
disabled: option.disabled,
icon: hasIcon && {option.prefixIcon},
@@ -83,6 +91,7 @@ const DropdownTmpComp = (function () {
return (
+ {console.log("props,", props)}
{props.onlyMenu ? (
diff --git a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
index d0e3bc517..7d753f43f 100644
--- a/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/buttonComp/linkComp.tsx
@@ -21,7 +21,7 @@ import { hasIcon } from "comps/utils";
import { RefControl } from "comps/controls/refControl";
const Link = styled(Button)<{ $style: LinkStyleType }>`
- ${(props) => `color: ${props.$style.text};`}
+ ${(props) => `color: ${props.$style.text};margin: ${props.$style.margin}; padding: ${props.$style.padding};`}
&.ant-btn {
display: inline-flex;
align-items: center;
diff --git a/client/packages/lowcoder/src/comps/comps/dateComp/dateCompUtil.ts b/client/packages/lowcoder/src/comps/comps/dateComp/dateCompUtil.ts
index 8759dc8d6..2b31c9d59 100644
--- a/client/packages/lowcoder/src/comps/comps/dateComp/dateCompUtil.ts
+++ b/client/packages/lowcoder/src/comps/comps/dateComp/dateCompUtil.ts
@@ -63,7 +63,7 @@ export const disabledTime = (min: string, max: string) => {
export const getStyle = (style: DateTimeStyleType) => {
return css`
border-radius: ${style.radius};
-
+ padding: ${style.padding};
&:not(.ant-picker-disabled) {
border-color: ${style.border};
background-color: ${style.background};
diff --git a/client/packages/lowcoder/src/comps/comps/dividerComp.tsx b/client/packages/lowcoder/src/comps/comps/dividerComp.tsx
index 1da6f8d2d..c3cede6c6 100644
--- a/client/packages/lowcoder/src/comps/comps/dividerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/dividerComp.tsx
@@ -8,7 +8,7 @@ import { Section, sectionNames } from "lowcoder-design";
import _ from "lodash";
import styled from "styled-components";
import { styleControl } from "comps/controls/styleControl";
-import { DividerStyle, DividerStyleType } from "comps/controls/styleControlConstants";
+import { DividerStyle, DividerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { migrateOldData } from "comps/generators/simpleGenerators";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
import { trans } from "i18n";
@@ -22,6 +22,17 @@ const StyledDivider = styled(Divider)`
display: flex;
align-items: center;
}
+ min-width: 0;
+ width: ${(props) => {
+ return widthCalculator(props.$style.margin);
+ }};
+ min-height: ${(props) => {
+ return heightCalculator(props.$style.margin);
+ }};
+ margin: ${(props) => {
+ return props.$style.margin;
+ }};
+ padding: ${(props) => props.$style.padding};
border-top: 1px ${(props) => (props.dashed ? "dashed" : "solid")} ${(props) => props.$style.color};
&.ant-divider-horizontal.ant-divider-with-text {
diff --git a/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx b/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx
index f26e9f3c3..a2eb3cd88 100644
--- a/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/fileComp/fileComp.tsx
@@ -6,7 +6,7 @@ import { darkenColor } from "components/colorSelect/colorUtils";
import { Section, sectionNames } from "components/Section";
import { IconControl } from "comps/controls/iconControl";
import { styleControl } from "comps/controls/styleControl";
-import { FileStyle, FileStyleType } from "comps/controls/styleControlConstants";
+import { FileStyle, FileStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { withMethodExposing } from "comps/generators/withMethodExposing";
import { hasIcon } from "comps/utils";
import { getComponentDocUrl } from "comps/utils/compDocUtil";
@@ -133,6 +133,10 @@ const getStyle = (style: FileStyleType) => {
return css`
.ant-btn {
border-radius: ${style.radius};
+ margin: ${style.margin};
+ padding: ${style.padding};
+ width: ${widthCalculator(style.margin)};
+ height: ${heightCalculator(style.margin)};
}
.ant-btn:not(:disabled) {
diff --git a/client/packages/lowcoder/src/comps/comps/fileViewerComp.tsx b/client/packages/lowcoder/src/comps/comps/fileViewerComp.tsx
index 8952c63a5..e49c6928e 100644
--- a/client/packages/lowcoder/src/comps/comps/fileViewerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/fileViewerComp.tsx
@@ -1,5 +1,5 @@
import { styleControl } from "comps/controls/styleControl";
-import { FileViewerStyle, FileViewerStyleType } from "comps/controls/styleControlConstants";
+import { FileViewerStyle, FileViewerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { isEmpty } from "lodash";
import { useState } from "react";
import { DocumentViewer } from "react-documents";
@@ -13,6 +13,11 @@ import { trans } from "i18n";
const getStyle = (style: FileViewerStyleType) => {
return css`
+ width: ${widthCalculator(style.margin)};
+ height: ${heightCalculator(style.margin)};
+ margin: ${style.margin};
+ padding: ${style.padding};
+
overflow: hidden;
background-color: ${style.background};
border: 1px solid ${style.border};
diff --git a/client/packages/lowcoder/src/comps/comps/imageComp.tsx b/client/packages/lowcoder/src/comps/comps/imageComp.tsx
index 297d97f45..871bfa9df 100644
--- a/client/packages/lowcoder/src/comps/comps/imageComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/imageComp.tsx
@@ -9,7 +9,7 @@ import { useEffect, useRef, useState } from "react";
import _ from "lodash";
import ReactResizeDetector from "react-resize-detector";
import { styleControl } from "comps/controls/styleControl";
-import { ImageStyle, ImageStyleType } from "comps/controls/styleControlConstants";
+import { ImageStyle, ImageStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
import { trans } from "i18n";
import { AutoHeightControl } from "comps/controls/autoHeightControl";
@@ -23,7 +23,6 @@ const Container = styled.div<{ $style: ImageStyleType | undefined }>`
display: flex;
align-items: center;
justify-content: center;
-
.ant-image,
img {
width: 100%;
@@ -43,6 +42,10 @@ const getStyle = (style: ImageStyleType) => {
img {
border: 1px solid ${style.border};
border-radius: ${style.radius};
+ margin: ${style.margin};
+ padding: ${style.padding};
+ max-width: ${widthCalculator(style.margin)};
+ max-height: ${heightCalculator(style.margin)};
}
.ant-image-mask {
diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
index a2e13ed11..4935e2d1d 100644
--- a/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/numberInputComp.tsx
@@ -30,7 +30,7 @@ import { formDataChildren, FormDataPropertyView } from "../formComp/formDataCons
import { withMethodExposing, refMethods } from "../../generators/withMethodExposing";
import { RefControl } from "../../controls/refControl";
import { styleControl } from "comps/controls/styleControl";
-import { InputLikeStyle, InputLikeStyleType } from "comps/controls/styleControlConstants";
+import { InputLikeStyle, InputLikeStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import {
disabledPropertyView,
hiddenPropertyView,
@@ -58,7 +58,9 @@ const getStyle = (style: InputLikeStyleType) => {
color: ${style.text};
background-color: ${style.background};
border-color: ${style.border};
-
+ //margin: ${style.margin};
+ padding: 0;
+ width: ${widthCalculator(style.margin)};
&.ant-input-number-focused {
border-color: ${style.accent};
}
@@ -71,6 +73,14 @@ const getStyle = (style: InputLikeStyleType) => {
color: ${style.text};
opacity: 0.4;
}
+ .ant-input-number {
+ margin: 0;
+ }
+ .ant-input-number input {
+ margin: 0;
+ padding: ${style.padding};
+ height: ${heightCalculator(style.margin)};
+ }
.ant-input-number-handler-wrap {
background-color: ${style.background};
diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx
index 4cb4e166e..bea60397c 100644
--- a/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/rangeSliderComp.tsx
@@ -28,6 +28,7 @@ const RangeSliderBasicComp = (function () {
range={true}
value={[props.start.value, props.end.value]}
$style={props.style}
+ style={{margin: 0}}
onChange={([start, end]) => {
props.start.onChange(start);
props.end.onChange(end);
diff --git a/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx b/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx
index 931fe3a27..b86b07ef6 100644
--- a/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/numberInputComp/sliderComp.tsx
@@ -31,6 +31,7 @@ const SliderBasicComp = (function () {
{...props}
value={props.value.value}
$style={props.style}
+ style={{margin: 0}}
onChange={(e) => {
props.value.onChange(e);
props.onEvent("change");
diff --git a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
index 777774f90..e20cbf668 100644
--- a/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/progressCircleComp.tsx
@@ -1,6 +1,6 @@
import { Progress } from "antd";
import { styleControl } from "comps/controls/styleControl";
-import { ProgressStyle, ProgressStyleType } from "comps/controls/styleControlConstants";
+import { ProgressStyle, ProgressStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import styled, { css } from "styled-components";
import { Section, sectionNames } from "lowcoder-design";
import { numberExposingStateControl } from "../controls/codeStateControl";
@@ -11,6 +11,10 @@ import { trans } from "i18n";
const getStyle = (style: ProgressStyleType) => {
return css`
+ width: ${widthCalculator(style.margin)};
+ height: ${heightCalculator(style.margin)};
+ margin: ${style.margin};
+ padding: ${style.padding};
.ant-progress-text {
color: ${style.text};
}
diff --git a/client/packages/lowcoder/src/comps/comps/progressComp.tsx b/client/packages/lowcoder/src/comps/comps/progressComp.tsx
index 1f3d74b42..d9ae4ed5d 100644
--- a/client/packages/lowcoder/src/comps/comps/progressComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/progressComp.tsx
@@ -5,7 +5,7 @@ import { BoolControl } from "../controls/boolControl";
import { UICompBuilder } from "../generators";
import { NameConfig, NameConfigHidden, withExposingConfigs } from "../generators/withExposing";
import { styleControl } from "comps/controls/styleControl";
-import { ProgressStyle, ProgressStyleType } from "comps/controls/styleControlConstants";
+import { ProgressStyle, ProgressStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import styled, { css } from "styled-components";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
import { trans } from "i18n";
@@ -16,6 +16,10 @@ const getStyle = (style: ProgressStyleType) => {
.ant-progress-text {
color: ${style.text};
}
+ width: ${widthCalculator(style.margin)};
+ height: ${heightCalculator(style.margin)};
+ margin: ${style.margin};
+ padding: ${style.padding};
.ant-progress-inner {
background-color: ${style.track};
.ant-progress-bg {
diff --git a/client/packages/lowcoder/src/comps/comps/qrCodeComp.tsx b/client/packages/lowcoder/src/comps/comps/qrCodeComp.tsx
index cbfbc8236..f302a4eed 100644
--- a/client/packages/lowcoder/src/comps/comps/qrCodeComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/qrCodeComp.tsx
@@ -3,7 +3,7 @@ import { BoolControl } from "comps/controls/boolControl";
import { stringExposingStateControl } from "comps/controls/codeStateControl";
import { dropdownControl } from "comps/controls/dropdownControl";
import { styleControl } from "comps/controls/styleControl";
-import { QRCodeStyle } from "comps/controls/styleControlConstants";
+import { QRCodeStyle, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { UICompBuilder } from "comps/generators/uiCompBuilder";
import { NameConfig, NameConfigHidden, withExposingConfigs } from "comps/generators/withExposing";
import { Section, sectionNames } from "lowcoder-design";
@@ -34,18 +34,28 @@ const QRCodeView = (props: RecordConstructorToView) => {
return <>{trans("QRCode.maxLength")}>;
}
return (
-
+
+
+
);
};
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderContants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderContants.tsx
index 21023e3d7..679abf1b0 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderContants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/cascaderContants.tsx
@@ -18,6 +18,9 @@ import { i18nObjs, trans } from "i18n";
import { RefControl } from "comps/controls/refControl";
import { CascaderRef } from "antd/lib/cascader";
+import { MarginControl } from "../../controls/marginControl";
+import { PaddingControl } from "../../controls/paddingControl";
+
export const defaultDataSource = JSON.stringify(i18nObjs.cascader, null, " ");
export const CascaderChildren = {
@@ -31,6 +34,8 @@ export const CascaderChildren = {
style: styleControl(CascaderStyle),
showSearch: BoolControl.DEFAULT_TRUE,
viewRef: RefControl,
+ margin: MarginControl,
+ padding: PaddingControl,
};
export const CascaderPropertyView = (
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
index 9b5284273..97bbab078 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/checkboxComp.tsx
@@ -64,6 +64,7 @@ export const getStyle = (style: CheckboxStyleType) => {
}
.ant-checkbox-wrapper {
+ padding: ${style.padding};
.ant-checkbox-inner,
.ant-checkbox-checked::after {
border-radius: ${style.radius};
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx
index 8e6db99e6..c052f89fb 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/multiSelectComp.tsx
@@ -12,11 +12,16 @@ import {
} from "./selectCompConstants";
import { SelectInputInvalidConfig, useSelectInputValidate } from "./selectInputConstants";
+import { PaddingControl } from "../../controls/paddingControl";
+import { MarginControl } from "../../controls/marginControl";
+
const MultiSelectBasicComp = (function () {
const childrenMap = {
...SelectChildrenMap,
value: arrayStringExposingStateControl("value", ["1", "2"]),
style: styleControl(MultiSelectStyle),
+ margin: MarginControl,
+ padding: PaddingControl,
};
return new UICompBuilder(childrenMap, (props, dispatch) => {
const valueSet = new Set(props.options.map((o) => o.value)); // Filter illegal default values entered by the user
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
index c2f457757..473d9c9f7 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/radioComp.tsx
@@ -16,9 +16,9 @@ const getStyle = (style: RadioStyleType) => {
return css`
.ant-radio-wrapper:not(.ant-radio-wrapper-disabled) {
color: ${style.staticText};
- height: 22px;
+ // height: 22px;
max-width: calc(100% - 8px);
-
+ padding: ${style.padding};
span:not(.ant-radio) {
${EllipsisTextCss};
}
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
index 3a791fc4a..694fbdeb1 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/segmentedControl.tsx
@@ -36,7 +36,9 @@ const getStyle = (style: SegmentStyleType) => {
color: ${style.text};
border-radius: ${style.radius};
}
-
+ .ant-segmented-item {
+ padding: ${style.padding};
+ }
.ant-segmented-item-selected,
.ant-segmented-thumb {
background-color: ${style.indicatorBackground};
@@ -52,7 +54,7 @@ const getStyle = (style: SegmentStyleType) => {
const Segmented = styled(AntdSegmented)<{ $style: SegmentStyleType }>`
width: 100%;
- height: 32px; // keep the height unchanged when there are no options
+ min-height: 24px; // keep the height unchanged when there are no options
${(props) => props.$style && getStyle(props.$style)}
`;
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
index f0b1eb87e..f58339f91 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
@@ -7,6 +7,8 @@ import {
import { BoolControl } from "../../controls/boolControl";
import { LabelControl } from "../../controls/labelControl";
import { BoolCodeControl, StringControl } from "../../controls/codeControl";
+import { PaddingControl } from "../../controls/paddingControl";
+import { MarginControl } from "../../controls/marginControl";
import {
ControlNode,
isDarkColor,
@@ -31,8 +33,10 @@ import {
MultiSelectStyleType,
SelectStyleType,
TreeSelectStyleType,
+ widthCalculator,
+ heightCalculator
} from "comps/controls/styleControlConstants";
-import { stateComp } from "../../generators";
+import { stateComp, withDefault } from "../../generators";
import {
allowClearPropertyView,
disabledPropertyView,
@@ -54,11 +58,24 @@ export const getStyle = (
&.ant-select .ant-select-selector,
&.ant-select-multiple .ant-select-selection-item {
border-radius: ${style.radius};
+ padding: ${style.padding};
+ height: auto;
+ }
+ .ant-select-selection-search {
+ padding: ${style.padding};
+ }
+ .ant-select-selector::after,
+ .ant-select-selection-placeholder,
+ .ant-select-selection-item {
+ line-height: 1.5715 !important;
}
&.ant-select:not(.ant-select-disabled) {
color: ${style.text};
-
+ .ant-select-selection-placeholder,
+ .ant-select-selection-item {
+ line-height: 1.5715 !important;
+ }
.ant-select-selection-placeholder,
&.ant-select-single.ant-select-open .ant-select-selection-item {
color: ${style.text};
@@ -142,11 +159,15 @@ const getDropdownStyle = (style: MultiSelectStyleType) => {
const Select = styled(AntdSelect)<{ $style: SelectStyleType & MultiSelectStyleType }>`
width: 100%;
+
${(props) => props.$style && getStyle(props.$style)}
`;
const DropdownStyled = styled.div<{ $style: MultiSelectStyleType }>`
${(props) => props.$style && getDropdownStyle(props.$style)}
+ .ant-select-item-option-content {
+ ${(props) => `padding: ${props.$style.padding}`};
+ }
.option-label img {
min-width: 14px;
margin-right: 0;
@@ -173,6 +194,8 @@ export const SelectChildrenMap = {
inputValue: stateComp(""), // user's input value when search
showSearch: BoolControl.DEFAULT_TRUE,
viewRef: RefControl,
+ margin: MarginControl,
+ padding: PaddingControl,
...SelectInputValidationChildren,
...formDataChildren,
};
diff --git a/client/packages/lowcoder/src/comps/comps/signatureComp.tsx b/client/packages/lowcoder/src/comps/comps/signatureComp.tsx
index 293d42a1c..ae4842388 100644
--- a/client/packages/lowcoder/src/comps/comps/signatureComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/signatureComp.tsx
@@ -9,6 +9,8 @@ import {
contrastColor,
SignatureStyle,
SignatureStyleType,
+ widthCalculator,
+ heightCalculator
} from "comps/controls/styleControlConstants";
import { stateComp, withDefault } from "comps/generators/simpleGenerators";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
@@ -33,7 +35,14 @@ const Wrapper = styled.div<{ $style: SignatureStyleType; isEmpty: boolean }>`
overflow: hidden;
width: 100%;
height: 100%;
-
+ width: ${(props) => {
+ return widthCalculator(props.$style.margin);
+ }};
+ height: ${(props) => {
+ return heightCalculator(props.$style.margin);
+ }};
+ margin: ${(props) => props.$style.margin};
+ padding: ${(props) => props.$style.padding};
.signature {
background-color: ${(props) => props.$style.background};
opacity: ${(props) => (props.isEmpty ? 0 : 1)};
diff --git a/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx b/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx
index 5abdf6a2a..a4a9ac6e3 100644
--- a/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tabs/tabbedContainerComp.tsx
@@ -7,7 +7,7 @@ import { stringExposingStateControl } from "comps/controls/codeStateControl";
import { eventHandlerControl } from "comps/controls/eventHandlerControl";
import { TabsOptionControl } from "comps/controls/optionsControl";
import { styleControl } from "comps/controls/styleControl";
-import { TabContainerStyle, TabContainerStyleType } from "comps/controls/styleControlConstants";
+import { TabContainerStyle, TabContainerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { sameTypeMap, UICompBuilder, withDefault } from "comps/generators";
import { addMapChildAction } from "comps/generators/sameTypeMap";
import { NameConfig, NameConfigHidden, withExposingConfigs } from "comps/generators/withExposing";
@@ -65,6 +65,7 @@ const getStyle = (style: TabContainerStyleType) => {
border: 1px solid ${style.border};
border-radius: ${style.radius};
overflow: hidden;
+ padding: ${style.padding};
> .ant-tabs-content-holder > .ant-tabs-content > div > .react-grid-layout {
background-color: ${style.background};
@@ -163,6 +164,7 @@ const TabbedContainer = (props: TabbedContainerProps) => {
// log.debug("TabbedContainer. props: ", props);
return (
+
{
);
})}
+
);
};
diff --git a/client/packages/lowcoder/src/comps/comps/textComp.tsx b/client/packages/lowcoder/src/comps/comps/textComp.tsx
index 4e7990617..8af381780 100644
--- a/client/packages/lowcoder/src/comps/comps/textComp.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textComp.tsx
@@ -10,11 +10,14 @@ import { UICompBuilder } from "../generators";
import { NameConfig, NameConfigHidden, withExposingConfigs } from "../generators/withExposing";
import { markdownCompCss, TacoMarkDown } from "lowcoder-design";
import { styleControl } from "comps/controls/styleControl";
-import { TextStyle, TextStyleType } from "comps/controls/styleControlConstants";
+import { TextStyle, TextStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
import { trans } from "i18n";
import { alignWithJustifyControl } from "comps/controls/alignControl";
+import { MarginControl } from "../controls/marginControl";
+import { PaddingControl } from "../controls/paddingControl";
+
const getStyle = (style: TextStyleType) => {
return css`
border-radius: 4px;
@@ -24,6 +27,10 @@ const getStyle = (style: TextStyleType) => {
color: ${style.links};
}
.markdown-body {
+ margin: ${style.margin} !important;
+ padding: ${style.padding};
+ width: ${widthCalculator(style.margin)};
+ height: ${heightCalculator(style.margin)};
h1 {
line-height: 1.5;
}
@@ -60,7 +67,7 @@ const TextContainer = styled.div<{ type: string; styleConfig: TextStyleType }>`
overflow: auto;
margin: 0;
${(props) =>
- props.type === "text" && "white-space:break-spaces;line-height: 1.9;padding: 3px 0;"};
+ props.type === "text" && "white-space:break-spaces;line-height: 1.9;"};
${(props) => props.styleConfig && getStyle(props.styleConfig)}
display: flex;
font-size: 13px;
@@ -107,6 +114,8 @@ let TextTmpComp = (function () {
horizontalAlignment: alignWithJustifyControl(),
verticalAlignment: dropdownControl(VerticalAlignmentOptions, "center"),
style: styleControl(TextStyle),
+ margin: MarginControl,
+ padding: PaddingControl,
};
return new UICompBuilder(childrenMap, (props) => {
const value = props.text.value;
diff --git a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
index ebc6a21f7..f6bdabe60 100644
--- a/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/textInputComp/textInputConstants.tsx
@@ -8,7 +8,7 @@ import {
} from "comps/controls/codeControl";
import { stringExposingStateControl } from "comps/controls/codeStateControl";
import { LabelControl } from "comps/controls/labelControl";
-import { InputLikeStyleType } from "comps/controls/styleControlConstants";
+import { InputLikeStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { Section, sectionNames, ValueFromOption } from "lowcoder-design";
import _ from "lodash";
import { css } from "styled-components";
@@ -219,6 +219,7 @@ export const TextInputValidationSection = (children: TextInputComp) => (
export function getStyle(style: InputLikeStyleType) {
return css`
border-radius: ${style.radius};
+ padding: ${style.padding};
// still use antd style when disabled
&:not(.ant-input-disabled, .ant-input-affix-wrapper-disabled),
input {
diff --git a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
index 886a0e6f3..9530c6f61 100644
--- a/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
+++ b/client/packages/lowcoder/src/comps/comps/triContainerComp/triContainer.tsx
@@ -1,4 +1,4 @@
-import { ContainerStyleType } from "comps/controls/styleControlConstants";
+import { ContainerStyleType, heightCalculator, widthCalculator } from "comps/controls/styleControlConstants";
import { EditorContext } from "comps/editorState";
import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
import { HintPlaceHolder } from "lowcoder-design";
@@ -13,6 +13,10 @@ const getStyle = (style: ContainerStyleType) => {
border-color: ${style.border};
border-radius: ${style.radius};
overflow: hidden;
+ // margin: ${style.margin};
+ padding: ${style.padding};
+ // width: ${widthCalculator(style.margin)};
+ // height: ${heightCalculator(style.margin)};
`;
};
@@ -74,6 +78,7 @@ export function TriContainer(props: TriContainerProps) {
const paddingWidth = isMobile ? 7 : 19;
return (
+
{showHeader && (
@@ -86,6 +91,7 @@ export function TriContainer(props: TriContainerProps) {
containerPadding={[paddingWidth, 3]}
showName={{ bottom: showBody || showFooter ? 20 : 0 }}
backgroundColor={style?.headerBackground}
+ style={{padding: style.containerheaderpadding}}
/>
)}
@@ -104,6 +110,7 @@ export function TriContainer(props: TriContainerProps) {
hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
backgroundColor={style?.background}
borderColor={style?.border}
+ style={{padding: style.containerbodypadding}}
/>
)}
@@ -120,9 +127,11 @@ export function TriContainer(props: TriContainerProps) {
showName={{ top: showHeader || showBody ? 20 : 0 }}
backgroundColor={style?.footerBackground}
borderColor={style?.border}
+ style={{padding: style.containerfooterpadding}}
/>
)}
+
);
}
diff --git a/client/packages/lowcoder/src/comps/controls/labelControl.tsx b/client/packages/lowcoder/src/comps/controls/labelControl.tsx
index fbe0d3d96..12413920d 100644
--- a/client/packages/lowcoder/src/comps/controls/labelControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/labelControl.tsx
@@ -15,6 +15,8 @@ import { AlignLeft } from "lowcoder-design";
import { AlignRight } from "lowcoder-design";
import { StarIcon } from "lowcoder-design";
+import { heightCalculator, widthCalculator } from "./styleControlConstants";
+
type LabelViewProps = Pick & {
children: ReactNode;
style?: Record;
@@ -146,7 +148,20 @@ export const LabelControl = (function () {
};
return new MultiCompBuilder(childrenMap, (props) => (args: LabelViewProps) => (
-
+
{!props.hidden && !isEmpty(props.text) && (
`
+ display: flex;
+ justify-content: space-between;
+ .hUXIwu {
+ flex: 0 0 36px;
+ }
+ .fgbLEe {
+ margin-right: 5px;
+ margin-bottom: 10px;
+ }
+`;
+export const MarginControl = (function () {
+ const childrenMap = {
+ left: withDefault(StringControl, ""),
+ right: withDefault(StringControl, ""),
+ top: withDefault(StringControl, ""),
+ bottom: withDefault(StringControl, ""),
+ };
+ return new MultiCompBuilder(childrenMap, (props) => props)
+ .setPropertyViewFn((children) => (
+ <>
+ {children.top.propertyView({
+ label: trans("componentDoc.top"),
+ })}
+ {children.right.propertyView({
+ label: trans("componentDoc.right"),
+ })}
+ {children.bottom.propertyView({
+ label: trans("componentDoc.bottom"),
+ })}
+ {children.left.propertyView({
+ label: trans("componentDoc.left"),
+ })}
+ >
+ ))
+ .build();
+})();
diff --git a/client/packages/lowcoder/src/comps/controls/paddingControl.tsx b/client/packages/lowcoder/src/comps/controls/paddingControl.tsx
new file mode 100644
index 000000000..d9db05108
--- /dev/null
+++ b/client/packages/lowcoder/src/comps/controls/paddingControl.tsx
@@ -0,0 +1,44 @@
+import { StringControl } from "comps/controls/codeControl";
+import { withDefault } from "comps/generators";
+import { MultiCompBuilder } from "comps/generators/multi";
+import { trans } from "i18n";
+import { Section } from "lowcoder-design";
+import styled from "styled-components";
+
+const PaddingContainer = styled.div<{}>`
+ display: flex;
+ justify-content: space-between;
+ .hUXIwu {
+ flex: 0 0 36px;
+ }
+ .fgbLEe {
+ margin-right: 5px;
+ margin-bottom: 10px;
+ }
+`;
+export const PaddingControl = (function () {
+ const childrenMap = {
+ left: withDefault(StringControl, ""),
+ right: withDefault(StringControl, ""),
+ top: withDefault(StringControl, ""),
+ bottom: withDefault(StringControl, ""),
+ };
+ return new MultiCompBuilder(childrenMap, (props) => props)
+ .setPropertyViewFn((children) => (
+ <>
+ {children.top.propertyView({
+ label: trans("componentDoc.top"),
+ })}
+ {children.right.propertyView({
+ label: trans("componentDoc.right"),
+ })}
+ {children.bottom.propertyView({
+ label: trans("componentDoc.bottom"),
+ })}
+ {children.left.propertyView({
+ label: trans("componentDoc.left"),
+ })}
+ >
+ ))
+ .build();
+})();
diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
index e3c3392f6..42311c187 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx
@@ -6,11 +6,11 @@ import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
import { ThemeContext } from "comps/utils/themeContext";
import { trans } from "i18n";
import _ from "lodash";
-import { controlItem, IconRadius, IconReset } from "lowcoder-design";
+import { controlItem, IconRadius, IconReset, ExpandIcon, CompressIcon, } from "lowcoder-design";
import { useContext } from "react";
import styled from "styled-components";
import { useIsMobile } from "util/hooks";
-import { RadiusControl } from "./codeControl";
+import { RadiusControl, StringControl } from "./codeControl";
import { ColorControl } from "./colorControl";
import {
defaultTheme,
@@ -19,6 +19,8 @@ import {
RadiusConfig,
SimpleColorConfig,
SingleColorConfig,
+ MarginConfig,
+ PaddingConfig,
} from "./styleControlConstants";
function isSimpleColorConfig(config: SingleColorConfig): config is SimpleColorConfig {
@@ -33,6 +35,14 @@ function isRadiusConfig(config: SingleColorConfig): config is RadiusConfig {
return config.hasOwnProperty("radius");
}
+function isMarginConfig(config: SingleColorConfig): config is MarginConfig {
+ return config.hasOwnProperty("margin");
+}
+
+function isPaddingConfig(config: SingleColorConfig): config is PaddingConfig {
+ return config.hasOwnProperty("padding");
+}
+
// function styleControl(colorConfig: Array) {
type Names = T[number]["name"];
export type StyleConfigType = { [K in Names]: string };
@@ -46,6 +56,13 @@ function isEmptyRadius(radius: string) {
return _.isEmpty(radius);
}
+function isEmptyMargin(margin: string) {
+ return _.isEmpty(margin);
+}
+function isEmptyPadding(padding: string) {
+ return _.isEmpty(padding);
+}
+
/**
* Calculate the actual used color from the dsl color
*/
@@ -60,15 +77,17 @@ function calcColors>(
let res: Record = {};
colorConfigs.forEach((config) => {
const name = config.name;
- if (!isEmptyRadius(props[name]) && isRadiusConfig(config)) {
- if (/^[0-9]+$/.test(props[name])) {
- res[name] = props[name] + "px";
- } else if (/^[0-9]+(px|%)$/.test(props[name])) {
- res[name] = props[name];
- } else {
- res[name] = config.radius;
- }
- return;
+ if (!isEmptyRadius(props[name]) && isRadiusConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyMargin(props[name]) && isMarginConfig(config)) {
+ res[name] = props[name];
+ return;
+ }
+ if (!isEmptyPadding(props[name]) && isPaddingConfig(config)) {
+ res[name] = props[name];
+ return;
}
if (!isEmptyColor(props[name])) {
if (isThemeColorKey(props[name])) {
@@ -84,6 +103,12 @@ function calcColors>(
if (isRadiusConfig(config)) {
res[name] = themeWithDefault[config.radius];
}
+ if (isMarginConfig(config)) {
+ res[name] = themeWithDefault[config.margin];
+ }
+ if (isPaddingConfig(config)) {
+ res[name] = themeWithDefault[config.padding];
+ }
});
// The second pass calculates dep
colorConfigs.forEach((config) => {
@@ -191,6 +216,13 @@ const RadiusIcon = styled(IconRadius)`
margin: 0 8px 0 -2px;
`;
+const MarginIcon = styled(ExpandIcon)`
+margin: 0 8px 0 -2px;
+`;
+const PaddingIcon = styled(CompressIcon)`
+margin: 0 8px 0 -2px;
+`;
+
const ResetIcon = styled(IconReset)`
&:hover g g {
stroke: #315efb;
@@ -202,10 +234,15 @@ export function styleControl(colorConfig
const childrenMap: any = {};
colorConfigs.map((config) => {
const name: Names = config.name;
- if (name === "radius") {
- childrenMap[name] = RadiusControl;
- } else {
- childrenMap[name] = ColorControl;
+ if (
+ name === "radius" ||
+ name === "cardRadius"
+ ) {
+ childrenMap[name] = StringControl;
+ } else if (name === "margin" || name === "padding" || name==="containerheaderpadding" || name==="containerfooterpadding" || name==="containerbodypadding") {
+ childrenMap[name] = StringControl;
+ } else {
+ childrenMap[name] = ColorControl;
}
});
// [K in Names]: new (params: CompParams) => ColorControl;
@@ -241,7 +278,14 @@ export function styleControl(colorConfig
onClick={() => {
colorConfigs.map((item) => {
const name: Names = item.name;
- if (name === "radius") {
+ if (
+ name === "radius" ||
+ name === "margin" ||
+ name === "padding" ||
+ name==="containerheaderpadding" ||
+ name==="containerfooterpadding" ||
+ name==="containerbodypadding"
+ ) {
children[name]?.dispatchChangeValueAction("");
} else {
children[name] &&
@@ -278,20 +322,43 @@ export function styleControl(colorConfig
}
return controlItem(
{ filterText: config.label },
-
- {name === "radius"
- ? (children[name] as InstanceType
).propertyView({
- label: config.label,
- preInputNode: ,
- placeholder: props[name],
- })
- : children[name].propertyView({
- label: config.label,
- panelDefaultColor: props[name],
- // isDep: isDepColorConfig(config),
- isDep: true,
- depMsg: depMsg,
- })}
+
+ {name === "radius" ||
+ name === "gap" ||
+ name === "cardRadius"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "margin"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : name === "padding" ||
+ name === "containerheaderpadding" ||
+ name === "containerfooterpadding" ||
+ name === "containerbodypadding"
+ ? (
+ children[name] as InstanceType
+ ).propertyView({
+ label: config.label,
+ preInputNode: ,
+ placeholder: props[name],
+ })
+ : children[name].propertyView({
+ label: config.label,
+ panelDefaultColor: props[name],
+ // isDep: isDepColorConfig(config),
+ isDep: true,
+ depMsg: depMsg,
+ })}
);
})}
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index b6c645999..24937f44c 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -16,13 +16,33 @@ export type SimpleColorConfig = CommonColorConfig & {
export type RadiusConfig = CommonColorConfig & {
readonly radius: string;
};
+
+export type ContainerHeaderPaddigConfig = CommonColorConfig & {
+ readonly containerheaderpadding: string;
+};
+
+export type ContainerBodyPaddigConfig = CommonColorConfig & {
+ readonly containerbodypadding: string;
+};
+
+export type ContainerFooterPaddigConfig = CommonColorConfig & {
+ readonly containerfooterpadding: string;
+};
+
+export type MarginConfig = CommonColorConfig & {
+ readonly margin: string;
+};
+export type PaddingConfig = CommonColorConfig & {
+ readonly padding: string;
+};
+
export type DepColorConfig = CommonColorConfig & {
readonly depName?: string;
readonly depTheme?: keyof ThemeDetail;
readonly depType?: DEP_TYPE;
transformer: (color: string, ...rest: string[]) => string;
};
-export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig;
+export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig;
export const defaultTheme: ThemeDetail = {
primary: "#3377FF",
@@ -31,6 +51,8 @@ export const defaultTheme: ThemeDetail = {
canvas: "#F5F5F6",
primarySurface: "#FFFFFF",
borderRadius: "4px",
+ margin: "3px",
+ padding: "3px",
gridColumns: "24",
};
@@ -226,6 +248,37 @@ const RADIUS = {
radius: "borderRadius",
} as const;
+const MARGIN = {
+ name: "margin",
+ label: trans("style.margin"),
+ margin: "margin",
+} as const;
+
+const PADDING = {
+ name: "padding",
+ label: trans("style.padding"),
+ padding: "padding",
+} as const;
+
+const CONTAINERHEADERPADDING = {
+ name: "containerheaderpadding",
+ label: trans("style.containerheaderpadding"),
+ containerheaderpadding: "padding",
+} as const;
+
+const CONTAINERFOOTERPADDING = {
+ name: "containerfooterpadding",
+ label: trans("style.containerfooterpadding"),
+ containerfooterpadding: "padding",
+} as const;
+
+
+const CONTAINERBODYPADDING = {
+ name: "containerbodypadding",
+ label: trans("style.containerbodypadding"),
+ containerbodypadding: "padding",
+} as const;
+
const getStaticBorder = (color: string = SECOND_SURFACE_COLOR) =>
({
name: "border",
@@ -293,7 +346,7 @@ function getStaticBackground(color: string) {
} as const;
}
-export const ButtonStyle = [...getBgBorderRadiusByBg("primary"), TEXT] as const;
+export const ButtonStyle = [...getBgBorderRadiusByBg("primary"), TEXT, MARGIN, PADDING] as const;
export const ToggleButtonStyle = [
getBackground("canvas"),
@@ -306,6 +359,8 @@ export const ToggleButtonStyle = [
transformer: toSelf,
},
RADIUS,
+ MARGIN,
+ PADDING,
] as const;
export const TextStyle = [
@@ -317,6 +372,8 @@ export const TextStyle = [
transformer: toSelf,
},
TEXT,
+ MARGIN,
+ PADDING,
{
name: "links",
label: trans("style.links"),
@@ -326,6 +383,15 @@ export const TextStyle = [
},
] as const;
+export const MarginStyle = [
+ {
+ name: "margin",
+ label: trans("style.margin"),
+ margin: "margin",
+ },
+];
+
+
export const ContainerStyle = [
...BG_STATIC_BORDER_RADIUS,
HEADER_BACKGROUND,
@@ -336,6 +402,11 @@ export const ContainerStyle = [
depType: DEP_TYPE.SELF,
transformer: toSelf,
},
+ MARGIN,
+ PADDING,
+ CONTAINERHEADERPADDING,
+ CONTAINERFOOTERPADDING,
+ CONTAINERBODYPADDING
] as const;
export const SliderStyle = [
@@ -354,12 +425,16 @@ export const SliderStyle = [
color: SURFACE_COLOR,
},
TRACK,
+ MARGIN,
+ PADDING,
] as const;
export const InputLikeStyle = [
LABEL,
...getStaticBgBorderRadiusByBg(SURFACE_COLOR),
TEXT,
+ MARGIN,
+ PADDING,
...ACCENT_VALIDATE,
] as const;
@@ -375,6 +450,8 @@ export const RatingStyle = [
label: trans("style.unchecked"),
color: SECOND_SURFACE_COLOR,
},
+ MARGIN,
+ PADDING,
] as const;
export const SwitchStyle = [
@@ -397,12 +474,16 @@ export const SwitchStyle = [
depType: DEP_TYPE.SELF,
transformer: toSelf,
},
+ MARGIN,
+ PADDING,
] as const;
export const SelectStyle = [
LABEL,
...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
TEXT,
+ MARGIN,
+ PADDING,
...ACCENT_VALIDATE,
] as const;
@@ -410,6 +491,8 @@ const multiSelectCommon = [
LABEL,
...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
TEXT,
+ MARGIN,
+ PADDING,
{
name: "tags",
label: trans("style.tags"),
@@ -456,6 +539,8 @@ export const TabContainerStyle = [
depType: DEP_TYPE.SELF,
transformer: toSelf,
},
+ MARGIN,
+ PADDING,
] as const;
export const ModalStyle = getBgBorderRadiusByBg();
@@ -465,6 +550,8 @@ export const CascaderStyle = [
...getStaticBgBorderRadiusByBg(SURFACE_COLOR, "pc"),
TEXT,
ACCENT,
+ MARGIN,
+ PADDING,
] as const;
function checkAndUncheck() {
@@ -503,6 +590,8 @@ export const CheckboxStyle = [
RADIUS,
STATIC_TEXT,
VALIDATE,
+ MARGIN,
+ PADDING,
] as const;
export const RadioStyle = [
@@ -517,6 +606,8 @@ export const RadioStyle = [
},
STATIC_TEXT,
VALIDATE,
+ MARGIN,
+ PADDING,
] as const;
export const SegmentStyle = [
@@ -541,6 +632,8 @@ export const SegmentStyle = [
},
RADIUS,
VALIDATE,
+ MARGIN,
+ PADDING,
] as const;
export const TableStyle = [
@@ -601,20 +694,24 @@ export const TableStyle = [
},
] as const;
-export const FileStyle = [...getStaticBgBorderRadiusByBg(SURFACE_COLOR), TEXT, ACCENT] as const;
+export const FileStyle = [...getStaticBgBorderRadiusByBg(SURFACE_COLOR), TEXT, ACCENT, MARGIN, PADDING] as const;
export const FileViewerStyle = [
getStaticBackground("#FFFFFF"),
getStaticBorder("#00000000"),
RADIUS,
+ MARGIN,
+ PADDING,
] as const;
-export const IframeStyle = [getBackground(), getStaticBorder("#00000000"), RADIUS] as const;
+export const IframeStyle = [getBackground(), getStaticBorder("#00000000"), RADIUS, MARGIN, PADDING] as const;
export const DateTimeStyle = [
LABEL,
...getStaticBgBorderRadiusByBg(SURFACE_COLOR),
TEXT,
+ MARGIN,
+ PADDING,
...ACCENT_VALIDATE,
] as const;
@@ -626,6 +723,8 @@ export const LinkStyle = [
depType: DEP_TYPE.SELF,
transformer: toSelf,
},
+ MARGIN,
+ PADDING,
] as const;
export const DividerStyle = [
@@ -640,6 +739,8 @@ export const DividerStyle = [
depName: "color",
transformer: handleToDividerText,
},
+ MARGIN,
+ PADDING,
] as const;
export const ProgressStyle = [
@@ -653,6 +754,8 @@ export const ProgressStyle = [
TRACK,
FILL,
SUCCESS,
+ MARGIN,
+ PADDING,
] as const;
export const NavigationStyle = [
@@ -666,9 +769,11 @@ export const NavigationStyle = [
ACCENT,
getStaticBackground("#FFFFFF00"),
getStaticBorder("#FFFFFF00"),
+ MARGIN,
+ PADDING,
] as const;
-export const ImageStyle = [getStaticBorder("#00000000"), RADIUS] as const;
+export const ImageStyle = [getStaticBorder("#00000000"), RADIUS, MARGIN, PADDING] as const;
export const ListViewStyle = BG_STATIC_BORDER_RADIUS;
@@ -681,6 +786,8 @@ export const QRCodeStyle = [
label: trans("color"),
color: "#000000",
},
+ MARGIN,
+ PADDING,
] as const;
export const TreeStyle = [
@@ -758,6 +865,8 @@ export const SignatureStyle = [
label: trans("style.footerIcon"),
color: "#222222",
},
+ MARGIN,
+ PADDING,
] as const;
//Added by Aqib Mirza
@@ -769,6 +878,8 @@ export const LottieStyle = [
depType: DEP_TYPE.CONTRAST_TEXT,
transformer: contrastText,
},
+ MARGIN,
+ PADDING,
] as const;
/////////////////////
@@ -811,3 +922,58 @@ export type CalendarStyleType = StyleConfigType;
export type SignatureStyleType = StyleConfigType;
export type CarouselStyleType = StyleConfigType;
export type RichTextEditorStyleType = StyleConfigType;
+
+export function widthCalculator(margin: string) {
+ const marginArr = margin?.trim().split(" ") || "";
+ if (marginArr.length === 1) {
+ return `calc(100% - ${
+ parseInt(margin.replace(/[^\d.]/g, "")) * 2 + margin.replace(/[0-9]/g, "")
+ })`;
+ } else if (marginArr.length === 2 || marginArr.length === 3) {
+ return `calc(100% - ${
+ parseInt(marginArr[1].replace(/[^\d.]/g, "")) * 2 +
+ marginArr[1].replace(/[0-9]/g, "")
+ })`;
+ } else {
+ return `calc(100% - ${
+ parseInt(marginArr[1]?.replace(/[^\d.]/g, "") || "0") +
+ marginArr[1]?.replace(/[0-9]/g, "" || "px")
+ } - ${
+ parseInt(marginArr[3]?.replace(/[^\d.]/g, "") || "0") +
+ marginArr[3]?.replace(/[0-9]/g, "" || "px")
+ })`;
+ }
+}
+
+export function heightCalculator(margin: string) {
+ const marginArr = margin?.trim().split(" ") || "";
+ if (marginArr.length === 1) {
+ return `calc(100% - ${
+ parseInt(margin.replace(/[^\d.]/g, "")) * 2 + margin.replace(/[0-9]/g, "")
+ })`;
+ } else if (marginArr.length === 2) {
+ return `calc(100% - ${
+ parseInt(marginArr[0].replace(/[^\d.]/g, "")) * 2 +
+ marginArr[0].replace(/[0-9]/g, "")
+ })`;
+ } else {
+ return `calc(100% - ${
+ parseInt(marginArr[0]?.replace(/[^\d.]/g, "") || "0") +
+ marginArr[0]?.replace(/[0-9]/g, "") || "px"
+ } - ${
+ parseInt(marginArr[2]?.replace(/[^\d.]/g, "") || "0") +
+ marginArr[2]?.replace(/[0-9]/g, "") || "px"
+ })`;
+ }
+}
+
+export function marginCalculator(margin: string) {
+ const marginArr = margin?.trim().split(" ") || "";
+ if (marginArr.length === 1) {
+ return parseInt(margin.replace(/[^\d.]/g, "")) * 2;
+ } else if (marginArr.length === 2) {
+ return parseInt(marginArr[0].replace(/[^\d.]/g, "")) * 2;
+ } else {
+ return parseInt(marginArr[0]?.replace(/[^\d.]/g, "") || "0") + parseInt(marginArr[2]?.replace(/[^\d.]/g, "") || "0")
+ }
+}
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index a0915ee1c..d7753eabb 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -280,6 +280,12 @@ export const en = {
chart: "Chart style",
chartDesc: "Input Echarts",
echartsJson: "Theme JSON",
+ margin: "Margin",
+ marginDesc: "The default margin is typically used for most components",
+ padding: "Padding",
+ paddingDesc: "The default padding is typically used for most components",
+ containerheaderpadding: "Header Padding",
+ containerheaderpaddingDesc: "The default headerpadding is typically used for most components",
//Added By Aqib Mirza
gridColumns: "Grid Columns",
gridColumnsDesc:
@@ -326,6 +332,15 @@ export const en = {
pen: "Pen",
footerIcon: "Footer icon",
tips: "Tips",
+ margin: "Margin",
+ padding: "Padding",
+ marginLeft: "Margin Left",
+ marginRight: "Margin Right",
+ marginTop: "Margin Top",
+ marginBottom: "Margin Bottom",
+ containerheaderpadding: "Header Padding",
+ containerfooterpadding: "Footer Padding",
+ containerbodypadding: "Body Padding",
},
export: {
hiddenDesc: "If true, the component is hidden",
@@ -2346,6 +2361,7 @@ export const en = {
left: "Left",
right: "Right",
center: "Center",
+ bottom: "Bottom",
justify: "Justify both ends",
},
playground: {
diff --git a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx
index 85cb98f1b..a17c2541f 100644
--- a/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx
+++ b/client/packages/lowcoder/src/pages/queryLibrary/LeftNav.tsx
@@ -51,7 +51,7 @@ const AddIcon = styled(BluePlusIcon)`
margin-right: 2px;
`;
const CreateBtn = styled(TacoButton)<{ readOnly?: boolean }>`
- height: 32px;
+ min-height: 24px;
width: 70px;
padding: 4px 12px;
display: flex;
diff --git a/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx b/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx
index 1fdd24283..cea0667cd 100644
--- a/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx
+++ b/client/packages/lowcoder/src/pages/setting/theme/detail/index.tsx
@@ -127,7 +127,7 @@ class ThemeDetailPage extends React.Component
+
+ {trans("themeDetail.margin")}
+ {
+ this.configChange(params);
+ }}
+ />
+
+
+ {trans("themeDetail.padding")}
+ {
+ this.configChange(params);
+ }}
+ />
+
{trans("themeDetail.gridColumns")}
`
+> div {
+ margin: 3px;
+ overflow: hidden;
+ > svg {
+ fill: currentColor;
+ }
+ }
+}
+`;
+export const Padding = styled.div<{ padding: string }>`
+> div {
+ margin: 3px;
+ overflow: hidden;
+ > svg {
+ fill: currentColor;
+ }
+ }
+}`
// Added By Aqib Mirza
export const GridColumns = styled.div<{ gridColumns: string }>`
> div {