import log from "loglevel"; import React, { useCallback } from "react"; import styled from "styled-components"; import * as Sentry from "@sentry/react"; import { useDispatch, useSelector } from "react-redux"; import type { CanvasWidgetStructure } from "WidgetProvider/constants"; import useWidgetFocus from "utils/hooks/useWidgetFocus"; import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; import { getViewportClassName } from "layoutSystems/autolayout/utils/AutoLayoutUtils"; import { ThemeProvider as WDSThemeProvider, useTheme, } from "@appsmith/wds-theming"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { CANVAS_ART_BOARD } from "constants/componentClassNameConstants"; import { renderAppsmithCanvas } from "layoutSystems/CanvasFactory"; import type { WidgetProps } from "widgets/BaseWidget"; import { getAppThemeSettings } from "ee/selectors/applicationSelectors"; import CodeModeTooltip from "pages/Editor/WidgetsEditor/components/CodeModeTooltip"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; import { focusWidget } from "actions/widgetActions"; interface CanvasProps { widgetsStructure: CanvasWidgetStructure; canvasWidth: number; 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`}; `; const Canvas = (props: CanvasProps) => { const { canvasWidth } = props; const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); const selectedTheme = useSelector(getSelectedAppTheme); const isAnvilLayout = useSelector(getIsAnvilLayout); const themeSetting = useSelector(getAppThemeSettings); const wdsThemeProps = { borderRadius: themeSetting.borderRadius, seedColor: themeSetting.accentColor, colorMode: themeSetting.colorMode.toLowerCase(), userSizing: themeSetting.sizing, userDensity: themeSetting.density, } as Parameters[0]; // in case of non-WDS theme, we will pass an empty object to useTheme hook // so that fixedLayout theme does not break because of calculations done in useTheme const { theme } = useTheme(isAnvilLayout ? wdsThemeProps : {}); const dispatch = useDispatch(); const unfocusAllWidgets = useCallback(() => { dispatch(focusWidget()); }, [dispatch]); /** * background for canvas */ let backgroundForCanvas: string; if (isPreviewMode || isAppSettingsPaneWithNavigationTabOpen) { backgroundForCanvas = "initial"; } else { backgroundForCanvas = selectedTheme.properties.colors.backgroundColor; } const focusRef = useWidgetFocus(); const marginHorizontalClass = props.enableMainCanvasResizer ? `mx-0` : `mx-auto`; const paddingBottomClass = props.enableMainCanvasResizer ? "" : "pb-52"; const renderChildren = () => { return ( {props.widgetsStructure.widgetId && renderAppsmithCanvas(props.widgetsStructure as WidgetProps)} ); }; try { if (isAnvilLayout) { return ( {renderChildren()} ); } return renderChildren(); } catch (error) { log.error("Error rendering DSL", error); Sentry.captureException(error); return null; } }; export default Canvas;