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 {