Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export default function ThemeSettingsSelector(props: ColorConfigProps) {
};

const gridPaddingInputBlur = (padding: string) => {
let result = 20;
let result = 0;
if (padding !== '') {
result = Number(padding);
}
Expand Down
22 changes: 13 additions & 9 deletions client/packages/lowcoder/src/comps/comps/appSettingsComp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,8 @@ const childrenMap = {
gridColumns: RangeControl.closed(1, 48, 24),
gridRowHeight: RangeControl.closed(4, 100, 8),
gridRowCount: withDefault(NumberControl, DEFAULT_ROW_COUNT),
gridPaddingX: withDefault(NumberControl, 20),
gridPaddingY: withDefault(NumberControl, 20),
gridPaddingX: withDefault(NumberControl, 0),
gridPaddingY: withDefault(NumberControl, 0),
gridBg: ColorControl,
gridBgImage: StringControl,
gridBgImageRepeat: StringControl,
Expand Down Expand Up @@ -342,6 +342,10 @@ function AppGeneralSettingsModal(props: ChildrenInstance) {

function AppCanvasSettingsModal(props: ChildrenInstance) {
const isPublicApp = useSelector(isPublicApplication);
const application = useSelector(currentApplication);
const isAggregation = !!application && isAggregationApp(
AppUILayoutType[application.applicationType]
);
const {
themeList,
defaultTheme,
Expand Down Expand Up @@ -397,7 +401,7 @@ function AppCanvasSettingsModal(props: ChildrenInstance) {
return (
<>
<BaseSection
name={"Theme Settings"}
name={trans("appSetting.themeSettings")}
width={288}
noMargin
style={{
Expand Down Expand Up @@ -454,33 +458,33 @@ function AppCanvasSettingsModal(props: ChildrenInstance) {
}}
>
<DivStyled>
{maxWidth.propertyView({
{!isAggregation && maxWidth.propertyView({
dropdownLabel: trans("appSetting.canvasMaxWidth"),
inputLabel: trans("appSetting.userDefinedMaxWidth"),
inputPlaceholder: trans("appSetting.inputUserDefinedPxValue"),
placement: "bottom",
min: 350,
lastNode: <span>{trans("appSetting.maxWidthTip")}</span>,
})}
{gridColumns.propertyView({
{!isAggregation && gridColumns.propertyView({
label: trans("appSetting.gridColumns"),
placeholder: '24',
})}
{gridRowHeight.propertyView({
{!isAggregation && gridRowHeight.propertyView({
label: trans("appSetting.gridRowHeight"),
placeholder: '8',
})}
{gridRowCount.propertyView({
{!isAggregation && gridRowCount.propertyView({
label: trans("appSetting.gridRowCount"),
placeholder: 'Infinity',
})}
{gridPaddingX.propertyView({
label: trans("appSetting.gridPaddingX"),
placeholder: '20',
placeholder: '0',
})}
{gridPaddingY.propertyView({
label: trans("appSetting.gridPaddingY"),
placeholder: '20',
placeholder: '0',
})}
{gridBg.propertyView({
label: trans("style.background"),
Expand Down
80 changes: 65 additions & 15 deletions client/packages/lowcoder/src/comps/comps/layout/mobileTabLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ import { AppSelectComp } from "comps/comps/layout/appSelectComp";
import { NameAndExposingInfo } from "comps/utils/exposingTypes";
import { ConstructorToComp, ConstructorToDataType } from "lowcoder-core";
import { CanvasContainer } from "comps/comps/gridLayoutComp/canvasView";
import { CanvasContainerID } from "constants/domLocators";
import { PreviewContainerID } from "constants/domLocators";
import { CanvasContainerID, PreviewContainerID } from "constants/domLocators";
import { EditorContainer, EmptyContent } from "pages/common/styledComponent";
import { Layers } from "constants/Layers";
import { ExternalEditorContext } from "util/context/ExternalEditorContext";
import { EditorContext } from "comps/editorState";
import { default as Skeleton } from "antd/es/skeleton";
import { hiddenPropertyView } from "comps/utils/propertyUtils";
import { dropdownControl } from "@lowcoder-ee/comps/controls/dropdownControl";
Expand Down Expand Up @@ -47,6 +47,21 @@ const TabBarItem = React.lazy(() =>
);
const EventOptions = [clickEvent] as const;

/** Mobile nav editor: tab bar uses position:absolute bottom; this root is the containing block */
const MobileNavCanvasRoot = styled(CanvasContainer)`
position: relative;
`;

/** Strip shared EditorContainer defaults (16px padding + scrollbar-gutter: stable) for mobile nav */
const MobileNavEditorContainer = styled(EditorContainer)`
padding: 0;
padding-right: 0;
scrollbar-gutter: auto;
overflow-x: auto;
overflow-y: auto;
background: transparent;
`;

const AppViewContainer = styled.div`
position: absolute;
width: 100%;
Expand Down Expand Up @@ -221,17 +236,17 @@ const TabBarWrapper = styled.div<{
$readOnly: boolean,
$canvasBg: string,
$tabBarHeight: string,
$maxWidth: number,
$verticalAlignment: string;
}>`
box-sizing: border-box;
max-width: inherit;
background: ${(props) => (props.$canvasBg)};
margin: 0 auto;
position: fixed;
position: ${(props) => (props.$readOnly ? "fixed" : "absolute")};
bottom: 0;
left: 0;
right: 0;
width: ${(props) => props.$readOnly ? "100%" : `${props.$maxWidth - 30}px`};
width: 100%;
z-index: ${Layers.tabBar};
padding-bottom: env(safe-area-inset-bottom, 0);

Expand Down Expand Up @@ -389,7 +404,6 @@ function convertTreeData(data: any) {

function TabBarView(props: TabBarProps & {
tabBarHeight: string;
maxWidth: number;
verticalAlignment: string;
showSeparator: boolean;
navIconSize: string;
Expand All @@ -404,7 +418,6 @@ function TabBarView(props: TabBarProps & {
$readOnly={props.readOnly}
$canvasBg={canvasBg}
$tabBarHeight={props.tabBarHeight}
$maxWidth={props.maxWidth}
$verticalAlignment={props.verticalAlignment}
>
<StyledTabBar
Expand Down Expand Up @@ -664,6 +677,36 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
const bgColor = (useContext(ThemeContext)?.theme || defaultTheme).canvas;
const onEvent = comp.children.onEvent.getView();

// Pull app-level Theme / Canvas Settings (managed via the left-sidebar
// "Canvas" pane and shared with normal apps + modules). Mobile nav already
// owns its own maxWidth + grid behaviour, so we only consume the
// background + padding subset here.
const editorState = useContext(EditorContext);
const appSettings = editorState?.getAppSettings();
const canvasBg = appSettings?.gridBg;
const canvasBgImage = appSettings?.gridBgImage;
const canvasBgImageRepeat = appSettings?.gridBgImageRepeat || "no-repeat";
const canvasBgImageSize = appSettings?.gridBgImageSize || "cover";
const canvasBgImagePosition = appSettings?.gridBgImagePosition || "center";
const canvasBgImageOrigin = appSettings?.gridBgImageOrigin || "padding-box";
const canvasPaddingX = appSettings?.gridPaddingX ?? 0;
const canvasPaddingY = appSettings?.gridPaddingY ?? 0;

const canvasBackgroundStyle: React.CSSProperties = {
background: "#FFFFFF",
};
if (canvasBg) {
canvasBackgroundStyle.background = canvasBg;
}
if (canvasBgImage) {
canvasBackgroundStyle.backgroundImage = `url('${canvasBgImage}')`;
canvasBackgroundStyle.backgroundRepeat = canvasBgImageRepeat;
canvasBackgroundStyle.backgroundSize = canvasBgImageSize;
canvasBackgroundStyle.backgroundPosition = canvasBgImagePosition;
canvasBackgroundStyle.backgroundOrigin = canvasBgImageOrigin;
}
const canvasContentPadding = `${canvasPaddingY}px ${canvasPaddingX}px`;

const getContainer = useCallback(() =>
document.querySelector(`#${PreviewContainerID}`) ||
document.querySelector(`#${CanvasContainerID}`) ||
Expand Down Expand Up @@ -702,7 +745,7 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
currentTab.children.app.getView()) || (
<EmptyContent
text={readOnly ? "" : trans("aggregation.emptyTabTooltip")}
style={{ height: "100%", backgroundColor: "white" }}
style={{ height: "100%" }}
/>
);
}
Expand All @@ -712,7 +755,7 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
currentTab.children.action.getView()) || (
<EmptyContent
text={readOnly ? "" : trans("aggregation.emptyTabTooltip")}
style={{ height: "100%", backgroundColor: "white" }}
style={{ height: "100%" }}
/>
)
}, [tabIndex, tabViews, dataOptionType]);
Expand Down Expand Up @@ -769,7 +812,6 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
tabItemActiveStyle={navItemActiveStyle}
tabBarHeight={tabBarHeight}
navIconSize={navIconSize}
maxWidth={maxWidth}
verticalAlignment={verticalAlignment}
showSeparator={showSeparator}
/>
Expand Down Expand Up @@ -870,8 +912,12 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {

if (readOnly) {
return (
<TabLayoutViewContainer maxWidth={maxWidth} tabBarHeight={containerTabBarHeight}>
<AppViewContainer>{appView}</AppViewContainer>
<TabLayoutViewContainer
maxWidth={maxWidth}
tabBarHeight={containerTabBarHeight}
style={canvasBackgroundStyle}
>
<AppViewContainer style={{ padding: canvasContentPadding }}>{appView}</AppViewContainer>
{menuMode === MobileMode.Hamburger ? (
<>
{hamburgerButton}
Expand All @@ -885,8 +931,12 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
}

return (
<CanvasContainer $maxWidth={maxWidth} id={CanvasContainerID}>
<EditorContainer>{appView}</EditorContainer>
<MobileNavCanvasRoot
$maxWidth={maxWidth}
id={CanvasContainerID}
style={canvasBackgroundStyle}
>
<MobileNavEditorContainer style={{ padding: canvasContentPadding }}>{appView}</MobileNavEditorContainer>
{menuMode === MobileMode.Hamburger ? (
<>
{hamburgerButton}
Expand All @@ -895,7 +945,7 @@ MobileTabLayoutTmp = withViewFn(MobileTabLayoutTmp, (comp) => {
) : (
tabBarView
)}
</CanvasContainer>
</MobileNavCanvasRoot>
);
});

Expand Down
47 changes: 44 additions & 3 deletions client/packages/lowcoder/src/comps/comps/layout/navLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import MainContent from "components/layout/MainContent";
import { LayoutMenuItemComp, LayoutMenuItemListComp } from "comps/comps/layout/layoutMenuItemComp";
import { menuPropertyView } from "comps/comps/navComp/components/MenuItemList";
import { registerLayoutMap } from "comps/comps/uiComp";
import { EditorContext } from "comps/editorState";
import { MultiCompBuilder, withDefault, withViewFn } from "comps/generators";
import { withDispatchHook } from "comps/generators/withDispatchHook";
import { NameAndExposingInfo } from "comps/utils/exposingTypes";
Expand All @@ -14,7 +15,7 @@ import { TopHeaderHeight } from "constants/style";
import { Section, controlItem, sectionNames } from "lowcoder-design";
import { trans } from "i18n";
import { EditorContainer, EmptyContent } from "pages/common/styledComponent";
import { useCallback, useEffect, useMemo, useState } from "react";
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
import styled from "styled-components";
import { isUserViewMode, useAppPathParam } from "util/hooks";
import { StringControl, jsonControl } from "comps/controls/codeControl";
Expand Down Expand Up @@ -381,6 +382,21 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
const dataOptionType = comp.children.dataOptionType.getView();
const onEvent = comp.children.onEvent.getView();

// Pull app-level Theme / Canvas Settings (managed via the left-sidebar
// "Canvas" pane and shared with normal apps + modules). For aggregation
// apps the grid sizing fields are intentionally hidden in the settings UI;
// we only consume the background + padding subset here.
const editorState = useContext(EditorContext);
const appSettings = editorState?.getAppSettings();
const canvasBg = appSettings?.gridBg;
const canvasBgImage = appSettings?.gridBgImage;
const canvasBgImageRepeat = appSettings?.gridBgImageRepeat || "no-repeat";
const canvasBgImageSize = appSettings?.gridBgImageSize || "cover";
const canvasBgImagePosition = appSettings?.gridBgImagePosition || "center";
const canvasBgImageOrigin = appSettings?.gridBgImageOrigin || "padding-box";
const canvasPaddingX = appSettings?.gridPaddingX ?? 0;
const canvasPaddingY = appSettings?.gridPaddingY ?? 0;

// filter out hidden. unauthorised items filtered by server
const filterItem = useCallback((item: LayoutMenuItemComp): boolean => {
return !item.children.hidden.getView();
Expand Down Expand Up @@ -685,8 +701,25 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
/>
);

// Build canvas background style (color + optional image), driven by the
// shared app-level Canvas Settings.
const canvasBackgroundStyle: React.CSSProperties = {};
if (canvasBg) {
canvasBackgroundStyle.background = canvasBg;
}
if (canvasBgImage) {
canvasBackgroundStyle.backgroundImage = `url('${canvasBgImage}')`;
canvasBackgroundStyle.backgroundRepeat = canvasBgImageRepeat;
canvasBackgroundStyle.backgroundSize = canvasBgImageSize;
canvasBackgroundStyle.backgroundPosition = canvasBgImagePosition;
canvasBackgroundStyle.backgroundOrigin = canvasBgImageOrigin;
}

let content = (
<Layout style={{ height: isPreview ? undefined : "100vh" }}>
<Layout style={{
height: isPreview ? undefined : "100vh",
...canvasBackgroundStyle,
}}>
{(navPosition === 'top') && (
<Header style={{ display: 'flex', alignItems: 'center', padding: 0 }}>
{ navMenu }
Expand All @@ -697,7 +730,15 @@ NavTmpLayout = withViewFn(NavTmpLayout, (comp) => {
{navMenu}
</StyledSide>
)}
<ViewerMainContent $isPreview={isPreview}>{pageView}</ViewerMainContent>
<ViewerMainContent
$isPreview={isPreview}
style={{
padding: `${canvasPaddingY}px ${canvasPaddingX}px`,
...canvasBackgroundStyle,
}}
>
{pageView}
</ViewerMainContent>
{(navPosition === 'bottom') && (
<Footer style={{ display: 'flex', alignItems: 'center', padding: 0 }}>
{ navMenu }
Expand Down
1 change: 1 addition & 0 deletions client/packages/lowcoder/src/i18n/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3758,6 +3758,7 @@ export const en = {
"inputUserDefinedPxValue": "Please Enter a Custom Pixel Value",
"maxWidthTip": "Max Width Should Be Greater Than or Equal to 350",
"themeSetting": "Applied Style Theme",
"themeSettings": "Theme Settings",
"themeSettingDefault": "Default",
"themeCreate": "Create Theme",
"appTitle": "Title",
Expand Down
17 changes: 9 additions & 8 deletions client/packages/lowcoder/src/pages/editor/editorView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,10 @@ const aggregationSiderItems = [
key: SiderKey.Setting,
icon: <LeftSettingIcon />,
},
{
key: SiderKey.Canvas,
icon: <LeftColorPaletteIcon />,
},
{
key: SiderKey.JS,
icon: <LeftJSSettingIcon />,
Expand Down Expand Up @@ -725,14 +729,11 @@ function EditorView(props: EditorViewProps) {
{menuKey === SiderKey.Canvas && (
<SettingsDiv>
<ScrollBar>
{application &&
!isAggregationApp(
AppUILayoutType[application.applicationType]
) && (
<>
{appSettingsComp.getPropertyView()}
</>
)}
{application && (
<>
{appSettingsComp.getPropertyView()}
</>
)}
</ScrollBar>
</SettingsDiv>
)}
Expand Down
Loading