fix: fix modal position and styles (#30805)
## Description Fixes for the modal widget: 1. Added support for clickOutside. The modal is closed only by clicking on the backdrop overlay. A click on the widget name has been added to the exceptions for close event. 2. Fixed the positioning of the modal. Now it is located in the center of the provider. 3. For the correct positioning of the modal, it was necessary to make fixes for canvas height. The fixes also affect fixed and autolayout. #### PR fixes following issue(s) Fixes #30788 Also fixed this https://www.notion.so/appsmith/Canvas-gets-cut-off-on-preview-mode-525b95f26c6e4644bf5ab7389c02e434 #### Media https://github.com/appsmithorg/appsmith/assets/11555074/6db9ecde-595b-4fa4-a21b-9ed08930d58f #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - Chore (housekeeping or task changes that don't impact user perception) > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [x] Manual - [ ] JUnit - [x] Jest - [x] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Popover and Modal components now support dismissing by clicking outside. Custom logic and selectors can be specified to control this behavior. - **Enhancements** - Simplified logic for closing Modals by directly setting open state. - Enhanced Modal styling options, allowing for better customization of width and height. - ErrorBoundary component now supports custom styles. - **Refactor** - Removed redundant code and unused properties across various components and layout systems. - Simplified state management and styling adjustments in editor components. - **Style** - Updated Modal component styles for improved layout and responsiveness. - **Chores** - Codebase cleanup including removal of unused classes, variables, and adjustments for more efficient layout rendering. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
parent
fa2b44c646
commit
f14b40cef6
|
|
@ -47,6 +47,10 @@ export interface PopoverProps {
|
|||
triggerRef?: MutableRefObject<HTMLElement | null>;
|
||||
/** Which element to initially focus. Can be either a number (tabbable index as specified by the order) or a ref. */
|
||||
initialFocus?: number | MutableRefObject<HTMLElement | null>;
|
||||
/** Determines whether clickOutside is work or not.
|
||||
* @default false
|
||||
*/
|
||||
dismissClickOutside?: boolean;
|
||||
}
|
||||
|
||||
export interface PopoverContentProps {
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Flex alignItems="center" gap="spacing-4" justifyContent="end">
|
||||
<Button onPress={closeHandler} variant="ghost">
|
||||
<Button onPress={() => setOpen(false)} variant="ghost">
|
||||
{closeText}
|
||||
</Button>
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Flex alignItems="center" gap="spacing-4" justifyContent="space-between">
|
||||
<Text id={id} lineClamp={1} title={title} variant="caption">
|
||||
{title}
|
||||
</Text>
|
||||
<IconButton icon="x" onPress={closeHandler} variant="ghost" />
|
||||
<IconButton icon="x" onPress={() => setOpen(false)} variant="ghost" />
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<PopoverModalContentProps, "overlayClassName"> {
|
||||
/** Size of the Modal
|
||||
|
|
|
|||
|
|
@ -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<Props, State> {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<ErrorBoundaryContainer className="error-boundary">
|
||||
<ErrorBoundaryContainer
|
||||
className="error-boundary"
|
||||
style={this.props.style}
|
||||
>
|
||||
{this.state.hasError ? (
|
||||
<p>
|
||||
Oops, Something went wrong.
|
||||
|
|
|
|||
|
|
@ -3,8 +3,3 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.main-anvil-canvas {
|
||||
height: calc(100% - 1rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ export const AnvilWidgetComponent = (props: BaseWidgetProps) => {
|
|||
if (!detachFromLayout) return props.children;
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
// delete style as soon as we switch to Anvil layout completely
|
||||
<ErrorBoundary style={{ height: "auto", width: "auto" }}>
|
||||
<WidgetComponentBoundary widgetType={type}>
|
||||
{props.children}
|
||||
</WidgetComponentBoundary>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ export function anvilDSLTransformer(dsl: DSLWidget) {
|
|||
layoutStyle: {
|
||||
border: "none",
|
||||
height: "100%",
|
||||
minHeight: "var(--canvas-height)",
|
||||
padding: "spacing-1",
|
||||
},
|
||||
isDropTarget: true,
|
||||
|
|
|
|||
|
|
@ -125,7 +125,6 @@ export function renderWidgetsInAlignedRow(
|
|||
> = {
|
||||
alignSelf: "stretch",
|
||||
canvasId,
|
||||
columnGap: "4px",
|
||||
direction: "row",
|
||||
flexBasis: { base: "auto", [`${MOBILE_BREAKPOINT}px`]: "0%" },
|
||||
flexGrow: 1,
|
||||
|
|
|
|||
|
|
@ -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<HTMLDivElement>(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%",
|
||||
}}
|
||||
>
|
||||
<div className="canvas-resizer-icon">
|
||||
|
|
|
|||
|
|
@ -71,10 +71,7 @@ export function AppPage(props: AppPageProps) {
|
|||
>
|
||||
<PageView className="t--app-viewer-page" width={width}>
|
||||
{props.widgetsStructure.widgetId &&
|
||||
renderAppsmithCanvas({
|
||||
...props.widgetsStructure,
|
||||
classList: isAnvilLayout ? ["main-anvil-canvas"] : [],
|
||||
} as WidgetProps)}
|
||||
renderAppsmithCanvas(props.widgetsStructure as WidgetProps)}
|
||||
</PageView>
|
||||
</PageViewWrapper>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<Wrapper
|
||||
$enableMainCanvasResizer={!!props.enableMainCanvasResizer}
|
||||
background={isWDSEnabled ? "" : backgroundForCanvas}
|
||||
className={`relative t--canvas-artboard ${height} ${paddingBottomClass} transition-all duration-400 ${marginHorizontalClass} ${getViewportClassName(
|
||||
className={`relative t--canvas-artboard ${paddingBottomClass} transition-all duration-400 ${marginHorizontalClass} ${getViewportClassName(
|
||||
canvasWidth,
|
||||
)}`}
|
||||
data-testid={"t--canvas-artboard"}
|
||||
|
|
@ -98,13 +99,7 @@ const Canvas = (props: CanvasProps) => {
|
|||
width={canvasWidth}
|
||||
>
|
||||
{props.widgetsStructure.widgetId &&
|
||||
renderAppsmithCanvas({
|
||||
...props.widgetsStructure,
|
||||
classList:
|
||||
layoutSystemType === LayoutSystemTypes.ANVIL
|
||||
? ["main-anvil-canvas"]
|
||||
: [],
|
||||
} as WidgetProps)}
|
||||
renderAppsmithCanvas(props.widgetsStructure as WidgetProps)}
|
||||
</Wrapper>
|
||||
);
|
||||
};
|
||||
|
|
@ -112,7 +107,9 @@ const Canvas = (props: CanvasProps) => {
|
|||
try {
|
||||
if (isWDSEnabled) {
|
||||
return (
|
||||
<WDSThemeProvider theme={theme}>{renderChildren()}</WDSThemeProvider>
|
||||
<StyledWDSThemeProvider theme={theme}>
|
||||
{renderChildren()}
|
||||
</StyledWDSThemeProvider>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<>
|
||||
<Wrapper
|
||||
$enableMainCanvasResizer={enableMainContainerResizer}
|
||||
$heightWithTopMargin={heightWithTopMargin}
|
||||
background={
|
||||
isPreviewMode ||
|
||||
isProtectedMode ||
|
||||
|
|
@ -226,7 +199,8 @@ function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
shouldHaveTopMargin &&
|
||||
!showCanvasTopSection &&
|
||||
!isPreviewingNavigation &&
|
||||
!showAnonymousDataPopup,
|
||||
!showAnonymousDataPopup &&
|
||||
!isAnvilLayout,
|
||||
"mt-24": shouldShowSnapShotBanner,
|
||||
})}
|
||||
id={CANVAS_VIEWPORT}
|
||||
|
|
@ -236,7 +210,7 @@ function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
isPreviewingNavigation={isPreviewingNavigation}
|
||||
navigationHeight={navigationHeight}
|
||||
style={{
|
||||
height: shouldHaveTopMargin ? heightWithTopMargin : "100vh",
|
||||
height: isPreviewMode ? `calc(100% - ${headerHeight})` : "auto",
|
||||
fontFamily: fontFamily,
|
||||
pointerEvents: isAutoCanvasResizing ? "none" : "auto",
|
||||
}}
|
||||
|
|
@ -257,7 +231,6 @@ function MainContainerWrapper(props: MainCanvasWrapperProps) {
|
|||
<MainContainerResizer
|
||||
currentPageId={currentPageId}
|
||||
enableMainCanvasResizer={enableMainContainerResizer && canShowResizer}
|
||||
heightWithTopMargin={heightWithTopMargin}
|
||||
isPageInitiated={!isPageInitializing && !!widgetsStructure}
|
||||
isPreview={isPreviewMode || isProtectedMode}
|
||||
shouldHaveTopMargin={shouldHaveTopMargin}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import {
|
|||
getCurrentPageName,
|
||||
previewModeSelector,
|
||||
} from "selectors/editorSelectors";
|
||||
import styled from "styled-components";
|
||||
import { LayoutSystemTypes } from "../../../layoutSystems/types";
|
||||
import { getLayoutSystemType } from "../../../selectors/layoutSystemSelectors";
|
||||
import NavigationPreview from "./NavigationPreview";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import PerformanceTracker, {
|
||||
|
|
@ -49,6 +52,10 @@ import {
|
|||
import OverlayCanvasContainer from "layoutSystems/common/WidgetNamesCanvas";
|
||||
import { protectedModeSelector } from "selectors/gitSyncSelectors";
|
||||
|
||||
const BannerWrapper = styled.div`
|
||||
z-index: calc(var(--on-canvas-ui-z-index) + 1);
|
||||
`;
|
||||
|
||||
function WidgetsEditor() {
|
||||
const dispatch = useDispatch();
|
||||
const currentPageId = useSelector(getCurrentPageId);
|
||||
|
|
@ -87,6 +94,9 @@ function WidgetsEditor() {
|
|||
LayoutSystemFeatures.ENABLE_CANVAS_OVERLAY_FOR_EDITOR_UI,
|
||||
]);
|
||||
|
||||
const layoutSystemType: LayoutSystemTypes = useSelector(getLayoutSystemType);
|
||||
const isAnvilLayout = layoutSystemType === LayoutSystemTypes.ANVIL;
|
||||
|
||||
useEffect(() => {
|
||||
if (navigationPreviewRef?.current) {
|
||||
const { offsetHeight } = navigationPreviewRef.current;
|
||||
|
|
@ -176,7 +186,7 @@ function WidgetsEditor() {
|
|||
PerformanceTracker.stopTracking();
|
||||
return (
|
||||
<EditorContextProvider renderMode="CANVAS">
|
||||
<div className="relative flex flex-row w-full overflow-hidden">
|
||||
<div className="relative flex flex-row h-full w-full overflow-hidden">
|
||||
<div
|
||||
className={classNames({
|
||||
"relative flex flex-col w-full overflow-hidden": true,
|
||||
|
|
@ -189,7 +199,7 @@ function WidgetsEditor() {
|
|||
)}
|
||||
<AnonymousDataPopup />
|
||||
<div
|
||||
className="relative flex flex-row w-full overflow-hidden"
|
||||
className="relative flex flex-row h-full w-full overflow-hidden"
|
||||
data-testid="widgets-editor"
|
||||
draggable
|
||||
id="widgets-editor"
|
||||
|
|
@ -218,11 +228,19 @@ function WidgetsEditor() {
|
|||
isPreview={isPreviewMode || isProtectedMode}
|
||||
isPublished={isPublished}
|
||||
sidebarWidth={isPreviewingNavigation ? sidebarWidth : 0}
|
||||
style={
|
||||
isAnvilLayout
|
||||
? {
|
||||
//This is necessary in order to place WDS modal with position: fixed; relatively to the canvas.
|
||||
transform: "scale(1)",
|
||||
}
|
||||
: {}
|
||||
}
|
||||
>
|
||||
{shouldShowSnapShotBanner && (
|
||||
<div className="absolute top-0 z-1 w-full">
|
||||
<BannerWrapper className="absolute top-0 w-full">
|
||||
<SnapShotBannerCTA />
|
||||
</div>
|
||||
</BannerWrapper>
|
||||
)}
|
||||
<MainContainerWrapper
|
||||
canvasWidth={canvasWidth}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,17 @@ import type {
|
|||
import { call } from "redux-saga/effects";
|
||||
import { pasteWidgetsIntoMainCanvas } from "layoutSystems/anvil/utils/paste/mainCanvasPasteUtils";
|
||||
|
||||
const modalBodyStyles: React.CSSProperties = {
|
||||
minHeight: "var(--sizing-16)",
|
||||
maxHeight:
|
||||
"calc(var(--canvas-height) - var(--outer-spacing-4) - var(--outer-spacing-4) - var(--outer-spacing-4) - 100px)",
|
||||
};
|
||||
|
||||
class WDSModalWidget extends BaseWidget<ModalWidgetProps, WidgetState> {
|
||||
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<ModalWidgetProps, WidgetState> {
|
|||
|
||||
return (
|
||||
<Modal
|
||||
isOpen={this.getModalVisibility()}
|
||||
isOpen={this.state.isVisible as boolean}
|
||||
onClose={this.onModalClose}
|
||||
setOpen={(val) => this.setState({ isVisible: val })}
|
||||
size={this.props.size}
|
||||
>
|
||||
<ModalContent className={this.props.className}>
|
||||
{this.props.showHeader && <ModalHeader title={this.props.title} />}
|
||||
<ModalBody
|
||||
className={WDS_MODAL_WIDGET_CLASSNAME}
|
||||
style={modalBodyStyles}
|
||||
>
|
||||
<ModalBody className={WDS_MODAL_WIDGET_CLASSNAME}>
|
||||
<LayoutProvider {...this.props} />
|
||||
</ModalBody>
|
||||
{this.props.showFooter && (
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user