diff --git a/app/client/cypress/fixtures/displayWidgetDsl.json b/app/client/cypress/fixtures/displayWidgetDsl.json index 878fd793bf..01da343433 100644 --- a/app/client/cypress/fixtures/displayWidgetDsl.json +++ b/app/client/cypress/fixtures/displayWidgetDsl.json @@ -209,7 +209,6 @@ { "isVisible": true, "text": "Label", - "textStyle": "LABEL", "textAlign": "LEFT", "widgetName": "Text1", "type": "TEXT_WIDGET", diff --git a/app/client/cypress/fixtures/example.json b/app/client/cypress/fixtures/example.json index 3dee58e627..3e446160e2 100644 --- a/app/client/cypress/fixtures/example.json +++ b/app/client/cypress/fixtures/example.json @@ -103,9 +103,9 @@ "FormModalName": "Form_Modal", "TextLabelValue": "Test Text Label", "TextName": "TestTextBox", - "TextLabel": "Label", - "TextBody": "Body", - "TextHeading": "Heading", + "TextLabel": "Paragraph", + "TextBody": "Heading 2", + "TextHeading": "Heading 1", "Datepickername": "Datepicker", "DatepickerLable": "date", "RichTextEditorName": "RichtextEditor", diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Derived_Column_Data_validation_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Derived_Column_Data_validation_spec.js index ebc6b6de6d..2104fa8e76 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Derived_Column_Data_validation_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Table_Derived_Column_Data_validation_spec.js @@ -1,3 +1,4 @@ +/* eslint-disable cypress/no-unnecessary-waiting */ const commonlocators = require("../../../../locators/commonlocators.json"); const dsl = require("../../../../fixtures/tableTextPaginationDsl.json"); const apiPage = require("../../../../locators/ApiEditor.json"); diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js index 354cbd4f32..cf610c78f5 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/DisplayWidgets/Text_spec.js @@ -29,11 +29,11 @@ describe("Text Widget Functionality", function() { commonlocators.headingTextStyle, this.data.TextLabelValue, ); + cy.wait("@updateLayout"); cy.PublishtheApp(); - cy.get(commonlocators.headingTextStyle).should( - "have.text", - this.data.TextLabelValue, - ); + cy.get(commonlocators.headingTextStyle) + .should("have.text", this.data.TextLabelValue) + .should("have.css", "font-size", "24px"); }); it("Text-TextStyle Label Validation", function() { @@ -44,10 +44,9 @@ describe("Text Widget Functionality", function() { this.data.TextLabelValue, ); cy.PublishtheApp(); - cy.get(commonlocators.labelTextStyle).should( - "have.text", - this.data.TextLabelValue, - ); + cy.get(commonlocators.labelTextStyle) + .should("have.text", this.data.TextLabelValue) + .should("have.css", "font-size", "14px"); }); it("Text-TextStyle Body Validation", function() { @@ -57,10 +56,9 @@ describe("Text Widget Functionality", function() { this.data.TextLabelValue, ); cy.PublishtheApp(); - cy.get(commonlocators.bodyTextStyle).should( - "have.text", - this.data.TextLabelValue, - ); + cy.get(commonlocators.bodyTextStyle) + .should("have.text", this.data.TextLabelValue) + .should("have.css", "font-size", "18px"); }); it("Text widget depends on itself", function() { diff --git a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/Onboarding_spec.js b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/Onboarding_spec.js index b80bdbe14b..d8712160d2 100644 --- a/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/Onboarding_spec.js +++ b/app/client/cypress/integration/Smoke_TestSuite/ClientSideTests/Onboarding/Onboarding_spec.js @@ -1,3 +1,4 @@ +/* eslint-disable cypress/no-unnecessary-waiting */ // const explorer = require("../../../../locators/explorerlocators.json"); const homePage = require("../../../../locators/HomePage.json"); const commonlocators = require("../../../../locators/commonlocators.json"); diff --git a/app/client/cypress/locators/Widgets.json b/app/client/cypress/locators/Widgets.json index fc3b5ec6fe..fda4bfc2c6 100644 --- a/app/client/cypress/locators/Widgets.json +++ b/app/client/cypress/locators/Widgets.json @@ -36,7 +36,7 @@ "deleteWidget": ".t--modal-widget>div .t--widget-delete-control", "textbuttonWidget": ".t--draggable-buttonwidget button.bp3-button[type='button']", "textInputval": ".t--draggable-textwidget span.t--widget-name", - "textAlign": ".t--property-control-textalign", + "textCenterAlign": ".t--property-control-textalign .t--icon-tab-CENTER", "ColumnAction": ".t--property-control-rowbutton button", "videoWidget": ".t--draggable-videowidget", "autoPlay": ".t--property-control-autoplay > .bp3-control > .bp3-control-indicator", diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json index 4203086dff..42ff11ca99 100644 --- a/app/client/cypress/locators/commonlocators.json +++ b/app/client/cypress/locators/commonlocators.json @@ -31,10 +31,10 @@ "visibleCheckbox": ".t--property-control-visible input[type='checkbox']", "disableCheckbox": ".t--property-control-disabled input[type='checkbox']", "labelTextStyle": ".bp3-ui-text span", - "bodyTextStyle": ".bp3-running-text span", - "headingTextStyle": ".bp3-heading span", + "bodyTextStyle": ".bp3-ui-text span", + "headingTextStyle": ".bp3-ui-text span", "editWidgetName": ".t--propery-page-title", - "dropDownIcon": ".t--property-control-textstyle .bp3-popover-target", + "dropDownIcon": ".t--property-control-textsize .bp3-popover-target", "onDateSelectedField": ".t--property-control-ondateselected", "TableRow": ".t--draggable-tablewidget .tbody", "Disablejs": ".t--property-control-disabled", diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 3e42b2b8ed..b0e86ac092 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -997,12 +997,7 @@ Cypress.Commands.add("createModal", (modalType, ModalName) => { cy.get(widgetsPage.textWidget + " " + commonlocators.editIcon).click(); cy.testCodeMirror(ModalName); - cy.get(widgetsPage.textAlign + " " + commonlocators.dropDownBtn) - .last() - .click(); - cy.get(widgetsPage.alignOpt) - .contains("Center") - .click(); + cy.get(widgetsPage.textCenterAlign).click({ force: true }); cy.assertPageSave(); cy.get(".bp3-overlay-backdrop").click({ force: true }); }); @@ -1042,12 +1037,7 @@ Cypress.Commands.add("updateModal", (modalType, ModalName) => { cy.get(widgetsPage.textWidget + " " + commonlocators.editIcon).click(); cy.testCodeMirror(ModalName); - cy.get(widgetsPage.textAlign + " " + commonlocators.dropDownBtn) - .last() - .click(); - cy.get(widgetsPage.alignOpt) - .contains("Center") - .click(); + cy.get(widgetsPage.textCenterAlign).click({ force: true }); cy.assertPageSave(); cy.get(".bp3-overlay-backdrop").click({ force: true }); }); diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/Constants.test.ts b/app/client/src/components/designSystems/appsmith/TableComponent/Constants.test.ts new file mode 100644 index 0000000000..356919af05 --- /dev/null +++ b/app/client/src/components/designSystems/appsmith/TableComponent/Constants.test.ts @@ -0,0 +1,76 @@ +import { ConditionFunctions } from "components/designSystems/appsmith/TableComponent/Constants"; +import moment from "moment"; + +describe("ConditionFunctions Constants", () => { + it("works as expected for isExactly", () => { + const conditionFunction = ConditionFunctions["isExactly"]; + expect(conditionFunction("test", "test")).toStrictEqual(true); + }); + it("works as expected for isExactly", () => { + const conditionFunction = ConditionFunctions["isExactly"]; + expect(conditionFunction("test", "random")).toStrictEqual(false); + }); + it("works as expected for empty", () => { + const conditionFunction = ConditionFunctions["empty"]; + expect(conditionFunction("", "")).toStrictEqual(true); + }); + it("works as expected for notEmpty", () => { + const conditionFunction = ConditionFunctions["notEmpty"]; + expect(conditionFunction("test", "")).toStrictEqual(true); + }); + it("works as expected for notEqualTo", () => { + const conditionFunction = ConditionFunctions["notEqualTo"]; + expect(conditionFunction("test", "random")).toStrictEqual(true); + }); + it("works as expected for isEqualTo", () => { + const conditionFunction = ConditionFunctions["isEqualTo"]; + expect(conditionFunction("test", "test")).toStrictEqual(true); + }); + it("works as expected for lessThan", () => { + const conditionFunction = ConditionFunctions["lessThan"]; + expect(conditionFunction(50, 100)).toStrictEqual(true); + }); + it("works as expected for lessThanEqualTo", () => { + const conditionFunction = ConditionFunctions["lessThanEqualTo"]; + expect(conditionFunction(50, 50)).toStrictEqual(true); + }); + it("works as expected for greaterThan", () => { + const conditionFunction = ConditionFunctions["greaterThan"]; + expect(conditionFunction(100, 50)).toStrictEqual(true); + }); + it("works as expected for contains", () => { + const conditionFunction = ConditionFunctions["contains"]; + expect(conditionFunction("random", "and")).toStrictEqual(true); + }); + it("works as expected for startsWith", () => { + const conditionFunction = ConditionFunctions["startsWith"]; + expect(conditionFunction("tested", "test")).toStrictEqual(true); + }); + it("works as expected for endsWith", () => { + const conditionFunction = ConditionFunctions["endsWith"]; + expect(conditionFunction("subtest", "test")).toStrictEqual(true); + }); + it("works as expected for is", () => { + const conditionFunction = ConditionFunctions["is"]; + const date1 = moment(); + expect(conditionFunction(date1, date1)).toStrictEqual(true); + }); + it("works as expected for isNot", () => { + const conditionFunction = ConditionFunctions["isNot"]; + const date1 = moment(); + const date2 = moment().add(1, "day"); + expect(conditionFunction(date1, date2)).toStrictEqual(true); + }); + it("works as expected for isAfter", () => { + const conditionFunction = ConditionFunctions["isAfter"]; + const date1 = moment(); + const date2 = moment().add(1, "day"); + expect(conditionFunction(date1, date2)).toStrictEqual(true); + }); + it("works as expected for isBefore", () => { + const conditionFunction = ConditionFunctions["isBefore"]; + const date1 = moment(); + const date2 = moment().subtract(1, "day"); + expect(conditionFunction(date1, date2)).toStrictEqual(true); + }); +}); diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/Constants.ts b/app/client/src/components/designSystems/appsmith/TableComponent/Constants.ts index 9f5ef588c1..0d3b923849 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/Constants.ts +++ b/app/client/src/components/designSystems/appsmith/TableComponent/Constants.ts @@ -1,5 +1,6 @@ import { isString } from "lodash"; import moment from "moment"; +import { TextSize } from "constants/WidgetConstants"; export type TableSizes = { COLUMN_HEADER_HEIGHT: number; @@ -26,21 +27,6 @@ export enum VerticalAlignmentTypes { CENTER = "CENTER", } -export enum TextSizes { - HEADING1 = "HEADING1", - HEADING2 = "HEADING2", - HEADING3 = "HEADING3", - PARAGRAPH = "PARAGRAPH", - PARAGRAPH2 = "PARAGRAPH2", -} - -export enum FontStyleTypes { - BOLD = "BOLD", - ITALIC = "ITALIC", - REGULAR = "REGULAR", - UNDERLINE = "UNDERLINE", -} - export const TABLE_SIZES: { [key: string]: TableSizes } = { [CompactModeTypes.DEFAULT]: { COLUMN_HEADER_HEIGHT: 38, @@ -90,8 +76,6 @@ export type Condition = keyof typeof ConditionFunctions | ""; export type Operator = keyof typeof OperatorTypes; export type CellAlignment = keyof typeof CellAlignmentTypes; export type VerticalAlignment = keyof typeof VerticalAlignmentTypes; -export type FontStyle = keyof typeof FontStyleTypes; -export type TextSize = keyof typeof TextSizes; export interface ReactTableFilter { column: string; diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx index fc0576778c..8fad0b6de1 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableStyledWrappers.tsx @@ -2,9 +2,9 @@ import styled, { css } from "styled-components"; import { TableSizes, CellLayoutProperties, - FontStyleTypes, } from "components/designSystems/appsmith/TableComponent/Constants"; import { Colors, Color } from "constants/Colors"; +import { FontStyleTypes, TEXT_SIZES } from "constants/WidgetConstants"; export const TableWrapper = styled.div<{ width: number; @@ -276,14 +276,6 @@ const ALIGN_ITEMS = { BOTTOM: "flex-end", }; -const TEXT_SIZES = { - HEADING1: "24px", - HEADING2: "18px", - HEADING3: "16px", - PARAGRAPH: "14px", - PARAGRAPH2: "12px", -}; - export const TableStyles = css<{ cellProperties?: CellLayoutProperties }>` font-weight: ${(props) => props?.cellProperties?.fontStyle?.includes(FontStyleTypes.BOLD) diff --git a/app/client/src/components/designSystems/appsmith/TableComponent/TableUtilities.tsx b/app/client/src/components/designSystems/appsmith/TableComponent/TableUtilities.tsx index c02c42307f..8db8f4f3bb 100644 --- a/app/client/src/components/designSystems/appsmith/TableComponent/TableUtilities.tsx +++ b/app/client/src/components/designSystems/appsmith/TableComponent/TableUtilities.tsx @@ -11,10 +11,8 @@ import { ColumnTypes, CellAlignmentTypes, VerticalAlignmentTypes, - FontStyleTypes, ColumnProperties, CellLayoutProperties, - TextSizes, TableStyles, } from "components/designSystems/appsmith/TableComponent/Constants"; import { isString, isEmpty, findIndex, without } from "lodash"; @@ -28,6 +26,7 @@ import { Colors } from "constants/Colors"; import { DropdownOption } from "widgets/DropdownWidget"; import { IconNames } from "@blueprintjs/icons"; import { Select, IItemRendererProps } from "@blueprintjs/select"; +import { FontStyleTypes, TextSizes } from "constants/WidgetConstants"; export const renderCell = ( value: any, diff --git a/app/client/src/components/designSystems/blueprint/TextComponent.tsx b/app/client/src/components/designSystems/blueprint/TextComponent.tsx index 3ea8928199..f359fec4de 100644 --- a/app/client/src/components/designSystems/blueprint/TextComponent.tsx +++ b/app/client/src/components/designSystems/blueprint/TextComponent.tsx @@ -1,11 +1,15 @@ import * as React from "react"; -import { Text, Classes } from "@blueprintjs/core"; +import { Text } from "@blueprintjs/core"; import styled from "styled-components"; import { ComponentProps } from "components/designSystems/appsmith/BaseComponent"; -import { TextStyle, TextAlign } from "widgets/TextWidget"; +import { TextAlign } from "widgets/TextWidget"; import Interweave from "interweave"; import { UrlMatcher, EmailMatcher } from "interweave-autolink"; -import { labelStyle } from "constants/DefaultTheme"; +import { + FontStyleTypes, + TextSize, + TEXT_SIZES, +} from "constants/WidgetConstants"; type TextStyleProps = { accent: "primary" | "secondary" | "error"; }; @@ -29,6 +33,10 @@ export const TextContainer = styled.div` export const StyledText = styled(Text)<{ scroll: boolean; textAlign: string; + backgroundColor?: string; + textColor?: string; + fontStyle?: string; + fontSize?: TextSize; }>` height: 100%; overflow-y: ${(props) => (props.scroll ? "auto" : "hidden")}; @@ -38,13 +46,15 @@ export const StyledText = styled(Text)<{ width: 100%; justify-content: flex-start; align-items: ${(props) => (props.scroll ? "flex-start" : "center")}; - &.bp3-heading { - font-weight: ${(props) => props.theme.fontWeights[4]}; - font-size: 21px; - } - &.bp3-ui-text { - ${labelStyle} - } + background: ${(props) => props?.backgroundColor}; + color: ${(props) => props?.textColor}; + font-style: ${(props) => + props?.fontStyle?.includes(FontStyleTypes.ITALIC) ? "italic" : ""}; + text-decoration: ${(props) => + props?.fontStyle?.includes(FontStyleTypes.UNDERLINE) ? "underline" : ""}; + font-weight: ${(props) => + props?.fontStyle?.includes(FontStyleTypes.BOLD) ? "bold" : "normal"}; + font-size: ${(props) => props?.fontSize && TEXT_SIZES[props?.fontSize]}; span { width: 100%; } @@ -54,44 +64,36 @@ export interface TextComponentProps extends ComponentProps { text?: string; textAlign: TextAlign; ellipsize?: boolean; - textStyle?: TextStyle; + fontSize?: TextSize; isLoading: boolean; shouldScroll?: boolean; + backgroundColor?: string; + textColor?: string; + fontStyle?: string; } class TextComponent extends React.Component { - getTextClass(textStyle?: TextStyle) { - const className = []; - - if (this.props.isLoading) { - className.push("bp3-skeleton"); - } - switch (textStyle) { - case "HEADING": - className.push(Classes.HEADING); - break; - case "BODY": - className.push(Classes.RUNNING_TEXT); - break; - case "LABEL": - className.push(Classes.UI_TEXT); - break; - default: - break; - } - - return className.join(" "); - } - render() { - const { textStyle, text, ellipsize, textAlign } = this.props; + const { + text, + ellipsize, + textAlign, + fontStyle, + fontSize, + textColor, + backgroundColor, + } = this.props; return ( ) => { currentDSL.version = 15; } + if (currentDSL.version === 15) { + currentDSL = migrateTextStyleFromTextWidget(currentDSL); + currentDSL.version = 16; + } + return currentDSL; }; diff --git a/app/client/src/utils/migrations/TableWidget.ts b/app/client/src/utils/migrations/TableWidget.ts index 3bf100e625..7daddef4de 100644 --- a/app/client/src/utils/migrations/TableWidget.ts +++ b/app/client/src/utils/migrations/TableWidget.ts @@ -1,14 +1,16 @@ import { ContainerWidgetProps } from "widgets/ContainerWidget"; import { WidgetProps } from "widgets/BaseWidget"; -import { WidgetTypes } from "constants/WidgetConstants"; +import { + WidgetTypes, + FontStyleTypes, + TextSizes, +} from "constants/WidgetConstants"; import { getAllTableColumnKeys } from "components/designSystems/appsmith/TableComponent/TableHelpers"; import { ColumnProperties, CellAlignmentTypes, VerticalAlignmentTypes, ColumnTypes, - TextSizes, - FontStyleTypes, } from "components/designSystems/appsmith/TableComponent/Constants"; import { Colors } from "constants/Colors"; import { ColumnAction } from "components/propertyControls/ColumnActionSelectorControl"; diff --git a/app/client/src/utils/migrations/TextWidgetReplaceTextStyle.test.ts b/app/client/src/utils/migrations/TextWidgetReplaceTextStyle.test.ts new file mode 100644 index 0000000000..e8e613e24c --- /dev/null +++ b/app/client/src/utils/migrations/TextWidgetReplaceTextStyle.test.ts @@ -0,0 +1,303 @@ +import { WidgetProps } from "widgets/BaseWidget"; +import { ContainerWidgetProps } from "widgets/ContainerWidget"; +import { migrateTextStyleFromTextWidget } from "utils/migrations/TextWidgetReplaceTextStyle"; +import { FontStyleTypes, TextSizes } from "constants/WidgetConstants"; + +const inputDsl1: ContainerWidgetProps = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1280, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 15, + minHeight: 1292, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + text: "Label", + textStyle: "LABEL", + textAlign: "LEFT", + widgetName: "Text1", + version: 1, + type: "TEXT_WIDGET", + isLoading: false, + parentColumnSpace: 67.375, + parentRowSpace: 40, + leftColumn: 3, + rightColumn: 7, + topRow: 1, + bottomRow: 2, + parentId: "0", + widgetId: "yf8bhokz7d", + dynamicBindingPathList: [], + renderMode: "CANVAS", + }, + ], +}; + +const inputDsl2: ContainerWidgetProps = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1280, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 15, + minHeight: 1292, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + text: "Label", + textStyle: "HEADING", + textAlign: "LEFT", + widgetName: "Text1", + version: 1, + type: "TEXT_WIDGET", + isLoading: false, + parentColumnSpace: 67.375, + parentRowSpace: 40, + leftColumn: 3, + rightColumn: 7, + topRow: 1, + bottomRow: 2, + parentId: "0", + widgetId: "yf8bhokz7d", + dynamicBindingPathList: [], + renderMode: "CANVAS", + }, + ], +}; + +const inputDsl3: ContainerWidgetProps = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1280, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 15, + minHeight: 1292, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + text: "Label", + textStyle: "BODY", + textAlign: "LEFT", + widgetName: "Text1", + version: 1, + type: "TEXT_WIDGET", + isLoading: false, + parentColumnSpace: 67.375, + parentRowSpace: 40, + leftColumn: 3, + rightColumn: 7, + topRow: 1, + bottomRow: 2, + parentId: "0", + widgetId: "yf8bhokz7d", + dynamicBindingPathList: [], + renderMode: "CANVAS", + }, + ], +}; + +const outputDsl1: ContainerWidgetProps = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1280, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 15, + minHeight: 1292, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + text: "Label", + textAlign: "LEFT", + widgetName: "Text1", + version: 1, + type: "TEXT_WIDGET", + isLoading: false, + parentColumnSpace: 67.375, + parentRowSpace: 40, + leftColumn: 3, + rightColumn: 7, + topRow: 1, + bottomRow: 2, + parentId: "0", + widgetId: "yf8bhokz7d", + dynamicBindingPathList: [], + fontSize: TextSizes.PARAGRAPH, + fontStyle: FontStyleTypes.BOLD, + renderMode: "CANVAS", + }, + ], +}; + +const outputDsl2: ContainerWidgetProps = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1280, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 15, + minHeight: 1292, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + text: "Label", + textAlign: "LEFT", + widgetName: "Text1", + version: 1, + type: "TEXT_WIDGET", + isLoading: false, + parentColumnSpace: 67.375, + parentRowSpace: 40, + leftColumn: 3, + rightColumn: 7, + topRow: 1, + bottomRow: 2, + parentId: "0", + widgetId: "yf8bhokz7d", + dynamicBindingPathList: [], + fontSize: TextSizes.HEADING1, + fontStyle: FontStyleTypes.BOLD, + renderMode: "CANVAS", + }, + ], +}; + +const outputDsl3: ContainerWidgetProps = { + widgetName: "MainContainer", + backgroundColor: "none", + rightColumn: 1118, + snapColumns: 16, + detachFromLayout: true, + widgetId: "0", + topRow: 0, + bottomRow: 1280, + containerStyle: "none", + snapRows: 33, + parentRowSpace: 1, + type: "CANVAS_WIDGET", + canExtend: true, + version: 15, + minHeight: 1292, + parentColumnSpace: 1, + dynamicTriggerPathList: [], + dynamicBindingPathList: [], + leftColumn: 0, + isLoading: false, + parentId: "", + renderMode: "CANVAS", + children: [ + { + isVisible: true, + text: "Label", + textAlign: "LEFT", + widgetName: "Text1", + version: 1, + type: "TEXT_WIDGET", + isLoading: false, + parentColumnSpace: 67.375, + parentRowSpace: 40, + leftColumn: 3, + rightColumn: 7, + topRow: 1, + bottomRow: 2, + parentId: "0", + widgetId: "yf8bhokz7d", + dynamicBindingPathList: [], + fontSize: TextSizes.PARAGRAPH, + renderMode: "CANVAS", + }, + ], +}; + +describe("Text Widget Property Pane Upgrade", () => { + it("To test text widget textStyle property is migrated", () => { + const newDsl = migrateTextStyleFromTextWidget(inputDsl1); + expect(JSON.stringify(newDsl) === JSON.stringify(outputDsl1)); + }); + it("To test text widget textStyle property is migrated", () => { + const newDsl = migrateTextStyleFromTextWidget(inputDsl2); + expect(JSON.stringify(newDsl) === JSON.stringify(outputDsl2)); + }); + it("To test text widget textStyle property is migrated", () => { + const newDsl = migrateTextStyleFromTextWidget(inputDsl3); + expect(JSON.stringify(newDsl) === JSON.stringify(outputDsl3)); + }); +}); diff --git a/app/client/src/utils/migrations/TextWidgetReplaceTextStyle.ts b/app/client/src/utils/migrations/TextWidgetReplaceTextStyle.ts new file mode 100644 index 0000000000..89659b0e1b --- /dev/null +++ b/app/client/src/utils/migrations/TextWidgetReplaceTextStyle.ts @@ -0,0 +1,36 @@ +import { ContainerWidgetProps } from "widgets/ContainerWidget"; +import { WidgetProps } from "widgets/BaseWidget"; +import { WidgetTypes } from "constants/WidgetConstants"; +import { FontStyleTypes, TextSizes } from "constants/WidgetConstants"; + +export const migrateTextStyleFromTextWidget = ( + currentDSL: ContainerWidgetProps, +): ContainerWidgetProps => { + currentDSL.children = currentDSL.children?.map((child: WidgetProps) => { + if (child.type === WidgetTypes.TEXT_WIDGET) { + const textStyle = child.textStyle; + switch (textStyle) { + case "HEADING": + child.fontSize = TextSizes.HEADING1; + child.fontStyle = FontStyleTypes.BOLD; + break; + case "BODY": + child.fontSize = TextSizes.PARAGRAPH; + child.fontStyle = ""; + break; + case "LABEL": + child.fontSize = TextSizes.PARAGRAPH; + child.fontStyle = FontStyleTypes.BOLD; + break; + default: + break; + } + child.textColor = "#231F20"; + delete child.textStyle; + } else if (child.children && child.children.length > 0) { + child = migrateTextStyleFromTextWidget(child); + } + return child; + }); + return currentDSL; +}; diff --git a/app/client/src/widgets/TextWidget.tsx b/app/client/src/widgets/TextWidget.tsx index e62b59b696..90b8603064 100644 --- a/app/client/src/widgets/TextWidget.tsx +++ b/app/client/src/widgets/TextWidget.tsx @@ -1,6 +1,6 @@ import React from "react"; import BaseWidget, { WidgetProps, WidgetState } from "./BaseWidget"; -import { WidgetType } from "constants/WidgetConstants"; +import { WidgetType, TextSize } from "constants/WidgetConstants"; import TextComponent from "components/designSystems/blueprint/TextComponent"; import { VALIDATION_TYPES } from "constants/WidgetValidation"; import { @@ -10,14 +10,6 @@ import { import { DerivedPropertiesMap } from "utils/WidgetFactory"; import * as Sentry from "@sentry/react"; -const LINE_HEIGHTS: { [key in TextStyle]: number } = { - // The following values are arrived at by multiplying line-height with font-size - BODY: 1.5 * 14, - HEADING: 1.28581 * 16, - LABEL: 1.28581 * 14, - SUB_TEXT: 1.28581 * 12, -}; - class TextWidget extends BaseWidget { static getPropertyPaneConfig() { return [ @@ -33,50 +25,6 @@ class TextWidget extends BaseWidget { isBindProperty: true, isTriggerProperty: false, }, - { - propertyName: "textAlign", - helpText: "Sets the alignments of the text", - label: "Text Align", - controlType: "DROP_DOWN", - options: [ - { - label: "Left", - value: "LEFT", - }, - { - label: "Center", - value: "CENTER", - }, - { - label: "Right", - value: "RIGHT", - }, - ], - isBindProperty: false, - isTriggerProperty: false, - }, - { - propertyName: "textStyle", - helpText: "Sets the font and style of the text", - label: "Text Style", - controlType: "DROP_DOWN", - options: [ - { - label: "Heading", - value: "HEADING", - }, - { - label: "Label", - value: "LABEL", - }, - { - label: "Body", - value: "BODY", - }, - ], - isBindProperty: false, - isTriggerProperty: false, - }, { propertyName: "shouldScroll", label: "Enable Scroll", @@ -96,6 +44,103 @@ class TextWidget extends BaseWidget { }, ], }, + { + sectionName: "Styles", + children: [ + { + propertyName: "backgroundColor", + label: "Cell Background", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "textColor", + label: "Text Color", + controlType: "COLOR_PICKER", + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "fontSize", + label: "Text Size", + controlType: "DROP_DOWN", + options: [ + { + label: "Heading 1", + value: "HEADING1", + subText: "24px", + icon: "HEADING_ONE", + }, + { + label: "Heading 2", + value: "HEADING2", + subText: "18px", + icon: "HEADING_TWO", + }, + { + label: "Heading 3", + value: "HEADING3", + subText: "16px", + icon: "HEADING_THREE", + }, + { + label: "Paragraph", + value: "PARAGRAPH", + subText: "14px", + icon: "PARAGRAPH", + }, + { + label: "Paragraph 2", + value: "PARAGRAPH2", + subText: "12px", + icon: "PARAGRAPH_TWO", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "fontStyle", + label: "Font Style", + controlType: "BUTTON_TABS", + options: [ + { + icon: "BOLD_FONT", + value: "BOLD", + }, + { + icon: "ITALICS_FONT", + value: "ITALIC", + }, + ], + isBindProperty: false, + isTriggerProperty: false, + }, + { + propertyName: "textAlign", + label: "Text Align", + controlType: "ICON_TABS", + options: [ + { + icon: "LEFT_ALIGN", + value: "LEFT", + }, + { + icon: "CENTER_ALIGN", + value: "CENTER", + }, + { + icon: "RIGHT_ALIGN", + value: "RIGHT", + }, + ], + defaultValue: "LEFT", + isBindProperty: false, + isTriggerProperty: false, + }, + ], + }, ]; } static getPropertyValidationMap(): WidgetPropertyValidationType { @@ -107,24 +152,19 @@ class TextWidget extends BaseWidget { }; } - getNumberOfLines() { - const height = (this.props.bottomRow - this.props.topRow) * 40; - const lineHeight = LINE_HEIGHTS[this.props.textStyle]; - return Math.floor(height / lineHeight); - } - getPageView() { - // const lines = this.getNumberOfLines(); return ( ); } @@ -140,14 +180,19 @@ class TextWidget extends BaseWidget { } } -export type TextStyle = "BODY" | "HEADING" | "LABEL" | "SUB_TEXT"; export type TextAlign = "LEFT" | "CENTER" | "RIGHT" | "JUSTIFY"; -export interface TextWidgetProps extends WidgetProps { +export interface TextStyles { + backgroundColor?: string; + textColor?: string; + fontStyle?: string; + fontSize?: TextSize; + textAlign?: TextAlign; +} + +export interface TextWidgetProps extends WidgetProps, TextStyles { text?: string; - textStyle: TextStyle; isLoading: boolean; - textAlign: TextAlign; shouldScroll: boolean; }