Text Widget new styling properties (#3167)

This commit is contained in:
Vicky Bansal 2021-04-01 14:00:33 +05:30 committed by GitHub
parent 91a7acea49
commit bdf31dbf37
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 628 additions and 166 deletions

View File

@ -209,7 +209,6 @@
{
"isVisible": true,
"text": "Label",
"textStyle": "LABEL",
"textAlign": "LEFT",
"widgetName": "Text1",
"type": "TEXT_WIDGET",

View File

@ -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",

View File

@ -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");

View File

@ -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() {

View File

@ -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");

View File

@ -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",

View File

@ -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",

View File

@ -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 });
});

View File

@ -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);
});
});

View File

@ -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;

View File

@ -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)

View File

@ -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,

View File

@ -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<TextComponentProps> {
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 (
<TextContainer>
<StyledText
scroll={!!this.props.shouldScroll}
textAlign={textAlign}
className={this.getTextClass(textStyle)}
fontSize={fontSize}
ellipsize={ellipsize}
fontStyle={fontStyle}
textColor={textColor}
backgroundColor={backgroundColor}
className={this.props.isLoading ? "bp3-skeleton" : "bp3-ui-text"}
>
<Interweave
content={text}

View File

@ -115,3 +115,28 @@ export const MAIN_CONTAINER_WIDGET_NAME = "MainContainer";
export const WIDGET_DELETE_UNDO_TIMEOUT = 7000;
export const DEFAULT_CENTER = { lat: -34.397, lng: 150.644 };
export enum FontStyleTypes {
BOLD = "BOLD",
ITALIC = "ITALIC",
REGULAR = "REGULAR",
UNDERLINE = "UNDERLINE",
}
export enum TextSizes {
HEADING1 = "HEADING1",
HEADING2 = "HEADING2",
HEADING3 = "HEADING3",
PARAGRAPH = "PARAGRAPH",
PARAGRAPH2 = "PARAGRAPH2",
}
export const TEXT_SIZES = {
HEADING1: "24px",
HEADING2: "18px",
HEADING3: "16px",
PARAGRAPH: "14px",
PARAGRAPH2: "12px",
};
export type TextSize = keyof typeof TextSizes;

View File

@ -3,6 +3,7 @@ import { WidgetProps } from "widgets/BaseWidget";
import moment from "moment-timezone";
import { generateReactKey } from "utils/generators";
import { FileDataTypes } from "widgets/FilepickerWidget";
import { Colors } from "constants/Colors";
const WidgetConfigResponse: WidgetConfigReducerState = {
config: {
@ -19,8 +20,10 @@ const WidgetConfigResponse: WidgetConfigReducerState = {
},
TEXT_WIDGET: {
text: "Label",
textStyle: "LABEL",
fontSize: "PARAGRAPH",
fontStyle: "BOLD",
textAlign: "LEFT",
textColor: Colors.THUNDER,
rows: 1,
columns: 4,
widgetName: "Text",

View File

@ -29,6 +29,7 @@ import {
} from "utils/migrations/TableWidget";
import { migrateIncorrectDynamicBindingPathLists } from "utils/migrations/IncorrectDynamicBindingPathLists";
import * as Sentry from "@sentry/react";
import { migrateTextStyleFromTextWidget } from "./migrations/TextWidgetReplaceTextStyle";
import { nextAvailableRowInContainer } from "entities/Widget/utils";
export type WidgetOperationParams = {
@ -476,6 +477,11 @@ const transformDSL = (currentDSL: ContainerWidgetProps<WidgetProps>) => {
currentDSL.version = 15;
}
if (currentDSL.version === 15) {
currentDSL = migrateTextStyleFromTextWidget(currentDSL);
currentDSL.version = 16;
}
return currentDSL;
};

View File

@ -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";

View File

@ -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<WidgetProps> = {
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<WidgetProps> = {
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<WidgetProps> = {
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<WidgetProps> = {
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<WidgetProps> = {
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<WidgetProps> = {
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));
});
});

View File

@ -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<WidgetProps>,
): ContainerWidgetProps<WidgetProps> => {
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;
};

View File

@ -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<TextWidgetProps, WidgetState> {
static getPropertyPaneConfig() {
return [
@ -33,50 +25,6 @@ class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
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<TextWidgetProps, WidgetState> {
},
],
},
{
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<TextWidgetProps, WidgetState> {
};
}
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 (
<TextComponent
widgetId={this.props.widgetId}
key={this.props.widgetId}
textStyle={this.props.textStyle}
text={this.props.text}
fontStyle={this.props.fontStyle}
fontSize={this.props.fontSize}
textColor={this.props.textColor}
backgroundColor={this.props.backgroundColor}
textAlign={this.props.textAlign ? this.props.textAlign : "LEFT"}
isLoading={this.props.isLoading}
shouldScroll={this.props.shouldScroll}
// lines={lines}
/>
);
}
@ -140,14 +180,19 @@ class TextWidget extends BaseWidget<TextWidgetProps, WidgetState> {
}
}
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;
}