diff --git a/client/packages/lowcoder-design/src/components/ScrollBar.tsx b/client/packages/lowcoder-design/src/components/ScrollBar.tsx
index cf51ee68b..e4a08601e 100644
--- a/client/packages/lowcoder-design/src/components/ScrollBar.tsx
+++ b/client/packages/lowcoder-design/src/components/ScrollBar.tsx
@@ -56,6 +56,8 @@ interface IProps {
};
$hideplaceholder?: boolean;
hideScrollbar?: boolean;
+ prefixNode?: React.ReactNode;
+ suffixNode?: React.ReactNode;
}
export const ScrollBar = ({
@@ -65,6 +67,8 @@ export const ScrollBar = ({
scrollableNodeProps,
hideScrollbar = false,
$hideplaceholder = false,
+ prefixNode,
+ suffixNode,
...otherProps
}: IProps) => {
const height = style?.height ?? '100%';
@@ -73,12 +77,24 @@ export const ScrollBar = ({
return hideScrollbar ? (
+ {prefixNode}
{children}
+ {suffixNode}
) : (
- {children}
+ {({ scrollableNodeProps, contentNodeProps }) => {
+ return (
+
+ {prefixNode}
+
+ {children}
+
+ {suffixNode}
+
+ );
+ }}
);
diff --git a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
index 40ca4b668..41851324f 100644
--- a/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
+++ b/client/packages/lowcoder/src/comps/comps/selectInputComp/selectCompConstants.tsx
@@ -78,7 +78,9 @@ export const getStyle = (
.ant-select-selection-search {
padding: ${style.padding};
}
- .ant-select-selection-search-input {
+ .ant-select-selection-search-input,
+ .ant-select-selection-item,
+ .ant-select-selection-item .option-label {
font-family:${(style as SelectStyleType).fontFamily} !important;
text-transform:${(style as SelectStyleType).textTransform} !important;
text-decoration:${(style as SelectStyleType).textDecoration} !important;
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
index 95ae17061..5c6ad7c44 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx
@@ -28,7 +28,7 @@ import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
import { PrimaryColor } from "constants/style";
import { trans } from "i18n";
import _ from "lodash";
-import { darkenColor, isDarkColor } from "lowcoder-design";
+import { darkenColor, isDarkColor, ScrollBar } from "lowcoder-design";
import React, { Children, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
import { Resizable } from "react-resizable";
import styled, { css } from "styled-components";
@@ -43,6 +43,7 @@ import { CellColorViewType } from "./column/tableColumnComp";
import { defaultTheme } from "@lowcoder-ee/constants/themeConstants";
import { useMergeCompStyles } from "@lowcoder-ee/util/hooks";
import { childrenToProps } from "@lowcoder-ee/comps/generators/multi";
+import { getVerticalMargin } from "@lowcoder-ee/util/cssUtil";
function genLinerGradient(color: string) {
@@ -141,17 +142,35 @@ const TitleResizeHandle = styled.span`
const BackgroundWrapper = styled.div<{
$style: TableStyleType;
$tableAutoHeight: boolean;
-}>`
+ $showHorizontalScrollbar: boolean;
+ $showVerticalScrollbar: boolean;
+}>`
+ display: flex;
+ flex-direction: column;
background: ${(props) => props.$style.background} !important;
- // border: ${(props) => `${props.$style.border} !important`};
border-radius: ${(props) => props.$style.radius} !important;
- // padding: unset !important;
padding: ${(props) => props.$style.padding} !important;
margin: ${(props) => props.$style.margin} !important;
- overflow: scroll !important;
border-style: ${(props) => props.$style.borderStyle} !important;
border-width: ${(props) => `${props.$style.borderWidth} !important`};
- ${(props) => props.$style}
+ border-color: ${(props) => `${props.$style.border} !important`};
+ height: calc(100% - ${(props) => getVerticalMargin(props.$style.margin.split(' '))});
+ overflow: hidden;
+
+ > div.table-scrollbar-wrapper {
+ height: auto;
+ overflow: auto;
+ ${(props) => !props.$showHorizontalScrollbar && `
+ div.simplebar-horizontal {
+ visibility: hidden !important;
+ }
+ `}
+ ${(props) => !props.$showVerticalScrollbar && `
+ div.simplebar-vertical {
+ visibility: hidden !important;
+ }
+ `}
+ }
`;
// TODO: find a way to limit the calc function for max-height only to first Margin value
@@ -166,8 +185,6 @@ const TableWrapper = styled.div<{
$visibleResizables: boolean;
$showHRowGridBorder?: boolean;
}>`
- overflow: unset !important;
-
.ant-table-wrapper {
border-top: unset;
border-color: inherit;
@@ -193,22 +210,18 @@ const TableWrapper = styled.div<{
}
.ant-table {
- overflow-y:scroll;
background: ${(props) =>props.$style.background};
.ant-table-container {
border-left: unset;
border-top: none !important;
border-inline-start: none !important;
- overflow-y:scroll;
- height:300px
&::after {
box-shadow: none !important;
}
.ant-table-content {
- overflow-y:scroll;
- overflow-x:scroll;
+ overflow: unset !important
}
// A table expand row contains table
@@ -220,6 +233,15 @@ const TableWrapper = styled.div<{
border-top: unset;
> .ant-table-thead {
+ ${(props) =>
+ props.$fixedHeader && `
+ position: sticky;
+ position: -webkit-sticky;
+ // top: ${props.$fixedToolbar ? '47px' : '0'};
+ top: 0;
+ z-index: 99;
+ `
+ }
> tr > th {
background-color: ${(props) => props.$headerStyle.headerBackground};
@@ -227,14 +249,7 @@ const TableWrapper = styled.div<{
border-width: ${(props) => props.$headerStyle.borderWidth};
color: ${(props) => props.$headerStyle.headerText};
// border-inline-end: ${(props) => `${props.$headerStyle.borderWidth} solid ${props.$headerStyle.border}`} !important;
- ${(props) =>
- props.$fixedHeader && `
- position: sticky;
- position: -webkit-sticky;
- top: ${props.$fixedToolbar ? '47px' : '0'};
- z-index: 99;
- `
- }
+
> div {
margin: ${(props) => props.$headerStyle.margin};
@@ -715,6 +730,8 @@ export function TableCompView(props: {
const toolbarStyle = compChildren.toolbarStyle.getView();
const rowAutoHeight = compChildren.rowAutoHeight.getView();
const tableAutoHeight = comp.getTableAutoHeight();
+ const showHorizontalScrollbar = compChildren.showHorizontalScrollbar.getView();
+ const showVerticalScrollbar = compChildren.showVerticalScrollbar.getView();
const visibleResizables = compChildren.visibleResizables.getView();
const showHRowGridBorder = compChildren.showHRowGridBorder.getView();
const columnsStyle = compChildren.columnsStyle.getView();
@@ -832,70 +849,84 @@ export function TableCompView(props: {
return (
-
- {toolbar.position === "above" && toolbarView}
-
+ {toolbar.position === "above" && toolbar.fixedToolbar && toolbarView}
+
-
- expandable={{
- ...expansion.expandableConfig,
- childrenColumnName: supportChildren
- ? COLUMN_CHILDREN_KEY
- : "OB_CHILDREN_KEY_PLACEHOLDER",
- fixed: "left",
- onExpand: (expanded) => {
- if (expanded) {
- handleChangeEvent('rowExpand')
- } else {
- handleChangeEvent('rowShrink')
+
+
+ expandable={{
+ ...expansion.expandableConfig,
+ childrenColumnName: supportChildren
+ ? COLUMN_CHILDREN_KEY
+ : "OB_CHILDREN_KEY_PLACEHOLDER",
+ fixed: "left",
+ onExpand: (expanded) => {
+ if (expanded) {
+ handleChangeEvent('rowExpand')
+ } else {
+ handleChangeEvent('rowShrink')
+ }
}
+ }}
+ rowColorFn={compChildren.rowColor.getView() as any}
+ rowHeightFn={compChildren.rowHeight.getView() as any}
+ {...compChildren.selection.getView()(onEvent)}
+ bordered={compChildren.showRowGridBorder.getView()}
+ onChange={(pagination, filters, sorter, extra) => {
+ onTableChange(pagination, filters, sorter, extra, comp.dispatch, onEvent);
+ }}
+ showHeader={!compChildren.hideHeader.getView()}
+ columns={antdColumns}
+ columnsStyle={columnsStyle}
+ viewModeResizable={compChildren.viewModeResizable.getView()}
+ visibleResizables={compChildren.visibleResizables.getView()}
+ dataSource={pageDataInfo.data}
+ size={compChildren.size.getView()}
+ rowAutoHeight={rowAutoHeight}
+ tableLayout="fixed"
+ loading={
+ loading ||
+ // fixme isLoading type
+ (compChildren.showDataLoadSpinner.getView() &&
+ (compChildren.data as any).isLoading()) ||
+ compChildren.loading.getView()
}
- }}
- rowColorFn={compChildren.rowColor.getView() as any}
- rowHeightFn={compChildren.rowHeight.getView() as any}
- {...compChildren.selection.getView()(onEvent)}
- bordered={compChildren.showRowGridBorder.getView()}
- onChange={(pagination, filters, sorter, extra) => {
- onTableChange(pagination, filters, sorter, extra, comp.dispatch, onEvent);
- }}
- showHeader={!compChildren.hideHeader.getView()}
- columns={antdColumns}
- columnsStyle={columnsStyle}
- viewModeResizable={compChildren.viewModeResizable.getView()}
- visibleResizables={compChildren.visibleResizables.getView()}
- dataSource={pageDataInfo.data}
- size={compChildren.size.getView()}
- rowAutoHeight={rowAutoHeight}
- tableLayout="fixed"
- loading={
- loading ||
- // fixme isLoading type
- (compChildren.showDataLoadSpinner.getView() &&
- (compChildren.data as any).isLoading()) ||
- compChildren.loading.getView()
- }
- onCellClick={(columnName: string, dataIndex: string) => {
- comp.children.selectedCell.dispatchChangeValueAction({
- name: columnName,
- dataIndex: dataIndex,
- });
- }}
- />
-
-
- {expansion.expandModalView}
-
-
- {toolbar.position === "below" && toolbarView}
+ onCellClick={(columnName: string, dataIndex: string) => {
+ comp.children.selectedCell.dispatchChangeValueAction({
+ name: columnName,
+ dataIndex: dataIndex,
+ });
+ }}
+ />
+
+
+ {expansion.expandModalView}
+
+
+
+ {toolbar.position === "below" && toolbar.fixedToolbar && toolbarView}
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx
index f45edf49b..636721c1f 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx
@@ -462,6 +462,12 @@ export function compTablePropertyView
radioButton: true,
})}
{comp.children.autoHeight.getPropertyView()}
+ {comp.children.showHorizontalScrollbar.propertyView({
+ label: trans("prop.showHorizontalScrollbar"),
+ })}
+ {!comp.children.autoHeight.getView() && comp.children.showVerticalScrollbar.propertyView({
+ label: trans("prop.showVerticalScrollbar"),
+ })}
{comp.children.fixedHeader.propertyView({
label: trans("table.fixedHeader"),
tooltip: trans("table.fixedHeaderTooltip")
diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx
index 987f8b1ee..310939f07 100644
--- a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx
+++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx
@@ -197,6 +197,8 @@ const tableChildrenMap = {
hideHeader: BoolControl,
fixedHeader: BoolControl,
autoHeight: withDefault(AutoHeightControl, "auto"),
+ showVerticalScrollbar: BoolControl,
+ showHorizontalScrollbar: BoolControl,
data: withIsLoadingMethod(JSONObjectArrayControl),
showDataLoadSpinner: withDefault(BoolPureControl, true),
columns: ColumnListComp,
diff --git a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
index 37dee183a..c82d6aa58 100644
--- a/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
+++ b/client/packages/lowcoder/src/comps/controls/styleControlConstants.tsx
@@ -1512,7 +1512,6 @@ export const TableHeaderStyle = [
},
TEXT_SIZE,
TEXT_WEIGHT,
- FONT_FAMILY,
] as const;
export const TableRowStyle = [
diff --git a/client/packages/lowcoder/src/i18n/locales/de.ts b/client/packages/lowcoder/src/i18n/locales/de.ts
index 9c4538827..1850c4391 100644
--- a/client/packages/lowcoder/src/i18n/locales/de.ts
+++ b/client/packages/lowcoder/src/i18n/locales/de.ts
@@ -200,6 +200,8 @@ export const de: typeof en = {
"className": "Klasse",
"dataTestId": "Test ID",
"horizontalGridCells": "Horizontale Gitterzellen",
+ "showHorizontalScrollbar": "Horizontale Bildlaufleiste anzeigen",
+ "showVerticalScrollbar": "Vertikale Bildlaufleiste anzeigen",
},
"autoHeightProp": {
...en.autoHeightProp,
diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts
index 08e7c7aa8..768b27c28 100644
--- a/client/packages/lowcoder/src/i18n/locales/en.ts
+++ b/client/packages/lowcoder/src/i18n/locales/en.ts
@@ -220,6 +220,8 @@ export const en = {
"preventOverwriting": "Prevent overwriting styles",
"color": "Color",
"horizontalGridCells": "Horizontal Grid Cells",
+ "showHorizontalScrollbar": "Show Horizontal Scrollbar",
+ "showVerticalScrollbar": "Show Vertical Scrollbar",
},
"autoHeightProp": {
"auto": "Auto",
diff --git a/client/packages/lowcoder/src/i18n/locales/pt.ts b/client/packages/lowcoder/src/i18n/locales/pt.ts
index f8f6c41a9..80a3369b6 100644
--- a/client/packages/lowcoder/src/i18n/locales/pt.ts
+++ b/client/packages/lowcoder/src/i18n/locales/pt.ts
@@ -231,6 +231,8 @@ export const pt: typeof en = {
"className": "Nome da Classe CSS",
"dataTestId": "ID Individual",
"horizontalGridCells": "Células de grade horizontal",
+ "showHorizontalScrollbar": "Mostrar barra de rolagem horizontal",
+ "showVerticalScrollbar": "Mostrar barra de rolagem vertical",
},
"autoHeightProp": {
...en.autoHeightProp,
diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts
index cd54a777a..235409561 100644
--- a/client/packages/lowcoder/src/i18n/locales/zh.ts
+++ b/client/packages/lowcoder/src/i18n/locales/zh.ts
@@ -220,6 +220,8 @@ export const zh: typeof en = {
"horizontal": "水平",
"minHorizontalWidth": "最小水平宽度",
"horizontalGridCells": "水平网格单元",
+ "showHorizontalScrollbar": "显示水平滚动条",
+ "showVerticalScrollbar": "显示垂直滚动条",
},
autoHeightProp: {
diff --git a/client/packages/lowcoder/src/util/cssUtil.tsx b/client/packages/lowcoder/src/util/cssUtil.tsx
new file mode 100644
index 000000000..eb0d5426a
--- /dev/null
+++ b/client/packages/lowcoder/src/util/cssUtil.tsx
@@ -0,0 +1,52 @@
+type Direction = {
+ top: string;
+ right: string;
+ bottom: string;
+ left: string;
+}
+
+export const parseMarginOrPadding = (style: string):Direction => {
+ const styles = style.split(' ');
+ if (styles.length === 1) {
+ return {
+ top: styles[0], right: styles[0], bottom: styles[0], left: styles[0],
+ };
+ }
+ if (styles.length === 2) {
+ return {
+ top: styles[0], right: styles[1], bottom: styles[0], left: styles[1],
+ };
+ }
+ if (styles.length === 3) {
+ return {
+ top: styles[0], right: styles[1], bottom: styles[2], left: styles[1],
+ };
+ }
+ if (styles.length === 4) {
+ return {
+ top: styles[0], right: styles[1], bottom: styles[2], left: styles[3],
+ };
+ }
+ // invalid margin/padding
+ return {
+ top: '0px', right: '0px', bottom: '0px', left: '0px',
+ };
+}
+
+export const getVerticalMargin = (margin: string[]) => {
+ if(margin.length === 1) return `(${margin[0]} + ${margin[0]})`;
+ if(margin.length === 2) return `(${margin[0]} + ${margin[0]})`;
+ if(margin.length === 3 || margin.length === 4)
+ return `(${margin[0]} + ${margin[2]})`;
+
+ return '0px';
+}
+
+export const getHorizontalMargin = (margin: string[]) => {
+ if(margin.length === 1) return `(${margin[0]} + ${margin[0]})`;
+ if(margin.length === 2) return `(${margin[1]} + ${margin[1]})`;
+ if(margin.length === 3 || margin.length === 4)
+ return `(${margin[1]} + ${margin[3]})`;
+
+ return '0px';
+}