diff --git a/app/client/src/index.css b/app/client/src/index.css index c42309263b..0ea4ab6d37 100755 --- a/app/client/src/index.css +++ b/app/client/src/index.css @@ -248,3 +248,15 @@ div.bp3-popover-arrow { .reconnect-datasource-modal { z-index: 9 !important; } + +/** Conditional vertical margin applied to widgets. + If in a row of widgets (.aligned-widget-row), one of the widgets has a label ([data-field-label-wrapper]), then + all widgets (.anvil-widget-wrapper) in the row other than the widget with the label, will shift down using the + margin-block-start property. This is to ensure that the widgets are aligned vertically. + + The value of the margin-block-start property is calculated based on the spacing tokens used by the labels in input like components +*/ +.aligned-widget-row:has(.anvil-widget-wrapper [data-field-label-wrapper]) + .anvil-widget-wrapper:not(:has([data-field-label-wrapper])) { + margin-block-start: calc(var(--inner-spacing-2) + var(--sizing-3)); +} diff --git a/app/client/src/layoutSystems/anvil/common/AnvilFlexComponent.tsx b/app/client/src/layoutSystems/anvil/common/AnvilFlexComponent.tsx index c49a72c07e..22ca674b04 100644 --- a/app/client/src/layoutSystems/anvil/common/AnvilFlexComponent.tsx +++ b/app/client/src/layoutSystems/anvil/common/AnvilFlexComponent.tsx @@ -107,7 +107,7 @@ export function AnvilFlexComponent(props: AnvilFlexComponentProps) { props.widgetType, )} t--widget-${props.widgetName.toLowerCase()} drop-target-${ props.layoutId - } row-index-${props.rowIndex}`, + } row-index-${props.rowIndex} anvil-widget-wrapper`, [ props.parentId, props.widgetId, @@ -129,6 +129,8 @@ export function AnvilFlexComponent(props: AnvilFlexComponentProps) { height: "auto", padding: "spacing-1", width: "auto", + minHeight: { base: "var(--sizing-12)" }, + alignItems: "center", }; if (props?.widgetSize) { // adding min max limits only if they are available, as WDS Flex doesn't handle undefined values. @@ -138,9 +140,7 @@ export function AnvilFlexComponent(props: AnvilFlexComponentProps) { 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( @@ -158,7 +158,7 @@ export function AnvilFlexComponent(props: AnvilFlexComponentProps) { return { position: "relative", // overflow is set to make sure widgets internal components/divs don't overflow this boundary causing scrolls - overflow: "hidden", + overflow: "visible", opacity: (isDragging && isSelected) || !props.isVisible ? 0.5 : 1, "&:hover": { zIndex: onHoverZIndex, diff --git a/app/client/src/layoutSystems/anvil/layoutComponents/components/AlignedWidgetRow.tsx b/app/client/src/layoutSystems/anvil/layoutComponents/components/AlignedWidgetRow.tsx index b0b7f1c109..f1e9713019 100644 --- a/app/client/src/layoutSystems/anvil/layoutComponents/components/AlignedWidgetRow.tsx +++ b/app/client/src/layoutSystems/anvil/layoutComponents/components/AlignedWidgetRow.tsx @@ -24,6 +24,7 @@ class AlignedWidgetRow extends BaseLayoutComponent { alignSelf: "stretch", direction: "row", wrap: "wrap", + className: "aligned-widget-row", }; } } diff --git a/app/client/src/layoutSystems/anvil/layoutComponents/components/FlexLayout.tsx b/app/client/src/layoutSystems/anvil/layoutComponents/components/FlexLayout.tsx index 85a34dbda3..251c2c4270 100644 --- a/app/client/src/layoutSystems/anvil/layoutComponents/components/FlexLayout.tsx +++ b/app/client/src/layoutSystems/anvil/layoutComponents/components/FlexLayout.tsx @@ -18,7 +18,7 @@ import type { } from "layoutSystems/anvil/utils/types"; import { usePositionObserver } from "layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver"; import { getAnvilLayoutDOMId } from "layoutSystems/common/utils/LayoutElementPositionsObserver/utils"; -import { type RenderMode, RenderModes } from "constants/WidgetConstants"; +import type { RenderMode } from "constants/WidgetConstants"; import type { LayoutComponentTypes } from "layoutSystems/anvil/utils/anvilTypes"; export const FLEX_LAYOUT_PADDING = 4; @@ -54,6 +54,7 @@ export interface FlexLayoutProps rowGap?: Responsive; padding?: Responsive; width?: Responsive; + className?: string; } export const FlexLayout = React.memo((props: FlexLayoutProps) => { @@ -62,6 +63,7 @@ export const FlexLayout = React.memo((props: FlexLayoutProps) => { border, canvasId, children, + className, columnGap, direction, flexBasis, @@ -118,10 +120,11 @@ export const FlexLayout = React.memo((props: FlexLayoutProps) => { maxWidth: maxWidth || "none", minHeight: minHeight || "unset", minWidth: minWidth || "unset", - padding: padding || (isDropTarget ? `${FLEX_LAYOUT_PADDING}px` : "0px"), + padding: padding || (isDropTarget ? `spacing-0` : "0px"), rowGap: rowGap || "0px", width: width || "auto", wrap: wrap || "nowrap", + className: className || "", }; }, [ alignSelf, @@ -146,17 +149,12 @@ export const FlexLayout = React.memo((props: FlexLayoutProps) => { // The following properties aren't included in type FlexProps but can be passed as style. const styleProps: CSSProperties = useMemo(() => { return { - border: - border || - (isDropTarget && renderMode === RenderModes.CANVAS - ? "1px dashed #979797" - : "none"), position: position || "relative", }; }, [border, isDropTarget, position, renderMode]); - const className = useMemo(() => { - return `layout-${layoutId} layout-index-${layoutIndex} ${ + const _className = useMemo(() => { + return `${className} layout-${layoutId} layout-index-${layoutIndex} ${ isContainer ? "make-container" : "" }`; }, [isContainer, layoutId, layoutIndex]); @@ -164,7 +162,7 @@ export const FlexLayout = React.memo((props: FlexLayoutProps) => { return ( +>` + height: 100%; + width: 100%; + overflow: hidden; + outline: none; + border: none; + position: relative; + + ${(props) => + props.elevatedBackground + ? `background: var(--color-bg-elevation-${props.elevation}); box-shadow: var(--box-shadow-${props.elevation});` + : ""} + + border-radius: var(--border-radius-1); + padding-block: var(--outer-spacing-1); + padding-inline: var(--outer-spacing-1); + ${(props) => + props.elevation === Elevations.SECTION_ELEVATION + ? `padding-block: var(--outer-spacing-0); padding-inline: var(--outer-spacing-0);` + : ""} + + border-width: var(--border-width-1); +`; + +export function ContainerComponent(props: ContainerComponentProps) { + return ( + + {props.children} + + ); +} + +export interface ContainerComponentProps { + widgetId: string; + children?: ReactNode; + elevation: Elevations; + elevatedBackground: boolean; +} diff --git a/app/client/src/widgets/anvil/SectionWidget/widget/config/defaultConfig.ts b/app/client/src/widgets/anvil/SectionWidget/widget/config/defaultConfig.ts index 0c6bca1a54..abb2d82247 100644 --- a/app/client/src/widgets/anvil/SectionWidget/widget/config/defaultConfig.ts +++ b/app/client/src/widgets/anvil/SectionWidget/widget/config/defaultConfig.ts @@ -12,7 +12,7 @@ import { sectionPreset } from "layoutSystems/anvil/layoutComponents/presets/sect import { ButtonBoxShadowTypes } from "components/constants"; export const defaultConfig: WidgetDefaultProps = { - backgroundColor: "lightslategrey", + elevatedBackground: false, borderRadius: "0.375rem", boxShadow: ButtonBoxShadowTypes.NONE, children: [], diff --git a/app/client/src/widgets/anvil/SectionWidget/widget/config/propertyPaneStyle.ts b/app/client/src/widgets/anvil/SectionWidget/widget/config/propertyPaneStyle.ts index ff5175a774..4cccba2557 100644 --- a/app/client/src/widgets/anvil/SectionWidget/widget/config/propertyPaneStyle.ts +++ b/app/client/src/widgets/anvil/SectionWidget/widget/config/propertyPaneStyle.ts @@ -2,64 +2,20 @@ import { ValidationTypes } from "constants/WidgetValidation"; export const propertyPaneStyle = [ { - sectionName: "Color", + sectionName: "Background", children: [ { - helpText: "Use a html color name, HEX, RGB or RGBA value", - placeholderText: "#FFFFFF / Gray / rgb(255, 99, 71)", - propertyName: "backgroundColor", - label: "Background color", - controlType: "COLOR_PICKER", + propertyName: "elevatedBackground", + label: "Background", + controlType: "SWITCH", + fullWidth: true, + helpText: "Sets the semantic elevated background of the section", isJSConvertible: true, isBindProperty: true, isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, - }, - { - helpText: "Use a html color name, HEX, RGB or RGBA value", - placeholderText: "#FFFFFF / Gray / rgb(255, 99, 71)", - propertyName: "borderColor", - label: "Border color", - controlType: "COLOR_PICKER", - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, - }, - ], - }, - { - sectionName: "Border and shadow", - children: [ - { - helpText: "Enter value for border width", - propertyName: "borderWidth", - label: "Border width", - placeholderText: "Enter value in px", - controlType: "INPUT_TEXT", - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.NUMBER }, - }, - { - propertyName: "borderRadius", - label: "Border radius", - helpText: "Rounds the corners of the icon button's outer border edge", - controlType: "BORDER_RADIUS_OPTIONS", - isJSConvertible: true, - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, - }, - { - propertyName: "boxShadow", - label: "Box shadow", - helpText: - "Enables you to cast a drop shadow from the frame of the widget", - controlType: "BOX_SHADOW_OPTIONS", - isJSConvertible: true, - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, + validation: { + type: ValidationTypes.BOOLEAN, + }, }, ], }, diff --git a/app/client/src/widgets/anvil/SectionWidget/widget/index.tsx b/app/client/src/widgets/anvil/SectionWidget/widget/index.tsx index 7352f15384..3f8ed8f0c3 100644 --- a/app/client/src/widgets/anvil/SectionWidget/widget/index.tsx +++ b/app/client/src/widgets/anvil/SectionWidget/widget/index.tsx @@ -20,9 +20,9 @@ import type { LayoutProps } from "layoutSystems/anvil/utils/anvilTypes"; import BaseWidget from "widgets/BaseWidget"; import type { ReactNode } from "react"; import React from "react"; -import ContainerComponent from "widgets/ContainerWidget/component"; +import { ContainerComponent } from "widgets/anvil/Container"; import { LayoutProvider } from "layoutSystems/anvil/layoutComponents/LayoutProvider"; -import { anvilWidgets } from "widgets/anvil/constants"; +import { Elevations, anvilWidgets } from "widgets/anvil/constants"; class SectionWidget extends BaseWidget { static type = anvilWidgets.SECTION_WIDGET; @@ -83,7 +83,11 @@ class SectionWidget extends BaseWidget { getWidgetView(): ReactNode { return ( - + ); diff --git a/app/client/src/widgets/anvil/ZoneWidget/widget/config/defaultConfig.ts b/app/client/src/widgets/anvil/ZoneWidget/widget/config/defaultConfig.ts index cfe71c6a05..d8aa8cf490 100644 --- a/app/client/src/widgets/anvil/ZoneWidget/widget/config/defaultConfig.ts +++ b/app/client/src/widgets/anvil/ZoneWidget/widget/config/defaultConfig.ts @@ -14,7 +14,7 @@ import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidg import { getWidgetBluePrintUpdates } from "utils/WidgetBlueprintUtils"; export const defaultConfig: WidgetDefaultProps = { - backgroundColor: "ghostwhite", + elevatedBackground: true, children: [], columns: 0, detachFromLayout: false, diff --git a/app/client/src/widgets/anvil/ZoneWidget/widget/config/propertyPaneStyle.ts b/app/client/src/widgets/anvil/ZoneWidget/widget/config/propertyPaneStyle.ts index ff5175a774..c6856be9fb 100644 --- a/app/client/src/widgets/anvil/ZoneWidget/widget/config/propertyPaneStyle.ts +++ b/app/client/src/widgets/anvil/ZoneWidget/widget/config/propertyPaneStyle.ts @@ -2,64 +2,20 @@ import { ValidationTypes } from "constants/WidgetValidation"; export const propertyPaneStyle = [ { - sectionName: "Color", + sectionName: "Background", children: [ { - helpText: "Use a html color name, HEX, RGB or RGBA value", - placeholderText: "#FFFFFF / Gray / rgb(255, 99, 71)", - propertyName: "backgroundColor", - label: "Background color", - controlType: "COLOR_PICKER", + propertyName: "elevatedBackground", + label: "Background", + controlType: "SWITCH", + fullWidth: true, + helpText: "Sets the semantic elevated background of the zone", isJSConvertible: true, isBindProperty: true, isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, - }, - { - helpText: "Use a html color name, HEX, RGB or RGBA value", - placeholderText: "#FFFFFF / Gray / rgb(255, 99, 71)", - propertyName: "borderColor", - label: "Border color", - controlType: "COLOR_PICKER", - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, - }, - ], - }, - { - sectionName: "Border and shadow", - children: [ - { - helpText: "Enter value for border width", - propertyName: "borderWidth", - label: "Border width", - placeholderText: "Enter value in px", - controlType: "INPUT_TEXT", - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.NUMBER }, - }, - { - propertyName: "borderRadius", - label: "Border radius", - helpText: "Rounds the corners of the icon button's outer border edge", - controlType: "BORDER_RADIUS_OPTIONS", - isJSConvertible: true, - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, - }, - { - propertyName: "boxShadow", - label: "Box shadow", - helpText: - "Enables you to cast a drop shadow from the frame of the widget", - controlType: "BOX_SHADOW_OPTIONS", - isJSConvertible: true, - isBindProperty: true, - isTriggerProperty: false, - validation: { type: ValidationTypes.TEXT }, + validation: { + type: ValidationTypes.BOOLEAN, + }, }, ], }, diff --git a/app/client/src/widgets/anvil/ZoneWidget/widget/index.tsx b/app/client/src/widgets/anvil/ZoneWidget/widget/index.tsx index 0237237be7..88019caefe 100644 --- a/app/client/src/widgets/anvil/ZoneWidget/widget/index.tsx +++ b/app/client/src/widgets/anvil/ZoneWidget/widget/index.tsx @@ -19,9 +19,9 @@ import BaseWidget from "widgets/BaseWidget"; import type { WidgetProps, WidgetState } from "widgets/BaseWidget"; import type { LayoutProps } from "layoutSystems/anvil/utils/anvilTypes"; import type { ContainerWidgetProps } from "widgets/ContainerWidget/widget"; -import ContainerComponent from "widgets/ContainerWidget/component"; +import { ContainerComponent } from "widgets/anvil/Container"; import { LayoutProvider } from "layoutSystems/anvil/layoutComponents/LayoutProvider"; -import { anvilWidgets } from "widgets/anvil/constants"; +import { Elevations, anvilWidgets } from "widgets/anvil/constants"; class ZoneWidget extends BaseWidget { static type = anvilWidgets.ZONE_WIDGET; @@ -82,7 +82,11 @@ class ZoneWidget extends BaseWidget { getWidgetView(): ReactNode { return ( - + ); diff --git a/app/client/src/widgets/anvil/constants.ts b/app/client/src/widgets/anvil/constants.ts index 62a9903449..b0cc740219 100644 --- a/app/client/src/widgets/anvil/constants.ts +++ b/app/client/src/widgets/anvil/constants.ts @@ -2,3 +2,8 @@ export const anvilWidgets = { SECTION_WIDGET: "SECTION_WIDGET", ZONE_WIDGET: "ZONE_WIDGET", }; + +export enum Elevations { + SECTION_ELEVATION = 1, + ZONE_ELEVATION = 2, +} diff --git a/app/client/src/widgets/wds/WDSParagraphWidget/widget/index.tsx b/app/client/src/widgets/wds/WDSParagraphWidget/widget/index.tsx index a0acbc612d..ad196e0409 100644 --- a/app/client/src/widgets/wds/WDSParagraphWidget/widget/index.tsx +++ b/app/client/src/widgets/wds/WDSParagraphWidget/widget/index.tsx @@ -73,9 +73,6 @@ class WDSParagraphWidget extends BaseWidget { isBold={this.props?.fontStyle?.includes("bold")} isItalic={this.props?.fontStyle?.includes("italic")} lineClamp={this.props.lineClamp ? this.props.lineClamp : undefined} - style={{ - paddingBottom: "0.5rem", - }} textAlign={this.props.textAlign} title={this.props.lineClamp ? this.props.text : undefined} variant={this.props.fontSize} diff --git a/app/client/src/widgets/wds/WDSTableWidget/widget/index.tsx b/app/client/src/widgets/wds/WDSTableWidget/widget/index.tsx index e49d3e51b3..17a67682fc 100644 --- a/app/client/src/widgets/wds/WDSTableWidget/widget/index.tsx +++ b/app/client/src/widgets/wds/WDSTableWidget/widget/index.tsx @@ -1181,8 +1181,6 @@ export class WDSTableWidget extends BaseWidget { }; getPaddingAdjustedDimensions = () => { - // eslint-disable-next-line prefer-const - let { componentHeight } = this.props; // Hacky fix for now to supply width to table widget let componentWidth: number = document @@ -1190,7 +1188,7 @@ export class WDSTableWidget extends BaseWidget { ?.getBoundingClientRect().width || this.props.componentWidth; // (2 * WIDGET_PADDING) gives the total horizontal padding (i.e. paddingLeft + paddingRight) componentWidth = componentWidth - 2 * WIDGET_PADDING; - return { componentHeight, componentWidth }; + return { componentHeight: 300, componentWidth }; }; getWidgetView() {