Skip to content

Commit f830bd5

Browse files
authored
Merge pull request #787 from lowcoder-org/feature-horizontal-list
Adding support for horizontal orientation for List Component
2 parents 530533d + 3967225 commit f830bd5

File tree

6 files changed

+66
-30
lines changed

6 files changed

+66
-30
lines changed

client/packages/lowcoder/src/comps/comps/containerComp/containerView.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ export function InnerGrid(props: ViewPropsWithSelect) {
339339
const editorState = useContext(EditorContext);
340340
const { readOnly } = useContext(ExternalEditorContext);
341341

342+
// Falk: TODO: Here we can define the inner grid columns dynamically
342343
//Added By Aqib Mirza
343344
const defaultGrid =
344345
useContext(ThemeContext)?.theme?.gridColumns ||

client/packages/lowcoder/src/comps/comps/listViewComp/listView.tsx

+50-29
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
44
import _ from "lodash";
55
import { ConstructorToView, deferAction } from "lowcoder-core";
66
import { HintPlaceHolder, ScrollBar, pageItemRender } from "lowcoder-design";
7-
import { RefObject, useContext, useEffect, useMemo, useRef } from "react";
7+
import { RefObject, useContext, createContext, useMemo, useRef } from "react";
88
import ReactResizeDetector from "react-resize-detector";
99
import styled from "styled-components";
1010
import { checkIsMobile } from "util/commonUtils";
@@ -40,21 +40,34 @@ const BodyWrapper = styled.div<{ $autoHeight: boolean }>`
4040
height: ${(props) => (props.$autoHeight ? "100%" : "calc(100% - 32px)")};
4141
`;
4242

43-
const FlexWrapper = styled.div`
43+
const FlexWrapper = styled.div`
4444
height: 100%;
4545
display: flex;
4646
align-items: center;
4747
justify-content: center;
48+
flex-wrap: 'wrap'};
4849
`;
4950

50-
const ContainerInListView = (props: ContainerBaseProps) => {
51+
const ListOrientationWrapper = styled.div<{ $isHorizontal: boolean, $autoHeight : boolean }>`
52+
height: ${(props) => (props.$autoHeight ? "auto" : "100%")};
53+
display: flex;
54+
flex-direction: ${(props) => (props.$isHorizontal ? "row" : "column")};
55+
height: 100%;
56+
`;
57+
58+
const MinHorizontalWidthContext = createContext(0);
59+
60+
const ContainerInListView = (props: ContainerBaseProps ) => {
61+
const minHorizontalWidth = useContext(MinHorizontalWidthContext);
5162
return (
52-
<InnerGrid
53-
{...props}
54-
emptyRows={15}
55-
containerPadding={[4, 4]}
56-
hintPlaceholder={HintPlaceHolder}
57-
/>
63+
<div style={{ width: minHorizontalWidth > 0 ? `${minHorizontalWidth}px` : "100%"}}>
64+
<InnerGrid
65+
{...props}
66+
emptyRows={15}
67+
containerPadding={[4, 4]}
68+
hintPlaceholder={HintPlaceHolder}
69+
/>
70+
</div>
5871
);
5972
};
6073

@@ -66,9 +79,10 @@ type ListItemProps = {
6679
scrollContainerRef?: RefObject<HTMLDivElement>;
6780
minHeight?: string;
6881
unMountFn?: () => void;
82+
minHorizontalWidth: number;
6983
};
7084

71-
function ListItem(props: ListItemProps) {
85+
function ListItem({ minHorizontalWidth, ...props }: ListItemProps) {
7286
const { itemIdx, offset, containerProps, autoHeight, scrollContainerRef, minHeight } = props;
7387

7488
// disable the unmount function to save user's state with pagination
@@ -80,23 +94,25 @@ function ListItem(props: ListItemProps) {
8094
// }, []);
8195

8296
return (
83-
<ContainerInListView
84-
layout={containerProps.layout}
85-
items={gridItemCompToGridItems(containerProps.items)}
86-
positionParams={containerProps.positionParams}
87-
// all layout changes should only reflect on the commonContainer
88-
dispatch={itemIdx === offset ? containerProps.dispatch : _.noop}
89-
style={{ height: "100%", backgroundColor: "transparent", flex: "auto" }}
90-
autoHeight={autoHeight}
91-
isDroppable={itemIdx === offset}
92-
isDraggable={itemIdx === offset}
93-
isResizable={itemIdx === offset}
94-
isSelectable={itemIdx === offset}
95-
scrollContainerRef={scrollContainerRef}
96-
overflow={"hidden"}
97-
minHeight={minHeight}
98-
enableGridLines={true}
99-
/>
97+
<MinHorizontalWidthContext.Provider value={minHorizontalWidth}>
98+
<ContainerInListView
99+
layout={containerProps.layout}
100+
items={gridItemCompToGridItems(containerProps.items)}
101+
positionParams={containerProps.positionParams}
102+
// all layout changes should only reflect on the commonContainer
103+
dispatch={itemIdx === offset ? containerProps.dispatch : _.noop}
104+
style={{ height: "100%", backgroundColor: "transparent", flex: "auto"}}
105+
autoHeight={autoHeight}
106+
isDroppable={itemIdx === offset}
107+
isDraggable={itemIdx === offset}
108+
isResizable={itemIdx === offset}
109+
isSelectable={itemIdx === offset}
110+
scrollContainerRef={scrollContainerRef}
111+
overflow={"hidden"}
112+
minHeight={minHeight}
113+
enableGridLines={true}
114+
/>
115+
</MinHorizontalWidthContext.Provider>
100116
);
101117
}
102118

@@ -126,6 +142,8 @@ export function ListView(props: Props) {
126142
);
127143
const autoHeight = useMemo(() => children.autoHeight.getView(), [children.autoHeight]);
128144
const scrollbars = useMemo(() => children.scrollbars.getView(), [children.scrollbars]);
145+
const horizontal = useMemo(() => children.horizontal.getView(), [children.horizontal]);
146+
const minHorizontalWidth = useMemo(() => children.minHorizontalWidth.getView(), [children.minHorizontalWidth]);
129147
const noOfColumns = useMemo(
130148
() => Math.max(1, children.noOfColumns.getView()),
131149
[children.noOfColumns]
@@ -163,7 +181,8 @@ export function ListView(props: Props) {
163181
key={rowIdx}
164182
style={{
165183
height: rowHeight,
166-
// border: "0.5px solid #d9d9d9"
184+
width: 100 / noOfColumns + "%",
185+
minWidth: minHorizontalWidth,
167186
}}
168187
>
169188
<FlexWrapper>
@@ -198,6 +217,7 @@ export function ListView(props: Props) {
198217
scrollContainerRef={ref}
199218
minHeight={minHeight}
200219
unMountFn={unMountFn}
220+
minHorizontalWidth={horizontal ? minHorizontalWidth : 0}
201221
/>
202222
);
203223
})}
@@ -214,10 +234,11 @@ export function ListView(props: Props) {
214234
return (
215235
<BackgroundColorContext.Provider value={style.background}>
216236
<ListViewWrapper $style={style} $paddingWidth={paddingWidth}>
237+
217238
<BodyWrapper ref={ref} $autoHeight={autoHeight}>
218239
<ScrollBar style={{ height: autoHeight ? "auto" : "100%", margin: "0px", padding: "0px" }} hideScrollbar={!scrollbars}>
219240
<>{<ReactResizeDetector onResize={(width?: number, height?: number) => { if (height) setListHeight(height); }} observerOptions={{ box: "border-box" }} >
220-
<div style={{ height: autoHeight ? "auto" : "100%" }}>{renders}</div>
241+
<ListOrientationWrapper $isHorizontal={horizontal} $autoHeight={autoHeight}>{renders}</ListOrientationWrapper>
221242
</ReactResizeDetector>}</>
222243
</ScrollBar>
223244
</BodyWrapper>

client/packages/lowcoder/src/comps/comps/listViewComp/listViewComp.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ const childrenMap = {
5252
showBorder: BoolControl,
5353
pagination: withDefault(PaginationControl, { pageSize: "6" }),
5454
style: styleControl(ListViewStyle),
55+
horizontal: withDefault(BoolControl, false),
56+
minHorizontalWidth: withDefault(NumberControl, 100),
5557
};
5658

5759
const ListViewTmpComp = new UICompBuilder(childrenMap, () => <></>)

client/packages/lowcoder/src/comps/comps/listViewComp/listViewPropertyView.tsx

+9-1
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,19 @@ export function listPropertyView(compType: ListCompType) {
6262
{(useContext(EditorContext).editorModeStatus === "layout" || useContext(EditorContext).editorModeStatus === "both") && (
6363
<><Section name={sectionNames.layout}>
6464
{children.autoHeight.getPropertyView()}
65-
{!children.autoHeight.getView() &&
65+
{(!children.autoHeight.getView() || children.horizontal.getView()) &&
6666
children.scrollbars.propertyView({
6767
label: trans("prop.scrollbar"),
6868
}
6969
)}
70+
{children.horizontal.propertyView({
71+
label: trans("prop.horizontal"),
72+
})}
73+
{children.horizontal.getView() && (
74+
children.minHorizontalWidth.propertyView({
75+
label: trans("prop.minHorizontalWidth"),
76+
})
77+
)}
7078
</Section>
7179
<Section name={sectionNames.style}>
7280
{children.style.getPropertyView()}

client/packages/lowcoder/src/i18n/locales/en.ts

+2
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ export const en = {
209209
"showApp": "Show an App in the content area",
210210
"showAppTooltip": "You can display whole Lowcoder Apps in the content area. Please mind, that for Modules we do not support Inputs, Outputs Events and Methods.",
211211
"baseURL": "Lowcoder API Base URL",
212+
"horizontal": "Horizontal",
213+
"minHorizontalWidth": "Minimum Horizontal Width",
212214
},
213215
"autoHeightProp": {
214216
"auto": "Auto",

client/packages/lowcoder/src/i18n/locales/zh.ts

+2
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ prop: {
203203
"showApp": "在内容区域显示应用程序",
204204
"showAppTooltip": "您可以在内容区域显示整个 Lowcoder 应用程序。请注意,对于模块,我们不支持输入、输出事件和方法。",
205205
"baseURL": "Lowcoder API 基本 URL",
206+
"horizontal": "水平",
207+
"minHorizontalWidth": "最小水平宽度",
206208
},
207209
autoHeightProp: {
208210
auto: "自动",

0 commit comments

Comments
 (0)