diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx index a3a14fd0a..b3e00f75a 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableComp.tsx @@ -58,6 +58,10 @@ export class TableImplComp extends TableInitComp implements IContainer { readonly filterData: RecordType[] = []; readonly columnAggrData: ColumnsAggrData = {}; + override autoHeight(): boolean { + return this.children.autoHeight.getView(); + } + private getSlotContainer() { return this.children.expansion.children.slot.getSelectedComp().getComp().children.container; } diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx index e43e45999..ceca6f8ea 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableCompView.tsx @@ -158,7 +158,8 @@ const TableWrapper = styled.div<{ $rowStyle: TableRowStyleType; toolbarPosition: "above" | "below" | "close"; }>` - overflow: hidden; + max-height: 100%; + overflow-y: auto; background: white; border: 1px solid #d7d9e0; @@ -275,6 +276,7 @@ const TableTd = styled.td<{ border-color: ${(props) => props.$style.border} !important; border-width: ${(props) => props.$style.borderWidth} !important; border-radius: ${(props) => props.$style.radius}; + padding: 0 !important; > div > div { color: ${(props) => props.$style.text}; @@ -362,6 +364,9 @@ type CustomTableProps = Omit, "components" | viewModeResizable: boolean; rowColorFn: RowColorViewType; columnsStyle: TableColumnStyleType; + fixedHeader: boolean; + height?: number; + autoHeight?: boolean; }; function TableCellView(props: { @@ -533,7 +538,12 @@ function ResizeableTable(props: CustomTableProps ); } @@ -546,10 +556,10 @@ export function TableCompView(props: { onDownload: (fileName: string) => void; }) { const editorState = useContext(EditorContext); - const { width, ref } = useResizeDetector({ + const { width, height, ref } = useResizeDetector({ refreshMode: "debounce", refreshRate: 600, - handleHeight: false, + handleHeight: true, }); const viewMode = useUserViewMode(); const compName = useContext(CompNameContext); @@ -574,6 +584,7 @@ export function TableCompView(props: { () => compChildren.dynamicColumnConfig.getView(), [compChildren.dynamicColumnConfig] ); + const autoHeight = compChildren.autoHeight.getView(); const columnsAggrData = comp.columnAggrData; const expansion = useMemo(() => compChildren.expansion.getView(), [compChildren.expansion]); const antdColumns = useMemo( @@ -665,8 +676,8 @@ export function TableCompView(props: { return ( +
+
); } diff --git a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx index 199bf1231..f2505ad6a 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tablePropertyView.tsx @@ -429,6 +429,7 @@ export function compTablePropertyView
{columnPropertyView(comp)}
{comp.children.expansion.getPropertyView()} + {comp.children.autoHeight.getPropertyView()} {hiddenPropertyView(comp.children)}
@@ -455,11 +456,15 @@ export function compTablePropertyView label: trans("table.tableSize"), radioButton: true, })} + {comp.children.hideBordered.propertyView({ + label: trans("table.hideBordered"), + })} {comp.children.hideHeader.propertyView({ label: trans("table.hideHeader"), })} - {comp.children.hideBordered.propertyView({ - label: trans("table.hideBordered"), + {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 e2f4c9acb..86770d316 100644 --- a/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx +++ b/client/packages/lowcoder/src/comps/comps/tableComp/tableTypes.tsx @@ -6,6 +6,7 @@ import { BoolCodeControl, ColorOrBoolCodeControl, JSONObjectArrayControl, + RadiusControl, } from "comps/controls/codeControl"; import { dropdownControl } from "comps/controls/dropdownControl"; import { eventHandlerControl } from "comps/controls/eventHandlerControl"; @@ -32,6 +33,7 @@ import { JSONObject } from "util/jsonTypes"; import { ExpansionControl } from "./expansionControl"; import { PaginationControl } from "./paginationControl"; import { SelectionControl } from "./selectionControl"; +import { AutoHeightControl } from "comps/controls/autoHeightControl"; const sizeOptions = [ { @@ -134,6 +136,8 @@ export type RowColorViewType = (param: { const tableChildrenMap = { hideBordered: BoolControl, hideHeader: BoolControl, + fixedHeader: BoolControl, + autoHeight: withDefault(AutoHeightControl, "auto"), data: withIsLoadingMethod(JSONObjectArrayControl), showDataLoadSpinner: withDefault(BoolPureControl, true), columns: ColumnListComp, diff --git a/client/packages/lowcoder/src/comps/hooks/screenInfoComp.tsx b/client/packages/lowcoder/src/comps/hooks/screenInfoComp.tsx index 6d983b265..00d0fceec 100644 --- a/client/packages/lowcoder/src/comps/hooks/screenInfoComp.tsx +++ b/client/packages/lowcoder/src/comps/hooks/screenInfoComp.tsx @@ -40,11 +40,16 @@ function useScreenInfo() { } const getScreenInfo = useCallback(() => { - const { width, height } = window.screen; + const { innerWidth, innerHeight } = window; const deviceType = getDeviceType(); const flags = getFlagsByDeviceType(deviceType); - return { width, height, deviceType, ...flags }; + return { + width: innerWidth, + height: innerHeight, + deviceType, + ...flags + }; }, []) const [screenInfo, setScreenInfo] = useState({}); diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index c0fac1d18..e77320c43 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -1248,6 +1248,8 @@ export const en = { type: "Type", tableSize: "Table size", hideHeader: "Hide table header", + fixedHeader: "Fixed table header", + fixedHeaderTooltip: "Header will be fixed for vertically scrollable table", hideBordered: "Hide column border", deleteColumn: "Delete column", confirmDeleteColumn: "Confirm delete column: ", diff --git a/client/packages/lowcoder/src/i18n/locales/zh.ts b/client/packages/lowcoder/src/i18n/locales/zh.ts index 05c31c38e..60f66ccec 100644 --- a/client/packages/lowcoder/src/i18n/locales/zh.ts +++ b/client/packages/lowcoder/src/i18n/locales/zh.ts @@ -1174,6 +1174,8 @@ table: { type: "类型", tableSize: "表格尺寸", hideHeader: "隐藏表头", + fixedHeader: "固定表头", + fixedHeaderTooltip: "垂直滚动表格的标题将被固定", hideBordered: "隐藏列边框", deleteColumn: "删除列", confirmDeleteColumn: "确认删除列:", diff --git a/client/packages/lowcoder/src/pages/editor/right/uiCompPanel.tsx b/client/packages/lowcoder/src/pages/editor/right/uiCompPanel.tsx index 1b854f7cf..a63b04af0 100644 --- a/client/packages/lowcoder/src/pages/editor/right/uiCompPanel.tsx +++ b/client/packages/lowcoder/src/pages/editor/right/uiCompPanel.tsx @@ -13,7 +13,7 @@ import { RightPanelContentWrapper, } from "pages/editor/right/styledComponent"; import { tableDragClassName } from "pages/tutorials/tutorialsConstant"; -import React, { useContext, useMemo, useState } from "react"; +import React, { useContext, useEffect, useMemo, useState } from "react"; import styled from "styled-components"; import { BaseSection, @@ -99,6 +99,7 @@ Object.keys(uiCompCategoryNames).forEach((cat) => { export const UICompPanel = () => { const { onDrag, searchValue } = useContext(RightContext); const [propertySectionState, setPropertySectionState] = useState(initialState); + const [searchedPropertySectionState, setSearchedPropertySectionState] = useState({}); const categories = useMemo(() => { const cats: Record = Object.fromEntries( @@ -113,11 +114,18 @@ export const UICompPanel = () => { }, []); const propertySectionContextValue = useMemo(() => { + const state = searchValue + ? searchedPropertySectionState + : propertySectionState; + const setStateFn = searchValue + ? setSearchedPropertySectionState + : setPropertySectionState; + return { compName: stateCompName, - state: propertySectionState, + state, toggle: (compName: string, sectionName: string) => { - setPropertySectionState((oldState) => { + setStateFn((oldState) => { const nextSectionState: PropertySectionState = { ...oldState }; const compState = nextSectionState[compName] || {}; compState[sectionName] = compState[sectionName] === false; @@ -126,7 +134,13 @@ export const UICompPanel = () => { }); }, }; - }, [propertySectionState]); + }, [searchValue, propertySectionState, searchedPropertySectionState]); + + useEffect(() => { + if(!searchValue) { + setSearchedPropertySectionState({}) + } + }, [searchValue]) const compList = useMemo( () => @@ -187,7 +201,6 @@ export const UICompPanel = () => { return ( - {/* {compList.length > 0 ? compList : } */}