Skip to content

Commit 8de6657

Browse files
Theme: added preventStyleOverwriting switches in app and component settings + set priority for comp styling
1 parent babfe02 commit 8de6657

File tree

11 files changed

+100
-39
lines changed

11 files changed

+100
-39
lines changed

client/packages/lowcoder/src/api/commonSettingApi.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export interface ThemeType {
3535
id: string;
3636
updateTime: number;
3737
theme: ThemeDetail;
38-
overwriteStyles?: boolean;
3938
}
4039

4140
export interface ThemeDetail {

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ const childrenMap = {
186186
showHeaderInPublic: withDefault(BoolControl, true),
187187
maxWidth: dropdownInputSimpleControl(OPTIONS, USER_DEFINE, "1920"),
188188
themeId: valueComp<string>(DEFAULT_THEMEID),
189+
preventAppStylesOverwriting: withDefault(BoolControl, false),
189190
customShortcuts: CustomShortcutsComp,
190191
disableCollision: valueComp<boolean>(false),
191192
};
@@ -205,6 +206,7 @@ function AppSettingsModal(props: ChildrenInstance) {
205206
icon,
206207
category,
207208
showHeaderInPublic,
209+
preventAppStylesOverwriting,
208210
} = props;
209211
const THEME_OPTIONS = themeList?.map((theme) => ({
210212
label: theme.name,
@@ -300,6 +302,11 @@ function AppSettingsModal(props: ChildrenInstance) {
300302
);
301303
}}
302304
/>
305+
<div style={{ margin: '20px 0'}}>
306+
{preventAppStylesOverwriting.propertyView({
307+
label: trans("prop.preventOverwriting"),
308+
})}
309+
</div>
303310
</DivStyled>
304311
{props.customShortcuts.getPropertyView()}
305312
</SettingsStyled>

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,17 @@ function RootView(props: RootViewProps) {
6565
const appThemeId = comp.children.settings.getView().themeId;
6666
const { orgCommonSettings } = getGlobalSettings();
6767
const themeList = orgCommonSettings?.themeList || [];
68+
const selectedTheme = getCurrentTheme(themeList, appThemeId);
6869

6970
const theme =
7071
previewTheme?.previewTheme ||
71-
getCurrentTheme(themeList, appThemeId)?.theme ||
72+
selectedTheme?.theme ||
7273
localDefaultTheme;
7374

74-
const overwriteStyles = Boolean(getCurrentTheme(themeList, appThemeId)?.overwriteStyles);
75-
75+
const themeId = selectedTheme ? selectedTheme.id : (
76+
previewTheme ? "" : 'default-theme-id'
77+
);
78+
7679
useEffect(() => {
7780
const newEditorState = new EditorState(comp, (changeEditorStateFn) => {
7881
setEditorState((oldState) => (oldState ? changeEditorStateFn(oldState) : undefined));
@@ -92,7 +95,7 @@ function RootView(props: RootViewProps) {
9295
const themeContextValue = useMemo(
9396
() => ({
9497
theme,
95-
overwriteStyles,
98+
themeId,
9699
}),
97100
[theme]
98101
);

client/packages/lowcoder/src/comps/controls/styleControl.tsx

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ import { JSONObject, JSONValue } from "@lowcoder-ee/util/jsonTypes";
8383
import { CompTypeContext } from "../utils/compTypeContext";
8484
import { defaultTheme } from "@lowcoder-ee/constants/themeConstants";
8585
import { CompContext } from "../utils/compContext";
86+
import { EditorContext } from "../editorState";
8687

8788
function isSimpleColorConfig(config: SingleColorConfig): config is SimpleColorConfig {
8889
return config.hasOwnProperty("color");
@@ -358,7 +359,7 @@ function calcColors<ColorMap extends Record<string, string>>(
358359
) {
359360
// let themeWithDefault = (theme || defaultTheme) as unknown as Record<string, string>;
360361
let themeWithDefault = {
361-
...defaultTheme,
362+
// ...defaultTheme,
362363
...(theme || {}),
363364
...(compTheme || {}),
364365
} as unknown as Record<string, string>;
@@ -858,21 +859,32 @@ export function styleControl<T extends readonly SingleColorConfig[]>(
858859
childrenMap as ToConstructor<{ [K in Names<T>]: ColorControl }>,
859860
(props) => {
860861
// const compType = useContext(CompTypeContext);
862+
const editorState = useContext(EditorContext);
861863
const {comp, compType} = useContext(CompContext);
862864
const theme = useContext(ThemeContext);
863865
const bgColor = useContext(BackgroundColorContext);
864-
const { overwriteStyles } = theme || {};
865-
const compTheme = compType
866+
867+
const appSettingsComp = editorState.getAppSettingsComp();
868+
const { preventAppStylesOverwriting } = appSettingsComp.getView();
869+
const { themeId } = theme || {};
870+
const { appliedThemeId, preventStyleOverwriting } = comp?.comp || {};
871+
const appTheme = !preventStyleOverwriting && !preventAppStylesOverwriting
872+
? theme?.theme
873+
: undefined;
874+
const compTheme = compType && !preventStyleOverwriting && !preventAppStylesOverwriting
866875
? {
867-
...(defaultTheme.components?.[compType]?.[styleKey] || {}) as unknown as Record<string, string>,
868876
...(theme?.theme?.components?.[compType]?.[styleKey] || {}) as unknown as Record<string, string>
869877
}
870878
: undefined;
879+
const styleProps = preventStyleOverwriting || preventAppStylesOverwriting || appliedThemeId === themeId
880+
? props as ColorMap
881+
: {} as ColorMap;
882+
871883

872884
return calcColors(
873-
overwriteStyles && !Boolean(comp?.comp?.themeApplied) ? {} as ColorMap : props as ColorMap,
885+
styleProps,
874886
colorConfigs,
875-
theme?.theme,
887+
appTheme,
876888
bgColor,
877889
compTheme as Record<string, string> | undefined,
878890
);

client/packages/lowcoder/src/comps/generators/uiCompBuilder.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,15 @@ import {
2424
} from "./withMethodExposing";
2525
import { Section } from "lowcoder-design";
2626
import { trans } from "i18n";
27+
import { BoolControl } from "../controls/boolControl";
28+
import { valueComp, withDefault } from "./simpleGenerators";
2729

2830
export type NewChildren<ChildrenCompMap extends Record<string, Comp<unknown>>> =
2931
ChildrenCompMap & {
3032
hidden: InstanceType<typeof BoolCodeControl>;
3133
className: InstanceType<typeof StringControl>;
3234
dataTestId: InstanceType<typeof StringControl>;
35+
preventStyleOverwriting: InstanceType<typeof BoolControl>;
3336
};
3437

3538
export function HidableView(props: {
@@ -67,6 +70,7 @@ export function ExtendedPropertyView<
6770
<Section name={trans("prop.component")}>
6871
{props.childrenMap.className?.propertyView({ label: trans("prop.className") })}
6972
{props.childrenMap.dataTestId?.propertyView({ label: trans("prop.dataTestId") })}
73+
{props.childrenMap.preventStyleOverwriting?.propertyView({ label: trans("prop.preventOverwriting") })}
7074
</Section>
7175
</>
7276
);
@@ -81,7 +85,9 @@ export function uiChildren<
8185
...childrenMap,
8286
hidden: BoolCodeControl,
8387
className: StringControl,
84-
dataTestId: StringControl
88+
dataTestId: StringControl,
89+
preventStyleOverwriting: withDefault(BoolControl, false),
90+
appliedThemeId: valueComp<string>(''),
8591
} as any;
8692
}
8793

@@ -149,7 +155,7 @@ export class UICompBuilder<
149155
}
150156

151157
build() {
152-
const reservedProps = ["hidden", "className", "dataTestId"];
158+
const reservedProps = ["hidden", "className", "dataTestId", "preventStyleOverwriting", "appliedThemeId"];
153159
for (const reservedProp of reservedProps) {
154160
if (this.childrenMap.hasOwnProperty(reservedProp)) {
155161
throw new Error(`Property »${reservedProp}« is reserved and must not be implemented in components!`);

client/packages/lowcoder/src/comps/utils/themeContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ import React from "react";
44
export class Theme {
55
readonly theme?: ThemeDetail;
66
readonly previewTheme?: ThemeDetail;
7-
readonly overwriteStyles?: boolean;
7+
readonly themeId?: string;
88
}
99
export const ThemeContext = React.createContext<Theme | undefined>(undefined);

client/packages/lowcoder/src/comps/utils/themeUtil.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ThemeType } from "api/commonSettingApi";
22
import { getLocalThemeId } from "util/localStorageUtil";
33
import { getGlobalSettings } from "./globalSettings";
4-
import { CompAction, multiChangeAction, changeValueAction } from "lowcoder-core";
4+
import { CompAction, multiChangeAction, changeValueAction, deferAction } from "lowcoder-core";
55
import { JSONObject, JSONValue } from "@lowcoder-ee/util/jsonTypes";
66

77
export const DEFAULT_THEMEID = "default";
@@ -27,22 +27,29 @@ export function setInitialCompStyles({
2727
dispatch,
2828
compTheme,
2929
styleProps,
30+
themeId,
3031
}: {
3132
dispatch: (action: CompAction) => void,
3233
compTheme?: JSONObject,
3334
styleProps: Record<string, any>,
35+
themeId?: string,
3436
}) {
3537
const styleKeys = Object.keys(styleProps);
36-
const actions: Record<string, any> = {};
38+
const actions: Record<string, any> = {
39+
appliedThemeId: changeValueAction(themeId || '', true),
40+
};
3741
styleKeys.forEach(styleKey => {
3842
actions[styleKey] = changeValueAction({
3943
...(compTheme?.[styleKey] as object || {}),
4044
...styleProps[styleKey],
41-
}, false);
45+
}, true);
4246
})
43-
actions['themeApplied'] = changeValueAction(true, false);
4447

45-
dispatch(
46-
multiChangeAction(actions),
47-
);
48+
setTimeout(() => {
49+
dispatch(
50+
deferAction(
51+
multiChangeAction(actions),
52+
)
53+
);
54+
}, 1000)
4855
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ export const en = {
216216
"component": "Own Component Identifiers",
217217
"className": "CSS Class name",
218218
"dataTestId": "Individual ID",
219+
"preventOverwriting": "Prevent overwriting styles",
219220
},
220221
"autoHeightProp": {
221222
"auto": "Auto",

client/packages/lowcoder/src/layout/gridLayout.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,10 +444,13 @@ class GridLayout extends React.Component<GridLayoutProps, GridLayoutState> {
444444
const selectable = isSelectable;
445445
const positionParams = genPositionParams(this.props);
446446
return (
447-
<CompContext.Provider value={{
448-
compType: extraItem?.compType,
449-
comp: extraItem?.comp?.toJsonValue(),
450-
}}>
447+
<CompContext.Provider
448+
key={item.i}
449+
value={{
450+
compType: extraItem?.compType,
451+
comp: extraItem?.comp?.toJsonValue(),
452+
}}
453+
>
451454
<CompTypeContext.Provider value={extraItem?.compType}>
452455
<GridItem
453456
compType={extraItem?.compType}

client/packages/lowcoder/src/pages/editor/right/styledComponent.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const NoShake = css`
1111
transform-style: preserve-3d;
1212
`;
1313

14-
export const CompIconDiv = styled.div<{ $h: number; $w: number }>`
14+
export const CompIconDiv = styled.div<{ $h: number; $w: number, $isSelected?: boolean }>`
1515
${NoShake};
1616
padding: 3px;
1717
background: #ffffff;
@@ -39,6 +39,17 @@ export const CompIconDiv = styled.div<{ $h: number; $w: number }>`
3939
transform-style: preserve-3d;
4040
backface-visibility: hidden;
4141
}
42+
43+
${(props) => props.$isSelected && `
44+
${NoShake};
45+
padding: 0;
46+
transform: scale(1.05);
47+
transition: all 0.2s ease;
48+
border: 2px solid #b3c4ff;
49+
box-shadow: 0 0 5px 0 rgba(51, 119, 255, 0.15);
50+
transform-style: preserve-3d;
51+
backface-visibility: hidden;
52+
`}
4253
`;
4354

4455
export const RightPanelContentWrapper = styled.div`

client/packages/lowcoder/src/pages/setting/theme/ThemeCompPanel.tsx

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
EmptyCompContent,
1212
RightPanelContentWrapper,
1313
} from "pages/editor/right/styledComponent";
14-
import { tableDragClassName } from "pages/tutorials/tutorialsConstant";
1514
import React, { Fragment, useEffect, useMemo, useState } from "react";
1615
import styled from "styled-components";
1716
import {
@@ -68,12 +67,21 @@ const HovDiv = styled.div`
6867
&:hover + ${CompNameLabel} {
6968
color: #315efb;
7069
}
70+
71+
&.selected + ${CompNameLabel} {
72+
font-weight: 500;
73+
color: #315efb;
74+
}
7175
`;
7276

73-
const IconContain = (props: { Icon: React.FunctionComponent<React.SVGProps<SVGSVGElement>> }) => {
74-
const { Icon } = props;
77+
const IconContain = (props: {
78+
Icon: React.FunctionComponent<React.SVGProps<SVGSVGElement>>,
79+
isSelected: boolean,
80+
}) => {
81+
const { Icon, isSelected } = props;
82+
console.log(isSelected);
7583
return (
76-
<CompIconDiv $w={64} $h={64}>
84+
<CompIconDiv $w={64} $h={64} $isSelected={isSelected}>
7785
<Icon />
7886
</CompIconDiv>
7987
);
@@ -85,6 +93,7 @@ const InsertContain = styled.div`
8593
padding: 4px 0 0 0;
8694
box-sizing: border-box;
8795
gap: 8px;
96+
margin: 0 1px;
8897
`;
8998

9099
const SectionWrapper = styled.div`
@@ -218,11 +227,11 @@ export const ThemeCompPanel = (props: any) => {
218227
layout: {
219228
[compKey]: {
220229
...compInfo.layoutInfo,
221-
w: (compInfo?.layoutInfo?.w || 5) * 1.5,
230+
w: (compInfo?.layoutInfo?.w || 5) * 2,
222231
h: (compInfo?.layoutInfo?.h || 5),
223232
i: compKey,
224-
x: 2,
225-
y: 2,
233+
x: 1,
234+
y: 1,
226235
}
227236
}
228237
}
@@ -256,9 +265,9 @@ export const ThemeCompPanel = (props: any) => {
256265
>
257266
<InsertContain>
258267
{infos.map((info) => (
259-
<CompDiv key={info[0]} className={info[0] === "table" ? tableDragClassName : ""} onClick={() => onCompSelect(info)}>
260-
<HovDiv>
261-
<IconContain Icon={info[1].icon}></IconContain>
268+
<CompDiv key={info[0]} onClick={() => onCompSelect(info)}>
269+
<HovDiv className={info[0] === selectedComp ? 'selected' : ''}>
270+
<IconContain isSelected={info[0] === selectedComp} Icon={info[1].icon}></IconContain>
262271
</HovDiv>
263272
<CompNameLabel>{info[1].name}</CompNameLabel>
264273
{language !== "en" && <CompEnNameLabel>{info[1].enName}</CompEnNameLabel>}
@@ -270,7 +279,7 @@ export const ThemeCompPanel = (props: any) => {
270279
);
271280
})
272281
.filter((t) => t != null),
273-
[categories, searchValue]
282+
[categories, searchValue, selectedComp]
274283
);
275284

276285
const stylePropertyView = useMemo(() => {
@@ -322,14 +331,17 @@ export const ThemeCompPanel = (props: any) => {
322331
// )
323332

324333
return (
325-
<Card style={{ marginBottom: "20px", minHeight : "200px" }}>
334+
<Card
335+
style={{ marginBottom: "20px", minHeight : "200px" }}
336+
bodyStyle={{ padding: '24px 14px'}}
337+
>
326338
<Flex style={{
327339
height: "650px",
328340
overflow: "hidden",
329341
gap: "middle",
330342
}}>
331343
<RightPanelContentWrapper style={{
332-
padding: "12px",
344+
padding: "0",
333345
overflow: "auto",
334346
}}>
335347
<Input.Search

0 commit comments

Comments
 (0)