From df4f9864995fa8838ca604fad72c63a460eee041 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Tue, 21 Nov 2023 17:51:14 +0500 Subject: [PATCH 1/6] feat: row expand event --- .../lowcoder/src/comps/comps/tableComp/tableCompView.tsx | 3 +++ .../lowcoder/src/comps/comps/tableComp/tableTypes.tsx | 5 +++++ client/packages/lowcoder/src/i18n/locales/en.ts | 1 + client/packages/lowcoder/src/i18n/locales/zh.ts | 1 + 4 files changed, 10 insertions(+) diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index 4e08fbfaf..03f6bddb9 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -643,6 +643,9 @@ export function TableCompView(props: { ? COLUMN_CHILDREN_KEY : "OB_CHILDREN_KEY_PLACEHOLDER", fixed: "left", + onExpand: (expanded) => { + if(expanded) handleChangeEvent('rowExpand') + } }} rowColor={compChildren.rowColor.getView() as any} {...compChildren.selection.getView()(onEvent)} diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx index cf05ffac2..5411b57ff 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx @@ -69,6 +69,11 @@ export const TableEventOptions = [ value: "rowClick", description: trans("table.rowClick"), }, + { + label: trans("table.rowExpand"), + value: "rowExpand", + description: trans("table.rowExpand"), + }, { label: trans("table.filterChange"), value: "filterChange", diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index cd946d31b..3094cea01 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1266,6 +1266,7 @@ export const en = { cancelChanges: "Cancel changes", rowSelectChange: "Row select change", rowClick: "Row click", + rowExpand: "Row expand", filterChange: "Filter change", sortChange: "Sort change", pageChange: "Page change", diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts index 6b97f4805..530e33b19 100644 --- a/client/packages/lowcoder/src/i18n/locales/zh.ts +++ b/client/packages/lowcoder/src/i18n/locales/zh.ts @@ -1197,6 +1197,7 @@ table: { cancelChanges: "取消更改", rowSelectChange: "行选中变化", rowClick: "行点击", + rowExpand: "行展开", filterChange: "筛选变化", sortChange: "排序变化", pageChange: "分页变化", From 4eb1c4b5bf4ff42722e28efeaa4a017af3e872a7 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Tue, 21 Nov 2023 21:36:06 +0500 Subject: [PATCH 2/6] fix: table's column width resizable --- .../lowcoder/src/comps/comps/tableComp/tableCompView.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index 03f6bddb9..8418b70a6 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -34,6 +34,7 @@ import { useResizeDetector } from "react-resize-detector"; import { SlotConfigContext } from "comps/controls/slotControl"; import { EmptyContent } from "pages/common/styledComponent"; import { messageInstance } from "lowcoder-design"; +import { ReactRef, ResizeHandleAxis } from "layout/gridLayoutPropTypes"; const TitleResizeHandle = styled.span` position: absolute; @@ -345,8 +346,9 @@ const ResizeableTitle = (props: any) => { }} onResizeStop={onResizeStop} draggableOpts={{ enableUserSelectHack: false }} - handle={() => ( + handle={(axis: ResizeHandleAxis, ref: ReactRef) => ( { e.preventDefault(); e.stopPropagation(); From 0938357802d14daf204232a81a5309a88559ab31 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Wed, 22 Nov 2023 21:51:18 +0500 Subject: [PATCH 3/6] feat: added column styles --- .../comps/comps/tableComp/tableCompView.tsx | 42 ++++++++++++++----- .../comps/tableComp/tablePropertyView.tsx | 3 ++ .../src/comps/comps/tableComp/tableTypes.tsx | 3 +- .../comps/controls/styleControlConstants.tsx | 12 ++++++ 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index 8418b70a6..18e237c78 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -17,6 +17,7 @@ import { defaultTheme, handleToHoverRow, handleToSelectedRow, + TableColumnStyleType, TableStyleType, } from "comps/controls/styleControlConstants"; import { CompNameContext, EditorContext } from "comps/editorState"; @@ -292,19 +293,29 @@ const TableTh = styled.th<{ width?: number }>` ${(props) => props.width && `width: ${props.width}px`}; `; -const TableTd = styled.td<{ background: string; $isEditing: boolean }>` +const TableTd = styled.td<{ + background: string; + columnStyle: TableColumnStyleType; + $isEditing: boolean; +}>` .ant-table-row-expand-icon, .ant-table-row-indent { display: ${(props) => (props.$isEditing ? "none" : "initial")}; } - - ${(props) => - props.background && - ` - background: ${props.background} !important; - `}; + > div > div { + background: ${(props) => props.background}; + color: ${(props) => props.columnStyle.cellText} !important; + border-radius: ${(props) => props.columnStyle.radius}; + border-color: ${(props) => props.columnStyle.border}; + } `; +// ${(props) => +// props.background && +// ` +// background: ${props.background} !important; +// `}; + const ResizeableTitle = (props: any) => { const { onResize, onResizeStop, width, viewModeResizable, ...restProps } = props; const [widthChild, setWidthChild] = useState(0); @@ -365,6 +376,7 @@ type CustomTableProps = Omit, "components" | columns: CustomColumnType[]; viewModeResizable: boolean; rowColor: RowColorViewType; + columnStyle: TableColumnStyleType; }; function TableCellView(props: { @@ -373,8 +385,10 @@ function TableCellView(props: { rowColor: RowColorViewType; rowIndex: number; children: any; + columnStyle: TableColumnStyleType; }) { - const { record, title, rowIndex, rowColor, children, ...restProps } = props; + const { record, title, rowIndex, rowColor, children, columnStyle, ...restProps } = props; + console.log(columnStyle) const [editing, setEditing] = useState(false); const rowContext = useContext(TableRowContext); let tdView; @@ -387,7 +401,7 @@ function TableCellView(props: { currentOriginalIndex: record[OB_ROW_ORI_INDEX], columnTitle: title, }); - let background = ""; + let { background } = columnStyle; if (color) { background = genLinerGradient(color); } @@ -398,7 +412,12 @@ function TableCellView(props: { background = genLinerGradient(handleToHoverRow(color)) + "," + background; } tdView = ( - + {children} ); @@ -466,6 +485,7 @@ function ResizeableTable(props: CustomTableProps ({ width: resizeWidth, @@ -533,6 +553,7 @@ export function TableCompView(props: { const changeSet = useMemo(() => compChildren.columns.getChangeSet(), [compChildren.columns]); const hasChange = useMemo(() => !_.isEmpty(changeSet), [changeSet]); const columns = useMemo(() => compChildren.columns.getView(), [compChildren.columns]); + const columnStyle = useMemo(() => compChildren.columnStyle.getView(), [compChildren.columnStyle]); const columnViews = useMemo(() => columns.map((c) => c.getView()), [columns]); const data = comp.filterData; const sort = useMemo(() => compChildren.sort.getView(), [compChildren.sort]); @@ -657,6 +678,7 @@ export function TableCompView(props: { }} showHeader={!compChildren.hideHeader.getView()} columns={antdColumns} + columnStyle={columnStyle} viewModeResizable={compChildren.viewModeResizable.getView()} dataSource={pageDataInfo.data} size={compChildren.size.getView()} diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx index 49d6ad7d0..a771a7f41 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx @@ -463,6 +463,9 @@ export function compTablePropertyView label: trans("table.hideBordered"), })} +
+ {comp.children.columnStyle.getPropertyView()} +
); } diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx index 5411b57ff..a865d482e 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx @@ -10,7 +10,7 @@ import { import { dropdownControl } from "comps/controls/dropdownControl"; import { eventHandlerControl } from "comps/controls/eventHandlerControl"; import { styleControl } from "comps/controls/styleControl"; -import { TableStyle } from "comps/controls/styleControlConstants"; +import { TableColumnStyle, TableStyle } from "comps/controls/styleControlConstants"; import { MultiCompBuilder, stateComp, @@ -143,6 +143,7 @@ const tableChildrenMap = { sort: valueComp>([]), toolbar: TableToolbarComp, style: styleControl(TableStyle), + columnStyle: styleControl(TableColumnStyle), viewModeResizable: BoolControl, // sample data for regenerating columns dataRowExample: stateComp(null), diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index 58b706771..63c70e65f 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx @@ -694,6 +694,17 @@ export const TableStyle = [ }, ] as const; +export const TableColumnStyle = [ + ...BG_STATIC_BORDER_RADIUS, + { + name: "cellText", + label: trans("style.tableCellText"), + depName: "background", + depType: DEP_TYPE.CONTRAST_TEXT, + transformer: contrastText, + } +] as const; + export const FileStyle = [...getStaticBgBorderRadiusByBg(SURFACE_COLOR), TEXT, ACCENT, MARGIN, PADDING] as const; export const FileViewerStyle = [ @@ -1001,6 +1012,7 @@ export type CheckboxStyleType = StyleConfigType; export type RadioStyleType = StyleConfigType; export type SegmentStyleType = StyleConfigType; export type TableStyleType = StyleConfigType; +export type TableColumnStyleType = StyleConfigType; export type FileStyleType = StyleConfigType; export type FileViewerStyleType = StyleConfigType; export type IframeStyleType = StyleConfigType; From 382f5644928813993bf9d4ac3af7ea06cf08dc48 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Sat, 25 Nov 2023 00:00:09 +0500 Subject: [PATCH 4/6] feat: allow table column styling --- .../tableComp/column/tableColumnComp.tsx | 75 ++++++- .../comps/comps/tableComp/tableCompView.tsx | 191 +++++++++--------- .../comps/tableComp/tablePropertyView.tsx | 11 +- .../src/comps/comps/tableComp/tableTypes.tsx | 5 +- .../src/comps/comps/tableComp/tableUtils.tsx | 13 +- .../comps/controls/styleControlConstants.tsx | 64 +++--- .../packages/lowcoder/src/i18n/locales/en.ts | 8 +- .../packages/lowcoder/src/i18n/locales/zh.ts | 7 +- 8 files changed, 235 insertions(+), 139 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx index 0e2ec9639..7172749e2 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx @@ -1,7 +1,7 @@ import { BoolControl } from "comps/controls/boolControl"; -import { NumberControl, StringControl } from "comps/controls/codeControl"; +import { ColorOrBoolCodeControl, NumberControl, RadiusControl, StringControl } from "comps/controls/codeControl"; import { dropdownControl, HorizontalAlignmentControl } from "comps/controls/dropdownControl"; -import { MultiCompBuilder, stateComp, valueComp } from "comps/generators"; +import { MultiCompBuilder, stateComp, valueComp, withContext, withDefault } from "comps/generators"; import { withSelectedMultiContext } from "comps/generators/withSelectedMultiContext"; import { genRandomKey } from "comps/utils/idGenerator"; import { trans } from "i18n"; @@ -9,6 +9,8 @@ import _ from "lodash"; import { changeChildAction, changeValueAction, + CompAction, + CompActionTypes, ConstructorToComp, ConstructorToDataType, ConstructorToNodeType, @@ -19,8 +21,10 @@ import { withFunction, wrapChildAction, } from "lowcoder-core"; -import { AlignClose, AlignLeft, AlignRight } from "lowcoder-design"; +import { AlignClose, AlignLeft, AlignRight, controlItem } from "lowcoder-design"; import { ColumnTypeComp, ColumnTypeCompMap } from "./columnTypeComp"; +import { ColorControl } from "comps/controls/colorControl"; +import { JSONValue } from "util/jsonTypes"; export type Render = ReturnType["getOriginalComp"]>; export const RenderComp = withSelectedMultiContext(ColumnTypeComp); @@ -51,6 +55,31 @@ const columnFixOptions = [ }, ] as const; +const cellColorLabel = trans("table.cellColor"); +const CellColorTempComp = withContext( + new MultiCompBuilder({ color: ColorOrBoolCodeControl }, (props) => props.color) + .setPropertyViewFn((children) => + children.color.propertyView({ + label: cellColorLabel, + tooltip: trans("table.cellColorDesc"), + }) + ) + .build(), + ["currentCell"] as const +); + +// @ts-ignore +export class CellColorComp extends CellColorTempComp { + override getPropertyView() { + return controlItem({ filterText: cellColorLabel }, super.getPropertyView()); + } +} + +// fixme, should be infer from RowColorComp, but withContext type incorrect +export type CellColorViewType = (param: { + currentCell: JSONValue | undefined; //number | string; +}) => string; + export const columnChildrenMap = { // column title title: StringControl, @@ -67,6 +96,11 @@ export const columnChildrenMap = { tempHide: stateComp(false), fixed: dropdownControl(columnFixOptions, "close"), editable: BoolControl, + background: withDefault(ColorControl, ""), + text: withDefault(ColorControl, ""), + border: withDefault(ColorControl, ""), + radius: withDefault(RadiusControl, ""), + cellColor: CellColorComp, }; /** @@ -90,6 +124,21 @@ const ColumnInitComp = new MultiCompBuilder(columnChildrenMap, (props, dispatch) .build(); export class ColumnComp extends ColumnInitComp { + override reduce(action: CompAction) { + let comp = super.reduce(action); + if (action.type === CompActionTypes.UPDATE_NODES_V2) { + comp = comp.setChild( + "cellColor", + comp.children.cellColor.reduce( + CellColorComp.changeContextDataAction({ + currentCell: undefined, + }) + ) + ); + } + return comp; + } + override getView() { const superView = super.getView(); const columnType = this.children.render.getSelectedComp().getComp().children.compType.getView(); @@ -143,6 +192,26 @@ export class ColumnComp extends ColumnInitComp { })} {this.children.autoWidth.getView() === "fixed" && this.children.width.propertyView({ label: trans("prop.width") })} + {controlItem({}, ( +
+ {"Style"} +
+ ))} + {this.children.background.propertyView({ + label: trans('style.background'), + })} + {this.children.text.propertyView({ + label: trans('text'), + })} + {this.children.border.propertyView({ + label: trans('style.border') + })} + {this.children.radius.propertyView({ + label: trans('style.borderRadius'), + // preInputNode: , + placeholder: '3px', + })} + {this.children.cellColor.getPropertyView()} ); } diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index 18e237c78..a6ba6dc04 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -18,6 +18,7 @@ import { handleToHoverRow, handleToSelectedRow, TableColumnStyleType, + TableRowStyleType, TableStyleType, } from "comps/controls/styleControlConstants"; import { CompNameContext, EditorContext } from "comps/editorState"; @@ -36,6 +37,7 @@ import { SlotConfigContext } from "comps/controls/slotControl"; import { EmptyContent } from "pages/common/styledComponent"; import { messageInstance } from "lowcoder-design"; import { ReactRef, ResizeHandleAxis } from "layout/gridLayoutPropTypes"; +import { CellColorViewType } from "./column/tableColumnComp"; const TitleResizeHandle = styled.span` position: absolute; @@ -51,12 +53,15 @@ function genLinerGradient(color: string) { return `linear-gradient(${color}, ${color})`; } -const getStyle = (style: TableStyleType) => { +const getStyle = ( + style: TableStyleType, + rowStyle: TableRowStyleType, +) => { const background = genLinerGradient(style.background); - const selectedRowBackground = genLinerGradient(style.selectedRowBackground); - const hoverRowBackground = genLinerGradient(style.hoverRowBackground); - const alternateBackground = genLinerGradient(style.alternateBackground); - const isDark = isDarkColor(style.background); + const selectedRowBackground = genLinerGradient(rowStyle.selectedRowBackground); + const hoverRowBackground = genLinerGradient(rowStyle.hoverRowBackground); + const alternateBackground = genLinerGradient(rowStyle.alternateBackground); + return css` border-color: ${style.border}; border-radius: ${style.radius}; @@ -74,6 +79,7 @@ const getStyle = (style: TableStyleType) => { > .ant-table-thead { > tr > th { background-color: ${style.headerBackground}; + border-color: ${style.border}; color: ${style.headerText}; &.ant-table-column-has-sorters:hover { @@ -90,30 +96,7 @@ const getStyle = (style: TableStyleType) => { > tr:nth-of-type(2n + 1) { &, > td { - background: ${background}; - color: ${style.cellText}; - // Column type view and edit color - > div > div { - &, - > .ant-badge > .ant-badge-status-text, - > div > .markdown-body { - color: ${style.cellText}; - } - - > div > svg g { - stroke: ${style.cellText}; - } - - // dark link|links color - > a, - > div > a { - color: ${isDark && "#A6FFFF"}; - - &:hover { - color: ${isDark && "#2EE6E6"}; - } - } - } + background: ${genLinerGradient(rowStyle.background)}; } } @@ -121,52 +104,29 @@ const getStyle = (style: TableStyleType) => { &, > td { background: ${alternateBackground}; - color: ${style.cellText}; - // Column type view and edit color - > div > div { - &, - > .ant-badge > .ant-badge-status-text, - > div > .markdown-body { - color: ${style.cellText}; - } - - > div > svg g { - stroke: ${style.cellText}; - } - - // dark link|links color - > a, - > div > a { - color: ${isDark && "#A6FFFF"}; - - &:hover { - color: ${isDark && "#2EE6E6"}; - } - } - } } } // selected row > tr:nth-of-type(2n + 1).ant-table-row-selected { > td { - background: ${selectedRowBackground}, ${background}; + background: ${selectedRowBackground}, ${rowStyle.background} !important; } > td.ant-table-cell-row-hover, &:hover > td { - background: ${hoverRowBackground}, ${selectedRowBackground}, ${background}; + background: ${hoverRowBackground}, ${selectedRowBackground}, ${rowStyle.background} !important; } } > tr:nth-of-type(2n).ant-table-row-selected { > td { - background: ${selectedRowBackground}, ${alternateBackground}; + background: ${selectedRowBackground}, ${alternateBackground} !important; } > td.ant-table-cell-row-hover, &:hover > td { - background: ${hoverRowBackground}, ${selectedRowBackground}, ${alternateBackground}; + background: ${hoverRowBackground}, ${selectedRowBackground}, ${alternateBackground} !important; } } @@ -174,16 +134,20 @@ const getStyle = (style: TableStyleType) => { > tr:nth-of-type(2n + 1) > td.ant-table-cell-row-hover { &, > div:nth-of-type(2) { - background: ${hoverRowBackground}, ${background}; + background: ${hoverRowBackground}, ${rowStyle.background} !important; } } > tr:nth-of-type(2n) > td.ant-table-cell-row-hover { &, > div:nth-of-type(2) { - background: ${hoverRowBackground}, ${alternateBackground}; + background: ${hoverRowBackground}, ${alternateBackground} !important; } } + + > tr.ant-table-expanded-row > td { + background: ${background}; + } } } `; @@ -191,6 +155,7 @@ const getStyle = (style: TableStyleType) => { const TableWrapper = styled.div<{ $style: TableStyleType; + $rowStyle: TableRowStyleType; toolbarPosition: "above" | "below" | "close"; }>` overflow: hidden; @@ -221,8 +186,11 @@ const TableWrapper = styled.div<{ } .ant-table { + background: ${(props) => props.$style.background}; .ant-table-container { border-left: unset; + border-top: none !important; + border-inline-start: none !important; .ant-table-content { // A table expand row contains table @@ -278,7 +246,8 @@ const TableWrapper = styled.div<{ } } - ${(props) => props.$style && getStyle(props.$style)} + ${(props) => + props.$style && getStyle(props.$style, props.$rowStyle)} `; const TableTh = styled.th<{ width?: number }>` @@ -295,27 +264,41 @@ const TableTh = styled.th<{ width?: number }>` const TableTd = styled.td<{ background: string; - columnStyle: TableColumnStyleType; + $style: TableColumnStyleType; $isEditing: boolean; }>` .ant-table-row-expand-icon, .ant-table-row-indent { display: ${(props) => (props.$isEditing ? "none" : "initial")}; } + background: ${(props) => props.background} !important; + border-color: ${(props) => props.$style.border} !important; + border-radius: ${(props) => props.$style.radius}; + > div > div { - background: ${(props) => props.background}; - color: ${(props) => props.columnStyle.cellText} !important; - border-radius: ${(props) => props.columnStyle.radius}; - border-color: ${(props) => props.columnStyle.border}; + color: ${(props) => props.$style.text}; + &, + > .ant-badge > .ant-badge-status-text, + > div > .markdown-body { + color: ${(props) => props.$style.text}; + } + + > div > svg g { + stroke: ${(props) => props.$style.text}; + } + + // dark link|links color + > a, + > div > a { + color: ${(props) => isDarkColor(props.background) && "#A6FFFF"}; + + &:hover { + color: ${(props) => isDarkColor(props.background) && "#2EE6E6"}; + } + } } `; -// ${(props) => -// props.background && -// ` -// background: ${props.background} !important; -// `}; - const ResizeableTitle = (props: any) => { const { onResize, onResizeStop, width, viewModeResizable, ...restProps } = props; const [widthChild, setWidthChild] = useState(0); @@ -375,47 +358,65 @@ const ResizeableTitle = (props: any) => { type CustomTableProps = Omit, "components" | "columns"> & { columns: CustomColumnType[]; viewModeResizable: boolean; - rowColor: RowColorViewType; - columnStyle: TableColumnStyleType; + rowColorFn: RowColorViewType; + columnsStyle: TableColumnStyleType; }; function TableCellView(props: { record: RecordType; title: string; - rowColor: RowColorViewType; + rowColorFn: RowColorViewType; + cellColorFn: CellColorViewType; rowIndex: number; children: any; + columnsStyle: TableColumnStyleType; columnStyle: TableColumnStyleType; }) { - const { record, title, rowIndex, rowColor, children, columnStyle, ...restProps } = props; - console.log(columnStyle) + const { + record, + title, + rowIndex, + rowColorFn, + cellColorFn, + children, + columnsStyle, + columnStyle, + ...restProps + } = props; const [editing, setEditing] = useState(false); const rowContext = useContext(TableRowContext); let tdView; if (!record) { tdView = {children}; } else { - const color = rowColor({ + const rowColor = rowColorFn({ currentRow: record, currentIndex: rowIndex, currentOriginalIndex: record[OB_ROW_ORI_INDEX], columnTitle: title, }); - let { background } = columnStyle; - if (color) { - background = genLinerGradient(color); + const cellColor = cellColorFn({ + currentCell: record[title.toLowerCase()], + }); + + const style: TableColumnStyleType = { + background: cellColor || rowColor || columnStyle.background || columnsStyle.background, + text: columnStyle.text || columnsStyle.text, + border: columnStyle.border || columnsStyle.border, + radius: columnStyle.radius || columnsStyle.radius, } - if (color && rowContext.selected) { - background = genLinerGradient(handleToSelectedRow(color)) + "," + background; + let { background } = style; + if (rowContext.selected) { + background = genLinerGradient(handleToSelectedRow(background)) + "," + background; } - if (color && rowContext.hover) { - background = genLinerGradient(handleToHoverRow(color)) + "," + background; + if (rowContext.hover) { + background = genLinerGradient(handleToHoverRow(background)) + "," + background; } tdView = ( {children} @@ -457,7 +458,7 @@ function ResizeableTable(props: CustomTableProps { - const { width, ...restCol } = col; + const { width, style, cellColorFn, ...restCol } = col; const resizeWidth = (resizeData.index === index ? resizeData.width : col.width) ?? 0; let colWidth: number | string = "auto"; let minWidth: number | string = COL_MIN_WIDTH; @@ -483,9 +484,11 @@ function ResizeableTable(props: CustomTableProps ({ record, title: col.titleText, - rowColor: props.rowColor, + rowColorFn: props.rowColorFn, + cellColorFn: cellColorFn, rowIndex: rowIndex, - columnStyle: props.columnStyle, + columnsStyle: props.columnsStyle, + columnStyle: style, }), onHeaderCell: () => ({ width: resizeWidth, @@ -550,10 +553,11 @@ export function TableCompView(props: { const { comp, onDownload, onRefresh } = props; const compChildren = comp.children; const style = compChildren.style.getView(); + const rowStyle = compChildren.rowStyle.getView(); + const columnsStyle = compChildren.columnsStyle.getView(); const changeSet = useMemo(() => compChildren.columns.getChangeSet(), [compChildren.columns]); const hasChange = useMemo(() => !_.isEmpty(changeSet), [changeSet]); const columns = useMemo(() => compChildren.columns.getView(), [compChildren.columns]); - const columnStyle = useMemo(() => compChildren.columnStyle.getView(), [compChildren.columnStyle]); const columnViews = useMemo(() => columns.map((c) => c.getView()), [columns]); const data = comp.filterData; const sort = useMemo(() => compChildren.sort.getView(), [compChildren.sort]); @@ -657,7 +661,12 @@ export function TableCompView(props: { return ( - + {toolbar.position === "above" && toolbarView} expandable={{ @@ -670,7 +679,7 @@ export function TableCompView(props: { if(expanded) handleChangeEvent('rowExpand') } }} - rowColor={compChildren.rowColor.getView() as any} + rowColorFn={compChildren.rowColor.getView() as any} {...compChildren.selection.getView()(onEvent)} bordered={!compChildren.hideBordered.getView()} onChange={(pagination, filters, sorter, extra) => { @@ -678,7 +687,7 @@ export function TableCompView(props: { }} showHeader={!compChildren.hideHeader.getView()} columns={antdColumns} - columnStyle={columnStyle} + columnsStyle={columnsStyle} viewModeResizable={compChildren.viewModeResizable.getView()} dataSource={pageDataInfo.data} size={compChildren.size.getView()} diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx index a771a7f41..199bf1231 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx @@ -449,9 +449,8 @@ export function compTablePropertyView tooltip: trans("table.viewModeResizableTooltip"), })} -
+
{comp.children.style.getPropertyView()} - {comp.children.rowColor.getPropertyView()} {comp.children.size.propertyView({ label: trans("table.tableSize"), radioButton: true, @@ -463,8 +462,12 @@ export function compTablePropertyView label: trans("table.hideBordered"), })}
-
- {comp.children.columnStyle.getPropertyView()} +
+ {comp.children.rowStyle.getPropertyView()} + {comp.children.rowColor.getPropertyView()} +
+
+ {comp.children.columnsStyle.getPropertyView()}
); diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx index a865d482e..e2f4c9acb 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx @@ -10,7 +10,7 @@ import { import { dropdownControl } from "comps/controls/dropdownControl"; import { eventHandlerControl } from "comps/controls/eventHandlerControl"; import { styleControl } from "comps/controls/styleControl"; -import { TableColumnStyle, TableStyle } from "comps/controls/styleControlConstants"; +import { TableColumnStyle, TableRowStyle, TableStyle } from "comps/controls/styleControlConstants"; import { MultiCompBuilder, stateComp, @@ -143,7 +143,8 @@ const tableChildrenMap = { sort: valueComp>([]), toolbar: TableToolbarComp, style: styleControl(TableStyle), - columnStyle: styleControl(TableColumnStyle), + rowStyle: styleControl(TableRowStyle), + columnsStyle: withDefault(styleControl(TableColumnStyle), {radius: '0px'}), viewModeResizable: BoolControl, // sample data for regenerating columns dataRowExample: stateComp(null), diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx index a2b7445d2..da35c761b 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx @@ -7,7 +7,7 @@ import { } from "antd/es/table/interface"; import { SortOrder } from "antd/lib/table/interface"; import { __COLUMN_DISPLAY_VALUE_FN } from "comps/comps/tableComp/column/columnTypeCompBuilder"; -import { RawColumnType, Render } from "comps/comps/tableComp/column/tableColumnComp"; +import { CellColorViewType, RawColumnType, Render } from "comps/comps/tableComp/column/tableColumnComp"; import { TableFilter, tableFilterOperatorMap } from "comps/comps/tableComp/tableToolbarComp"; import { SortValue, TableOnEventView } from "comps/comps/tableComp/tableTypes"; import _ from "lodash"; @@ -17,6 +17,7 @@ import { tryToNumber } from "util/convertUtils"; import { JSONObject, JSONValue } from "util/jsonTypes"; import { StatusType } from "./column/columnTypeComps/columnStatusComp"; import { ColumnListComp, tableDataRowExample } from "./column/tableColumnListComp"; +import { TableColumnStyleType } from "comps/controls/styleControlConstants"; export const COLUMN_CHILDREN_KEY = "children"; export const OB_ROW_ORI_INDEX = "__ob_origin_index"; @@ -173,7 +174,6 @@ export function getOriDisplayData( displayData[col.dataIndex] = colValue; } }); - // console.info("getOriDisplayData. idx: ", idx, " displayData: ", JSON.stringify(displayData)); return displayData; }); } @@ -253,6 +253,8 @@ function renderTitle(props: { title: string; editable: boolean }) { export type CustomColumnType = ColumnType & { onWidthResize?: (width: number) => void; titleText: string; + style: TableColumnStyleType; + cellColorFn: CellColorViewType; }; /** @@ -314,6 +316,13 @@ export function columnsToAntdFormat( align: column.align, width: column.autoWidth === "auto" ? 0 : column.width, fixed: column.fixed === "close" ? false : column.fixed, + style: { + background: column.background, + text: column.text, + border: column.border, + radius: column.radius, + }, + cellColorFn: column.cellColor, onWidthResize: column.onWidthResize, render: (value: any, record: RecordType, index: number) => { return column diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index 63c70e65f..37030c03e 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx @@ -67,7 +67,7 @@ export enum DEP_TYPE { } export function contrastText(color: string, textDark: string, textLight: string) { - return isDarkColor(color) ? textLight : textDark; + return isDarkColor(color) && color !== '#00000000' ? textLight : textDark; } // return similar background color @@ -638,33 +638,6 @@ export const SegmentStyle = [ export const TableStyle = [ ...BG_STATIC_BORDER_RADIUS, - { - name: "cellText", - label: trans("style.tableCellText"), - depName: "background", - depType: DEP_TYPE.CONTRAST_TEXT, - transformer: contrastText, - }, - { - name: "selectedRowBackground", - label: trans("style.selectedRowBackground"), - depName: "background", - depTheme: "primary", - transformer: handleToSelectedRow, - }, - { - name: "hoverRowBackground", - label: trans("style.hoverRowBackground"), - depName: "background", - transformer: handleToHoverRow, - }, - { - name: "alternateBackground", - label: trans("style.alternateRowBackground"), - depName: "background", - depType: DEP_TYPE.SELF, - transformer: toSelf, - }, { name: "headerBackground", label: trans("style.tableHeaderBackground"), @@ -694,15 +667,35 @@ export const TableStyle = [ }, ] as const; -export const TableColumnStyle = [ - ...BG_STATIC_BORDER_RADIUS, +export const TableRowStyle = [ + getBackground(), { - name: "cellText", - label: trans("style.tableCellText"), + name: "selectedRowBackground", + label: trans("style.selectedRowBackground"), depName: "background", - depType: DEP_TYPE.CONTRAST_TEXT, - transformer: contrastText, - } + depTheme: "primary", + transformer: handleToSelectedRow, + }, + { + name: "hoverRowBackground", + label: trans("style.hoverRowBackground"), + depName: "background", + transformer: handleToHoverRow, + }, + { + name: "alternateBackground", + label: trans("style.alternateRowBackground"), + depName: "background", + depType: DEP_TYPE.SELF, + transformer: toSelf, + }, +] as const; + +export const TableColumnStyle = [ + getStaticBackground("#00000000"), + getStaticBorder(), + RADIUS, + TEXT, ] as const; export const FileStyle = [...getStaticBgBorderRadiusByBg(SURFACE_COLOR), TEXT, ACCENT, MARGIN, PADDING] as const; @@ -1012,6 +1005,7 @@ export type CheckboxStyleType = StyleConfigType; export type RadioStyleType = StyleConfigType; export type SegmentStyleType = StyleConfigType; export type TableStyleType = StyleConfigType; +export type TableRowStyleType = StyleConfigType; export type TableColumnStyleType = StyleConfigType; export type FileStyleType = StyleConfigType; export type FileViewerStyleType = StyleConfigType; diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 3094cea01..56f4fa2e3 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -311,6 +311,7 @@ export const en = { style: { resetTooltip: "Reset styles. Delete the input's value to reset an individual field.", + textColor: "Text color", contrastText: "Contrast text color", generated: "Generated", customize: "Customize", @@ -1271,12 +1272,17 @@ export const en = { sortChange: "Sort change", pageChange: "Page change", refresh: "Refresh", - rowColor: "Row color", + rowColor: "Conditional row color", rowColorDesc: "Conditionally set the row color based on the optional variables:\n" + "currentRow, currentOriginalIndex, currentIndex, columnTitle. \n" + "For example:\n" + `'{{ currentRow.id > 3 ? "green" : "red" }}'`, + cellColor: "Conditional cell color", + cellColorDesc: + "Conditionally set the cell color based on the cell value using currentCell:\n" + + "For example:\n" + + `'{{ currentCell == 3 ? "green" : "red" }}'`, saveChangesNotBind: "No event handler configured for saving changes. Please bind at least one event handler before click.", dynamicColumn: "Use dynamic column setting", diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts index 530e33b19..28938fa8b 100644 --- a/client/packages/lowcoder/src/i18n/locales/zh.ts +++ b/client/packages/lowcoder/src/i18n/locales/zh.ts @@ -293,6 +293,7 @@ themeDetail: { }, style: { resetTooltip: "重置样式.删除输入框的值以重置单个字段.", + textColor: "文字颜色", contrastText: "对比文本颜色", generated: "已生成", customize: "自定义", @@ -1202,11 +1203,15 @@ table: { sortChange: "排序变化", pageChange: "分页变化", refresh: "刷新", - rowColor: "行颜色", + rowColor: "条件行颜色", rowColorDesc: "基于可选变量条件设置行颜色:\n" + "currentRow, currentOriginalIndex, currentIndex, columnTitle.\n" + "例如:'{{ currentRow.id > 3 ? \"green\" : \"red\" }}'", + cellColor: "条件单元格颜色", + cellColorDesc: + "使用 currentCell 根据单元格值有条件地设置单元格颜色:\n" + + "例如:'{{ currentCell == 3 ? \"green\" : \"red\" }}'", saveChangesNotBind: "未配置保存更改的事件处理程序.请在点击之前绑定至少一个事件处理程序.", dynamicColumn: "使用动态列设置", From 0f9d2ef3e1cc0070355af173f90ca880eabafd9e Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Sat, 25 Nov 2023 23:44:10 +0500 Subject: [PATCH 5/6] feat: add text-size option in styling --- .../src/icons/icon-text-size.svg | 1 + .../lowcoder-design/src/icons/index.ts | 3 +- .../lowcoder/src/api/commonSettingApi.ts | 4 ++ .../tableComp/column/tableColumnComp.tsx | 15 +++++- .../comps/comps/tableComp/tableCompView.tsx | 2 + .../src/comps/comps/tableComp/tableUtils.tsx | 1 + .../src/comps/controls/styleControl.tsx | 49 ++++++++++++++++--- .../comps/controls/styleControlConstants.tsx | 14 +++++- .../packages/lowcoder/src/i18n/locales/en.ts | 1 + .../packages/lowcoder/src/i18n/locales/zh.ts | 1 + 10 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 client/packages/lowcoder-design/src/icons/icon-text-size.svg diff --git a/client/packages/lowcoder-design/src/icons/icon-text-size.svg b/client/packages/lowcoder-design/src/icons/icon-text-size.svg new file mode 100644 index 000000000..86299a0c9 --- /dev/null +++ b/client/packages/lowcoder-design/src/icons/icon-text-size.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/packages/lowcoder-design/src/icons/index.ts b/client/packages/lowcoder-design/src/icons/index.ts index 4be847768..833e83ded 100644 --- a/client/packages/lowcoder-design/src/icons/index.ts +++ b/client/packages/lowcoder-design/src/icons/index.ts @@ -296,4 +296,5 @@ export { ReactComponent as CommentIcon } from "icons/icon-comment-comp.svg"; export { ReactComponent as MentionIcon } from "icons/icon-mention-comp.svg"; export { ReactComponent as AutoCompleteCompIcon } from "icons/icon-autocomplete-comp.svg"; export { ReactComponent as WidthIcon } from "icons/icon-width.svg"; -export { ReactComponent as ResponsiveLayoutCompIcon } from "icons/icon-responsive-layout-comp.svg"; \ No newline at end of file +export { ReactComponent as ResponsiveLayoutCompIcon } from "icons/icon-responsive-layout-comp.svg"; +export { ReactComponent as TextSizeIcon } from "./icon-text-size.svg"; \ No newline at end of file diff --git a/client/packages/lowcoder/src/api/commonSettingApi.ts b/client/packages/lowcoder/src/api/commonSettingApi.ts index f1e1ac9f4..48a17cc2a 100644 --- a/client/packages/lowcoder/src/api/commonSettingApi.ts +++ b/client/packages/lowcoder/src/api/commonSettingApi.ts @@ -47,6 +47,7 @@ export interface ThemeDetail { margin?: string; padding?: string; gridColumns?: string; //Added By Aqib Mirza + textSize?: string; } export function getThemeDetailName(key: keyof ThemeDetail) { @@ -70,6 +71,8 @@ export function getThemeDetailName(key: keyof ThemeDetail) { //Added By Aqib Mirza case "gridColumns": return trans("themeDetail.gridColumns"); + case "textSize": + return trans("style.textSize"); } return ""; } @@ -84,6 +87,7 @@ export function isThemeColorKey(key: string) { case "margin": case "padding": case "gridColumns": //Added By Aqib Mirza + case "textSize": return true; } return false; diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx index 7172749e2..1ac5f5388 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx @@ -21,10 +21,11 @@ import { withFunction, wrapChildAction, } from "lowcoder-core"; -import { AlignClose, AlignLeft, AlignRight, controlItem } from "lowcoder-design"; +import { AlignClose, AlignLeft, AlignRight, IconRadius, TextSizeIcon, controlItem } from "lowcoder-design"; import { ColumnTypeComp, ColumnTypeCompMap } from "./columnTypeComp"; import { ColorControl } from "comps/controls/colorControl"; import { JSONValue } from "util/jsonTypes"; +import styled from "styled-components"; export type Render = ReturnType["getOriginalComp"]>; export const RenderComp = withSelectedMultiContext(ColumnTypeComp); @@ -100,9 +101,14 @@ export const columnChildrenMap = { text: withDefault(ColorControl, ""), border: withDefault(ColorControl, ""), radius: withDefault(RadiusControl, ""), + textSize: withDefault(RadiusControl, ""), cellColor: CellColorComp, }; +const StyledIcon = styled.span` + margin: 0 4px 0 14px; +`; + /** * export for test. * Put it here temporarily to avoid circular dependencies @@ -208,9 +214,14 @@ export class ColumnComp extends ColumnInitComp { })} {this.children.radius.propertyView({ label: trans('style.borderRadius'), - // preInputNode: , + preInputNode: , placeholder: '3px', })} + {this.children.textSize.propertyView({ + label: trans('style.textSize'), + preInputNode: , + placeholder: '14px', + })} {this.children.cellColor.getPropertyView()} ); diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index a6ba6dc04..c0d2417a5 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -277,6 +277,7 @@ const TableTd = styled.td<{ > div > div { color: ${(props) => props.$style.text}; + font-size: ${(props) => props.$style.textSize}; &, > .ant-badge > .ant-badge-status-text, > div > .markdown-body { @@ -404,6 +405,7 @@ function TableCellView(props: { text: columnStyle.text || columnsStyle.text, border: columnStyle.border || columnsStyle.border, radius: columnStyle.radius || columnsStyle.radius, + textSize: columnStyle.textSize || columnsStyle.textSize, } let { background } = style; if (rowContext.selected) { diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx index da35c761b..2add07a38 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx @@ -321,6 +321,7 @@ export function columnsToAntdFormat( text: column.text, border: column.border, radius: column.radius, + textSize: column.textSize, }, cellColorFn: column.cellColor, onWidthResize: column.onWidthResize, diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx index 42311c187..b2f38be76 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx @@ -6,7 +6,14 @@ import { BackgroundColorContext } from "comps/utils/backgroundColorContext"; import { ThemeContext } from "comps/utils/themeContext"; import { trans } from "i18n"; import _ from "lodash"; -import { controlItem, IconRadius, IconReset, ExpandIcon, CompressIcon, } from "lowcoder-design"; +import { + controlItem, + IconRadius, + IconReset, + ExpandIcon, + CompressIcon, + TextSizeIcon, +} from "lowcoder-design"; import { useContext } from "react"; import styled from "styled-components"; import { useIsMobile } from "util/hooks"; @@ -21,6 +28,7 @@ import { SingleColorConfig, MarginConfig, PaddingConfig, + TextSizeConfig, } from "./styleControlConstants"; function isSimpleColorConfig(config: SingleColorConfig): config is SimpleColorConfig { @@ -35,6 +43,10 @@ function isRadiusConfig(config: SingleColorConfig): config is RadiusConfig { return config.hasOwnProperty("radius"); } +function isTextSizeConfig(config: SingleColorConfig): config is TextSizeConfig { + return config.hasOwnProperty("textSize"); +} + function isMarginConfig(config: SingleColorConfig): config is MarginConfig { return config.hasOwnProperty("margin"); } @@ -56,6 +68,10 @@ function isEmptyRadius(radius: string) { return _.isEmpty(radius); } +function isEmptyTextSize(textSize: string) { + return _.isEmpty(textSize); +} + function isEmptyMargin(margin: string) { return _.isEmpty(margin); } @@ -80,6 +96,10 @@ function calcColors>( if (!isEmptyRadius(props[name]) && isRadiusConfig(config)) { res[name] = props[name]; return; + } + if (!isEmptyTextSize(props[name]) && isTextSizeConfig(config)) { + res[name] = props[name]; + return; } if (!isEmptyMargin(props[name]) && isMarginConfig(config)) { res[name] = props[name]; @@ -103,6 +123,10 @@ function calcColors>( if (isRadiusConfig(config)) { res[name] = themeWithDefault[config.radius]; } + if (isTextSizeConfig(config)) { + // TODO: remove default textSize after added in theme in backend. + res[name] = themeWithDefault[config.textSize] || '14px'; + } if (isMarginConfig(config)) { res[name] = themeWithDefault[config.margin]; } @@ -222,7 +246,9 @@ margin: 0 8px 0 -2px; const PaddingIcon = styled(CompressIcon)` margin: 0 8px 0 -2px; `; - +const StyledTextSizeIcon = styled(TextSizeIcon)` +margin: 0 8px 0 -2px; +`; const ResetIcon = styled(IconReset)` &:hover g g { stroke: #315efb; @@ -236,7 +262,8 @@ export function styleControl(colorConfig const name: Names = config.name; if ( name === "radius" || - name === "cardRadius" + name === "cardRadius" || + name === "textSize" ) { childrenMap[name] = StringControl; } else if (name === "margin" || name === "padding" || name==="containerheaderpadding" || name==="containerfooterpadding" || name==="containerbodypadding") { @@ -323,9 +350,9 @@ export function styleControl(colorConfig return controlItem( { filterText: config.label },
- {name === "radius" || + {(name === "radius" || name === "gap" || - name === "cardRadius" + name === "cardRadius") ? ( children[name] as InstanceType ).propertyView({ @@ -341,10 +368,10 @@ export function styleControl(colorConfig preInputNode: , placeholder: props[name], }) - : name === "padding" || + : (name === "padding" || name === "containerheaderpadding" || name === "containerfooterpadding" || - name === "containerbodypadding" + name === "containerbodypadding") ? ( children[name] as InstanceType ).propertyView({ @@ -352,6 +379,14 @@ export function styleControl(colorConfig preInputNode: , placeholder: props[name], }) + : name === "textSize" + ? ( + children[name] as InstanceType + ).propertyView({ + label: config.label, + preInputNode: , + placeholder: props[name], + }) : children[name].propertyView({ label: config.label, panelDefaultColor: props[name], diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index 37030c03e..e79f2f0b5 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx @@ -17,6 +17,10 @@ export type RadiusConfig = CommonColorConfig & { readonly radius: string; }; +export type TextSizeConfig = CommonColorConfig & { + readonly textSize: string; +}; + export type ContainerHeaderPaddigConfig = CommonColorConfig & { readonly containerheaderpadding: string; }; @@ -42,7 +46,7 @@ export type DepColorConfig = CommonColorConfig & { readonly depType?: DEP_TYPE; transformer: (color: string, ...rest: string[]) => string; }; -export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig; +export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | TextSizeConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig; export const defaultTheme: ThemeDetail = { primary: "#3377FF", @@ -54,6 +58,7 @@ export const defaultTheme: ThemeDetail = { margin: "3px", padding: "3px", gridColumns: "24", + textSize: "14px", }; export const SURFACE_COLOR = "#FFFFFF"; @@ -260,6 +265,12 @@ const PADDING = { padding: "padding", } as const; +const TEXT_SIZE = { + name: "textSize", + label: trans("style.textSize"), + textSize: "textSize", +} as const; + const CONTAINERHEADERPADDING = { name: "containerheaderpadding", label: trans("style.containerheaderpadding"), @@ -696,6 +707,7 @@ export const TableColumnStyle = [ getStaticBorder(), RADIUS, TEXT, + TEXT_SIZE, ] as const; export const FileStyle = [...getStaticBgBorderRadiusByBg(SURFACE_COLOR), TEXT, ACCENT, MARGIN, PADDING] as const; diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 56f4fa2e3..d5a6cbd4a 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -362,6 +362,7 @@ export const en = { containerfooterpadding: "Footer Padding", containerbodypadding: "Body Padding", minWidth: "Minimum Width", + textSize: "Text Size", }, export: { hiddenDesc: "If true, the component is hidden", diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts index 28938fa8b..f923913b6 100644 --- a/client/packages/lowcoder/src/i18n/locales/zh.ts +++ b/client/packages/lowcoder/src/i18n/locales/zh.ts @@ -343,6 +343,7 @@ style: { containerfooterpadding: "下内边距", containerbodypadding: "内边距", minWidth: "最小宽度", + textSize: "字体大小", }, export: { hiddenDesc: "如果为true,则隐藏组件", From b19a0b31614f08bd33ab9072f152d62728cccae8 Mon Sep 17 00:00:00 2001 From: RAHEEL Date: Sun, 26 Nov 2023 00:11:48 +0500 Subject: [PATCH 6/6] feat: add border-width option in styling --- .../tableComp/column/tableColumnComp.tsx | 6 +++++ .../comps/comps/tableComp/tableCompView.tsx | 2 ++ .../src/comps/comps/tableComp/tableUtils.tsx | 1 + .../src/comps/controls/styleControl.tsx | 22 ++++++++++++++++--- .../comps/controls/styleControlConstants.tsx | 13 ++++++++++- .../packages/lowcoder/src/i18n/locales/en.ts | 6 ++--- .../packages/lowcoder/src/i18n/locales/zh.ts | 3 ++- 7 files changed, 45 insertions(+), 8 deletions(-) diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx index 1ac5f5388..3dcca917e 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/column/tableColumnComp.tsx @@ -100,6 +100,7 @@ export const columnChildrenMap = { background: withDefault(ColorControl, ""), text: withDefault(ColorControl, ""), border: withDefault(ColorControl, ""), + borderWidth: withDefault(RadiusControl, ""), radius: withDefault(RadiusControl, ""), textSize: withDefault(RadiusControl, ""), cellColor: CellColorComp, @@ -212,6 +213,11 @@ export class ColumnComp extends ColumnInitComp { {this.children.border.propertyView({ label: trans('style.border') })} + {this.children.borderWidth.propertyView({ + label: trans('style.borderWidth'), + preInputNode: , + placeholder: '1px', + })} {this.children.radius.propertyView({ label: trans('style.borderRadius'), preInputNode: , diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index c0d2417a5..e43e45999 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -273,6 +273,7 @@ const TableTd = styled.td<{ } background: ${(props) => props.background} !important; border-color: ${(props) => props.$style.border} !important; + border-width: ${(props) => props.$style.borderWidth} !important; border-radius: ${(props) => props.$style.radius}; > div > div { @@ -405,6 +406,7 @@ function TableCellView(props: { text: columnStyle.text || columnsStyle.text, border: columnStyle.border || columnsStyle.border, radius: columnStyle.radius || columnsStyle.radius, + borderWidth: columnStyle.borderWidth || columnsStyle.borderWidth, textSize: columnStyle.textSize || columnsStyle.textSize, } let { background } = style; diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx index 2add07a38..e56f05f25 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableUtils.tsx @@ -322,6 +322,7 @@ export function columnsToAntdFormat( border: column.border, radius: column.radius, textSize: column.textSize, + borderWidth: column.borderWidth, }, cellColorFn: column.cellColor, onWidthResize: column.onWidthResize, diff --git a/client/packages/lowcoder/src/comps/controls/styleControl.tsx b/client/packages/lowcoder/src/comps/controls/styleControl.tsx index b2f38be76..278944ac9 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControl.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControl.tsx @@ -29,6 +29,7 @@ import { MarginConfig, PaddingConfig, TextSizeConfig, + BorderWidthConfig, } from "./styleControlConstants"; function isSimpleColorConfig(config: SingleColorConfig): config is SimpleColorConfig { @@ -43,6 +44,10 @@ function isRadiusConfig(config: SingleColorConfig): config is RadiusConfig { return config.hasOwnProperty("radius"); } +function isBorderWidthConfig(config: SingleColorConfig): config is BorderWidthConfig { + return config.hasOwnProperty("borderWidth"); +} + function isTextSizeConfig(config: SingleColorConfig): config is TextSizeConfig { return config.hasOwnProperty("textSize"); } @@ -67,7 +72,9 @@ function isEmptyColor(color: string) { function isEmptyRadius(radius: string) { return _.isEmpty(radius); } - +function isEmptyBorderWidth(borderWidth: string) { + return _.isEmpty(borderWidth); +} function isEmptyTextSize(textSize: string) { return _.isEmpty(textSize); } @@ -97,6 +104,10 @@ function calcColors>( res[name] = props[name]; return; } + if (!isEmptyBorderWidth(props[name]) && isBorderWidthConfig(config)) { + res[name] = props[name]; + return; + } if (!isEmptyTextSize(props[name]) && isTextSizeConfig(config)) { res[name] = props[name]; return; @@ -123,6 +134,9 @@ function calcColors>( if (isRadiusConfig(config)) { res[name] = themeWithDefault[config.radius]; } + if (isBorderWidthConfig(config)) { + res[name] = '1px'; + } if (isTextSizeConfig(config)) { // TODO: remove default textSize after added in theme in backend. res[name] = themeWithDefault[config.textSize] || '14px'; @@ -261,7 +275,8 @@ export function styleControl(colorConfig colorConfigs.map((config) => { const name: Names = config.name; if ( - name === "radius" || + name === "radius" || + name === "borderWidth" || name === "cardRadius" || name === "textSize" ) { @@ -350,7 +365,8 @@ export function styleControl(colorConfig return controlItem( { filterText: config.label },
- {(name === "radius" || + {(name === "radius" || + name === "borderWidth" || name === "gap" || name === "cardRadius") ? ( diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx index e79f2f0b5..f173f7d1f 100644 --- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx +++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx @@ -17,6 +17,10 @@ export type RadiusConfig = CommonColorConfig & { readonly radius: string; }; +export type BorderWidthConfig = CommonColorConfig & { + readonly borderWidth: string; +}; + export type TextSizeConfig = CommonColorConfig & { readonly textSize: string; }; @@ -46,7 +50,7 @@ export type DepColorConfig = CommonColorConfig & { readonly depType?: DEP_TYPE; transformer: (color: string, ...rest: string[]) => string; }; -export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | TextSizeConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig; +export type SingleColorConfig = SimpleColorConfig | DepColorConfig | RadiusConfig | BorderWidthConfig | TextSizeConfig | MarginConfig | PaddingConfig | ContainerHeaderPaddigConfig | ContainerFooterPaddigConfig | ContainerBodyPaddigConfig; export const defaultTheme: ThemeDetail = { primary: "#3377FF", @@ -253,6 +257,12 @@ const RADIUS = { radius: "borderRadius", } as const; +const BORDER_WIDTH = { + name: "borderWidth", + label: trans("style.borderWidth"), + borderWidth: "borderWidth", +} as const; + const MARGIN = { name: "margin", label: trans("style.margin"), @@ -705,6 +715,7 @@ export const TableRowStyle = [ export const TableColumnStyle = [ getStaticBackground("#00000000"), getStaticBorder(), + BORDER_WIDTH, RADIUS, TEXT, TEXT_SIZE, diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index d5a6cbd4a..fa6620863 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -318,9 +318,9 @@ export const en = { staticText: "Static text", accent: "Accent", validate: "Validation message", - border: "Border", + border: "Border color", borderRadius: "Border radius", - borderwidth: "Border width", + borderWidth: "Border width", background: "Background", headerBackground: "Header background", footerBackground: "Footer background", @@ -362,7 +362,7 @@ export const en = { containerfooterpadding: "Footer Padding", containerbodypadding: "Body Padding", minWidth: "Minimum Width", - textSize: "Text Size", + textSize: "Text size", }, export: { hiddenDesc: "If true, the component is hidden", diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts index f923913b6..927c7a05b 100644 --- a/client/packages/lowcoder/src/i18n/locales/zh.ts +++ b/client/packages/lowcoder/src/i18n/locales/zh.ts @@ -300,8 +300,9 @@ style: { staticText: "静态文本", accent: "强调色", validate: "验证消息", - border: "边框", + border: "边框颜色", borderRadius: "边框半径", + borderWidth: "边框宽度", background: "背景", headerBackground: "头部背景", footerBackground: "底部背景",