Skip to content

Commit 7bbda3a

Browse files
author
FalkWolsky
committed
Introduce a Floating Text Container
1 parent 824cbec commit 7bbda3a

File tree

9 files changed

+384
-6
lines changed

9 files changed

+384
-6
lines changed

client/packages/lowcoder-design/src/components/ScrollBar.tsx

+3-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ export const ScrollBar = ({ height = "100%", className, children, style, scrolla
6868
</ScrollBarWrapper>
6969
) : (
7070
<ScrollBarWrapper className={className}>
71-
{children}
71+
<SimpleBar style={combinedStyle} scrollableNodeProps={scrollableNodeProps} {...otherProps}>
72+
{children}
73+
</SimpleBar>
7274
</ScrollBarWrapper>
7375
);
7476
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
import { BoolCodeControl, StringControl } from "comps/controls/codeControl";
2+
import { stringExposingStateControl } from "comps/controls/codeStateControl";
3+
import { ToDataType } from "comps/generators/multi";
4+
import {
5+
NameConfigHidden,
6+
withExposingConfigs,
7+
} from "comps/generators/withExposing";
8+
import { NameGenerator } from "comps/utils/nameGenerator";
9+
import { hiddenPropertyView } from "comps/utils/propertyUtils";
10+
import { trans } from "i18n";
11+
import { CompParams } from "lowcoder-core";
12+
import { Section, sectionNames } from "lowcoder-design";
13+
import { oldContainerParamsToNew } from "../containerBase";
14+
import { toSimpleContainerData } from "../containerBase/simpleContainerComp";
15+
import {
16+
ContainerChildren,
17+
ContainerCompBuilder,
18+
} from "../triContainerComp/triContainerCompBuilder";
19+
import { TriContainer } from "../triContainerComp/triFloatTextContainer";
20+
import { dropdownControl } from "comps/controls/dropdownControl";
21+
import { withDefault } from "@lowcoder-ee/index.sdk";
22+
23+
const typeOptions = [
24+
{
25+
label: "Markdown",
26+
value: "markdown",
27+
},
28+
{
29+
label: trans("text"),
30+
value: "text",
31+
},
32+
] as const;
33+
34+
const floatOptions = [
35+
{
36+
label: "None",
37+
value: "none",
38+
},
39+
{
40+
label: "Right",
41+
value: "right",
42+
},
43+
{
44+
label: "Left",
45+
value: "left",
46+
},
47+
] as const;
48+
49+
export const ContainerBaseComp = (function () {
50+
const childrenMap = {
51+
disabled: BoolCodeControl,
52+
text: stringExposingStateControl(
53+
"text",
54+
trans("textShow.text", { name: "{{currentUser.name}}" })
55+
),
56+
type: dropdownControl(typeOptions, "markdown"),
57+
float: dropdownControl(floatOptions, "none"),
58+
width: withDefault(StringControl, "60"),
59+
};
60+
return new ContainerCompBuilder(childrenMap, (props, dispatch) => {
61+
return <TriContainer {...props} />;
62+
})
63+
.setPropertyViewFn((children) => {
64+
return (
65+
<>
66+
<Section name={sectionNames.basic}>
67+
{children.type.propertyView({
68+
label: trans("value"),
69+
tooltip: trans("textShow.valueTooltip"),
70+
radioButton: true,
71+
})}
72+
{children.text.propertyView({})}
73+
{children.width.propertyView({
74+
label: trans("container.flowWidth"),
75+
})}
76+
</Section>
77+
<Section name={sectionNames.layout}>
78+
{children.container.getPropertyView()}
79+
{children.float.propertyView({
80+
label: trans("container.floatType"),
81+
tooltip: trans("textShow.valueTooltip"),
82+
radioButton: true,
83+
})}
84+
85+
{hiddenPropertyView(children)}
86+
</Section>
87+
<Section name={sectionNames.style}>
88+
{children.container.stylePropertyView()}
89+
</Section>
90+
</>
91+
);
92+
})
93+
.build();
94+
})();
95+
96+
// Compatible with old data
97+
function convertOldContainerParams(params: CompParams<any>) {
98+
// convert older params to old params
99+
let tempParams = oldContainerParamsToNew(params);
100+
101+
if (tempParams.value) {
102+
const container = tempParams.value.container;
103+
// old params
104+
if (
105+
container &&
106+
(container.hasOwnProperty("layout") || container.hasOwnProperty("items"))
107+
) {
108+
const autoHeight = tempParams.value.autoHeight;
109+
return {
110+
...tempParams,
111+
value: {
112+
container: {
113+
showHeader: false,
114+
body: { 0: { view: container } },
115+
showBody: true,
116+
showFooter: false,
117+
autoHeight: autoHeight,
118+
},
119+
},
120+
};
121+
}
122+
}
123+
return tempParams;
124+
}
125+
126+
class ContainerTmpComp extends ContainerBaseComp {
127+
constructor(params: CompParams<any>) {
128+
super(convertOldContainerParams(params));
129+
}
130+
}
131+
132+
export const ContainerComp = withExposingConfigs(ContainerTmpComp, [
133+
NameConfigHidden,
134+
]);
135+
136+
type ContainerDataType = ToDataType<ContainerChildren<{}>>;
137+
138+
export function defaultContainerData(
139+
compName: string,
140+
nameGenerator: NameGenerator
141+
): ContainerDataType {
142+
return {
143+
container: {
144+
header: toSimpleContainerData([
145+
{
146+
item: {
147+
compType: "text",
148+
name: nameGenerator.genItemName("containerTitle"),
149+
comp: {
150+
text: "### " + trans("container.title"),
151+
},
152+
},
153+
layoutItem: {
154+
i: "",
155+
h: 5,
156+
w: 24,
157+
x: 0,
158+
y: 0,
159+
},
160+
},
161+
]),
162+
},
163+
};
164+
}

client/packages/lowcoder/src/comps/comps/gridLayoutComp/canvasView.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ import { CanvasContainerID } from "constants/domLocators";
2121
import { CNRootContainer } from "constants/styleSelectors";
2222
import { ScrollBar } from "lowcoder-design";
2323

24+
// min-height: 100vh;
25+
2426
const UICompContainer = styled.div<{ $maxWidth?: number; readOnly?: boolean; $bgColor: string }>`
2527
height: 100%;
26-
min-height: 100vh;
2728
margin: 0 auto;
2829
max-width: ${(props) => props.$maxWidth || 1600}px;
2930
background-color: ${(props) => props.$bgColor};
@@ -114,7 +115,7 @@ export function CanvasView(props: ContainerBaseProps) {
114115
$bgColor={bgColor}
115116
>
116117
<div>
117-
{/* <ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}> */}
118+
<ScrollBar style={{ height: "100%", margin: "0px", padding: "0px" }}>
118119
<Profiler id="Panel" onRender={profilerCallback}>
119120
<InnerGrid
120121
containerPadding={rootContainerPadding}
@@ -126,7 +127,7 @@ export function CanvasView(props: ContainerBaseProps) {
126127
radius="0px"
127128
/>
128129
</Profiler>
129-
{/*</ScrollBar> */}
130+
</ScrollBar>
130131
</div>
131132
</UICompContainer>
132133
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import {
2+
ContainerStyleType,
3+
heightCalculator,
4+
widthCalculator,
5+
} from "comps/controls/styleControlConstants";
6+
import { EditorContext } from "comps/editorState";
7+
import { BackgroundColorContext } from "comps/utils/backgroundColorContext";
8+
import { HintPlaceHolder, TacoMarkDown } from "lowcoder-design";
9+
import { ReactNode, useContext } from "react";
10+
import styled, { css } from "styled-components";
11+
import { checkIsMobile } from "util/commonUtils";
12+
import {
13+
gridItemCompToGridItems,
14+
InnerGrid,
15+
} from "../containerComp/containerView";
16+
import { TriContainerViewProps } from "../triContainerComp/triContainerCompBuilder";
17+
18+
const getStyle = (style: ContainerStyleType) => {
19+
return css`
20+
border-color: ${style.border};
21+
border-radius: ${style.radius};
22+
border-width: ${style.borderWidth};
23+
overflow: hidden;
24+
margin: ${style.margin};
25+
padding: ${style.padding};
26+
27+
width: ${widthCalculator(style.margin)};
28+
height: ${heightCalculator(style.margin)};
29+
`;
30+
};
31+
32+
const Wrapper = styled.div<{ $style: ContainerStyleType }>`
33+
display: flex;
34+
flex-flow: column;
35+
height: 100%;
36+
border: 1px solid #d7d9e0;
37+
border-radius: 4px;
38+
${(props) => props.$style && getStyle(props.$style)}
39+
`;
40+
41+
const HeaderInnerGrid = styled(InnerGrid)<{ backgroundColor: string }>`
42+
overflow: visible;
43+
${(props) =>
44+
props.backgroundColor && `background-color: ${props.backgroundColor};`}
45+
border-radius: 0;
46+
`;
47+
48+
const BodyInnerGrid = styled(InnerGrid)<{
49+
showBorder: boolean;
50+
backgroundColor: string;
51+
borderColor: string;
52+
}>`
53+
border-top: ${(props) =>
54+
`${props.showBorder ? 1 : 0}px solid ${props.borderColor}`};
55+
flex: 1;
56+
${(props) =>
57+
props.backgroundColor && `background-color: ${props.backgroundColor};`}
58+
border-radius: 0;
59+
`;
60+
61+
const FooterInnerGrid = styled(InnerGrid)<{
62+
showBorder: boolean;
63+
backgroundColor: string;
64+
borderColor: string;
65+
}>`
66+
border-top: ${(props) =>
67+
`${props.showBorder ? 1 : 0}px solid ${props.borderColor}`};
68+
overflow: visible;
69+
${(props) =>
70+
props.backgroundColor && `background-color: ${props.backgroundColor};`}
71+
border-radius: 0;
72+
`;
73+
74+
export type TriContainerProps = TriContainerViewProps & {
75+
hintPlaceholder?: ReactNode;
76+
text: {
77+
value: string;
78+
};
79+
type: string;
80+
float: string;
81+
width: string;
82+
};
83+
84+
export function TriContainer(props: TriContainerProps) {
85+
const { container, text } = props;
86+
const { showHeader, showFooter } = container;
87+
// When the header and footer are not displayed, the body must be displayed
88+
const showBody = container.showBody || (!showHeader && !showFooter);
89+
90+
const { items: headerItems, ...otherHeaderProps } = container.header;
91+
const { items: bodyItems, ...otherBodyProps } =
92+
container.body["0"].children.view.getView();
93+
const { items: footerItems, ...otherFooterProps } = container.footer;
94+
const { style } = container;
95+
96+
const editorState = useContext(EditorContext);
97+
const maxWidth = editorState.getAppSettings().maxWidth;
98+
const isMobile = checkIsMobile(maxWidth);
99+
const paddingWidth = isMobile ? 7 : 19;
100+
101+
return (
102+
<Wrapper $style={style}>
103+
{showHeader && (
104+
<BackgroundColorContext.Provider
105+
value={container.style.background}
106+
>
107+
<HeaderInnerGrid
108+
{...otherHeaderProps}
109+
items={gridItemCompToGridItems(headerItems)}
110+
autoHeight={true}
111+
emptyRows={5}
112+
minHeight="46px"
113+
containerPadding={[paddingWidth, 3]}
114+
showName={{ bottom: showBody || showFooter ? 20 : 0 }}
115+
backgroundColor={style?.background}
116+
/>
117+
</BackgroundColorContext.Provider>
118+
)}
119+
{showBody && (
120+
<BackgroundColorContext.Provider value={container.style.background}>
121+
<div
122+
style={{
123+
overflowY: "scroll",
124+
background: `${container.style.background}`,
125+
}}
126+
>
127+
<BodyInnerGrid
128+
showBorder={showHeader}
129+
{...otherBodyProps}
130+
items={gridItemCompToGridItems(bodyItems)}
131+
autoHeight={container.autoHeight}
132+
emptyRows={14}
133+
minHeight={showHeader ? "143px" : "142px"}
134+
containerPadding={
135+
(showHeader && showFooter) || showHeader
136+
? [paddingWidth, 11.5]
137+
: [paddingWidth, 11]
138+
}
139+
hintPlaceholder={props.hintPlaceholder ?? HintPlaceHolder}
140+
backgroundColor={style?.background}
141+
borderColor={style?.border}
142+
style={{
143+
float: `${props.float}`,
144+
width: `${props.float === "none" ? "100%" : `${props.width}%`}`,
145+
height: "100%",
146+
}}
147+
/>
148+
<p style={{ textAlign: "justify", margin: "20px 30px" }}>
149+
{props.type === "markdown" ? (
150+
<TacoMarkDown>{text.value}</TacoMarkDown>
151+
) : (
152+
text.value
153+
)}
154+
</p>
155+
</div>
156+
</BackgroundColorContext.Provider>
157+
)}
158+
{showFooter && (
159+
<BackgroundColorContext.Provider
160+
value={container.style.background}
161+
>
162+
<FooterInnerGrid
163+
showBorder={showHeader || showBody}
164+
{...otherFooterProps}
165+
items={gridItemCompToGridItems(footerItems)}
166+
autoHeight={true}
167+
emptyRows={5}
168+
minHeight={showBody ? "47px" : "46px"}
169+
containerPadding={
170+
showBody || showHeader ? [paddingWidth, 3.5] : [paddingWidth, 3]
171+
}
172+
showName={{ top: showHeader || showBody ? 20 : 0 }}
173+
backgroundColor={style?.background}
174+
borderColor={style?.border}
175+
/>
176+
</BackgroundColorContext.Provider>
177+
)}
178+
</Wrapper>
179+
);
180+
}

0 commit comments

Comments
 (0)