diff --git a/app/client/packages/design-system/headless/src/components/Popover/src/types.ts b/app/client/packages/design-system/headless/src/components/Popover/src/types.ts index 214fcac64d..f7e40e1eeb 100644 --- a/app/client/packages/design-system/headless/src/components/Popover/src/types.ts +++ b/app/client/packages/design-system/headless/src/components/Popover/src/types.ts @@ -47,6 +47,10 @@ export interface PopoverProps { triggerRef?: MutableRefObject; /** Which element to initially focus. Can be either a number (tabbable index as specified by the order) or a ref. */ initialFocus?: number | MutableRefObject; + /** Determines whether clickOutside is work or not. + * @default false + */ + dismissClickOutside?: boolean; } export interface PopoverContentProps { diff --git a/app/client/packages/design-system/headless/src/components/Popover/src/usePopover.ts b/app/client/packages/design-system/headless/src/components/Popover/src/usePopover.ts index 8cce903f3d..674ae60427 100644 --- a/app/client/packages/design-system/headless/src/components/Popover/src/usePopover.ts +++ b/app/client/packages/design-system/headless/src/components/Popover/src/usePopover.ts @@ -17,6 +17,7 @@ const DEFAULT_POPOVER_OFFSET = 10; export function usePopover({ defaultOpen = false, + dismissClickOutside = false, duration = 0, initialFocus, isOpen: controlledOpen, @@ -56,7 +57,17 @@ export function usePopover({ const click = useClick(context, { enabled: controlledOpen == null, }); - const dismiss = useDismiss(context); + const dismiss = useDismiss(context, { + escapeKey: !dismissClickOutside, + outsidePress: (event) => { + if (dismissClickOutside) return false; + + // By default, click to close popup only work inside the provider + return Boolean( + (event?.target as HTMLElement).closest("[data-theme-provider]"), + ); + }, + }); const role = useRole(context); const interactions = useInteractions([click, dismiss, role]); diff --git a/app/client/packages/design-system/widgets/src/components/Modal/src/ModalFooter.tsx b/app/client/packages/design-system/widgets/src/components/Modal/src/ModalFooter.tsx index 55d0f45304..020c0df2d2 100644 --- a/app/client/packages/design-system/widgets/src/components/Modal/src/ModalFooter.tsx +++ b/app/client/packages/design-system/widgets/src/components/Modal/src/ModalFooter.tsx @@ -7,7 +7,7 @@ import type { ModalFooterProps } from "./types"; export const ModalFooter = (props: ModalFooterProps) => { const { closeText = "Close", onSubmit, submitText = "Submit" } = props; - const { onClose, setOpen } = usePopoverContext(); + const { setOpen } = usePopoverContext(); const [isLoading, setIsLoading] = useState(false); const handleSubmit = async () => { @@ -19,14 +19,9 @@ export const ModalFooter = (props: ModalFooterProps) => { } }; - const closeHandler = () => { - onClose && onClose(); - setOpen(false); - }; - return ( - diff --git a/app/client/packages/design-system/widgets/src/components/Modal/src/ModalHeader.tsx b/app/client/packages/design-system/widgets/src/components/Modal/src/ModalHeader.tsx index 7f9071493b..2b50fa3e5f 100644 --- a/app/client/packages/design-system/widgets/src/components/Modal/src/ModalHeader.tsx +++ b/app/client/packages/design-system/widgets/src/components/Modal/src/ModalHeader.tsx @@ -10,7 +10,7 @@ import type { ModalHeaderProps } from "./types"; export const ModalHeader = (props: ModalHeaderProps) => { const { title } = props; - const { onClose, setLabelId, setOpen } = usePopoverContext(); + const { setLabelId, setOpen } = usePopoverContext(); const id = useId(); // Only sets `aria-labelledby` on the Dialog root element @@ -20,17 +20,12 @@ export const ModalHeader = (props: ModalHeaderProps) => { return () => setLabelId(undefined); }, [id, setLabelId]); - const closeHandler = () => { - onClose && onClose(); - setOpen(false); - }; - return ( {title} - + setOpen(false)} variant="ghost" /> ); }; diff --git a/app/client/packages/design-system/widgets/src/components/Modal/src/styles.module.css b/app/client/packages/design-system/widgets/src/components/Modal/src/styles.module.css index 2f1ea60afd..b460d819b4 100644 --- a/app/client/packages/design-system/widgets/src/components/Modal/src/styles.module.css +++ b/app/client/packages/design-system/widgets/src/components/Modal/src/styles.module.css @@ -1,18 +1,18 @@ .overlay { - /* Redefining the overlay positioning so that the dialog is centered relative to the provider, not the viewport */ - position: absolute !important; background: var(--color-bg-neutral-opacity); display: grid; place-items: center; z-index: var(--z-index-99); + max-width: var(--provider-width); + margin: 0 auto; } .content { background: var(--color-bg); border-radius: var(--border-radius-1); box-shadow: var(--box-shadow-1); - max-width: calc(100vw - var(--outer-spacing-6)); - max-height: calc(100vh - var(--outer-spacing-6)); + max-width: calc(var(--provider-width) - var(--outer-spacing-8)); + max-height: calc(var(--provider-width) - var(--outer-spacing-8)); outline: none; display: flex; flex-direction: column; @@ -38,7 +38,7 @@ } [data-size="large"] .content { - width: calc(var(--provider-width) - var(--outer-spacing-6)); + width: calc(var(--provider-width) - var(--outer-spacing-8)); height: 100%; } diff --git a/app/client/packages/design-system/widgets/src/components/Modal/src/types.ts b/app/client/packages/design-system/widgets/src/components/Modal/src/types.ts index 7761bfdac1..11277f435e 100644 --- a/app/client/packages/design-system/widgets/src/components/Modal/src/types.ts +++ b/app/client/packages/design-system/widgets/src/components/Modal/src/types.ts @@ -8,7 +8,12 @@ import type { SIZES } from "../../../shared"; export interface ModalProps extends Pick< PopoverProps, - "isOpen" | "setOpen" | "onClose" | "triggerRef" | "initialFocus" + | "isOpen" + | "setOpen" + | "onClose" + | "triggerRef" + | "initialFocus" + | "dismissClickOutside" >, Pick { /** Size of the Modal diff --git a/app/client/src/components/editorComponents/ErrorBoundry.tsx b/app/client/src/components/editorComponents/ErrorBoundry.tsx index 99acb2bff2..9783ddc4ae 100644 --- a/app/client/src/components/editorComponents/ErrorBoundry.tsx +++ b/app/client/src/components/editorComponents/ErrorBoundry.tsx @@ -1,11 +1,13 @@ -import type { ReactNode } from "react"; import React from "react"; import styled from "styled-components"; import * as Sentry from "@sentry/react"; import * as log from "loglevel"; +import type { ReactNode, CSSProperties } from "react"; + interface Props { children: ReactNode; + style?: CSSProperties; } interface State { hasError: boolean; @@ -39,7 +41,10 @@ class ErrorBoundary extends React.Component { render() { return ( - + {this.state.hasError ? (

Oops, Something went wrong. diff --git a/app/client/src/layoutSystems/anvil/canvas/styles.css b/app/client/src/layoutSystems/anvil/canvas/styles.css index bb836d6a5d..c8fd2927c9 100644 --- a/app/client/src/layoutSystems/anvil/canvas/styles.css +++ b/app/client/src/layoutSystems/anvil/canvas/styles.css @@ -3,8 +3,3 @@ width: 100%; height: 100%; } - -.main-anvil-canvas { - height: calc(100% - 1rem); - overflow-y: auto; -} diff --git a/app/client/src/layoutSystems/anvil/common/widgetComponent/AnvilWidgetComponent.tsx b/app/client/src/layoutSystems/anvil/common/widgetComponent/AnvilWidgetComponent.tsx index 79176cc842..7bb702df19 100644 --- a/app/client/src/layoutSystems/anvil/common/widgetComponent/AnvilWidgetComponent.tsx +++ b/app/client/src/layoutSystems/anvil/common/widgetComponent/AnvilWidgetComponent.tsx @@ -22,7 +22,8 @@ export const AnvilWidgetComponent = (props: BaseWidgetProps) => { if (!detachFromLayout) return props.children; return ( - + // delete style as soon as we switch to Anvil layout completely + {props.children} diff --git a/app/client/src/layoutSystems/anvil/utils/AnvilDSLTransformer.ts b/app/client/src/layoutSystems/anvil/utils/AnvilDSLTransformer.ts index 64585681cb..3d033fb242 100644 --- a/app/client/src/layoutSystems/anvil/utils/AnvilDSLTransformer.ts +++ b/app/client/src/layoutSystems/anvil/utils/AnvilDSLTransformer.ts @@ -22,7 +22,6 @@ export function anvilDSLTransformer(dsl: DSLWidget) { layoutStyle: { border: "none", height: "100%", - minHeight: "var(--canvas-height)", padding: "spacing-1", }, isDropTarget: true, diff --git a/app/client/src/layoutSystems/anvil/utils/layouts/renderUtils.tsx b/app/client/src/layoutSystems/anvil/utils/layouts/renderUtils.tsx index 175bade339..bba5a3c9ea 100644 --- a/app/client/src/layoutSystems/anvil/utils/layouts/renderUtils.tsx +++ b/app/client/src/layoutSystems/anvil/utils/layouts/renderUtils.tsx @@ -125,7 +125,6 @@ export function renderWidgetsInAlignedRow( > = { alignSelf: "stretch", canvasId, - columnGap: "4px", direction: "row", flexBasis: { base: "auto", [`${MOBILE_BREAKPOINT}px`]: "0%" }, flexGrow: 1, diff --git a/app/client/src/layoutSystems/common/mainContainerResizer/MainContainerResizer.tsx b/app/client/src/layoutSystems/common/mainContainerResizer/MainContainerResizer.tsx index 4f2576015e..01c428e9c3 100644 --- a/app/client/src/layoutSystems/common/mainContainerResizer/MainContainerResizer.tsx +++ b/app/client/src/layoutSystems/common/mainContainerResizer/MainContainerResizer.tsx @@ -13,13 +13,12 @@ const CanvasResizerIcon = importSvg( ); const AutoLayoutCanvasResizer = styled.div` - position: sticky; + position: relative; z-index: var(--on-canvas-ui-z-index); cursor: col-resize; user-select: none; -webkit-user-select: none; width: 2px; - height: 100%; display: flex; background: var(--ads-v2-color-border); align-items: center; @@ -59,12 +58,9 @@ const AutoLayoutCanvasResizer = styled.div` export function MainContainerResizer({ currentPageId, enableMainCanvasResizer, - heightWithTopMargin, isPageInitiated, isPreview, - shouldHaveTopMargin, }: { - heightWithTopMargin: string; isPageInitiated: boolean; shouldHaveTopMargin: boolean; isPreview: boolean; @@ -74,6 +70,7 @@ export function MainContainerResizer({ const appLayout = useSelector(getCurrentApplicationLayout); const ref = useRef(null); const dispatch = useDispatch(); + const topHeaderHeight = "48px"; useEffect(() => { const ele: HTMLElement | null = document.getElementById(CANVAS_VIEWPORT); @@ -174,8 +171,8 @@ export function MainContainerResizer({ }} ref={ref} style={{ - top: "100%", - height: shouldHaveTopMargin ? heightWithTopMargin : "100vh", + top: isPreview ? topHeaderHeight : "0", + height: isPreview ? `calc(100% - ${topHeaderHeight})` : "100%", }} >

diff --git a/app/client/src/pages/AppViewer/AppPage.tsx b/app/client/src/pages/AppViewer/AppPage.tsx index 71e3fdbba2..8fe9bf7abf 100644 --- a/app/client/src/pages/AppViewer/AppPage.tsx +++ b/app/client/src/pages/AppViewer/AppPage.tsx @@ -71,10 +71,7 @@ export function AppPage(props: AppPageProps) { > {props.widgetsStructure.widgetId && - renderAppsmithCanvas({ - ...props.widgetsStructure, - classList: isAnvilLayout ? ["main-anvil-canvas"] : [], - } as WidgetProps)} + renderAppsmithCanvas(props.widgetsStructure as WidgetProps)} ); diff --git a/app/client/src/pages/Editor/Canvas.tsx b/app/client/src/pages/Editor/Canvas.tsx index 29a7e30ce5..11a6adb116 100644 --- a/app/client/src/pages/Editor/Canvas.tsx +++ b/app/client/src/pages/Editor/Canvas.tsx @@ -18,8 +18,6 @@ import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettings import { CANVAS_ART_BOARD } from "constants/componentClassNameConstants"; import { renderAppsmithCanvas } from "layoutSystems/CanvasFactory"; import type { WidgetProps } from "widgets/BaseWidget"; -import { LayoutSystemTypes } from "layoutSystems/types"; -import { getLayoutSystemType } from "selectors/layoutSystemSelectors"; import { getAppThemeSettings } from "@appsmith/selectors/applicationSelectors"; interface CanvasProps { @@ -28,11 +26,17 @@ interface CanvasProps { enableMainCanvasResizer?: boolean; } +const StyledWDSThemeProvider = styled(WDSThemeProvider)` + min-height: 100%; + display: flex; +`; + const Wrapper = styled.section<{ background: string; width: number; $enableMainCanvasResizer: boolean; }>` + flex: 1; background: ${({ background }) => background}; width: ${({ $enableMainCanvasResizer, width }) => $enableMainCanvasResizer ? `100%` : `${width}px`}; @@ -45,7 +49,6 @@ const Canvas = (props: CanvasProps) => { ); const selectedTheme = useSelector(getSelectedAppTheme); const isWDSEnabled = useFeatureFlag("ab_wds_enabled"); - const layoutSystemType: LayoutSystemTypes = useSelector(getLayoutSystemType); const themeSetting = useSelector(getAppThemeSettings); const themeProps = { @@ -82,14 +85,12 @@ const Canvas = (props: CanvasProps) => { : `mx-auto`; const paddingBottomClass = props.enableMainCanvasResizer ? "" : "pb-52"; - const height = layoutSystemType === LayoutSystemTypes.ANVIL ? "h-full" : ""; - const renderChildren = () => { return ( { width={canvasWidth} > {props.widgetsStructure.widgetId && - renderAppsmithCanvas({ - ...props.widgetsStructure, - classList: - layoutSystemType === LayoutSystemTypes.ANVIL - ? ["main-anvil-canvas"] - : [], - } as WidgetProps)} + renderAppsmithCanvas(props.widgetsStructure as WidgetProps)} ); }; @@ -112,7 +107,9 @@ const Canvas = (props: CanvasProps) => { try { if (isWDSEnabled) { return ( - {renderChildren()} + + {renderChildren()} + ); } diff --git a/app/client/src/pages/Editor/WidgetsEditor/MainContainerWrapper.tsx b/app/client/src/pages/Editor/WidgetsEditor/MainContainerWrapper.tsx index 89d76302da..1654602467 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/MainContainerWrapper.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/MainContainerWrapper.tsx @@ -21,12 +21,10 @@ import { getAppThemeIsChanging, getSelectedAppTheme, } from "selectors/appThemingSelectors"; -import { getCurrentThemeDetails } from "selectors/themeSelectors"; import { getCanvasWidgetsStructure } from "@appsmith/selectors/entitiesSelector"; -import { - AUTOLAYOUT_RESIZER_WIDTH_BUFFER, - useDynamicAppLayout, -} from "utils/hooks/useDynamicAppLayout"; +import { useDynamicAppLayout } from "utils/hooks/useDynamicAppLayout"; +import { LayoutSystemTypes } from "../../../layoutSystems/types"; +import { getLayoutSystemType } from "../../../selectors/layoutSystemSelectors"; import Canvas from "../Canvas"; import type { AppState } from "@appsmith/reducers"; import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; @@ -51,14 +49,8 @@ const Wrapper = styled.section<{ isPreviewingNavigation?: boolean; isAppSettingsPaneWithNavigationTabOpen?: boolean; navigationHeight?: number; - $heightWithTopMargin: string; }>` - /* Create a custom variable that will allow us to measure the height of the canvas down the road */ - --canvas-height: ${(props) => props.$heightWithTopMargin}; - width: ${({ $enableMainCanvasResizer }) => - $enableMainCanvasResizer - ? `calc(100% - ${AUTOLAYOUT_RESIZER_WIDTH_BUFFER}px)` - : `100%`}; + width: 100%; position: relative; overflow-x: auto; overflow-y: auto; @@ -131,7 +123,6 @@ function MainContainerWrapper(props: MainCanvasWrapperProps) { const isFetchingPage = useSelector(getIsFetchingPage); const widgetsStructure = useSelector(getCanvasWidgetsStructure, equal); const pages = useSelector(getViewModePageList); - const theme = useSelector(getCurrentThemeDetails); const selectedTheme = useSelector(getSelectedAppTheme); const shouldHaveTopMargin = !(isPreviewMode || isProtectedMode) || @@ -145,6 +136,9 @@ function MainContainerWrapper(props: MainCanvasWrapperProps) { const isWDSV2Enabled = useFeatureFlag("ab_wds_enabled"); const { canShowResizer, enableMainContainerResizer } = useMainContainerResizer(); + const layoutSystemType: LayoutSystemTypes = useSelector(getLayoutSystemType); + const isAnvilLayout = layoutSystemType === LayoutSystemTypes.ANVIL; + const headerHeight = "40px"; useEffect(() => { return () => { @@ -181,31 +175,10 @@ function MainContainerWrapper(props: MainCanvasWrapperProps) { const isPreviewingNavigation = isPreviewMode || isProtectedMode || isAppSettingsPaneWithNavigationTabOpen; - /** - * calculating exact height to not allow scroll at this component, - * calculating total height of the canvas minus - * - 1. navigation height - * - 1.1 height for top + stacked or top + inline nav style is calculated - * - 1.2 in case of sidebar nav, height is 0 - * - 2. top bar (header with preview/share/deploy buttons) - * - 3. bottom bar (footer with debug/logs buttons) - */ - const topMargin = shouldShowSnapShotBanner ? "4rem" : "0rem"; - const bottomBarHeight = - isPreviewMode || isProtectedMode ? "0px" : theme.bottomBarHeight; - const smallHeaderHeight = showCanvasTopSection - ? theme.smallHeaderHeight - : "0px"; - const scrollBarHeight = - isPreviewMode || isProtectedMode || isPreviewingNavigation ? "8px" : "40px"; - // calculating exact height to not allow scroll at this component, - // calculating total height minus margin on top, top bar and bottom bar and scrollbar height at the bottom - const heightWithTopMargin = `calc(100vh - 2rem - ${topMargin} - ${smallHeaderHeight} - ${bottomBarHeight} - ${scrollBarHeight} - ${navigationHeight}px)`; return ( <> { if (navigationPreviewRef?.current) { const { offsetHeight } = navigationPreviewRef.current; @@ -176,7 +186,7 @@ function WidgetsEditor() { PerformanceTracker.stopTracking(); return ( -
+
{shouldShowSnapShotBanner && ( -
+ -
+ )} { static type = "WDS_MODAL_WIDGET"; + constructor(props: ModalWidgetProps) { + super(props); + + this.state = { + isVisible: this.getModalVisibility(), + }; + } + static getConfig() { return config.metaConfig; } @@ -117,16 +119,14 @@ class WDSModalWidget extends BaseWidget { return ( this.setState({ isVisible: val })} size={this.props.size} > {this.props.showHeader && } - + {this.props.showFooter && (