chore: Create layout system structure for Anvil and AnvilFlexComponent. (#27178)
## Description
1. Add new ```appPositioningType``` : ANVIL.
2. Create new code path and folder structure for Anvil layout system.
3. Move common pieces of functionalities between autoLayout and anvil to
anvil folder structure (e.g. ```CanvasResizer```).
4. Create ```AnvilFlexComponent```.
5. Use WDS Flex component in AnvilFlexComponent.
6. Pass min max size props in a data structure that is supported by
container queries in the Flex component.
e.g. min-width: { base: "120px", "480px": "200px" }
7. Supply the following flex properties (flex-grow flex-shrink
flex-basis) to widgets depending on their ```responsiveBehvaiour```:
a) Fill: ```flex: 1 1 0%;```
b) Hug: ```flex: 0 0 auto;```
#### PR fixes following issue(s)
Fixes # (issue number)
1. [#26987](https://github.com/appsmithorg/appsmith/issues/26987)
2. [#26609](https://github.com/appsmithorg/appsmith/issues/26609)
3. [#26611](https://github.com/appsmithorg/appsmith/issues/26611)
#### Type of change
- New feature (non-breaking change which adds functionality)
## 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
- [ ] Cypress
## 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
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [x] 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
---------
Co-authored-by: Ashok Kumar M <35134347+marks0351@users.noreply.github.com>
Co-authored-by: Aswath K <aswath.sana@gmail.com>
Co-authored-by: rahulramesha <rahul@appsmith.com>
Co-authored-by: rahulramesha <71900764+rahulramesha@users.noreply.github.com>
This commit is contained in:
parent
e1d2804349
commit
46dcf3a8f0
|
|
@ -1,5 +1,5 @@
|
|||
import { WIDGET_PADDING } from "../../../../../src/constants/WidgetConstants";
|
||||
import { MOBILE_ROW_GAP } from "../../../../../src/layoutSystems/autolayout/utils/constants";
|
||||
import { MOBILE_ROW_GAP } from "../../../../../src/layoutSystems/common/utils/constants";
|
||||
import {
|
||||
agHelper,
|
||||
autoLayout,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { WIDGET_PADDING } from "../../../../../src/constants/WidgetConstants";
|
|||
import {
|
||||
MOBILE_ROW_GAP,
|
||||
ROW_GAP,
|
||||
} from "../../../../../src/layoutSystems/autolayout/utils/constants";
|
||||
} from "../../../../../src/layoutSystems/common/utils/constants";
|
||||
import {
|
||||
agHelper,
|
||||
autoLayout,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { WIDGET_PADDING } from "../../../../../src/constants/WidgetConstants";
|
|||
import {
|
||||
MOBILE_ROW_GAP,
|
||||
ROW_GAP,
|
||||
} from "../../../../../src/layoutSystems/autolayout/utils/constants";
|
||||
} from "../../../../../src/layoutSystems/common/utils/constants";
|
||||
import {
|
||||
agHelper,
|
||||
autoLayout,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { WIDGET_PADDING } from "../../../../../src/constants/WidgetConstants";
|
|||
import {
|
||||
MOBILE_ROW_GAP,
|
||||
ROW_GAP,
|
||||
} from "../../../../../src/layoutSystems/autolayout/utils/constants";
|
||||
} from "../../../../../src/layoutSystems/common/utils/constants";
|
||||
import {
|
||||
agHelper,
|
||||
autoLayout,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import * as _ from "../../../../support/Objects/ObjectsCore";
|
|||
import {
|
||||
MOBILE_ROW_GAP,
|
||||
ROW_GAP,
|
||||
} from "../../../../../src/layoutSystems/autolayout/utils/constants";
|
||||
} from "../../../../../src/layoutSystems/common/utils/constants";
|
||||
|
||||
describe("Validating use cases for Auto Dimension", () => {
|
||||
before(() => {
|
||||
|
|
|
|||
|
|
@ -9,11 +9,6 @@ import { WIDGET_STATIC_PROPS } from "constants/WidgetConstants";
|
|||
import type { Stylesheet } from "entities/AppTheming";
|
||||
import { omit } from "lodash";
|
||||
import moment from "moment";
|
||||
import type {
|
||||
LayoutDirection,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
||||
import type { WidgetFeatures } from "utils/WidgetFeatures";
|
||||
import type { WidgetProps } from "../widgets/BaseWidget";
|
||||
|
|
@ -24,6 +19,11 @@ import type {
|
|||
WidgetQueryGenerationConfig,
|
||||
WidgetQueryGenerationFormConfig,
|
||||
} from "WidgetQueryGenerators/types";
|
||||
import type {
|
||||
LayoutDirection,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
|
||||
export type WidgetSizeConfig = {
|
||||
viewportMinWidth: number;
|
||||
|
|
@ -32,8 +32,8 @@ export type WidgetSizeConfig = {
|
|||
|
||||
type ResizableValues = { vertical?: boolean; horizontal?: boolean };
|
||||
type ResizableOptions = ResizableValues | ((props: any) => ResizableValues);
|
||||
type AutoDimensionValues = { width?: boolean; height?: boolean };
|
||||
type AutoDimensionOptions =
|
||||
export type AutoDimensionValues = { width?: boolean; height?: boolean };
|
||||
export type AutoDimensionOptions =
|
||||
| AutoDimensionValues
|
||||
| ((props: any) => AutoDimensionValues);
|
||||
|
||||
|
|
|
|||
167
app/client/src/layoutSystems/anvil/common/AnvilFlexComponent.tsx
Normal file
167
app/client/src/layoutSystems/anvil/common/AnvilFlexComponent.tsx
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import type { CSSProperties, MouseEvent } from "react";
|
||||
import { Flex } from "@design-system/widgets";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import { snipingModeSelector } from "selectors/editorSelectors";
|
||||
import { useClickToSelectWidget } from "utils/hooks/useClickToSelectWidget";
|
||||
import { usePositionedContainerZIndex } from "utils/hooks/usePositionedContainerZIndex";
|
||||
import {
|
||||
getIsResizing,
|
||||
isCurrentWidgetFocused,
|
||||
isWidgetSelected,
|
||||
} from "selectors/widgetSelectors";
|
||||
import { widgetTypeClassname } from "widgets/WidgetUtils";
|
||||
import {
|
||||
FlexVerticalAlignment,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type { FlexProps } from "@design-system/widgets/src/components/Flex/src/types";
|
||||
import { WIDGET_PADDING } from "constants/WidgetConstants";
|
||||
import { checkIsDropTarget } from "WidgetProvider/factory/helpers";
|
||||
import type { AnvilFlexComponentProps } from "../utils/types";
|
||||
import {
|
||||
getResponsiveMinWidth,
|
||||
validateResponsiveProp,
|
||||
} from "../utils/widgetUtils";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import type { WidgetConfigProps } from "WidgetProvider/constants";
|
||||
|
||||
/**
|
||||
* Adds following functionalities to the widget:
|
||||
* 1. Click handler to select the widget and open property pane.
|
||||
* 2. Widget size based on responsiveBehavior:
|
||||
* 2a. Hug widgets will stick to the size provided to them. (flex: 0 0 auto;)
|
||||
* 2b. Fill widgets will automatically take up all available width in the parent container. (flex: 1 1 0%;)
|
||||
* 3. Widgets can optionally have auto width or height which is dictated by the props.
|
||||
*
|
||||
* Uses Flex component provided by WDS.
|
||||
* @param props | AnvilFlexComponentProps
|
||||
* @returns Widget
|
||||
*/
|
||||
|
||||
export const AnvilFlexComponent = (props: AnvilFlexComponentProps) => {
|
||||
const isDropTarget = checkIsDropTarget(props.widgetType);
|
||||
const isFocused = useSelector(isCurrentWidgetFocused(props.widgetId));
|
||||
const isResizing = useSelector(getIsResizing);
|
||||
const isSelected = useSelector(isWidgetSelected(props.widgetId));
|
||||
const isSnipingMode = useSelector(snipingModeSelector);
|
||||
const isCurrentWidgetResizing = isResizing && isSelected;
|
||||
|
||||
const [isFillWidget, setIsFillWidget] = useState<boolean>(false);
|
||||
const [verticalAlignment, setVerticalAlignment] =
|
||||
useState<FlexVerticalAlignment>(FlexVerticalAlignment.Top);
|
||||
|
||||
const clickToSelectWidget = useClickToSelectWidget(props.widgetId);
|
||||
const onClickFn = useCallback(
|
||||
(e) => {
|
||||
clickToSelectWidget(e);
|
||||
},
|
||||
[props.widgetId, clickToSelectWidget],
|
||||
);
|
||||
|
||||
const stopEventPropagation = (e: MouseEvent<HTMLElement>) => {
|
||||
!isSnipingMode && e.stopPropagation();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const widgetConfig:
|
||||
| (Partial<WidgetProps> & WidgetConfigProps & { type: string })
|
||||
| undefined = WidgetFactory.getConfig(props.widgetType);
|
||||
if (!widgetConfig) return;
|
||||
setIsFillWidget(
|
||||
widgetConfig?.responsiveBehavior === ResponsiveBehavior.Fill,
|
||||
);
|
||||
setVerticalAlignment(
|
||||
widgetConfig?.flexVerticalAlignment || FlexVerticalAlignment.Top,
|
||||
);
|
||||
}, [props.widgetType]);
|
||||
|
||||
const { onHoverZIndex } = usePositionedContainerZIndex(
|
||||
isDropTarget,
|
||||
props.widgetId,
|
||||
isFocused,
|
||||
isSelected,
|
||||
);
|
||||
|
||||
const className = useMemo(
|
||||
() =>
|
||||
`anvil-layout-parent-${props.parentId} anvil-layout-child-${
|
||||
props.widgetId
|
||||
} ${widgetTypeClassname(
|
||||
props.widgetType,
|
||||
)} t--widget-${props.widgetName.toLowerCase()}`,
|
||||
[props.parentId, props.widgetId, props.widgetType, props.widgetName],
|
||||
);
|
||||
|
||||
// Memoize flex props to be passed to the WDS Flex component.
|
||||
// If the widget is being resized => update width and height to auto.
|
||||
const flexProps: FlexProps = useMemo(() => {
|
||||
const data: FlexProps = {
|
||||
alignSelf: verticalAlignment || FlexVerticalAlignment.Top,
|
||||
flexGrow: isFillWidget ? 1 : 0,
|
||||
flexShrink: isFillWidget ? 1 : 0,
|
||||
flexBasis: isFillWidget ? "0%" : "auto",
|
||||
height:
|
||||
props.hasAutoHeight || isCurrentWidgetResizing
|
||||
? "auto"
|
||||
: `${props.componentHeight}px`,
|
||||
padding: WIDGET_PADDING + "px",
|
||||
width:
|
||||
isFillWidget || props.hasAutoWidth || isCurrentWidgetResizing
|
||||
? "auto"
|
||||
: `${props.componentWidth}px`,
|
||||
};
|
||||
if (props?.widgetSize) {
|
||||
// adding min max limits only if they are available, as WDS Flex doesn't handle undefined values.
|
||||
if (validateResponsiveProp(props.widgetSize?.maxHeight)) {
|
||||
data.maxHeight = props.widgetSize.maxHeight;
|
||||
}
|
||||
if (validateResponsiveProp(props.widgetSize?.maxWidth)) {
|
||||
data.maxWidth = props.widgetSize.maxWidth;
|
||||
}
|
||||
if (validateResponsiveProp(props.widgetSize?.minHeight)) {
|
||||
data.minHeight = props.widgetSize.minHeight;
|
||||
}
|
||||
if (validateResponsiveProp(props.widgetSize?.minWidth)) {
|
||||
// Setting a base of 100% for Fill widgets to ensure that they expand on smaller sizes.
|
||||
data.minWidth = getResponsiveMinWidth(
|
||||
props.widgetSize?.minWidth,
|
||||
isFillWidget,
|
||||
);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}, [
|
||||
isCurrentWidgetResizing,
|
||||
isFillWidget,
|
||||
props.componentHeight,
|
||||
props.hasAutoHeight,
|
||||
props.hasAutoWidth,
|
||||
props.componentWidth,
|
||||
props.widgetSize,
|
||||
verticalAlignment,
|
||||
]);
|
||||
|
||||
const styleProps: CSSProperties = useMemo(() => {
|
||||
return {
|
||||
position: "relative",
|
||||
"&:hover": {
|
||||
zIndex: onHoverZIndex,
|
||||
},
|
||||
};
|
||||
}, [onHoverZIndex]);
|
||||
|
||||
return (
|
||||
<Flex {...flexProps} className={className} style={styleProps}>
|
||||
<div
|
||||
className="w-full h-full"
|
||||
onClick={stopEventPropagation}
|
||||
onClickCapture={onClickFn}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import React from "react";
|
||||
|
||||
export const AnvilResizable = () => <div />;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import React from "react";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
|
||||
export const AnvilResizableLayer = (props: BaseWidgetProps) => {
|
||||
if (props.resizeDisabled || props.type === "SKELETON_WIDGET") {
|
||||
return props.children;
|
||||
}
|
||||
// TODO: Does anvil need a new ResizableComponent?
|
||||
return <div className="w-full h-full">{props.children}</div>;
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
import ErrorBoundary from "components/editorComponents/ErrorBoundry";
|
||||
import WidgetComponentBoundary from "layoutSystems/common/widgetComponent/WidgetComponentBoundary";
|
||||
import React from "react";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import Skeleton from "widgets/Skeleton";
|
||||
|
||||
export const AnvilWidgetComponent = (props: BaseWidgetProps) => {
|
||||
const { deferRender, detachFromLayout, type } = props;
|
||||
/**
|
||||
* The widget mount calls the withWidgetProps with the widgetId and type to fetch the
|
||||
* widget props. During the computation of the props (in withWidgetProps) if the evaluated
|
||||
* values are not present (which will not be during mount), the widget type is changed to
|
||||
* SKELETON_WIDGET.
|
||||
*
|
||||
* Note:- This is done to retain the old rendering flow without any breaking changes.
|
||||
* This could be refactored into not changing the widget type but to have a boolean flag.
|
||||
*/
|
||||
if (type === "SKELETON_WIDGET" || deferRender) {
|
||||
return <Skeleton />;
|
||||
}
|
||||
|
||||
if (!detachFromLayout) return <div>{props.children}</div>;
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<WidgetComponentBoundary widgetType={type}>
|
||||
{props.children}
|
||||
</WidgetComponentBoundary>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
import React from "react";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetComponent";
|
||||
import { ModalOverlayLayer } from "layoutSystems/common/modalOverlay/ModalOverlayLayer";
|
||||
import { ClickContentToOpenPropPane } from "utils/hooks/useClickToSelectWidget";
|
||||
import { ModalResizableLayer } from "layoutSystems/common/resizer/ModalResizableLayer";
|
||||
|
||||
/**
|
||||
* AnvilEditorModalOnion
|
||||
*
|
||||
* Component that wraps the BaseWidget implementation of a Modal Widget with Editor specific wrappers
|
||||
* needed in Anvil.
|
||||
*
|
||||
* Editor specific wrappers are wrappers added to perform actions in the editor.
|
||||
* - AnvilWidgetComponent: provides layer to auto update dimensions based on content/ add skeleton widget on loading state
|
||||
* - ModalOverlayLayer: provides blueprint library overlay for the modal widget to be rendered.
|
||||
* - ModalResizableLayer: provides the resize handles required to set dimension for a modal widget.
|
||||
* - ClickContentToOpenPropPane: provides a way to open property pane on clicking on a modal widget content.
|
||||
*
|
||||
* @returns Enhanced Widget
|
||||
*/
|
||||
export const AnvilEditorModalOnion = (props: BaseWidgetProps) => {
|
||||
return (
|
||||
<AnvilWidgetComponent {...props}>
|
||||
<ModalOverlayLayer {...props} isEditMode>
|
||||
<ModalResizableLayer
|
||||
enableHorizontalResize
|
||||
enableVerticalResize={false}
|
||||
widgetProps={props}
|
||||
>
|
||||
<ClickContentToOpenPropPane widgetId={props.widgetId}>
|
||||
{props.children}
|
||||
</ClickContentToOpenPropPane>
|
||||
</ModalResizableLayer>
|
||||
</ModalOverlayLayer>
|
||||
</AnvilWidgetComponent>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
import React from "react";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import { AnvilFlexComponent } from "../common/AnvilFlexComponent";
|
||||
import SnipeableComponent from "layoutSystems/common/snipeable/SnipeableComponent";
|
||||
import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetComponent";
|
||||
import DraggableComponent from "layoutSystems/common/draggable/DraggableComponent";
|
||||
import { AnvilResizableLayer } from "../common/resizer/AnvilResizableLayer";
|
||||
|
||||
/**
|
||||
* AnvilEditorWidgetOnion
|
||||
*
|
||||
* Component that wraps the BaseWidget implementation of a Widget with Editor specific wrappers
|
||||
* needed in Anvil.
|
||||
*
|
||||
* Editor specific wrappers are wrappers added to perform actions in the editor.
|
||||
* - AnvilFlexComponent: provides dimensions of a widget in anvil layout system.
|
||||
* - SnipeableComponent: provides ability to snipe a widget(Makes sure the widget is focused on Hover and allows the widget to be snipped on clicking on it)
|
||||
* - DraggableComponent: provides DnD html apis to make the widget draggable.
|
||||
* - WidgetNameLayer: provides the widget name in editing mode and also show error state if there are any.
|
||||
* - AnvilWidgetComponent: provides layer to auto update dimensions based on content/ add skeleton widget on loading state
|
||||
*
|
||||
* @returns Enhanced Widget
|
||||
*/
|
||||
export const AnvilEditorWidgetOnion = (props: BaseWidgetProps) => {
|
||||
return (
|
||||
<AnvilFlexComponent
|
||||
componentHeight={props.componentHeight}
|
||||
componentWidth={props.componentWidth}
|
||||
hasAutoHeight={!!props.hasAutoHeight}
|
||||
hasAutoWidth={!!props.hasAutoWidth}
|
||||
isResizeDisabled={props.resizeDisabled}
|
||||
parentId={props.parentId}
|
||||
widgetId={props.widgetId}
|
||||
widgetName={props.widgetName}
|
||||
widgetSize={props.widgetSize}
|
||||
widgetType={props.type}
|
||||
>
|
||||
<SnipeableComponent type={props.type} widgetId={props.widgetId}>
|
||||
<DraggableComponent
|
||||
bottomRow={props.bottomRow}
|
||||
isFlexChild
|
||||
leftColumn={props.leftColumn}
|
||||
parentColumnSpace={props.parentColumnSpace}
|
||||
parentId={props.parentId}
|
||||
parentRowSpace={props.parentRowSpace}
|
||||
resizeDisabled={props.resizeDisabled}
|
||||
rightColumn={props.rightColumn}
|
||||
topRow={props.topRow}
|
||||
type={props.type}
|
||||
widgetId={props.widgetId}
|
||||
>
|
||||
<AnvilResizableLayer {...props}>
|
||||
<AnvilWidgetComponent {...props}>
|
||||
{props.children}
|
||||
</AnvilWidgetComponent>
|
||||
</AnvilResizableLayer>
|
||||
</DraggableComponent>
|
||||
</SnipeableComponent>
|
||||
</AnvilFlexComponent>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import React, { useMemo } from "react";
|
||||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import { AnvilEditorModalOnion } from "./AnvilEditorModalOnion";
|
||||
import { AnvilEditorWidgetOnion } from "./AnvilEditorWidgetOnion";
|
||||
|
||||
/**
|
||||
* AnvilEditorWrapper
|
||||
*
|
||||
* Component that wraps a BaseWidget implementation of a widget with editor specific layers of Anvil.
|
||||
* check out AnvilEditorWidgetOnion and AnvilEditorModalOnion to further understand what they implement under the hood.
|
||||
*
|
||||
* @param props | WidgetProps
|
||||
* @returns Enhanced BaseWidget with Editor specific Layers.
|
||||
*/
|
||||
export const AnvilEditorWrapper = (props: WidgetProps) => {
|
||||
//Widget Onion
|
||||
const WidgetOnion = useMemo(() => {
|
||||
return props.type === "MODAL_WIDGET"
|
||||
? AnvilEditorModalOnion
|
||||
: AnvilEditorWidgetOnion;
|
||||
}, [props.type]);
|
||||
|
||||
//Canvas_Onion
|
||||
if (props.type === "CANVAS_WIDGET") {
|
||||
return props.children;
|
||||
}
|
||||
|
||||
return <WidgetOnion {...props}>{props.children}</WidgetOnion>;
|
||||
};
|
||||
60
app/client/src/layoutSystems/anvil/index.ts
Normal file
60
app/client/src/layoutSystems/anvil/index.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import { RenderModes } from "constants/WidgetConstants";
|
||||
import { AnvilEditorWrapper } from "./editor/AnvilEditorWrapper";
|
||||
import { AnvilViewerWrapper } from "./viewer/AnvilViewerWrapper";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import {
|
||||
getAutoDimensionsConfig,
|
||||
getAutoLayoutWidgetConfig,
|
||||
restructureWidgetSizeConfig,
|
||||
} from "layoutSystems/common/utils/commonUtils";
|
||||
import type {
|
||||
AutoDimensionOptions,
|
||||
AutoDimensionValues,
|
||||
AutoLayoutConfig,
|
||||
} from "WidgetProvider/constants";
|
||||
import { getAnvilComponentDimensions } from "layoutSystems/common/utils/ComponentSizeUtils";
|
||||
|
||||
export const getAnvilDimensionsConfig = (
|
||||
props: BaseWidgetProps,
|
||||
): {
|
||||
autoDimension: AutoDimensionOptions | undefined;
|
||||
widgetSize: { [key: string]: Record<string, string | number> };
|
||||
} => {
|
||||
const config: AutoLayoutConfig = getAutoLayoutWidgetConfig(props);
|
||||
return {
|
||||
autoDimension: getAutoDimensionsConfig(config, props),
|
||||
widgetSize: restructureWidgetSizeConfig(config.widgetSize, props),
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* getAnvilSystemPropsEnhancer
|
||||
*
|
||||
* utility function to enhance BaseWidgetProps with Anvil specific props
|
||||
*
|
||||
*/
|
||||
const getAnvilSystemPropsEnhancer = (props: BaseWidgetProps) => {
|
||||
const { autoDimension, widgetSize } = getAnvilDimensionsConfig(props);
|
||||
const { componentHeight, componentWidth } =
|
||||
getAnvilComponentDimensions(props);
|
||||
return {
|
||||
...props,
|
||||
componentHeight,
|
||||
componentWidth,
|
||||
hasAutoHeight: !!(autoDimension as AutoDimensionValues)?.height,
|
||||
hasAutoWidth: !!(autoDimension as AutoDimensionValues)?.width,
|
||||
widgetSize,
|
||||
};
|
||||
};
|
||||
|
||||
const getAnvilSystemWrapper = (renderMode: RenderModes) => {
|
||||
if (renderMode === RenderModes.CANVAS) return AnvilEditorWrapper;
|
||||
return AnvilViewerWrapper;
|
||||
};
|
||||
|
||||
export function getAnvilSystem(renderMode: RenderModes) {
|
||||
return {
|
||||
LayoutSystemWrapper: getAnvilSystemWrapper(renderMode),
|
||||
propertyEnhancer: getAnvilSystemPropsEnhancer,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import { Flex } from "@design-system/widgets";
|
||||
import type {
|
||||
AlignSelf,
|
||||
FlexDirection,
|
||||
FlexProps,
|
||||
FlexWrap,
|
||||
JustifyContent,
|
||||
} from "@design-system/widgets";
|
||||
import { MOBILE_BREAKPOINT } from "layoutSystems/anvil/utils/constants";
|
||||
import type {
|
||||
OverflowValues,
|
||||
PositionValues,
|
||||
} from "layoutSystems/anvil/utils/types";
|
||||
import { addPixelToSize } from "layoutSystems/common/utils/commonUtils";
|
||||
import { MOBILE_ROW_GAP, ROW_GAP } from "layoutSystems/common/utils/constants";
|
||||
import React, { useMemo } from "react";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
interface FlexLayoutProps
|
||||
extends AlignSelf,
|
||||
FlexDirection,
|
||||
FlexWrap,
|
||||
JustifyContent {
|
||||
canvasId: string;
|
||||
children: ReactNode;
|
||||
isDropTarget?: boolean;
|
||||
layoutId: string;
|
||||
|
||||
border?: string;
|
||||
columnGap?: string;
|
||||
flexBasis?: string;
|
||||
flexGrow?: number;
|
||||
flexShrink?: number;
|
||||
height?: string;
|
||||
maxHeight?: string;
|
||||
maxWidth?: string;
|
||||
minWidth?: string;
|
||||
minHeight?: string;
|
||||
overflowX?: OverflowValues;
|
||||
overflow?: OverflowValues;
|
||||
position?: PositionValues;
|
||||
rowGap?: string;
|
||||
padding?: string;
|
||||
width?: string;
|
||||
}
|
||||
|
||||
export const FlexLayout = (props: FlexLayoutProps) => {
|
||||
const layoutStyle: FlexProps = useMemo(() => {
|
||||
return {
|
||||
alignSelf: props.alignSelf || "flex-start",
|
||||
columnGap: props.columnGap || "0px",
|
||||
flexDirection: props.direction || "column",
|
||||
flexGrow: props.flexGrow || 0,
|
||||
flexShrink: props.flexShrink || 0,
|
||||
flexBasis: props.flexBasis || "auto",
|
||||
flexWrap: props.wrap || "nowrap",
|
||||
justifyContent: props.justifyContent || "start",
|
||||
overflowX: props.overflowX || "hidden",
|
||||
overflowY: props.overflow || "hidden",
|
||||
height: props.height || "auto",
|
||||
maxHeight: props.maxHeight || "none",
|
||||
minWidth: props.minWidth || "none",
|
||||
minHeight: props.minHeight || "none",
|
||||
position: props.position || "relative",
|
||||
width: props.width || "auto",
|
||||
border: props.border || "none",
|
||||
padding: props.padding || "none",
|
||||
rowGap: props.rowGap || {
|
||||
base: addPixelToSize(MOBILE_ROW_GAP),
|
||||
[addPixelToSize(MOBILE_BREAKPOINT)]: addPixelToSize(ROW_GAP),
|
||||
},
|
||||
};
|
||||
}, [props]);
|
||||
|
||||
return <Flex {...layoutStyle}>{props.children}</Flex>;
|
||||
};
|
||||
12
app/client/src/layoutSystems/anvil/utils/anvilTypes.ts
Normal file
12
app/client/src/layoutSystems/anvil/utils/anvilTypes.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
export interface LayoutComponentProps {
|
||||
layout: LayoutComponentProps[] | string[] | string[][]; // Array of layout components or widgets to render.
|
||||
layoutId: string; // Identifier of layout
|
||||
layoutStyle?: { [key: string]: any }; // React.CSSProperties for overriding default layout style.
|
||||
layoutType: string; // Used to identify the correct layout component to render.
|
||||
|
||||
allowedWidgetTypes?: string[]; // Array of widget types that can be dropped on the layout component.
|
||||
childTemplate?: LayoutComponentProps; // The template of child layout components to wrap new widgets in.
|
||||
isDropTarget?: boolean; // Whether the layout component is a drop target. Accordingly, renders
|
||||
insertChild?: boolean; // Identifies which of the child layout components in childTemplate to add new widgets to.
|
||||
isPermanent?: boolean; // Whether the layout component can exist without any children.
|
||||
}
|
||||
1
app/client/src/layoutSystems/anvil/utils/constants.ts
Normal file
1
app/client/src/layoutSystems/anvil/utils/constants.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const MOBILE_BREAKPOINT = 480;
|
||||
27
app/client/src/layoutSystems/anvil/utils/types.ts
Normal file
27
app/client/src/layoutSystems/anvil/utils/types.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import type { ReactNode } from "react";
|
||||
import type { WidgetType } from "WidgetProvider/factory";
|
||||
|
||||
export interface AnvilFlexComponentProps {
|
||||
children: ReactNode;
|
||||
componentHeight: number;
|
||||
componentWidth: number;
|
||||
hasAutoHeight: boolean;
|
||||
hasAutoWidth: boolean;
|
||||
isResizeDisabled?: boolean;
|
||||
focused?: boolean;
|
||||
parentId?: string;
|
||||
selected?: boolean;
|
||||
widgetId: string;
|
||||
widgetName: string;
|
||||
widgetSize?: { [key: string]: Record<string, string | number> };
|
||||
widgetType: WidgetType;
|
||||
}
|
||||
|
||||
export type PositionValues =
|
||||
| "absolute"
|
||||
| "relative"
|
||||
| "fixed"
|
||||
| "sticky"
|
||||
| "Static";
|
||||
|
||||
export type OverflowValues = "overflow" | "hidden" | "visible" | "scroll";
|
||||
24
app/client/src/layoutSystems/anvil/utils/widgetUtils.test.ts
Normal file
24
app/client/src/layoutSystems/anvil/utils/widgetUtils.test.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { getResponsiveMinWidth } from "./widgetUtils";
|
||||
|
||||
describe("WidgetUtils tests", () => {
|
||||
describe("getResponsiveMinWidth", () => {
|
||||
it("should return the min width as is for Hug widgets", () => {
|
||||
const config = { base: "100px" };
|
||||
const result = getResponsiveMinWidth(config, false);
|
||||
expect(result).toEqual(config);
|
||||
});
|
||||
it("should return undefined if the min width is undefined for a Hug widget", () => {
|
||||
const result = getResponsiveMinWidth(undefined, false);
|
||||
expect(result).toEqual(undefined);
|
||||
});
|
||||
it("should set base as 100% for Fill widgets if minWidth config is undefined", () => {
|
||||
const result = getResponsiveMinWidth(undefined, true);
|
||||
expect(result).toEqual({ base: "100%", "480px": "" });
|
||||
});
|
||||
it("should set base as 100% for Fill widgets if minWidth config is defined as assign given minWidth at 480px", () => {
|
||||
const config = { base: "100px" };
|
||||
const result = getResponsiveMinWidth(config, true);
|
||||
expect(result).toEqual({ base: "100%", "480px": "100px" });
|
||||
});
|
||||
});
|
||||
});
|
||||
30
app/client/src/layoutSystems/anvil/utils/widgetUtils.ts
Normal file
30
app/client/src/layoutSystems/anvil/utils/widgetUtils.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { MOBILE_BREAKPOINT } from "./constants";
|
||||
|
||||
/**
|
||||
* Updates minWidth style for the widget based on its responsiveBehavior:
|
||||
* A Fill widget will expand to assume 100% of its parent's width when its parent width < 480px.
|
||||
* For other situations, it will adopt the minWidth provided in its widget config.
|
||||
* @param config Record<string, string | number> | undefined
|
||||
* @returns Record<string, string | number> | undefined
|
||||
*/
|
||||
export const getResponsiveMinWidth = (
|
||||
config: Record<string, string | number> | undefined,
|
||||
isFillWidget: boolean,
|
||||
): Record<string, string | number> | undefined => {
|
||||
if (!config) {
|
||||
return isFillWidget
|
||||
? { base: "100%", [`${MOBILE_BREAKPOINT}px`]: "" }
|
||||
: undefined;
|
||||
}
|
||||
if (!isFillWidget) return config;
|
||||
const minWidth = config["base"];
|
||||
return {
|
||||
...config,
|
||||
base: "100%",
|
||||
[`${MOBILE_BREAKPOINT}px`]: config[`${MOBILE_BREAKPOINT}px`] || minWidth,
|
||||
};
|
||||
};
|
||||
|
||||
export const validateResponsiveProp = (
|
||||
data: Record<string, string | number> | undefined,
|
||||
) => data && Object.keys(data)?.length;
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import React from "react";
|
||||
import { Classes } from "@blueprintjs/core";
|
||||
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetComponent";
|
||||
import { ModalOverlayLayer } from "layoutSystems/common/modalOverlay/ModalOverlayLayer";
|
||||
|
||||
/**
|
||||
* AnvilViewerModalOnion
|
||||
*
|
||||
* Component that wraps the BaseWidget implementation of a Modal Widget with Viewer(Deployed Application Viewer) specific wrappers
|
||||
* needed in Anvil.
|
||||
*
|
||||
* Viewer specific wrappers are wrappers added to perform actions in the viewer.
|
||||
* - AnvilWidgetComponent: provides layer to auto update dimensions based on content/ add skeleton widget on loading state
|
||||
* - ModalOverlayLayer: provides blueprint library overlay for the modal widget to be rendered.
|
||||
*
|
||||
* @returns Enhanced Widget
|
||||
*/
|
||||
export const AnvilViewerModalOnion = (props: BaseWidgetProps) => {
|
||||
return (
|
||||
<AnvilWidgetComponent {...props}>
|
||||
<ModalOverlayLayer {...props} isEditMode={false}>
|
||||
<div className={Classes.OVERLAY_CONTENT}>{props.children}</div>
|
||||
</ModalOverlayLayer>
|
||||
</AnvilWidgetComponent>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import React from "react";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import { AnvilFlexComponent } from "../common/AnvilFlexComponent";
|
||||
import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetComponent";
|
||||
|
||||
/**
|
||||
* AnvilViewerWidgetOnion
|
||||
*
|
||||
* Component that wraps the BaseWidget implementation of a Widget with Viewer(Deployed Application Viewer) specific wrappers
|
||||
* needed in Anvil.
|
||||
*
|
||||
* Viewer specific wrappers are wrappers added to perform actions in the viewer.
|
||||
* - AnvilFlexComponent: provides dimensions of a widget in anvil layout system.
|
||||
* - AnvilWidgetComponent: provides layer to auto update dimensions based on content/ add skeleton widget on loading state
|
||||
*
|
||||
* @returns Enhanced Widget
|
||||
*/
|
||||
export const AnvilViewerWidgetOnion = (props: BaseWidgetProps) => {
|
||||
return (
|
||||
<AnvilFlexComponent
|
||||
componentHeight={props.componentHeight}
|
||||
componentWidth={props.componentWidth}
|
||||
hasAutoHeight={!!props.hasAutoHeight}
|
||||
hasAutoWidth={!!props.hasAutoWidth}
|
||||
isResizeDisabled={props.resizeDisabled}
|
||||
parentId={props.parentId}
|
||||
widgetId={props.widgetId}
|
||||
widgetName={props.widgetName}
|
||||
widgetSize={props.widgetSize}
|
||||
widgetType={props.type}
|
||||
>
|
||||
<AnvilWidgetComponent {...props}>{props.children}</AnvilWidgetComponent>
|
||||
</AnvilFlexComponent>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import React, { useMemo } from "react";
|
||||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import { AnvilViewerModalOnion } from "./AnvilViewerModalOnion";
|
||||
import { AnvilViewerWidgetOnion } from "./AnvilViewerWidgetOnion";
|
||||
|
||||
/**
|
||||
* AnvilViewerWrapper
|
||||
*
|
||||
* Component that wraps a BaseWidget implementation of a widget with viewer(Deployed Application Viewer) specific layers of Anvil Layout System.
|
||||
* check out AnvilViewerWidgetOnion and AnvilViewerModalOnion to further understand what they implement under the hood.
|
||||
*
|
||||
* @param props
|
||||
* @returns Enhanced BaseWidget with Viewer specific Layers.
|
||||
*/
|
||||
export const AnvilViewerWrapper = (props: WidgetProps) => {
|
||||
const WidgetOnion = useMemo(() => {
|
||||
return props.type === "MODAL_WIDGET"
|
||||
? AnvilViewerModalOnion
|
||||
: AnvilViewerWidgetOnion;
|
||||
}, [props.type]);
|
||||
|
||||
if (props.type === "CANVAS_WIDGET") {
|
||||
return props.children;
|
||||
}
|
||||
|
||||
return <WidgetOnion {...props}>{props.children}</WidgetOnion>;
|
||||
};
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import type { CSSProperties, ReactNode } from "react";
|
||||
import type { CSSProperties } from "react";
|
||||
import React, { useCallback, useMemo } from "react";
|
||||
import styled from "styled-components";
|
||||
|
||||
import type { RenderMode, WidgetType } from "constants/WidgetConstants";
|
||||
import { WIDGET_PADDING } from "constants/WidgetConstants";
|
||||
import { useSelector } from "react-redux";
|
||||
import {
|
||||
|
|
@ -10,42 +9,18 @@ import {
|
|||
snipingModeSelector,
|
||||
} from "selectors/editorSelectors";
|
||||
import { getIsResizing } from "selectors/widgetSelectors";
|
||||
import type {
|
||||
FlexVerticalAlignment,
|
||||
LayoutDirection,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
import { useClickToSelectWidget } from "utils/hooks/useClickToSelectWidget";
|
||||
import { usePositionedContainerZIndex } from "utils/hooks/usePositionedContainerZIndex";
|
||||
import { widgetTypeClassname } from "widgets/WidgetUtils";
|
||||
import { RESIZE_BORDER_BUFFER } from "layoutSystems/common/resizer/common";
|
||||
import { checkIsDropTarget } from "WidgetProvider/factory/helpers";
|
||||
|
||||
export type AutoLayoutProps = {
|
||||
alignment: FlexVerticalAlignment;
|
||||
children: ReactNode;
|
||||
componentHeight: number;
|
||||
componentWidth: number;
|
||||
direction: LayoutDirection;
|
||||
focused?: boolean;
|
||||
parentId?: string;
|
||||
responsiveBehavior?: ResponsiveBehavior;
|
||||
selected?: boolean;
|
||||
isResizeDisabled?: boolean;
|
||||
widgetId: string;
|
||||
widgetName: string;
|
||||
widgetType: WidgetType;
|
||||
parentColumnSpace: number;
|
||||
flexVerticalAlignment: FlexVerticalAlignment;
|
||||
isMobile: boolean;
|
||||
renderMode: RenderMode;
|
||||
};
|
||||
import type { FlexComponentProps } from "../../autolayout/utils/types";
|
||||
|
||||
const FlexWidget = styled.div`
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
export function FlexComponent(props: AutoLayoutProps) {
|
||||
export function FlexComponent(props: FlexComponentProps) {
|
||||
const isSnipingMode = useSelector(snipingModeSelector);
|
||||
|
||||
const clickToSelectWidget = useClickToSelectWidget(props.widgetId);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { EditorContext } from "components/editorComponents/EditorContextProvider
|
|||
import { FLEXBOX_PADDING } from "constants/WidgetConstants";
|
||||
import { isFunction } from "lodash";
|
||||
import React, { useContext } from "react";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { getWidgetMinMaxDimensionsInPixel } from "layoutSystems/autolayout/utils/flexWidgetUtils";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ import type { ReactNode } from "react";
|
|||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { getAlignmentMarginInfo } from "layoutSystems/autolayout/utils/AutoLayoutUtils";
|
||||
import { FlexLayerAlignment } from "layoutSystems/autolayout/utils/constants";
|
||||
import type { LayoutDirection } from "layoutSystems/autolayout/utils/constants";
|
||||
import {
|
||||
MOBILE_ROW_GAP,
|
||||
type LayoutDirection,
|
||||
ROW_GAP,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
FlexLayerAlignment,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
|
||||
/**
|
||||
* 1. Given a direction if should employ flex in perpendicular direction.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import {
|
|||
LayoutDirection,
|
||||
MOBILE_ROW_GAP,
|
||||
ROW_GAP,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { APP_MODE } from "entities/App";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getAppMode } from "@appsmith/selectors/entitiesSelector";
|
||||
|
|
@ -16,10 +16,10 @@ import { FLEXBOX_PADDING, GridDefaults } from "constants/WidgetConstants";
|
|||
import type {
|
||||
AlignmentColumnInfo,
|
||||
FlexBoxAlignmentColumnInfo,
|
||||
FlexLayer,
|
||||
} from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
} from "layoutSystems/autolayout/utils/types";
|
||||
import { getColumnsForAllLayers } from "selectors/autoLayoutSelectors";
|
||||
import { WidgetNameComponentHeight } from "layoutSystems/common/widgetName";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/types";
|
||||
|
||||
export interface FlexBoxProps {
|
||||
direction: LayoutDirection;
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import {
|
|||
import {
|
||||
FlexLayerAlignment,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { useReflow } from "utils/hooks/useReflow";
|
||||
import PerformanceTracker, {
|
||||
PerformanceTransactionName,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import React from "react";
|
|||
import { useSelector } from "react-redux";
|
||||
import { getNearestParentCanvas } from "utils/generators";
|
||||
import { useCanvasDragging } from "./hooks/useCanvasDragging";
|
||||
import type { LayoutDirection } from "layoutSystems/autolayout/utils/constants";
|
||||
import type { LayoutDirection } from "layoutSystems/common/utils/constants";
|
||||
import { StickyCanvasArena } from "layoutSystems/common/CanvasArenas/StickyCanvasArena";
|
||||
|
||||
export interface AutoCanvasDraggingArenaProps {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getWidgets } from "sagas/selectors";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import type { HighlightInfo } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import type { HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
import { useRef } from "react";
|
||||
import { getIsAutoLayoutMobileBreakPoint } from "selectors/editorSelectors";
|
||||
import type { WidgetDraggingBlock } from "layoutSystems/common/CanvasArenas/ArenaTypes";
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ import { SelectionRequestType } from "sagas/WidgetSelectUtils";
|
|||
import { useContext, useEffect, useRef } from "react";
|
||||
import type { AutoCanvasDraggingArenaProps } from "../AutoCanvasDraggingArena";
|
||||
import type { WidgetDraggingBlock } from "../../../../common/CanvasArenas/ArenaTypes";
|
||||
import type { HighlightInfo } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import type { HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
import {
|
||||
LayoutDirection,
|
||||
AlignItems,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import {
|
||||
getBlocksToDraw,
|
||||
getParentDiff,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { useAutoLayoutHighlights } from "./useAutoLayoutHighlights";
|
|||
import type { WidgetDraggingBlock } from "../../../../common/CanvasArenas/ArenaTypes";
|
||||
import { useBlocksToBeDraggedOnCanvas } from "./useBlocksToBeDraggedOnCanvas";
|
||||
import { useRenderBlocksOnCanvas } from "./useRenderBlocksOnCanvas";
|
||||
import type { HighlightInfo } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import type { HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
import type { AutoCanvasDraggingArenaProps } from "../AutoCanvasDraggingArena";
|
||||
import { useCanvasDragToScroll } from "layoutSystems/common/CanvasArenas/useCanvasDragToScroll";
|
||||
import { modifyBlockDimension } from "layoutSystems/common/utils/canvasDraggingUtils";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Colors } from "constants/Colors";
|
|||
import { CONTAINER_GRID_PADDING } from "constants/WidgetConstants";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getZoomLevel } from "selectors/editorSelectors";
|
||||
import type { HighlightInfo } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import type { HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
import { getAbsolutePixels } from "utils/helpers";
|
||||
import type { WidgetDraggingBlock } from "../../../../common/CanvasArenas/ArenaTypes";
|
||||
import { modifyDrawingRectangles } from "layoutSystems/common/utils/canvasDraggingUtils";
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
|||
import { WidgetNameLayer } from "../../common/widgetName/WidgetNameLayer";
|
||||
import { AutoLayoutWidgetComponent } from "../common/widgetComponent/AutoLayoutWidgetComponent";
|
||||
import FlexComponent from "../common/FlexComponent";
|
||||
import { FlexVerticalAlignment, LayoutDirection } from "../utils/constants";
|
||||
import { AutoResizableLayer } from "../common/resizer/AutoResizableLayer";
|
||||
import DraggableComponent from "layoutSystems/common/draggable/DraggableComponent";
|
||||
import { FlexVerticalAlignment } from "layoutSystems/common/utils/constants";
|
||||
import { AutoResizableLayer } from "../common/resizer/AutoResizableLayer";
|
||||
|
||||
/**
|
||||
* AutoLayoutEditorWidgetOnion
|
||||
|
|
@ -33,7 +33,6 @@ export const AutoLayoutEditorWidgetOnion = (props: BaseWidgetProps) => {
|
|||
alignment={props.alignment}
|
||||
componentHeight={props.componentHeight}
|
||||
componentWidth={props.componentWidth}
|
||||
direction={props.direction || LayoutDirection.Horizontal}
|
||||
flexVerticalAlignment={
|
||||
props.flexVerticalAlignment || FlexVerticalAlignment.Bottom
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import { isFunction } from "lodash";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import { RenderModes } from "../../constants/WidgetConstants";
|
||||
import { AutoLayoutEditorWrapper } from "./editor/AutoLayoutEditorWrapper";
|
||||
import { AutoLayoutViewerWrapper } from "./viewer/AutoLayoutViewerWrapper";
|
||||
import { getAutoLayoutComponentDimensions } from "layoutSystems/common/utils/ComponentSizeUtils";
|
||||
import {
|
||||
getAutoDimensionsConfig,
|
||||
getAutoLayoutWidgetConfig,
|
||||
} from "layoutSystems/common/utils/commonUtils";
|
||||
import type { AutoDimensionOptions } from "WidgetProvider/constants";
|
||||
|
||||
/**
|
||||
* getAutoLayoutDimensionsConfig
|
||||
|
|
@ -14,18 +17,10 @@ import { getAutoLayoutComponentDimensions } from "layoutSystems/common/utils/Com
|
|||
*
|
||||
* @returns AutoDimensionValues | undefined
|
||||
*/
|
||||
|
||||
const getAutoLayoutDimensionsConfig = (props: BaseWidgetProps) => {
|
||||
let autoDimensionConfig = WidgetFactory.getWidgetAutoLayoutConfig(
|
||||
props.type,
|
||||
).autoDimension;
|
||||
if (isFunction(autoDimensionConfig)) {
|
||||
autoDimensionConfig = autoDimensionConfig(props);
|
||||
}
|
||||
if (props.isListItemContainer && autoDimensionConfig) {
|
||||
autoDimensionConfig.height = false;
|
||||
}
|
||||
return autoDimensionConfig;
|
||||
export const getAutoLayoutDimensionsConfig = (
|
||||
props: BaseWidgetProps,
|
||||
): AutoDimensionOptions | undefined => {
|
||||
return getAutoDimensionsConfig(getAutoLayoutWidgetConfig(props), props);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,8 +1,3 @@
|
|||
import type {
|
||||
AlignmentColumnData,
|
||||
FlexLayer,
|
||||
LayerChild,
|
||||
} from "./autoLayoutTypes";
|
||||
import {
|
||||
FLEXBOX_PADDING,
|
||||
layoutConfigurations,
|
||||
|
|
@ -18,23 +13,26 @@ import type {
|
|||
FlattenedWidgetProps,
|
||||
} from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import { AppPositioningTypes } from "reducers/entityReducers/pageListReducer";
|
||||
import {
|
||||
defaultAutoLayoutWidgets,
|
||||
FlexLayerAlignment,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
SNAPSHOT_EXPIRY_IN_DAYS,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
import {
|
||||
updatePositionsOfParentAndSiblings,
|
||||
updateWidgetPositions,
|
||||
} from "layoutSystems/autolayout/utils/positionUtils";
|
||||
import type { AlignmentColumnInfo } from "./autoLayoutTypes";
|
||||
import { getWidgetWidth } from "./flexWidgetUtils";
|
||||
import type { DSLWidget } from "WidgetProvider/constants";
|
||||
import { getHumanizedTime, getReadableDateInFormat } from "utils/dayJsUtils";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import { isFunction } from "lodash";
|
||||
import { SNAPSHOT_EXPIRY_IN_DAYS, defaultAutoLayoutWidgets } from "./constants";
|
||||
import {
|
||||
FlexLayerAlignment,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type {
|
||||
AlignmentColumnData,
|
||||
AlignmentColumnInfo,
|
||||
} from "layoutSystems/autolayout/utils/types";
|
||||
import type { FlexLayer, LayerChild } from "./types";
|
||||
|
||||
export type ReadableSnapShotDetails = {
|
||||
timeSince: string;
|
||||
|
|
@ -506,7 +504,7 @@ function getCanvasWidth(
|
|||
//modal will be the total width instead of the mainCanvasWidth
|
||||
if (widget.type === "MODAL_WIDGET") {
|
||||
width = Math.min(
|
||||
widget.width,
|
||||
widget.width || 0,
|
||||
mainCanvasWidth * MAX_MODAL_WIDTH_FROM_MAIN_WIDTH,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import type { FlexLayer } from "./autoLayoutTypes";
|
||||
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import {
|
||||
addNewLayer,
|
||||
|
|
@ -8,8 +7,9 @@ import {
|
|||
updateRelationships,
|
||||
} from "./autoLayoutDraggingUtils";
|
||||
import { getLayerIndexOfWidget } from "./AutoLayoutUtils";
|
||||
import { FlexLayerAlignment } from "./constants";
|
||||
import { data } from "./testData";
|
||||
import type { FlexLayer } from "./types";
|
||||
import { FlexLayerAlignment } from "layoutSystems/common/utils/constants";
|
||||
|
||||
describe("test AutoLayoutDraggingUtils methods", () => {
|
||||
describe("test createFlexLayer method", () => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { FlexLayerAlignment } from "layoutSystems/autolayout/utils/constants";
|
||||
import type { FlexLayer, LayerChild } from "./autoLayoutTypes";
|
||||
import { FlexLayerAlignment } from "layoutSystems/common/utils/constants";
|
||||
import { isArray } from "lodash";
|
||||
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import { updateWidgetPositions } from "./positionUtils";
|
||||
import type { FlexLayer, LayerChild } from "./types";
|
||||
|
||||
/**
|
||||
* Transform movedWidgets to FlexLayer format,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,4 @@
|
|||
import type {
|
||||
AlignmentColumnData,
|
||||
FlexLayer,
|
||||
LayerChild,
|
||||
} from "./autoLayoutTypes";
|
||||
import type { AlignmentColumnData } from "../../autolayout/utils/types";
|
||||
import type {
|
||||
CanvasWidgetsReduxState,
|
||||
FlattenedWidgetProps,
|
||||
|
|
@ -17,8 +13,9 @@ import {
|
|||
updateFlexLayersOnDelete,
|
||||
} from "./AutoLayoutUtils";
|
||||
import { data, dataForgetCanvasDimensions } from "./testData";
|
||||
import { FlexLayerAlignment } from "./constants";
|
||||
import { FlexLayerAlignment } from "../../common/utils/constants";
|
||||
import { AUTO_LAYOUT_CONTAINER_PADDING } from "constants/WidgetConstants";
|
||||
import type { FlexLayer, LayerChild } from "./types";
|
||||
|
||||
describe("test AutoLayoutUtils methods", () => {
|
||||
const mainCanvasWidth = 960;
|
||||
|
|
|
|||
|
|
@ -1,81 +1,5 @@
|
|||
export const SNAPSHOT_EXPIRY_IN_DAYS = 5;
|
||||
|
||||
export enum LayoutDirection {
|
||||
Horizontal = "Horizontal",
|
||||
Vertical = "Vertical",
|
||||
}
|
||||
|
||||
export enum JustifyContent {
|
||||
FlexStart = "flex-start",
|
||||
Center = "center",
|
||||
SpaceAround = "space-around",
|
||||
SpaceBetween = "space-between",
|
||||
SpaceEvenly = "space-evenly",
|
||||
FlexEnd = "flex-end",
|
||||
}
|
||||
|
||||
export enum AlignItems {
|
||||
FlexStart = "flex-start",
|
||||
Center = "center",
|
||||
Stretch = "stretch",
|
||||
FlexEnd = "flex-end",
|
||||
}
|
||||
|
||||
export enum Positioning {
|
||||
Fixed = "fixed",
|
||||
Horizontal = "horizontal",
|
||||
Vertical = "vertical",
|
||||
}
|
||||
|
||||
export enum ResponsiveBehavior {
|
||||
Fill = "fill",
|
||||
Hug = "hug",
|
||||
}
|
||||
|
||||
export enum FlexDirection {
|
||||
Row = "row",
|
||||
RowReverse = "row-reverse",
|
||||
Column = "column",
|
||||
ColumnReverse = "column-reverse",
|
||||
}
|
||||
|
||||
export enum Alignment {
|
||||
Top = "top",
|
||||
Bottom = "bottom",
|
||||
Left = "left",
|
||||
Right = "right",
|
||||
}
|
||||
|
||||
export enum Spacing {
|
||||
None = "none",
|
||||
Equal = "equal",
|
||||
SpaceBetween = "space-between",
|
||||
}
|
||||
|
||||
export enum Overflow {
|
||||
Wrap = "wrap",
|
||||
NoWrap = "nowrap",
|
||||
Hidden = "hidden",
|
||||
Scroll = "scroll",
|
||||
Auto = "auto",
|
||||
}
|
||||
|
||||
export enum FlexLayerAlignment {
|
||||
None = "none",
|
||||
Start = "start",
|
||||
Center = "center",
|
||||
End = "end",
|
||||
}
|
||||
|
||||
export enum FlexVerticalAlignment {
|
||||
Top = "start",
|
||||
Center = "center",
|
||||
Bottom = "end",
|
||||
}
|
||||
|
||||
export const ROW_GAP = 12;
|
||||
export const MOBILE_ROW_GAP = 8;
|
||||
|
||||
export const defaultAutoLayoutWidgets = [
|
||||
"CONTAINER_WIDGET",
|
||||
"TABS_WIDGET",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { RenderModes } from "constants/WidgetConstants";
|
||||
import { LayoutDirection, ResponsiveBehavior } from "../constants";
|
||||
import {
|
||||
LayoutDirection,
|
||||
ResponsiveBehavior,
|
||||
} from "../../../common/utils/constants";
|
||||
|
||||
/**
|
||||
* MAIN CONTAINER
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { HighlightInfo } from "./autoLayoutTypes";
|
||||
import type { HighlightInfo } from "../../common/utils/types";
|
||||
|
||||
export interface Point {
|
||||
x: number;
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ import {
|
|||
FlexLayerAlignment,
|
||||
ResponsiveBehavior,
|
||||
ROW_GAP,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
import type { HighlightInfo } from "./autoLayoutTypes";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { getWidgetHeight } from "./flexWidgetUtils";
|
||||
import type { VerticalHighlightsPayload } from "./highlightUtils";
|
||||
import {
|
||||
|
|
@ -12,6 +11,7 @@ import {
|
|||
generateHighlightsForAlignment,
|
||||
generateVerticalHighlights,
|
||||
} from "./highlightUtils";
|
||||
import type { HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
|
||||
describe("test HighlightUtils methods", () => {
|
||||
describe("test deriveHighlightsFromLayers method", () => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import {
|
|||
FlexLayerAlignment,
|
||||
MOBILE_ROW_GAP,
|
||||
ROW_GAP,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import {
|
||||
FLEXBOX_PADDING,
|
||||
GridDefaults,
|
||||
|
|
@ -23,13 +23,11 @@ import { getAlignmentSizeInfo, getWrappedAlignmentInfo } from "./positionUtils";
|
|||
import type {
|
||||
AlignmentChildren,
|
||||
AlignmentInfo,
|
||||
DropZone,
|
||||
FlexLayer,
|
||||
HighlightInfo,
|
||||
LayerChild,
|
||||
} from "./autoLayoutTypes";
|
||||
} from "../../autolayout/utils/types";
|
||||
import { getTotalRowsOfAllChildren } from "./heightUpdateUtils";
|
||||
import { DEFAULT_HIGHLIGHT_SIZE } from "../common/flexCanvas/FlexBoxComponent";
|
||||
import type { FlexLayer, LayerChild } from "./types";
|
||||
import type { DropZone, HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
|
||||
/**
|
||||
* @param allWidgets : CanvasWidgetsReduxState
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import {
|
|||
FlexLayerAlignment,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
import type { AlignmentInfo, FlexLayer, Row } from "./autoLayoutTypes";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type { AlignmentInfo, Row } from "../../autolayout/utils/types";
|
||||
import { RenderModes } from "constants/WidgetConstants";
|
||||
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import {
|
||||
|
|
@ -19,6 +19,7 @@ import {
|
|||
import { AppPositioningTypes } from "reducers/entityReducers/pageListReducer";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import * as utils from "./flexWidgetUtils";
|
||||
import type { FlexLayer } from "./types";
|
||||
|
||||
describe("test PositionUtils methods", () => {
|
||||
const mainCanvasWidth = 960;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
import type {
|
||||
AlignmentChildren,
|
||||
AlignmentInfo,
|
||||
FlexLayer,
|
||||
LayerChild,
|
||||
Row,
|
||||
} from "./autoLayoutTypes";
|
||||
} from "../../autolayout/utils/types";
|
||||
import {
|
||||
GridDefaults,
|
||||
MAIN_CONTAINER_WIDGET_ID,
|
||||
|
|
@ -19,7 +17,7 @@ import {
|
|||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
ROW_GAP,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import {
|
||||
getWidgetHeight,
|
||||
getWidgetMinMaxDimensionsInPixel,
|
||||
|
|
@ -39,6 +37,7 @@ import {
|
|||
shouldUpdateParentHeight,
|
||||
updateParentHeight,
|
||||
} from "./heightUpdateUtils";
|
||||
import type { FlexLayer, LayerChild } from "./types";
|
||||
|
||||
/**
|
||||
* Calculate widget position on canvas.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { RenderModes } from "constants/WidgetConstants";
|
||||
import { LayoutDirection, ResponsiveBehavior } from "./constants";
|
||||
import {
|
||||
LayoutDirection,
|
||||
ResponsiveBehavior,
|
||||
} from "../../common/utils/constants";
|
||||
|
||||
export const data = {
|
||||
"0": {
|
||||
|
|
|
|||
74
app/client/src/layoutSystems/autolayout/utils/types.ts
Normal file
74
app/client/src/layoutSystems/autolayout/utils/types.ts
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import type { FlattenedWidgetProps } from "WidgetProvider/constants";
|
||||
import type { WidgetType } from "WidgetProvider/factory";
|
||||
import type { RenderMode } from "constants/WidgetConstants";
|
||||
import type {
|
||||
FlexLayerAlignment,
|
||||
FlexVerticalAlignment,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
export interface LayerChild {
|
||||
id: string;
|
||||
align: FlexLayerAlignment;
|
||||
}
|
||||
|
||||
export interface FlexLayer {
|
||||
children: LayerChild[];
|
||||
}
|
||||
|
||||
export type FlexComponentProps = {
|
||||
alignment: FlexVerticalAlignment;
|
||||
children: ReactNode;
|
||||
componentHeight: number;
|
||||
componentWidth: number;
|
||||
focused?: boolean;
|
||||
parentId?: string;
|
||||
responsiveBehavior?: ResponsiveBehavior;
|
||||
selected?: boolean;
|
||||
isResizeDisabled?: boolean;
|
||||
widgetId: string;
|
||||
widgetName: string;
|
||||
widgetType: WidgetType;
|
||||
parentColumnSpace: number;
|
||||
flexVerticalAlignment: FlexVerticalAlignment;
|
||||
isMobile: boolean;
|
||||
renderMode: RenderMode;
|
||||
};
|
||||
|
||||
export type AlignmentColumnInfo = {
|
||||
[key in FlexLayerAlignment]: number;
|
||||
};
|
||||
|
||||
export type FlexBoxAlignmentColumnInfo = {
|
||||
[key: number]: AlignmentColumnInfo;
|
||||
};
|
||||
|
||||
export type AlignmentColumnData = {
|
||||
alignment: FlexLayerAlignment;
|
||||
columns: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Start: Position utils types
|
||||
*/
|
||||
|
||||
export interface AlignmentChildren {
|
||||
widget: FlattenedWidgetProps;
|
||||
columns: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface AlignmentInfo {
|
||||
alignment: FlexLayerAlignment;
|
||||
columns: number;
|
||||
children: AlignmentChildren[];
|
||||
}
|
||||
|
||||
export interface Row extends AlignmentInfo {
|
||||
height: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* End: Position utils types
|
||||
*/
|
||||
|
|
@ -2,7 +2,7 @@ import React from "react";
|
|||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
import { AutoLayoutWidgetComponent } from "../common/widgetComponent/AutoLayoutWidgetComponent";
|
||||
import FlexComponent from "../common/FlexComponent";
|
||||
import { FlexVerticalAlignment, LayoutDirection } from "../utils/constants";
|
||||
import { FlexVerticalAlignment } from "layoutSystems/common/utils/constants";
|
||||
|
||||
/**
|
||||
* AutoLayoutViewerWidgetOnion
|
||||
|
|
@ -23,7 +23,6 @@ export const AutoLayoutViewerWidgetOnion = (props: BaseWidgetProps) => {
|
|||
alignment={props.alignment}
|
||||
componentHeight={props.componentHeight}
|
||||
componentWidth={props.componentWidth}
|
||||
direction={props.direction || LayoutDirection.Horizontal}
|
||||
flexVerticalAlignment={
|
||||
props.flexVerticalAlignment || FlexVerticalAlignment.Bottom
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,189 @@
|
|||
import { layoutConfigurations } from "constants/WidgetConstants";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { getCurrentApplicationLayout } from "selectors/editorSelectors";
|
||||
import { setAutoCanvasResizing } from "actions/autoLayoutActions";
|
||||
import styled from "styled-components";
|
||||
import { AUTOLAYOUT_RESIZER_WIDTH_BUFFER } from "utils/hooks/useDynamicAppLayout";
|
||||
import { importSvg } from "design-system-old";
|
||||
import { CANVAS_VIEWPORT } from "constants/componentClassNameConstants";
|
||||
|
||||
const CanvasResizerIcon = importSvg(
|
||||
() => import("assets/icons/ads/app-icons/canvas-resizer.svg"),
|
||||
);
|
||||
|
||||
const AutoLayoutCanvasResizer = styled.div`
|
||||
position: sticky;
|
||||
cursor: col-resize;
|
||||
width: 2px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
background: var(--ads-v2-color-border);
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
margin-left: 2px;
|
||||
transition: width 300ms ease;
|
||||
transition: background 300ms ease;
|
||||
.canvas-resizer-icon {
|
||||
border-left: 2px solid;
|
||||
border-color: var(--ads-v2-color-border);
|
||||
transition: border 300ms ease;
|
||||
margin-left: 2px;
|
||||
& > svg {
|
||||
fill: var(--ads-v2-color-border);
|
||||
transition: fill 300ms ease;
|
||||
}
|
||||
}
|
||||
&:hover,
|
||||
&:active {
|
||||
width: 3px;
|
||||
transition: width 300ms ease;
|
||||
background: #ff9b4e;
|
||||
transition: background 300ms ease;
|
||||
.canvas-resizer-icon {
|
||||
border-color: #ff9b4e;
|
||||
transition: border 300ms ease;
|
||||
& > svg {
|
||||
fill: #ff9b4e;
|
||||
transition: fill 300ms ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* OldName: CanvasResizer
|
||||
*/
|
||||
export function MainContainerResizer({
|
||||
currentPageId,
|
||||
enableMainCanvasResizer,
|
||||
heightWithTopMargin,
|
||||
isPageInitiated,
|
||||
isPreviewMode,
|
||||
shouldHaveTopMargin,
|
||||
}: {
|
||||
heightWithTopMargin: string;
|
||||
isPageInitiated: boolean;
|
||||
shouldHaveTopMargin: boolean;
|
||||
isPreviewMode: boolean;
|
||||
currentPageId: string;
|
||||
enableMainCanvasResizer: boolean;
|
||||
}) {
|
||||
const appLayout = useSelector(getCurrentApplicationLayout);
|
||||
const ref = useRef(null);
|
||||
const dispatch = useDispatch();
|
||||
useEffect(() => {
|
||||
const ele: HTMLElement | null = document.getElementById(CANVAS_VIEWPORT);
|
||||
|
||||
if (isPageInitiated && enableMainCanvasResizer) {
|
||||
const buffer = isPreviewMode ? AUTOLAYOUT_RESIZER_WIDTH_BUFFER : 0;
|
||||
const fullWidthCSS = `calc(100% - ${AUTOLAYOUT_RESIZER_WIDTH_BUFFER}px)`;
|
||||
const wrapperElement: any = document.getElementById("widgets-editor");
|
||||
|
||||
let maxWidth =
|
||||
wrapperElement.offsetWidth - AUTOLAYOUT_RESIZER_WIDTH_BUFFER;
|
||||
|
||||
if (ele && ele.offsetWidth >= maxWidth) {
|
||||
ele.style.width = fullWidthCSS;
|
||||
}
|
||||
|
||||
if (appLayout?.type === "FLUID") {
|
||||
const smallestWidth = layoutConfigurations.MOBILE.minWidth;
|
||||
// The current position of mouse
|
||||
let x = 0;
|
||||
// let y = 0;
|
||||
|
||||
// The dimension of the element
|
||||
let w = 0;
|
||||
// let h = 0;
|
||||
let events: any = [];
|
||||
|
||||
// Handle the mousedown event
|
||||
// that's triggered when user drags the resizer
|
||||
const mouseDownHandler = function (e: any) {
|
||||
if (!ele) return;
|
||||
maxWidth =
|
||||
wrapperElement.offsetWidth - AUTOLAYOUT_RESIZER_WIDTH_BUFFER;
|
||||
// Get the current mouse position
|
||||
x = e.clientX;
|
||||
// y = e.clientY;
|
||||
|
||||
// Calculate the dimension of element
|
||||
const styles = window.getComputedStyle(ele);
|
||||
dispatch(setAutoCanvasResizing(true));
|
||||
w = parseInt(styles.width, 10) + buffer;
|
||||
// h = parseInt(styles.height, 10);
|
||||
const mouseMove = (e: any) => mouseMoveHandler(e);
|
||||
events.push(mouseMove);
|
||||
// Attach the listeners to `document`
|
||||
document.addEventListener("mousemove", mouseMove);
|
||||
document.addEventListener("mouseup", mouseUpHandler);
|
||||
// e.stopPropagation();
|
||||
};
|
||||
|
||||
const mouseMoveHandler = function (e: any) {
|
||||
if (!ele) return;
|
||||
// How far the mouse has been moved
|
||||
// const multiplier = rightHandle ? 2 : -2;
|
||||
const multiplier = 2;
|
||||
const dx = (e.clientX - x) * multiplier;
|
||||
if (maxWidth >= w + dx && smallestWidth <= w + dx) {
|
||||
// Adjust the dimension of element
|
||||
ele.style.width = `${w + dx}px`;
|
||||
}
|
||||
if (maxWidth < w + dx) {
|
||||
ele.style.width = fullWidthCSS;
|
||||
}
|
||||
if (smallestWidth > w + dx) {
|
||||
ele.style.width = `${smallestWidth}px`;
|
||||
}
|
||||
// e.stopPropagation();
|
||||
};
|
||||
|
||||
const mouseUpHandler = function (e: any) {
|
||||
// Remove the handlers of `mousemove` and `mouseup`
|
||||
mouseMoveHandler(e);
|
||||
dispatch(setAutoCanvasResizing(false));
|
||||
document.removeEventListener("mousemove", events[0] as any);
|
||||
document.removeEventListener("mouseup", mouseUpHandler);
|
||||
events = [];
|
||||
};
|
||||
const rightResizer: any = ref.current;
|
||||
const rightMove = (e: any) => mouseDownHandler(e);
|
||||
rightResizer && rightResizer.addEventListener("mousedown", rightMove);
|
||||
|
||||
return () => {
|
||||
rightResizer &&
|
||||
rightResizer.removeEventListener("mousedown", rightMove);
|
||||
};
|
||||
}
|
||||
} else {
|
||||
ele?.style.removeProperty("width");
|
||||
}
|
||||
}, [
|
||||
appLayout,
|
||||
isPreviewMode,
|
||||
currentPageId,
|
||||
enableMainCanvasResizer,
|
||||
isPageInitiated,
|
||||
]);
|
||||
return enableMainCanvasResizer ? (
|
||||
<AutoLayoutCanvasResizer
|
||||
className="resizer-right"
|
||||
draggable
|
||||
onDragStart={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}}
|
||||
ref={ref}
|
||||
style={{
|
||||
top: "100%",
|
||||
height: shouldHaveTopMargin ? heightWithTopMargin : "100vh",
|
||||
}}
|
||||
>
|
||||
<div className="canvas-resizer-icon">
|
||||
<CanvasResizerIcon />
|
||||
</div>
|
||||
</AutoLayoutCanvasResizer>
|
||||
) : null;
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ import {
|
|||
isWidgetSelected,
|
||||
} from "selectors/widgetSelectors";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import {
|
||||
getWidgetHeight,
|
||||
getWidgetWidth,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { WidgetRowCols } from "widgets/BaseWidget";
|
|||
import { GridDefaults } from "constants/WidgetConstants";
|
||||
import type { XYCord } from "layoutSystems/common/CanvasArenas/ArenaTypes";
|
||||
import { ReflowDirection } from "reflow/reflowTypes";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
||||
export type UIElementSize = { height: number; width: number };
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import styled from "styled-components";
|
|||
import type {
|
||||
LayoutDirection,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { getNearestParentCanvas } from "utils/generators";
|
||||
import memoize from "micro-memoize";
|
||||
|
||||
|
|
|
|||
|
|
@ -77,6 +77,35 @@ export const getFixedLayoutComponentDimensions = ({
|
|||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* getAnvilComponentDimensions
|
||||
*
|
||||
* utility function to compute a widgets dimensions in Anvil layout system
|
||||
*
|
||||
*/
|
||||
export const getAnvilComponentDimensions = ({
|
||||
bottomRow,
|
||||
height,
|
||||
leftColumn,
|
||||
rightColumn,
|
||||
topRow,
|
||||
width,
|
||||
}: BaseWidgetProps) => {
|
||||
/**
|
||||
* Anvil widgets are part of a fluid layout.
|
||||
* Component width is calculated as a percentage of the grid width.
|
||||
* Component height is calculated in pixels.
|
||||
*/
|
||||
// TODO: Update this when positionsObserver is merged in. Since typeof componentWidth = number, convert percentage to pixel width. or reverse.
|
||||
return {
|
||||
componentWidth:
|
||||
width ||
|
||||
((rightColumn - leftColumn) * 100) / GridDefaults.DEFAULT_GRID_COLUMNS,
|
||||
componentHeight:
|
||||
height || (bottomRow - topRow) * GridDefaults.DEFAULT_GRID_ROW_HEIGHT,
|
||||
};
|
||||
};
|
||||
|
||||
export const getComponentDimensions = memo(
|
||||
(
|
||||
props: BaseWidgetProps,
|
||||
|
|
|
|||
27
app/client/src/layoutSystems/common/utils/commonTypes.ts
Normal file
27
app/client/src/layoutSystems/common/utils/commonTypes.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import type { WidgetType } from "WidgetProvider/factory";
|
||||
import type { RenderMode } from "constants/WidgetConstants";
|
||||
import type {
|
||||
FlexLayerAlignment,
|
||||
FlexVerticalAlignment,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
export type AutoLayoutProps = {
|
||||
alignment: FlexLayerAlignment;
|
||||
children: ReactNode;
|
||||
componentHeight: number;
|
||||
componentWidth: number;
|
||||
focused?: boolean;
|
||||
parentId?: string;
|
||||
responsiveBehavior?: ResponsiveBehavior;
|
||||
selected?: boolean;
|
||||
isResizeDisabled?: boolean;
|
||||
widgetId: string;
|
||||
widgetName: string;
|
||||
widgetType: WidgetType;
|
||||
parentColumnSpace: number;
|
||||
flexVerticalAlignment: FlexVerticalAlignment;
|
||||
isMobile: boolean;
|
||||
renderMode: RenderMode;
|
||||
};
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* eslint-disable no-console */
|
||||
import type {
|
||||
AutoDimensionOptions,
|
||||
AutoDimensionValues,
|
||||
AutoLayoutConfig,
|
||||
} from "WidgetProvider/constants";
|
||||
import {
|
||||
getAutoDimensionsConfig,
|
||||
restructureWidgetSizeConfig,
|
||||
} from "./commonUtils";
|
||||
import InputWidget from "widgets/InputWidgetV2/widget";
|
||||
import ButtonWidget from "widgets/ButtonWidget/widget";
|
||||
import { inputProps } from "mocks/widgetProps/input";
|
||||
|
||||
describe("Common Utils tests", () => {
|
||||
describe("getAutoDimensionsConfig", () => {
|
||||
it("autoDimension.height for InputWidgetV2 should be true", () => {
|
||||
const config: AutoLayoutConfig | undefined =
|
||||
InputWidget.getAutoLayoutConfig();
|
||||
const autoDimension: AutoDimensionOptions | undefined =
|
||||
getAutoDimensionsConfig(config || {}, inputProps);
|
||||
expect((autoDimension as AutoDimensionValues)?.height).toBeTruthy();
|
||||
});
|
||||
it("autoDimension.width for button widget should be true", () => {
|
||||
const config: AutoLayoutConfig | undefined =
|
||||
ButtonWidget.getAutoLayoutConfig();
|
||||
const autoDimension: AutoDimensionOptions | undefined =
|
||||
getAutoDimensionsConfig(config || {}, {
|
||||
...inputProps,
|
||||
type: "BUTTON_WIDGET",
|
||||
});
|
||||
expect((autoDimension as AutoDimensionValues)?.width).toBeTruthy();
|
||||
expect((autoDimension as AutoDimensionValues)?.height).toBeFalsy();
|
||||
});
|
||||
});
|
||||
describe("restructureWidgetSizeConfig", () => {
|
||||
it("should return widget size config in the structure accepted by WDS Flex component - BUTTON widget", () => {
|
||||
const config: AutoLayoutConfig | undefined =
|
||||
ButtonWidget.getAutoLayoutConfig();
|
||||
const sizeConfig: {
|
||||
maxHeight: Record<string, string | number>;
|
||||
maxWidth: Record<string, string | number>;
|
||||
minHeight: Record<string, string | number>;
|
||||
minWidth: Record<string, string | number>;
|
||||
} = restructureWidgetSizeConfig(config?.widgetSize || [], {
|
||||
...inputProps,
|
||||
type: "BUTTON_WIDGET",
|
||||
});
|
||||
|
||||
expect(sizeConfig.minWidth.base).toEqual("120px");
|
||||
expect(sizeConfig.minHeight.base).toEqual("40px");
|
||||
expect(sizeConfig.maxWidth.base).toEqual("360px");
|
||||
expect(sizeConfig.maxHeight.base).toBeFalsy();
|
||||
});
|
||||
it("should return widget size config in the structure accepted by WDS Flex component - INPUT widget", () => {
|
||||
const config: AutoLayoutConfig | undefined =
|
||||
InputWidget.getAutoLayoutConfig();
|
||||
const sizeConfig: {
|
||||
maxHeight: Record<string, string | number>;
|
||||
maxWidth: Record<string, string | number>;
|
||||
minHeight: Record<string, string | number>;
|
||||
minWidth: Record<string, string | number>;
|
||||
} = restructureWidgetSizeConfig(config?.widgetSize || [], inputProps);
|
||||
|
||||
expect(sizeConfig.minWidth.base).toEqual("120px");
|
||||
expect(sizeConfig.minHeight.base).toBeFalsy();
|
||||
expect(sizeConfig.maxWidth.base).toBeFalsy();
|
||||
expect(sizeConfig.maxHeight.base).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
131
app/client/src/layoutSystems/common/utils/commonUtils.ts
Normal file
131
app/client/src/layoutSystems/common/utils/commonUtils.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
import type {
|
||||
AutoDimensionOptions,
|
||||
AutoLayoutConfig,
|
||||
WidgetSizeConfig,
|
||||
} from "WidgetProvider/constants";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import { isFunction } from "lodash";
|
||||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
|
||||
export const getAutoDimensionsConfig = (
|
||||
config: AutoLayoutConfig,
|
||||
props: BaseWidgetProps,
|
||||
): AutoDimensionOptions | undefined => {
|
||||
let autoDimensionConfig = config.autoDimension;
|
||||
if (isFunction(autoDimensionConfig)) {
|
||||
autoDimensionConfig = autoDimensionConfig(props);
|
||||
}
|
||||
if (props.isListItemContainer && autoDimensionConfig) {
|
||||
autoDimensionConfig.height = false;
|
||||
}
|
||||
return autoDimensionConfig;
|
||||
};
|
||||
|
||||
export const getAutoLayoutWidgetConfig = (
|
||||
props: BaseWidgetProps,
|
||||
): AutoLayoutConfig => {
|
||||
return WidgetFactory.getWidgetAutoLayoutConfig(props.type);
|
||||
};
|
||||
|
||||
// TODO: update sizeConfig structure and get rid of this method.
|
||||
export const restructureWidgetSizeConfig = (
|
||||
sizeConfig: Array<WidgetSizeConfig> | undefined,
|
||||
props: BaseWidgetProps,
|
||||
): {
|
||||
maxHeight: Record<string, string | number>;
|
||||
maxWidth: Record<string, string | number>;
|
||||
minHeight: Record<string, string | number>;
|
||||
minWidth: Record<string, string | number>;
|
||||
} => {
|
||||
/**
|
||||
* Size config is stored as an array of objects.
|
||||
* Each object has a viewportMinWidth and a configuration function that returns the minMax sizes at the viewport.
|
||||
* e.g [{ viewportMinWidth: 0, configuration: (props) => ({ maxHeight: 400, minWidth: 100 })}]
|
||||
*
|
||||
* WDS flex component requires the same information in a different structure (Responsive<T>):
|
||||
* minWidth: { base: '100px', '480px': '200px' }, // default min width is 100px. However, above container width of 480px, min width changes to 200px.
|
||||
* maxHeight: { base: 400 },
|
||||
*/
|
||||
// TODO: We should look into how size config is stored. Both structure and values can be updated.
|
||||
const res: {
|
||||
maxHeight: Record<string, string | number>;
|
||||
maxWidth: Record<string, string | number>;
|
||||
minHeight: Record<string, string | number>;
|
||||
minWidth: Record<string, string | number>;
|
||||
} = {
|
||||
maxHeight: {},
|
||||
maxWidth: {},
|
||||
minHeight: {},
|
||||
minWidth: {},
|
||||
};
|
||||
if (!sizeConfig || !sizeConfig.length) return res;
|
||||
|
||||
return sizeConfig.reduce(
|
||||
(acc: any, size: WidgetSizeConfig) => {
|
||||
const data = size.configuration(props);
|
||||
if (size.viewportMinWidth === 0) {
|
||||
// WDS flex component doesn't handle null || undefined values. Hence, add in properties only if they are defined.
|
||||
const res = {
|
||||
maxHeight: {},
|
||||
maxWidth: {},
|
||||
minHeight: {},
|
||||
minWidth: {},
|
||||
};
|
||||
if (data?.maxHeight)
|
||||
res.maxHeight = { base: addPixelToSize(data.maxHeight) };
|
||||
if (data?.maxWidth)
|
||||
res.maxWidth = { base: addPixelToSize(data.maxWidth) };
|
||||
if (data?.minHeight)
|
||||
res.minHeight = { base: addPixelToSize(data.minHeight) };
|
||||
if (data?.minWidth)
|
||||
res.minWidth = { base: addPixelToSize(data.minWidth) };
|
||||
return res;
|
||||
}
|
||||
return {
|
||||
maxHeight: data?.maxHeight
|
||||
? {
|
||||
...acc.maxHeight,
|
||||
[addPixelToSize(size.viewportMinWidth)]: addPixelToSize(
|
||||
data?.maxHeight,
|
||||
),
|
||||
}
|
||||
: acc,
|
||||
maxWidth: data?.maxWidth
|
||||
? {
|
||||
...acc.maxWidth,
|
||||
[addPixelToSize(size.viewportMinWidth)]: addPixelToSize(
|
||||
data?.maxWidth,
|
||||
),
|
||||
}
|
||||
: acc,
|
||||
minHeight: data?.minHeight
|
||||
? {
|
||||
...acc.minHeight,
|
||||
[addPixelToSize(size.viewportMinWidth)]: addPixelToSize(
|
||||
data?.minHeight,
|
||||
),
|
||||
}
|
||||
: acc,
|
||||
minWidth: data?.minWidth
|
||||
? {
|
||||
...acc.minWidth,
|
||||
[addPixelToSize(size.viewportMinWidth)]: addPixelToSize(
|
||||
data?.minWidth,
|
||||
),
|
||||
}
|
||||
: acc,
|
||||
};
|
||||
},
|
||||
{
|
||||
maxHeight: {},
|
||||
maxWidth: {},
|
||||
minHeight: {},
|
||||
minWidth: {},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
export const addPixelToSize = (size: number | string): string => {
|
||||
if (!size) return "";
|
||||
return typeof size === "string" ? size : `${size}px`;
|
||||
};
|
||||
75
app/client/src/layoutSystems/common/utils/constants.ts
Normal file
75
app/client/src/layoutSystems/common/utils/constants.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
export enum LayoutDirection {
|
||||
Horizontal = "Horizontal",
|
||||
Vertical = "Vertical",
|
||||
}
|
||||
|
||||
export enum JustifyContent {
|
||||
FlexStart = "flex-start",
|
||||
Center = "center",
|
||||
SpaceAround = "space-around",
|
||||
SpaceBetween = "space-between",
|
||||
SpaceEvenly = "space-evenly",
|
||||
FlexEnd = "flex-end",
|
||||
}
|
||||
|
||||
export enum AlignItems {
|
||||
FlexStart = "flex-start",
|
||||
Center = "center",
|
||||
Stretch = "stretch",
|
||||
FlexEnd = "flex-end",
|
||||
}
|
||||
|
||||
export enum Positioning {
|
||||
Fixed = "fixed",
|
||||
Horizontal = "horizontal",
|
||||
Vertical = "vertical",
|
||||
}
|
||||
|
||||
export enum ResponsiveBehavior {
|
||||
Fill = "fill",
|
||||
Hug = "hug",
|
||||
}
|
||||
|
||||
export enum FlexDirection {
|
||||
Row = "row",
|
||||
RowReverse = "row-reverse",
|
||||
Column = "column",
|
||||
ColumnReverse = "column-reverse",
|
||||
}
|
||||
|
||||
export enum Alignment {
|
||||
Top = "top",
|
||||
Bottom = "bottom",
|
||||
Left = "left",
|
||||
Right = "right",
|
||||
}
|
||||
|
||||
export enum Spacing {
|
||||
None = "none",
|
||||
Equal = "equal",
|
||||
SpaceBetween = "space-between",
|
||||
}
|
||||
|
||||
export enum Overflow {
|
||||
Wrap = "wrap",
|
||||
NoWrap = "nowrap",
|
||||
Hidden = "hidden",
|
||||
Scroll = "scroll",
|
||||
Auto = "auto",
|
||||
}
|
||||
|
||||
export enum FlexLayerAlignment {
|
||||
None = "none",
|
||||
Start = "start",
|
||||
Center = "center",
|
||||
End = "end",
|
||||
}
|
||||
|
||||
export enum FlexVerticalAlignment {
|
||||
Top = "start",
|
||||
Center = "center",
|
||||
Bottom = "end",
|
||||
}
|
||||
|
||||
export const ROW_GAP = 12;
|
||||
export const MOBILE_ROW_GAP = 8;
|
||||
|
|
@ -1,28 +1,5 @@
|
|||
import type { FlattenedWidgetProps } from "WidgetProvider/constants";
|
||||
import type { FlexLayerAlignment } from "./constants";
|
||||
|
||||
export type AlignmentColumnInfo = {
|
||||
[key in FlexLayerAlignment]: number;
|
||||
};
|
||||
|
||||
export type FlexBoxAlignmentColumnInfo = {
|
||||
[key: number]: AlignmentColumnInfo;
|
||||
};
|
||||
|
||||
export type AlignmentColumnData = {
|
||||
alignment: FlexLayerAlignment;
|
||||
columns: number;
|
||||
};
|
||||
|
||||
export interface LayerChild {
|
||||
id: string;
|
||||
align: FlexLayerAlignment;
|
||||
}
|
||||
|
||||
export interface FlexLayer {
|
||||
children: LayerChild[];
|
||||
}
|
||||
|
||||
export interface DropZone {
|
||||
top?: number;
|
||||
bottom?: number;
|
||||
|
|
@ -44,27 +21,3 @@ export interface HighlightInfo {
|
|||
canvasId: string; // widgetId of the canvas to which the highlight belongs.
|
||||
dropZone: DropZone; // size of the drop zone of this highlight.
|
||||
}
|
||||
|
||||
/**
|
||||
* Start: Position utils types
|
||||
*/
|
||||
|
||||
export interface AlignmentChildren {
|
||||
widget: FlattenedWidgetProps;
|
||||
columns: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface AlignmentInfo {
|
||||
alignment: FlexLayerAlignment;
|
||||
columns: number;
|
||||
children: AlignmentChildren[];
|
||||
}
|
||||
|
||||
export interface Row extends AlignmentInfo {
|
||||
height: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* End: Position utils types
|
||||
*/
|
||||
|
|
@ -11,7 +11,7 @@ import { withLayoutSystemHOC } from "./withLayoutSystemHOC";
|
|||
|
||||
describe("Layout System HOC's Tests", () => {
|
||||
describe("Fixed Layout Layers", () => {
|
||||
it("Layout system hoc should return Fixed Editor for FIXED positioing and CANVAS render mode", () => {
|
||||
it("Layout system hoc should return Fixed Editor for FIXED positioning and CANVAS render mode", () => {
|
||||
const widget = InputWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[InputWidget.type].build();
|
||||
|
|
@ -29,7 +29,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(positionedLayer).toBeTruthy();
|
||||
expect(resizerLayer).toBeTruthy();
|
||||
});
|
||||
it("Layout system hoc should return Fixed Modal Editor for FIXED positioing and CANVAS render mode", () => {
|
||||
it("Layout system hoc should return Fixed Modal Editor for FIXED positioning and CANVAS render mode", () => {
|
||||
const widget = ModalWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[ModalWidget.type].build({
|
||||
|
|
@ -52,7 +52,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(overlayLayer).toBeTruthy();
|
||||
expect(resizerLayer).toBeTruthy();
|
||||
});
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for FIXED positioing and CANVAS render mode", () => {
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for FIXED positioning and CANVAS render mode", () => {
|
||||
const widget = CanvasWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[CanvasWidget.type].build();
|
||||
|
|
@ -70,7 +70,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(positionedLayer).toBeFalsy();
|
||||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
it("Layout system hoc should return Fixed Modal Viewer for FIXED positioing and PAGE render mode", () => {
|
||||
it("Layout system hoc should return Fixed Modal Viewer for FIXED positioning and PAGE render mode", () => {
|
||||
const widget = ModalWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[ModalWidget.type].build({
|
||||
|
|
@ -93,7 +93,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(overlayLayer).toBeTruthy();
|
||||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
it("Layout system hoc should return Fixed Viewer for FIXED positioing and PAGE render mode", () => {
|
||||
it("Layout system hoc should return Fixed Viewer for FIXED positioning and PAGE render mode", () => {
|
||||
const widget = InputWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[InputWidget.type].build();
|
||||
|
|
@ -112,7 +112,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for FIXED positioing and PAGE render mode", () => {
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for FIXED positioning and PAGE render mode", () => {
|
||||
const widget = CanvasWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[CanvasWidget.type].build();
|
||||
|
|
@ -132,7 +132,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
});
|
||||
});
|
||||
describe("Auto Layout Layers", () => {
|
||||
it("Layout system hoc should return Auto Layout Editor for AUTO positioing and CANVAS render mode", () => {
|
||||
it("Layout system hoc should return Auto Layout Editor for AUTO positioning and CANVAS render mode", () => {
|
||||
const widget = InputWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[InputWidget.type].build();
|
||||
|
|
@ -151,7 +151,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(flexPositionedLayer).toBeTruthy();
|
||||
expect(resizerLayer).toBeTruthy();
|
||||
});
|
||||
it("Layout system hoc should return Auto Modal Editor for AUTO positioing and CANVAS render mode", () => {
|
||||
it("Layout system hoc should return Auto Modal Editor for AUTO positioning and CANVAS render mode", () => {
|
||||
const widget = ModalWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[ModalWidget.type].build({
|
||||
|
|
@ -175,7 +175,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(overlayLayer).toBeTruthy();
|
||||
expect(resizerLayer).toBeTruthy();
|
||||
});
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for AUTO positioing and CANVAS render mode", () => {
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for AUTO positioning and CANVAS render mode", () => {
|
||||
const widget = CanvasWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[CanvasWidget.type].build();
|
||||
|
|
@ -194,7 +194,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(flexPositionedLayer).toBeFalsy();
|
||||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
it("Layout system hoc should return Auto Modal Viewer for AUTO positioing and PAGE render mode", () => {
|
||||
it("Layout system hoc should return Auto Modal Viewer for AUTO positioning and PAGE render mode", () => {
|
||||
const widget = ModalWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[ModalWidget.type].build({
|
||||
|
|
@ -218,7 +218,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(overlayLayer).toBeTruthy();
|
||||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
it("Layout system hoc should return Auto Viewer for Auto positioing and PAGE render mode", () => {
|
||||
it("Layout system hoc should return Auto Viewer for Auto positioning and PAGE render mode", () => {
|
||||
const widget = InputWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[InputWidget.type].build();
|
||||
|
|
@ -238,7 +238,7 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for Auto positioing and PAGE render mode", () => {
|
||||
it("Layout system hoc should return no wrapper for CANVAS WIDGET for Auto positioning and PAGE render mode", () => {
|
||||
const widget = CanvasWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[CanvasWidget.type].build();
|
||||
|
|
@ -258,4 +258,112 @@ describe("Layout System HOC's Tests", () => {
|
|||
expect(resizerLayer).toBeFalsy();
|
||||
});
|
||||
});
|
||||
describe("Anvil Layers", () => {
|
||||
it("Layout system hoc should return Anvil Editor for ANVIL positioning and CANVAS render mode", () => {
|
||||
const widget = InputWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[InputWidget.type].build();
|
||||
jest
|
||||
.spyOn(editorSelectors, "getRenderMode")
|
||||
.mockImplementation(() => RenderModes.CANVAS);
|
||||
jest
|
||||
.spyOn(editorSelectors, "getAppPositioningType")
|
||||
.mockImplementation(() => AppPositioningTypes.ANVIL);
|
||||
const component = render(<HOC {...widgetProps} />);
|
||||
const flexPositionedLayer = component.container.getElementsByClassName(
|
||||
"anvil-layout-child-" + widgetProps.widgetId,
|
||||
)[0];
|
||||
expect(flexPositionedLayer).toBeTruthy();
|
||||
});
|
||||
it("should return Auto Modal Editor for ANVIL positioning and CANVAS render mode", () => {
|
||||
const widget = ModalWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[ModalWidget.type].build({
|
||||
isVisible: true,
|
||||
});
|
||||
jest
|
||||
.spyOn(editorSelectors, "getRenderMode")
|
||||
.mockImplementation(() => RenderModes.CANVAS);
|
||||
jest
|
||||
.spyOn(editorSelectors, "getAppPositioningType")
|
||||
.mockImplementation(() => AppPositioningTypes.ANVIL);
|
||||
const component = render(<HOC {...widgetProps} />);
|
||||
const flexPositionedLayer = component.container.getElementsByClassName(
|
||||
"anvil-layout-child-" + widgetProps.widgetId,
|
||||
)[0];
|
||||
const overlayLayer =
|
||||
component.container.getElementsByClassName("bp3-overlay")[0];
|
||||
expect(flexPositionedLayer).toBeFalsy();
|
||||
expect(overlayLayer).toBeTruthy();
|
||||
});
|
||||
it("should return no wrapper for CANVAS WIDGET for ANVIL positioning and CANVAS render mode", () => {
|
||||
const widget = CanvasWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[CanvasWidget.type].build();
|
||||
jest
|
||||
.spyOn(editorSelectors, "getRenderMode")
|
||||
.mockImplementation(() => RenderModes.CANVAS);
|
||||
jest
|
||||
.spyOn(editorSelectors, "getAppPositioningType")
|
||||
.mockImplementation(() => AppPositioningTypes.ANVIL);
|
||||
const component = render(<HOC {...widgetProps} />);
|
||||
const flexPositionedLayer = component.container.getElementsByClassName(
|
||||
"anvil-layout-child-" + widgetProps.widgetId,
|
||||
)[0];
|
||||
expect(flexPositionedLayer).toBeFalsy();
|
||||
});
|
||||
it("should return Auto Modal Viewer for ANVIL positioning and PAGE render mode", () => {
|
||||
const widget = ModalWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[ModalWidget.type].build({
|
||||
isVisible: true,
|
||||
});
|
||||
jest
|
||||
.spyOn(editorSelectors, "getRenderMode")
|
||||
.mockImplementation(() => RenderModes.PAGE);
|
||||
jest
|
||||
.spyOn(editorSelectors, "getAppPositioningType")
|
||||
.mockImplementation(() => AppPositioningTypes.ANVIL);
|
||||
const component = render(<HOC {...widgetProps} />);
|
||||
const flexPositionedLayer = component.container.getElementsByClassName(
|
||||
"anvil-layout-child-" + widgetProps.widgetId,
|
||||
)[0];
|
||||
const overlayLayer =
|
||||
component.container.getElementsByClassName("bp3-overlay")[0];
|
||||
expect(flexPositionedLayer).toBeFalsy();
|
||||
expect(overlayLayer).toBeTruthy();
|
||||
});
|
||||
it("should return Anvil Viewer for ANVIL positioning and PAGE render mode", () => {
|
||||
const widget = InputWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[InputWidget.type].build();
|
||||
jest
|
||||
.spyOn(editorSelectors, "getRenderMode")
|
||||
.mockImplementation(() => RenderModes.PAGE);
|
||||
jest
|
||||
.spyOn(editorSelectors, "getAppPositioningType")
|
||||
.mockImplementation(() => AppPositioningTypes.ANVIL);
|
||||
const component = render(<HOC {...widgetProps} />);
|
||||
const flexPositionedLayer = component.container.getElementsByClassName(
|
||||
"anvil-layout-child-" + widgetProps.widgetId,
|
||||
)[0];
|
||||
expect(flexPositionedLayer).toBeTruthy();
|
||||
});
|
||||
it("should return no wrapper for CANVAS WIDGET for ANVIL positioning and PAGE render mode", () => {
|
||||
const widget = CanvasWidget;
|
||||
const HOC = withLayoutSystemHOC(widget);
|
||||
const widgetProps = WidgetTypeFactories[CanvasWidget.type].build();
|
||||
jest
|
||||
.spyOn(editorSelectors, "getRenderMode")
|
||||
.mockImplementation(() => RenderModes.PAGE);
|
||||
jest
|
||||
.spyOn(editorSelectors, "getAppPositioningType")
|
||||
.mockImplementation(() => AppPositioningTypes.ANVIL);
|
||||
const component = render(<HOC {...widgetProps} />);
|
||||
const flexPositionedLayer = component.container.getElementsByClassName(
|
||||
"anvil-layout-child-" + widgetProps.widgetId,
|
||||
)[0];
|
||||
expect(flexPositionedLayer).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import { getAutoLayoutSystem } from "./autolayout";
|
||||
import { getFixedLayoutSystem } from "./fixedlayout";
|
||||
import { getAnvilSystem } from "./anvil";
|
||||
|
||||
export type LayoutSystem = {
|
||||
LayoutSystemWrapper: (props: WidgetProps) => any;
|
||||
|
|
@ -19,10 +20,13 @@ export const getLayoutSystem = (
|
|||
renderMode: RenderModes,
|
||||
appPositioningType: AppPositioningTypes,
|
||||
): LayoutSystem => {
|
||||
if (appPositioningType === AppPositioningTypes.AUTO) {
|
||||
return getAutoLayoutSystem(renderMode);
|
||||
} else {
|
||||
return getFixedLayoutSystem(renderMode);
|
||||
switch (appPositioningType) {
|
||||
case AppPositioningTypes.ANVIL:
|
||||
return getAnvilSystem(renderMode);
|
||||
case AppPositioningTypes.AUTO:
|
||||
return getAutoLayoutSystem(renderMode);
|
||||
default:
|
||||
return getFixedLayoutSystem(renderMode);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
16
app/client/src/mocks/widgetProps/input.ts
Normal file
16
app/client/src/mocks/widgetProps/input.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC";
|
||||
|
||||
export const inputProps: BaseWidgetProps = {
|
||||
type: "INPUT_WIDGET_V2",
|
||||
widgetId: "1",
|
||||
widgetName: "Input1",
|
||||
renderMode: "CANVAS",
|
||||
version: 1,
|
||||
isLoading: false,
|
||||
parentColumnSpace: 10,
|
||||
parentRowSpace: 10,
|
||||
leftColumn: 0,
|
||||
rightColumn: 10,
|
||||
topRow: 0,
|
||||
bottomRow: 7,
|
||||
};
|
||||
|
|
@ -255,6 +255,7 @@ export interface AppLayoutConfig {
|
|||
|
||||
export enum AppPositioningTypes {
|
||||
FIXED = "FIXED",
|
||||
ANVIL = "ANVIL",
|
||||
AUTO = "AUTO",
|
||||
}
|
||||
export interface AppPositioningTypeConfig {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import {
|
|||
ReduxActionErrorTypes,
|
||||
ReduxActionTypes,
|
||||
} from "@appsmith/constants/ReduxActionConstants";
|
||||
import type { FlexLayerAlignment } from "layoutSystems/autolayout/utils/constants";
|
||||
import { LayoutDirection } from "layoutSystems/autolayout/utils/constants";
|
||||
import type { FlexLayerAlignment } from "layoutSystems/common/utils/constants";
|
||||
import { LayoutDirection } from "layoutSystems/common/utils/constants";
|
||||
import {
|
||||
GridDefaults,
|
||||
MAIN_CONTAINER_WIDGET_ID,
|
||||
|
|
@ -23,10 +23,7 @@ import {
|
|||
updateExistingLayer,
|
||||
updateRelationships,
|
||||
} from "layoutSystems/autolayout/utils/autoLayoutDraggingUtils";
|
||||
import type {
|
||||
HighlightInfo,
|
||||
FlexLayer,
|
||||
} from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import type { HighlightInfo } from "layoutSystems/common/utils/types";
|
||||
import { updatePositionsOfParentAndSiblings } from "layoutSystems/autolayout/utils/positionUtils";
|
||||
import {
|
||||
getCanvasWidth,
|
||||
|
|
@ -34,6 +31,7 @@ import {
|
|||
} from "selectors/editorSelectors";
|
||||
import { executeWidgetBlueprintBeforeOperations } from "sagas/WidgetBlueprintSagas";
|
||||
import { BlueprintOperationTypes } from "WidgetProvider/constants";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/types";
|
||||
|
||||
function* addWidgetAndReorderSaga(
|
||||
actionPayload: ReduxAction<{
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ import { recalculateAutoLayoutColumnsAndSave } from "./AutoLayoutUpdateSagas";
|
|||
import {
|
||||
FlexLayerAlignment,
|
||||
LayoutDirection,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
const WidgetTypes = WidgetFactory.widgetTypes;
|
||||
|
||||
export function* createModalSaga(action: ReduxAction<{ modalName: string }>) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ import { klona as clone } from "klona/full";
|
|||
import type { DataTree } from "@appsmith/entities/DataTree/types";
|
||||
import { generateAutoHeightLayoutTreeAction } from "actions/autoHeightActions";
|
||||
import { toast } from "design-system";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { isStack } from "../layoutSystems/autolayout/utils/AutoLayoutUtils";
|
||||
import {
|
||||
getCanvasWidth,
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@ import {
|
|||
} from "entities/Widget/utils";
|
||||
import { getSelectedWidgets } from "selectors/ui";
|
||||
import { getReflow } from "selectors/widgetReflowSelectors";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import {
|
||||
addChildToPastedFlexLayers,
|
||||
getFlexLayersForSelectedWidgets,
|
||||
|
|
@ -181,8 +180,9 @@ import { getWidgetWidth } from "layoutSystems/autolayout/utils/flexWidgetUtils";
|
|||
import {
|
||||
FlexLayerAlignment,
|
||||
LayoutDirection,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import localStorage from "utils/localStorage";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/types";
|
||||
import { EMPTY_BINDING } from "components/editorComponents/ActionCreator/constants";
|
||||
|
||||
export function* resizeSaga(resizeAction: ReduxAction<WidgetResize>) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ import type { WidgetEntity } from "@appsmith/entities/DataTree/types";
|
|||
import { isWidget } from "@appsmith/workers/Evaluation/evaluationUtils";
|
||||
import { CANVAS_DEFAULT_MIN_HEIGHT_PX } from "constants/AppConstants";
|
||||
import type { MetaState } from "reducers/entityReducers/metaReducer";
|
||||
import { Positioning } from "layoutSystems/autolayout/utils/constants";
|
||||
import { Positioning } from "layoutSystems/common/utils/constants";
|
||||
import { AppPositioningTypes } from "reducers/entityReducers/pageListReducer";
|
||||
|
||||
export interface CopiedWidgetGroup {
|
||||
|
|
|
|||
|
|
@ -5,11 +5,13 @@ import { getCanvasAndMetaWidgets } from "sagas/selectors";
|
|||
import type {
|
||||
AlignmentColumnInfo,
|
||||
FlexBoxAlignmentColumnInfo,
|
||||
FlexLayer,
|
||||
LayerChild,
|
||||
} from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
} from "layoutSystems/autolayout/utils/types";
|
||||
import { getAlignmentColumnInfo } from "layoutSystems/autolayout/utils/AutoLayoutUtils";
|
||||
import { getIsAutoLayoutMobileBreakPoint } from "./editorSelectors";
|
||||
import type {
|
||||
FlexLayer,
|
||||
LayerChild,
|
||||
} from "layoutSystems/autolayout/utils/types";
|
||||
|
||||
export const getIsCurrentlyConvertingLayout = (state: AppState) =>
|
||||
state.ui.layoutConversion.isConverting;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {
|
|||
alterLayoutForDesktop,
|
||||
alterLayoutForMobile,
|
||||
} from "layoutSystems/autolayout/utils/AutoLayoutUtils";
|
||||
import { Positioning } from "layoutSystems/autolayout/utils/constants";
|
||||
import { Positioning } from "layoutSystems/common/utils/constants";
|
||||
import {
|
||||
getTopRow,
|
||||
getBottomRow,
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ import {
|
|||
MAIN_CONTAINER_WIDGET_ID,
|
||||
} from "constants/WidgetConstants";
|
||||
import { get, partition } from "lodash";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import { alterLayoutForDesktop } from "layoutSystems/autolayout/utils/AutoLayoutUtils";
|
||||
import {
|
||||
FlexLayerAlignment,
|
||||
FlexVerticalAlignment,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type { DynamicPath } from "utils/DynamicBindingUtils";
|
||||
import {
|
||||
isDynamicValue,
|
||||
|
|
@ -22,6 +21,7 @@ import WidgetFactory from "WidgetProvider/factory";
|
|||
// import { DynamicHeight } from "utils/WidgetFeatures";
|
||||
import type { WidgetProps } from "widgets/BaseWidget";
|
||||
import type { DSLWidget } from "WidgetProvider/constants";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/types";
|
||||
|
||||
const unHandledWidgets = ["LIST_WIDGET"];
|
||||
const specialCaseWidgets = ["LIST_WIDGET_V2"];
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import type { DSLWidget } from "WidgetProvider/constants";
|
||||
import {
|
||||
fitChildWidgetsIntoLayers,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import {
|
|||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
Spacing,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
|
||||
export interface LayoutProperties {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import AudioRecorderComponent from "../component";
|
|||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants";
|
|||
import { getAssetUrl } from "@appsmith/utils/airgapHelpers";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import BaseInputComponent from "../component";
|
|||
import { InputTypes } from "../constants";
|
||||
import { checkInputTypeTextByProps } from "../utils";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
||||
import IconSVG from "../icon.svg";
|
||||
import type {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import IconSVG from "../icon.svg";
|
|||
import type { BaseInputWidgetProps } from "./types";
|
||||
import { propertyPaneContentConfig } from "./contentConfig";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import type { WidgetBaseConfiguration } from "WidgetProvider/constants";
|
||||
|
||||
class BaseInputWidget<
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import type {
|
|||
FlexVerticalAlignment,
|
||||
LayoutDirection,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { AppPositioningTypes } from "reducers/entityReducers/pageListReducer";
|
||||
import type { FeatureFlag } from "@appsmith/entities/FeatureFlag";
|
||||
import store from "store";
|
||||
|
|
@ -421,6 +421,9 @@ export interface WidgetBaseProps {
|
|||
additionalStaticProps?: string[];
|
||||
mainCanvasWidth?: number;
|
||||
isMobile?: boolean;
|
||||
hasAutoHeight?: boolean;
|
||||
hasAutoWidth?: boolean;
|
||||
widgetSize?: { [key: string]: Record<string, string | number> };
|
||||
}
|
||||
|
||||
export type WidgetRowCols = {
|
||||
|
|
@ -455,6 +458,7 @@ export interface WidgetPositionProps extends WidgetRowCols {
|
|||
appPositioningType?: AppPositioningTypes;
|
||||
widthInPercentage?: number; // Stores the widget's width set by the user
|
||||
mobileWidthInPercentage?: number;
|
||||
width?: number;
|
||||
}
|
||||
|
||||
export const WIDGET_DISPLAY_PROPS = {
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { klona as clone } from "klona/full";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { BlueprintOperationTypes } from "WidgetProvider/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { WIDGET_TAGS, layoutConfigurations } from "constants/WidgetConstants";
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { isAirgapped } from "@appsmith/utils/airgapHelpers";
|
||||
import { BUTTON_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
|
||||
import type {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import { COLORS, BUTTON_VARIANTS } from "@design-system/widgets";
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { ButtonPlacementTypes, RecaptchaTypes } from "components/constants";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import type { ExecutionResult } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
||||
class ButtonWidget extends BaseWidget<ButtonWidgetProps, ButtonWidgetState> {
|
||||
constructor(props: ButtonWidgetProps) {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import {
|
|||
DEFAULT_CAMERA_LABEL_DESCRIPTION,
|
||||
FRONT_CAMERA_LABEL,
|
||||
} from "@appsmith/constants/messages";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import {
|
|||
LayoutDirection,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import DropTargetComponent from "components/editorComponents/DropTargetComponent";
|
||||
import { CANVAS_DEFAULT_MIN_HEIGHT_PX } from "constants/AppConstants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { Alignment } from "@blueprintjs/core";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import { ChartErrorComponent } from "../component/ChartErrorComponent";
|
|||
import { syntaxErrorsFromProps } from "./SyntaxErrorsEvaluation";
|
||||
import { EmptyChartData } from "../component/EmptyChartData";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { generateReactKey } from "widgets/WidgetUtils";
|
||||
import { LabelOrientation } from "../constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import BaseWidget from "../../BaseWidget";
|
|||
import CheckboxComponent from "../component";
|
||||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import type {
|
||||
SnipingModeProperty,
|
||||
PropertyUpdates,
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import IconSVG from "../icon.svg";
|
|||
|
||||
import { ButtonPlacementTypes } from "components/constants";
|
||||
import { ScannerLayout } from "../constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
class CodeScannerWidget extends BaseWidget<
|
||||
CodeScannerWidgetProps,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import { compact, map, sortBy } from "lodash";
|
|||
import WidgetsMultiSelectBox from "pages/Editor/WidgetsMultiSelectBox";
|
||||
|
||||
import type { SetterConfig, Stylesheet } from "entities/AppTheming";
|
||||
import { Positioning } from "layoutSystems/autolayout/utils/constants";
|
||||
import { getSnappedGrid } from "sagas/WidgetOperationUtils";
|
||||
import { ReduxActionTypes } from "@appsmith/constants/ReduxActionConstants";
|
||||
import {
|
||||
|
|
@ -36,8 +35,9 @@ import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
|||
import { GridDefaults, WidgetHeightLimits } from "constants/WidgetConstants";
|
||||
import {
|
||||
FlexVerticalAlignment,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
|
||||
export class ContainerWidget extends BaseWidget<
|
||||
ContainerWidgetProps<WidgetProps>,
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ import { NumberInputStepButtonPosition } from "widgets/BaseInputWidget/constants
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||
import { getDefaultCurrency } from "../component/CurrencyCodeDropdown";
|
||||
import IconSVG from "../icon.svg";
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import { isAutoLayout } from "layoutSystems/autolayout/utils/flexWidgetUtils";
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import moment from "moment";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||
import IconSVG from "../icon.svg";
|
||||
import type {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
|||
import type { SetterConfig } from "entities/AppTheming";
|
||||
import { Colors } from "constants/Colors";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import DocumentViewerComponent from "../component";
|
|||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import type { SetterConfig } from "entities/AppTheming";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
|
||||
import { isAirgapped } from "@appsmith/utils/airgapHelpers";
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
|||
import parseFileData from "./FileParser";
|
||||
import { FilePickerGlobalStyles } from "./index.styled";
|
||||
import { BUTTON_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
||||
|
|
|
|||
|
|
@ -5,8 +5,11 @@ import type { WidgetProps } from "../../BaseWidget";
|
|||
import type { ContainerWidgetProps } from "widgets/ContainerWidget/widget";
|
||||
import { ContainerWidget } from "widgets/ContainerWidget/widget";
|
||||
import type { ContainerComponentProps } from "widgets/ContainerWidget/component";
|
||||
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
||||
import { Positioning } from "layoutSystems/autolayout/utils/constants";
|
||||
import {
|
||||
FlexLayerAlignment,
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
|
|
@ -17,16 +20,13 @@ import { Colors } from "constants/Colors";
|
|||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { GridDefaults, WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer";
|
||||
import {
|
||||
FlexLayerAlignment,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
import { getWidgetBluePrintUpdates } from "utils/WidgetBlueprintUtils";
|
||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||
import { BlueprintOperationTypes } from "WidgetProvider/constants";
|
||||
import type { FlattenedWidgetProps } from "WidgetProvider/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/autoLayoutTypes";
|
||||
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
||||
import type { FlexLayer } from "layoutSystems/autolayout/utils/types";
|
||||
|
||||
class FormWidget extends ContainerWidget {
|
||||
static type = "FORM_WIDGET";
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import IconButtonComponent from "../component";
|
|||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { ICON_BUTTON_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import type { IframeWidgetProps } from "../constants";
|
|||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import IconSVG from "../icon.svg";
|
||||
import { isAirgapped } from "@appsmith/utils/airgapHelpers";
|
||||
import type {
|
||||
|
|
@ -17,6 +16,7 @@ import type {
|
|||
PropertyUpdates,
|
||||
} from "WidgetProvider/constants";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
||||
const isAirgappedInstance = isAirgapped();
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import { checkInputTypeTextByProps } from "widgets/BaseInputWidget/utils";
|
|||
import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
||||
import { LabelPosition } from "components/constants";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||
|
||||
import IconSVG from "../icon.svg";
|
||||
|
|
@ -46,6 +45,7 @@ import type {
|
|||
PropertyUpdates,
|
||||
} from "WidgetProvider/constants";
|
||||
import { WIDGET_TAGS } from "constants/WidgetConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
||||
export function defaultValueValidation(
|
||||
value: any,
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
|||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { BaseInputWidgetProps } from "widgets/BaseInputWidgetV2";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
|
||||
class InputWidget extends BaseInputWidget<InputWidgetProps, WidgetState> {
|
||||
static getConfig() {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import type { AutocompletionDefinitions } from "WidgetProvider/constants";
|
|||
import { ButtonVariantTypes } from "components/constants";
|
||||
import { Colors } from "constants/Colors";
|
||||
import { FILL_WIDGET_MIN_WIDTH } from "constants/minWidthConstants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/autolayout/utils/constants";
|
||||
import { ResponsiveBehavior } from "layoutSystems/common/utils/constants";
|
||||
import { DynamicHeight } from "utils/WidgetFeatures";
|
||||
import { BlueprintOperationTypes } from "WidgetProvider/constants";
|
||||
import type {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
Positioning,
|
||||
ResponsiveBehavior,
|
||||
} from "layoutSystems/autolayout/utils/constants";
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { EventType } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { GridDefaults, RenderModes } from "constants/WidgetConstants";
|
||||
import { ValidationTypes } from "constants/WidgetValidation";
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user