chore: add color validation + native color picker (#25355)
## Description
1. Reduced the number of default colors. Because the amount of suggested
options was too much: very little difference between shades and
sometimes with hues too. By removing half of them, we allow builders
make better choices faster. The transparent color has also been removed.
2. Added validation of color values because HTML colors are remarkably
easy to get wrong, because they allow so many different values and now
we support and validate all these guys
- `hex` - `#bada55`
- `name` - `LightGoldenrodYellow`
- `special name` - `currentColor`
- `rgb` - `rgb(0 0 0)`
- `rgba` - `rgba(0, 0, 0, .45)`
- `hsl` - `hsl(4.71239rad, 60%, 70%)`
- `hsla` - `hsla(180deg 100% 50% / .8)`
- `hwb` - `hwb(180deg 0% 0% / 100%)`
- `lab` - `lab(2000.1337% -8.6911 -159.131231 / .987189732)`
- `lch` - `lch(54.292% 106.839 40.853)`
<img width="283" alt="Снимок экрана 2023-08-02 в 17 58 07"
src="https://github.com/appsmithorg/appsmith/assets/11555074/a8fef365-506d-432e-85ad-cdb550de1f60">
3. Added support for a Full color picker. Now we can easily switch
between modes and builders can easily choose any colors.
<img width="259" alt="Снимок экрана 2023-08-02 в 17 43 34"
src="https://github.com/appsmithorg/appsmith/assets/11555074/be09cd92-7c69-43eb-812a-0b1fe3ac9ef6">
#### PR fixes following issue(s)
Fixes #22996
#### Media
https://www.loom.com/share/098e0116e49744e7b10689d4a18ab664?sid=15405577-160e-4b48-bfef-bc8dcfa97efe
#### 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
- [x] Jest
- [x] 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
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] 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: Valera Melnikov <melnikov.vv@greendatasoft.ru>
This commit is contained in:
parent
75eea5b87d
commit
8be4936ca0
|
|
@ -29,7 +29,7 @@ describe("Entity explorer Drag and Drop widgets testcases", function () {
|
||||||
cy.selectColor("backgroundcolor");
|
cy.selectColor("backgroundcolor");
|
||||||
cy.get(formWidgetsPage.formD)
|
cy.get(formWidgetsPage.formD)
|
||||||
.should("have.css", "background-color")
|
.should("have.css", "background-color")
|
||||||
.and("eq", "rgb(126, 34, 206)");
|
.and("eq", "rgb(219, 234, 254)");
|
||||||
/**
|
/**
|
||||||
* @param{toggleButton Css} Assert to be checked
|
* @param{toggleButton Css} Assert to be checked
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ describe("Undo/Redo functionality", function () {
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
cy.readTextDataValidateCSS("color", "rgb(126, 34, 206)");
|
cy.readTextDataValidateCSS("color", "rgb(219, 234, 254)");
|
||||||
cy.get("body").click({ force: true }).type(`{${modifierKey}}z`);
|
cy.get("body").click({ force: true }).type(`{${modifierKey}}z`);
|
||||||
entityExplorer.NavigateToSwitcher("Explorer");
|
entityExplorer.NavigateToSwitcher("Explorer");
|
||||||
entityExplorer.SelectEntityByName("Text1");
|
entityExplorer.SelectEntityByName("Text1");
|
||||||
|
|
@ -191,7 +191,7 @@ describe("Undo/Redo functionality", function () {
|
||||||
cy.get(widgetsPage.textColor)
|
cy.get(widgetsPage.textColor)
|
||||||
.first()
|
.first()
|
||||||
.invoke("attr", "value")
|
.invoke("attr", "value")
|
||||||
.should("contain", "#7e22ce");
|
.should("contain", "#dbeafe");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("8. checks undo/redo for option control for radio button", function () {
|
it("8. checks undo/redo for option control for radio button", function () {
|
||||||
|
|
|
||||||
|
|
@ -364,7 +364,7 @@ describe("App Theming funtionality", function () {
|
||||||
.find(".t--theme-card > main > main")
|
.find(".t--theme-card > main > main")
|
||||||
.invoke("css", "background-color")
|
.invoke("css", "background-color")
|
||||||
.then((backgroudColor) => {
|
.then((backgroudColor) => {
|
||||||
expect(backgroudColor).to.eq("rgb(131, 24, 67)");
|
expect(backgroudColor).to.eq("rgb(236, 72, 153)");
|
||||||
});
|
});
|
||||||
|
|
||||||
//Check if the saved theme is present under 'Yours Themes' section with Trash button
|
//Check if the saved theme is present under 'Yours Themes' section with Trash button
|
||||||
|
|
@ -669,7 +669,7 @@ describe("App Theming funtionality", function () {
|
||||||
.eq(0)
|
.eq(0)
|
||||||
.invoke("css", "background-color")
|
.invoke("css", "background-color")
|
||||||
.then((backgroudColor) => {
|
.then((backgroudColor) => {
|
||||||
expect(backgroudColor).to.eq("rgb(126, 34, 206)");
|
expect(backgroudColor).to.eq("rgb(219, 234, 254)");
|
||||||
});
|
});
|
||||||
|
|
||||||
cy.contains("Applied theme")
|
cy.contains("Applied theme")
|
||||||
|
|
@ -680,7 +680,7 @@ describe("App Theming funtionality", function () {
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.invoke("css", "background-color")
|
.invoke("css", "background-color")
|
||||||
.then((backgroudColor) => {
|
.then((backgroudColor) => {
|
||||||
expect(backgroudColor).to.eq("rgb(253, 224, 71)");
|
expect(backgroudColor).to.eq("rgb(29, 78, 216)");
|
||||||
});
|
});
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
@ -696,17 +696,17 @@ describe("App Theming funtionality", function () {
|
||||||
cy.xpath("//div[@id='root']//section/parent::div").should(
|
cy.xpath("//div[@id='root']//section/parent::div").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(253, 224, 71)",
|
"rgb(29, 78, 216)",
|
||||||
); //Background Color
|
); //Background Color
|
||||||
cy.get(widgetsPage.widgetBtn).should(
|
cy.get(widgetsPage.widgetBtn).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //Widget Color
|
); //Widget Color
|
||||||
cy.get(publish.iconWidgetBtn).should(
|
cy.get(publish.iconWidgetBtn).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //Widget Color
|
); //Widget Color
|
||||||
|
|
||||||
cy.get(widgetsPage.widgetBtn).should("have.css", "border-radius", "24px"); //Border Radius
|
cy.get(widgetsPage.widgetBtn).should("have.css", "border-radius", "24px"); //Border Radius
|
||||||
|
|
@ -738,12 +738,12 @@ describe("App Theming funtionality", function () {
|
||||||
cy.get(".t--widget-button1 button").should(
|
cy.get(".t--widget-button1 button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //old widgets still conforming to theme color
|
); //old widgets still conforming to theme color
|
||||||
cy.get(widgetsPage.iconWidgetBtn).should(
|
cy.get(widgetsPage.iconWidgetBtn).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -789,20 +789,20 @@ describe("App Theming funtionality", function () {
|
||||||
cy.get(".t--widget-buttonwidget:nth-child(4) button").should(
|
cy.get(".t--widget-buttonwidget:nth-child(4) button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(134, 239, 172)", //rgb(134, 239, 172)
|
"rgb(190, 24, 93)",
|
||||||
); //new widget with its own color
|
); //new widget with its own color
|
||||||
|
|
||||||
////old widgets still conforming to theme color
|
////old widgets still conforming to theme color
|
||||||
cy.get(".t--widget-buttonwidget button").should(
|
cy.get(".t--widget-buttonwidget button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
|
|
||||||
cy.get(publish.iconWidgetBtn).should(
|
cy.get(publish.iconWidgetBtn).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
|
|
||||||
//Verify Border radius
|
//Verify Border radius
|
||||||
|
|
@ -845,7 +845,7 @@ describe("App Theming funtionality", function () {
|
||||||
cy.get(".t--widget-button2 button").should(
|
cy.get(".t--widget-button2 button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //verify widget reverted to theme color
|
); //verify widget reverted to theme color
|
||||||
cy.get(".t--property-control-borderradius .reset-button").then(($elem) => {
|
cy.get(".t--property-control-borderradius .reset-button").then(($elem) => {
|
||||||
$elem[0].removeAttribute("display: none");
|
$elem[0].removeAttribute("display: none");
|
||||||
|
|
@ -866,12 +866,12 @@ describe("App Theming funtionality", function () {
|
||||||
cy.xpath("//div[@id='root']//section/parent::div").should(
|
cy.xpath("//div[@id='root']//section/parent::div").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(253, 224, 71)",
|
"rgb(29, 78, 216)",
|
||||||
); //Background Color
|
); //Background Color
|
||||||
cy.get(".t--widget-button1 button").should(
|
cy.get(".t--widget-button1 button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //Widget Color
|
); //Widget Color
|
||||||
cy.get("body").then(($ele) => {
|
cy.get("body").then(($ele) => {
|
||||||
if ($ele.find(widgetsPage.widgetBtn).length <= 1) {
|
if ($ele.find(widgetsPage.widgetBtn).length <= 1) {
|
||||||
|
|
@ -882,12 +882,12 @@ describe("App Theming funtionality", function () {
|
||||||
cy.get(".t--widget-button2 button").should(
|
cy.get(".t--widget-button2 button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //Widget Color
|
); //Widget Color
|
||||||
cy.get(publish.iconWidgetBtn).should(
|
cy.get(publish.iconWidgetBtn).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
); //Widget Color
|
); //Widget Color
|
||||||
|
|
||||||
cy.get(".t--widget-button1 button").should(
|
cy.get(".t--widget-button1 button").should(
|
||||||
|
|
@ -1004,7 +1004,7 @@ describe("App Theming funtionality", function () {
|
||||||
cy.get(".t--widget-button1 button").should(
|
cy.get(".t--widget-button1 button").should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(252, 165, 165)",
|
"rgb(161, 98, 7)",
|
||||||
); //new widget with its own color
|
); //new widget with its own color
|
||||||
|
|
||||||
////old widgets still conforming to theme color
|
////old widgets still conforming to theme color
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ describe("Theme validation usecases", function () {
|
||||||
cy.get(themelocator.inputColor).clear({ force: true });
|
cy.get(themelocator.inputColor).clear({ force: true });
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
theme.ChangeThemeColor(16, "Background");
|
theme.ChangeThemeColor(16, "Background");
|
||||||
cy.get(themelocator.inputColor).should("have.value", "#dc2626"); //Red
|
cy.get(themelocator.inputColor).should("have.value", "#86efac"); //Red
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
|
|
||||||
cy.get(themelocator.inputColor).eq(0).click({ force: true });
|
cy.get(themelocator.inputColor).eq(0).click({ force: true });
|
||||||
|
|
@ -107,7 +107,7 @@ describe("Theme validation usecases", function () {
|
||||||
cy.get(themelocator.inputColor).clear({ force: true });
|
cy.get(themelocator.inputColor).clear({ force: true });
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
theme.ChangeThemeColor(9, "Primary");
|
theme.ChangeThemeColor(9, "Primary");
|
||||||
cy.get(themelocator.inputColor).should("have.value", "#18181b"); //Black
|
cy.get(themelocator.inputColor).should("have.value", "#7f1d1d"); //Black
|
||||||
cy.wait(2000);
|
cy.wait(2000);
|
||||||
cy.contains("Color").click({ force: true });
|
cy.contains("Color").click({ force: true });
|
||||||
appSettings.ClosePane();
|
appSettings.ClosePane();
|
||||||
|
|
|
||||||
|
|
@ -190,13 +190,13 @@ describe("List Widget Functionality", function () {
|
||||||
agHelper.AssertCSS(
|
agHelper.AssertCSS(
|
||||||
locators._listWidget,
|
locators._listWidget,
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
// Verify List Item Background Color
|
// Verify List Item Background Color
|
||||||
agHelper.AssertCSS(
|
agHelper.AssertCSS(
|
||||||
locators._itemContainerWidget,
|
locators._itemContainerWidget,
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
deployMode.NavigateBacktoEditor();
|
deployMode.NavigateBacktoEditor();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,13 @@ describe("Container Widget Functionality", function () {
|
||||||
cy.get(widgetsPage.listWidget).should(
|
cy.get(widgetsPage.listWidget).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
// Verify List Item Background Color
|
// Verify List Item Background Color
|
||||||
cy.get(widgetsPage.itemContainerWidget).should(
|
cy.get(widgetsPage.itemContainerWidget).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
_.deployMode.NavigateBacktoEditor();
|
_.deployMode.NavigateBacktoEditor();
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ describe("Table Widget property pane feature validation", function () {
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
// Verify the text color is green
|
// Verify the text color is green
|
||||||
cy.readTabledataValidateCSS("1", "0", "color", "rgb(126, 34, 206)");
|
cy.readTabledataValidateCSS("1", "0", "color", "rgb(219, 234, 254)");
|
||||||
// Change the text color and enter purple in input field
|
// Change the text color and enter purple in input field
|
||||||
cy.get(widgetsPage.textColor)
|
cy.get(widgetsPage.textColor)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
|
|
@ -41,13 +41,15 @@ describe("Table Widget property pane feature validation", function () {
|
||||||
"1",
|
"1",
|
||||||
"1",
|
"1",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
_.deployMode.NavigateBacktoEditor();
|
_.deployMode.NavigateBacktoEditor();
|
||||||
cy.openPropertyPane("tablewidget");
|
cy.openPropertyPane("tablewidget");
|
||||||
|
|
||||||
// Change the cell background color and enter purple in input field
|
// Change the cell background color and enter purple in input field
|
||||||
cy.get(`${widgetsPage.cellBackground_tablev1} input`)
|
cy.get(
|
||||||
|
`${widgetsPage.cellBackground_tablev1} [data-testid='t--color-picker-input']`,
|
||||||
|
)
|
||||||
.clear({ force: true })
|
.clear({ force: true })
|
||||||
.type("purple", { force: true });
|
.type("purple", { force: true });
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
|
|
|
||||||
|
|
@ -28,23 +28,23 @@ describe("Table Widget empty row color validation", function () {
|
||||||
"1",
|
"1",
|
||||||
"0",
|
"0",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(99, 102, 241)",
|
"rgb(185, 28, 28)",
|
||||||
);
|
);
|
||||||
// Verify the cell background color of second column
|
// Verify the cell background color of second column
|
||||||
cy.readTabledataValidateCSS(
|
cy.readTabledataValidateCSS(
|
||||||
"1",
|
"1",
|
||||||
"1",
|
"1",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(30, 58, 138)",
|
"rgb(113, 113, 122)",
|
||||||
);
|
);
|
||||||
//Test 2. Validate empty row background
|
//Test 2. Validate empty row background
|
||||||
// first cell of first row should be transparent
|
// first cell of first row should be transparent
|
||||||
cy.get(
|
cy.get(
|
||||||
".t--widget-tablewidget .tbody div[data-testid='empty-row-0-cell-0']",
|
".t--widget-tablewidget .tbody div[data-testid='empty-row-0-cell-0']",
|
||||||
).should("have.css", "background-color", "rgb(99, 102, 241)");
|
).should("have.css", "background-color", "rgb(185, 28, 28)");
|
||||||
// second cell of first row should be transparent
|
// second cell of first row should be transparent
|
||||||
cy.get(
|
cy.get(
|
||||||
".t--widget-tablewidget .tbody div[data-testid='empty-row-0-cell-1']",
|
".t--widget-tablewidget .tbody div[data-testid='empty-row-0-cell-1']",
|
||||||
).should("have.css", "background-color", "rgb(30, 58, 138)");
|
).should("have.css", "background-color", "rgb(113, 113, 122)");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -171,12 +171,12 @@ describe("Table Widget property pane feature validation", function () {
|
||||||
it("6. Test to validate text color and text background", function () {
|
it("6. Test to validate text color and text background", function () {
|
||||||
cy.openPropertyPane("tablewidget");
|
cy.openPropertyPane("tablewidget");
|
||||||
|
|
||||||
// Changing text color to rgb(126, 34, 206) and validate
|
// Changing text color to rgb(219, 234, 254) and validate
|
||||||
cy.selectColor("textcolor");
|
cy.selectColor("textcolor");
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
cy.wait(5000);
|
cy.wait(5000);
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
cy.readTabledataValidateCSS("1", "0", "color", "rgb(126, 34, 206)");
|
cy.readTabledataValidateCSS("1", "0", "color", "rgb(219, 234, 254)");
|
||||||
|
|
||||||
// Changing text color to PURPLE and validate using JS
|
// Changing text color to PURPLE and validate using JS
|
||||||
cy.get(widgetsPage.toggleJsColor).click({ force: true });
|
cy.get(widgetsPage.toggleJsColor).click({ force: true });
|
||||||
|
|
@ -185,13 +185,13 @@ describe("Table Widget property pane feature validation", function () {
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
cy.readTabledataValidateCSS("1", "0", "color", "rgb(128, 0, 128)");
|
cy.readTabledataValidateCSS("1", "0", "color", "rgb(128, 0, 128)");
|
||||||
cy.get(commonlocators.editPropBackButton).click();
|
cy.get(commonlocators.editPropBackButton).click();
|
||||||
// Changing Cell backgroud color to rgb(126, 34, 206) and validate
|
// Changing Cell backgroud color to rgb(219, 234, 254) and validate
|
||||||
cy.selectColor("cellbackgroundcolor");
|
cy.selectColor("cellbackgroundcolor");
|
||||||
cy.readTabledataValidateCSS(
|
cy.readTabledataValidateCSS(
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
"background",
|
"background",
|
||||||
"rgb(126, 34, 206) none repeat scroll 0% 0% / auto padding-box border-box",
|
"rgb(219, 234, 254) none repeat scroll 0% 0% / auto padding-box border-box",
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
// Changing Cell backgroud color to PURPLE and validate using JS
|
// Changing Cell backgroud color to PURPLE and validate using JS
|
||||||
|
|
|
||||||
|
|
@ -325,20 +325,4 @@ describe("Table Widget property pane feature validation", function () {
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.get("[data-testid='t--property-pane-back-btn']").click({ force: true });
|
cy.get("[data-testid='t--property-pane-back-btn']").click({ force: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("7. Table widget test on button when transparent", () => {
|
|
||||||
cy.openPropertyPane("tablewidget");
|
|
||||||
// Open column details of "id".
|
|
||||||
cy.editColumn("id");
|
|
||||||
// Changing column "Button" color to transparent
|
|
||||||
|
|
||||||
cy.get(widgetsPage.buttonColor).click({ force: true });
|
|
||||||
cy.wait(2000);
|
|
||||||
cy.get(widgetsPage.transparent).click({ force: true });
|
|
||||||
cy.get(".td[data-colindex=5][data-rowindex=0] .bp3-button").should(
|
|
||||||
"have.css",
|
|
||||||
"background-color",
|
|
||||||
"rgba(0, 0, 0, 0)",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ describe("Table Widget V2 property pane feature validation", function () {
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
// Verify the text color is green
|
// Verify the text color is green
|
||||||
cy.readTableV2dataValidateCSS("1", "0", "color", "rgb(126, 34, 206)");
|
cy.readTableV2dataValidateCSS("1", "0", "color", "rgb(219, 234, 254)");
|
||||||
// Change the text color and enter purple in input field
|
// Change the text color and enter purple in input field
|
||||||
cy.get(widgetsPage.textColor)
|
cy.get(widgetsPage.textColor)
|
||||||
.scrollIntoView()
|
.scrollIntoView()
|
||||||
|
|
@ -49,13 +49,15 @@ describe("Table Widget V2 property pane feature validation", function () {
|
||||||
"1",
|
"1",
|
||||||
"1",
|
"1",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
_.deployMode.NavigateBacktoEditor();
|
_.deployMode.NavigateBacktoEditor();
|
||||||
cy.openPropertyPane("tablewidgetv2");
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
cy.moveToStyleTab();
|
cy.moveToStyleTab();
|
||||||
// Change the cell background color and enter purple in input field
|
// Change the cell background color and enter purple in input field
|
||||||
cy.get(`.t--property-control-cellbackgroundcolor input`)
|
cy.get(
|
||||||
|
`.t--property-control-cellbackgroundcolor [data-testid='t--color-picker-input']`,
|
||||||
|
)
|
||||||
.clear({ force: true })
|
.clear({ force: true })
|
||||||
.type("purple", { force: true });
|
.type("purple", { force: true });
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ describe("Table Widget V2 property pane feature validation", function () {
|
||||||
cy.openPropertyPane("tablewidgetv2");
|
cy.openPropertyPane("tablewidgetv2");
|
||||||
cy.editColumn("id");
|
cy.editColumn("id");
|
||||||
cy.moveToStyleTab();
|
cy.moveToStyleTab();
|
||||||
// Changing text color to rgb(126, 34, 206) and validate
|
// Changing text color to rgb(219, 234, 254) and validate
|
||||||
cy.selectColor("textcolor");
|
cy.selectColor("textcolor");
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
cy.wait(5000);
|
cy.wait(5000);
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
cy.readTableV2dataValidateCSS("1", "0", "color", "rgb(126, 34, 206)");
|
cy.readTableV2dataValidateCSS("1", "0", "color", "rgb(219, 234, 254)");
|
||||||
|
|
||||||
// Changing text color to PURPLE and validate using JS
|
// Changing text color to PURPLE and validate using JS
|
||||||
cy.get(widgetsPage.toggleJsColor).click();
|
cy.get(widgetsPage.toggleJsColor).click();
|
||||||
|
|
@ -31,13 +31,13 @@ describe("Table Widget V2 property pane feature validation", function () {
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
cy.readTableV2dataValidateCSS("1", "0", "color", "rgb(128, 0, 128)");
|
cy.readTableV2dataValidateCSS("1", "0", "color", "rgb(128, 0, 128)");
|
||||||
|
|
||||||
// Changing Cell backgroud color to rgb(126, 34, 206) and validate
|
// Changing Cell backgroud color to rgb(219, 234, 254) and validate
|
||||||
cy.selectColor("cellbackground");
|
cy.selectColor("cellbackground");
|
||||||
cy.readTableV2dataValidateCSS(
|
cy.readTableV2dataValidateCSS(
|
||||||
"0",
|
"0",
|
||||||
"0",
|
"0",
|
||||||
"background",
|
"background",
|
||||||
"rgb(113, 30, 184) none repeat scroll 0% 0% / auto padding-box border-box",
|
"rgb(194, 220, 253) none repeat scroll 0% 0% / auto padding-box border-box",
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
// Changing Cell backgroud color to PURPLE and validate using JS
|
// Changing Cell backgroud color to PURPLE and validate using JS
|
||||||
|
|
|
||||||
|
|
@ -289,20 +289,4 @@ describe("Table Widget V2 property pane feature validation", function () {
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.get("[data-testid='t--property-pane-back-btn']").click({ force: true });
|
cy.get("[data-testid='t--property-pane-back-btn']").click({ force: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it("8. Table widget test on button when transparent", () => {
|
|
||||||
cy.openPropertyPane("tablewidgetv2");
|
|
||||||
// Open column details of "id".
|
|
||||||
cy.editColumn("id");
|
|
||||||
// Changing column "Button" color to transparent
|
|
||||||
cy.moveToStyleTab();
|
|
||||||
cy.get(widgetsPage.buttonColor).click({ force: true });
|
|
||||||
cy.wait(2000);
|
|
||||||
cy.get(widgetsPage.transparent).click({ force: true });
|
|
||||||
cy.get(".td[data-colindex=5][data-rowindex=0] .bp3-button").should(
|
|
||||||
"have.css",
|
|
||||||
"background-color",
|
|
||||||
"rgba(0, 0, 0, 0)",
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ describe("Text Widget Cell Background and Text Size Validation", function () {
|
||||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
|
|
||||||
//Toggle to JS mode
|
//Toggle to JS mode
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ describe("Text Widget color/font/alignment Functionality", function () {
|
||||||
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
// eslint-disable-next-line cypress/no-unnecessary-waiting
|
||||||
cy.wait(500);
|
cy.wait(500);
|
||||||
cy.wait("@updateLayout");
|
cy.wait("@updateLayout");
|
||||||
cy.readTextDataValidateCSS("color", "rgb(126, 34, 206)");
|
cy.readTextDataValidateCSS("color", "rgb(219, 234, 254)");
|
||||||
cy.get(widgetsPage.textColor)
|
cy.get(widgetsPage.textColor)
|
||||||
.clear({ force: true })
|
.clear({ force: true })
|
||||||
.type("purple", { force: true });
|
.type("purple", { force: true });
|
||||||
|
|
@ -105,7 +105,7 @@ describe("Text Widget color/font/alignment Functionality", function () {
|
||||||
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
cy.get(`${widgetsPage.textWidget} .bp3-ui-text`).should(
|
||||||
"have.css",
|
"have.css",
|
||||||
"background-color",
|
"background-color",
|
||||||
"rgb(126, 34, 206)",
|
"rgb(219, 234, 254)",
|
||||||
);
|
);
|
||||||
|
|
||||||
//Toggle JS check with cell background:
|
//Toggle JS check with cell background:
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ describe("Json & JsonB Datatype tests", function () {
|
||||||
agHelper.AddDsl("Datatypes/JsonDTdsl");
|
agHelper.AddDsl("Datatypes/JsonDTdsl");
|
||||||
|
|
||||||
entityExplorer.NavigateToSwitcher("Widgets");
|
entityExplorer.NavigateToSwitcher("Widgets");
|
||||||
appSettings.OpenPaneAndChangeThemeColors(33, 39);
|
appSettings.OpenPaneAndChangeThemeColors(16, 20);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"popover": ".rc-tooltip-inner",
|
"popover": ".rc-tooltip-inner",
|
||||||
"shadow": ".t--theme-appBoxShadow",
|
"shadow": ".t--theme-appBoxShadow",
|
||||||
"color": ".t--property-pane-sidebar .bp3-popover-target .cursor-pointer",
|
"color": ".t--property-pane-sidebar .bp3-popover-target .cursor-pointer",
|
||||||
"inputColor": ".t--colorpicker-v2-popover input",
|
"inputColor": ".t--colorpicker-v2-popover [data-testid='t--color-picker-input']",
|
||||||
"colorPicker": "[data-testid='color-picker']",
|
"colorPicker": "[data-testid='color-picker']",
|
||||||
"greenColor": "[style='background-color: rgb(21, 128, 61);']",
|
"greenColor": "[style='background-color: rgb(21, 128, 61);']",
|
||||||
"fontsSelected": ".leading-normal",
|
"fontsSelected": ".leading-normal",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
"inputPropsDataType": ".t--property-control-datatype input",
|
"inputPropsDataType": ".t--property-control-datatype input",
|
||||||
"inputdatatypeplaceholder": ".t--property-control-placeholder",
|
"inputdatatypeplaceholder": ".t--property-control-placeholder",
|
||||||
"buttonWidget": ".t--draggable-buttonwidget",
|
"buttonWidget": ".t--draggable-buttonwidget",
|
||||||
"buttonColor": ".t--property-control-buttoncolor input",
|
"buttonColor": ".t--property-control-buttoncolor [data-testid='t--color-picker-input']",
|
||||||
"checkboxWidget": ".t--draggable-checkboxwidget",
|
"checkboxWidget": ".t--draggable-checkboxwidget",
|
||||||
"buttonStyleDropdown": ".t--property-control-buttonstyle [name='downArrow']",
|
"buttonStyleDropdown": ".t--property-control-buttonstyle [name='downArrow']",
|
||||||
"buttonBackground": ".sc-ecQjpJ > div > .bp3-button",
|
"buttonBackground": ".sc-ecQjpJ > div > .bp3-button",
|
||||||
|
|
@ -38,7 +38,7 @@
|
||||||
"requiredjs": ".t--property-control-required input",
|
"requiredjs": ".t--property-control-required input",
|
||||||
"visible": ".t--property-control-visible input",
|
"visible": ".t--property-control-visible input",
|
||||||
"disable": ".t--property-control-disabled",
|
"disable": ".t--property-control-disabled",
|
||||||
"menuColor": ".t--property-control-menucolor input",
|
"menuColor": ".t--property-control-menucolor [data-testid='t--color-picker-input']",
|
||||||
"menubar": ".bp3-menu",
|
"menubar": ".bp3-menu",
|
||||||
"menupop": ".bp3-popover",
|
"menupop": ".bp3-popover",
|
||||||
"defaultcheck": ".t--property-control-defaultstate input",
|
"defaultcheck": ".t--property-control-defaultstate input",
|
||||||
|
|
@ -94,17 +94,16 @@
|
||||||
"verticalTop": "[data-value='TOP']",
|
"verticalTop": "[data-value='TOP']",
|
||||||
"verticalCenter": "[data-value='CENTER']",
|
"verticalCenter": "[data-value='CENTER']",
|
||||||
"verticalBottom": "[data-value='BOTTOM']",
|
"verticalBottom": "[data-value='BOTTOM']",
|
||||||
"textColor": ".t--property-control-textcolor input",
|
"textColor": ".t--property-control-textcolor [data-testid='t--color-picker-input']",
|
||||||
"boadercolorPicker": ".t--property-control-bordercolour input",
|
"boadercolorPicker": ".t--property-control-bordercolour input",
|
||||||
"boxShadowColorPicker": ".t--property-control-shadowcolor input",
|
"boxShadowColorPicker": ".t--property-control-shadowcolor input",
|
||||||
"boxShadow": ".t--property-control-boxshadow .bp3-button-group",
|
"boxShadow": ".t--property-control-boxshadow .bp3-button-group",
|
||||||
"inputStepArrows": ".bp3-button-group",
|
"inputStepArrows": ".bp3-button-group",
|
||||||
"backgroundcolorPicker": ".t--property-control-backgroundcolour input",
|
"backgroundcolorPicker": ".t--property-control-backgroundcolour input",
|
||||||
"backgroundcolorPickerNew": ".t--property-control-backgroundcolor input",
|
"backgroundcolorPickerNew": ".t--property-control-backgroundcolor [data-testid='t--color-picker-input']",
|
||||||
"greenColorHex": "#03b365",
|
"greenColorHex": "#03b365",
|
||||||
"yellowColorHex": "#FFC13D",
|
"yellowColorHex": "#FFC13D",
|
||||||
"greenColor": "//div[@color='#03b365']",
|
"greenColor": "//div[@color='#03b365']",
|
||||||
"transparent": ".diagnol-cross",
|
|
||||||
"yellowColor": "//div[@color='#FFC13D']",
|
"yellowColor": "//div[@color='#FFC13D']",
|
||||||
"blueColor": "//div[@color='#3366FF']",
|
"blueColor": "//div[@color='#3366FF']",
|
||||||
"toggleJsColor": ".t--property-control-textcolor .t--js-toggle",
|
"toggleJsColor": ".t--property-control-textcolor .t--js-toggle",
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ export class ThemeSettings {
|
||||||
"']//ancestor::div[@class= 'space-y-1 group']",
|
"']//ancestor::div[@class= 'space-y-1 group']",
|
||||||
_colorPickerV2Popover: ".t--colorpicker-v2-popover",
|
_colorPickerV2Popover: ".t--colorpicker-v2-popover",
|
||||||
_colorPickerV2Color:
|
_colorPickerV2Color:
|
||||||
"//h3[text()='All Colors']/following-sibling::div//div[contains(@class,'t--colorpicker-v2-color')]",
|
"[data-testid='t--all-colors'] .t--colorpicker-v2-color",
|
||||||
_colorRingPrimary: "[data-testid='theme-primaryColor']",
|
_colorRingPrimary: "[data-testid='theme-primaryColor']",
|
||||||
_colorRingBackground: "[data-testid='theme-backgroundColor']",
|
_colorRingBackground: "[data-testid='theme-backgroundColor']",
|
||||||
_colorInput: (option: string) =>
|
_colorInput: (option: string) =>
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,7 @@
|
||||||
"unescape-js": "^1.1.4",
|
"unescape-js": "^1.1.4",
|
||||||
"url-search-params-polyfill": "^8.0.0",
|
"url-search-params-polyfill": "^8.0.0",
|
||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
|
"validate-color": "^2.2.4",
|
||||||
"webfontloader": "^1.6.28",
|
"webfontloader": "^1.6.28",
|
||||||
"webpack-retry-chunk-load-plugin": "^3.1.1",
|
"webpack-retry-chunk-load-plugin": "^3.1.1",
|
||||||
"yjs": "^13.5.12",
|
"yjs": "^13.5.12",
|
||||||
|
|
|
||||||
|
|
@ -56,13 +56,6 @@ and .Toastify__toast-container--bottom-center classes, which messes with the pla
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.diagnol-cross {
|
|
||||||
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 99 L99 0 L100 1 L1 100' fill='red' /></svg>");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center center;
|
|
||||||
background-size: 100% 100%, auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden-scrollbar {
|
.hidden-scrollbar {
|
||||||
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
-ms-overflow-style: none; /* for Internet Explorer, Edge */
|
||||||
scrollbar-width: none; /* for Firefox */
|
scrollbar-width: none; /* for Firefox */
|
||||||
|
|
|
||||||
|
|
@ -1901,3 +1901,6 @@ export const DEFAULT_CAMERA_LABEL_DESCRIPTION = () =>
|
||||||
"Default choice for mobile users. Not applicable for other devices";
|
"Default choice for mobile users. Not applicable for other devices";
|
||||||
export const FRONT_CAMERA_LABEL = () => "Front (Selfie)";
|
export const FRONT_CAMERA_LABEL = () => "Front (Selfie)";
|
||||||
export const BACK_CAMERA_LABEL = () => "Back (Rear)";
|
export const BACK_CAMERA_LABEL = () => "Back (Rear)";
|
||||||
|
|
||||||
|
// Color picker
|
||||||
|
export const FULL_COLOR_PICKER_LABEL = () => "Full color picker";
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,7 @@ describe("<ColorPicker /> - Keyboard Navigation", () => {
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.keyboard("{Enter}");
|
userEvent.keyboard("{Enter}");
|
||||||
|
|
||||||
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
expect(
|
expect(
|
||||||
document.querySelectorAll("[tabindex='0'].t--colorpicker-v2-color")[0],
|
document.querySelectorAll("[tabindex='0'].t--colorpicker-v2-color")[0],
|
||||||
|
|
@ -133,6 +134,7 @@ describe("<ColorPicker /> - Keyboard Navigation", () => {
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.keyboard("{Enter}");
|
userEvent.keyboard("{Enter}");
|
||||||
|
|
||||||
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
|
|
||||||
|
|
@ -153,6 +155,7 @@ describe("<ColorPicker /> - Keyboard Navigation", () => {
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.keyboard("{Enter}");
|
userEvent.keyboard("{Enter}");
|
||||||
|
|
||||||
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
|
|
||||||
|
|
@ -180,6 +183,7 @@ describe("<ColorPicker /> - Keyboard Navigation", () => {
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.keyboard("{Enter}");
|
userEvent.keyboard("{Enter}");
|
||||||
|
|
||||||
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
|
|
||||||
|
|
@ -199,6 +203,7 @@ describe("<ColorPicker /> - Keyboard Navigation", () => {
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.keyboard("{Enter}");
|
userEvent.keyboard("{Enter}");
|
||||||
|
|
||||||
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
userEvent.tab();
|
userEvent.tab();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import React, {
|
||||||
useCallback,
|
useCallback,
|
||||||
} from "react";
|
} from "react";
|
||||||
import styled from "styled-components";
|
import styled from "styled-components";
|
||||||
import { Icon } from "design-system";
|
import { Icon, Switch } from "design-system";
|
||||||
import {
|
import {
|
||||||
Popover,
|
Popover,
|
||||||
InputGroup,
|
InputGroup,
|
||||||
|
|
@ -21,11 +21,15 @@ import {
|
||||||
getThemePropertyBinding,
|
getThemePropertyBinding,
|
||||||
} from "constants/ThemeConstants";
|
} from "constants/ThemeConstants";
|
||||||
import { getWidgets } from "sagas/selectors";
|
import { getWidgets } from "sagas/selectors";
|
||||||
import { extractColorsFromString } from "utils/helpers";
|
import { extractColorsFromString, isValidColor } from "utils/helpers";
|
||||||
import { TAILWIND_COLORS } from "constants/ThemeConstants";
|
import { TAILWIND_COLORS } from "constants/ThemeConstants";
|
||||||
import useDSEvent from "utils/hooks/useDSEvent";
|
import useDSEvent from "utils/hooks/useDSEvent";
|
||||||
import { DSEventTypes } from "utils/AppsmithUtils";
|
import { DSEventTypes } from "utils/AppsmithUtils";
|
||||||
import { getBrandColors } from "@appsmith/selectors/tenantSelectors";
|
import { getBrandColors } from "@appsmith/selectors/tenantSelectors";
|
||||||
|
import {
|
||||||
|
createMessage,
|
||||||
|
FULL_COLOR_PICKER_LABEL,
|
||||||
|
} from "@appsmith/constants/messages";
|
||||||
|
|
||||||
const FocusTrap = require("focus-trap-react");
|
const FocusTrap = require("focus-trap-react");
|
||||||
|
|
||||||
|
|
@ -46,6 +50,7 @@ interface ColorPickerProps {
|
||||||
isOpen?: boolean;
|
isOpen?: boolean;
|
||||||
placeholderText?: string;
|
placeholderText?: string;
|
||||||
portalContainer?: HTMLElement;
|
portalContainer?: HTMLElement;
|
||||||
|
onPopupClosed?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,7 +78,10 @@ const ColorPickerIconContainer = styled.div`
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledInputGroup = styled(InputGroup)`
|
const StyledInputGroup = styled(InputGroup)<{
|
||||||
|
$isValid?: boolean;
|
||||||
|
$isFullColorPicker?: boolean;
|
||||||
|
}>`
|
||||||
.${Classes.INPUT} {
|
.${Classes.INPUT} {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
border: 1px solid var(--ads-v2-color-border);
|
border: 1px solid var(--ads-v2-color-border);
|
||||||
|
|
@ -83,23 +91,30 @@ const StyledInputGroup = styled(InputGroup)`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&&& input {
|
&&& input {
|
||||||
padding-left: 36px;
|
padding: ${({ $isFullColorPicker }) =>
|
||||||
|
$isFullColorPicker ? "0px 2px" : "0 10px 0 36px"};
|
||||||
height: 36px;
|
height: 36px;
|
||||||
border: 1px solid var(--ads-v2-color-border);
|
border: ${({ $isValid }) =>
|
||||||
|
$isValid
|
||||||
|
? "1px solid var(--ads-v2-color-border)"
|
||||||
|
: "1px solid var(--ads-v2-color-border-error)"};
|
||||||
background: ${(props) =>
|
background: ${(props) =>
|
||||||
props.theme.colors.propertyPane.multiDropdownBoxHoverBg};
|
props.theme.colors.propertyPane.multiDropdownBoxHoverBg};
|
||||||
color: ${(props) => props.theme.colors.propertyPane.label};
|
color: ${(props) => props.theme.colors.propertyPane.label};
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-color: var(--ads-v2-color-border-emphasis);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 1px solid var(--ads-v2-color-border-emphasis);
|
|
||||||
outline: var(--ads-v2-border-width-outline) solid
|
outline: var(--ads-v2-border-width-outline) solid
|
||||||
var(--ads-v2-color-outline);
|
var(--ads-v2-color-outline);
|
||||||
outline-offset: var(--ads-v2-offset-outline);
|
outline-offset: var(--ads-v2-offset-outline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border-color: ${({ $isValid }) =>
|
||||||
|
$isValid
|
||||||
|
? "var(--ads-v2-color-border-emphasis)"
|
||||||
|
: "var(--ads-v2-color-border-error)"};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|
@ -117,7 +132,6 @@ interface ColorPickerPopupProps {
|
||||||
|
|
||||||
const PopupContainer = styled.div`
|
const PopupContainer = styled.div`
|
||||||
padding: 0.75rem;
|
padding: 0.75rem;
|
||||||
width: 18rem;
|
|
||||||
border-radius: var(--ads-v2-border-radius);
|
border-radius: var(--ads-v2-border-radius);
|
||||||
border: 1px solid var(--ads-v2-color-border);
|
border: 1px solid var(--ads-v2-color-border);
|
||||||
`;
|
`;
|
||||||
|
|
@ -126,10 +140,9 @@ function ColorPickerPopup(props: ColorPickerPopupProps) {
|
||||||
const themeColors = useSelector(getSelectedAppThemeProperties).colors;
|
const themeColors = useSelector(getSelectedAppThemeProperties).colors;
|
||||||
const brandColors = useSelector(getBrandColors);
|
const brandColors = useSelector(getBrandColors);
|
||||||
const widgets = useSelector(getWidgets);
|
const widgets = useSelector(getWidgets);
|
||||||
const DSLStringified = JSON.stringify(widgets);
|
|
||||||
const applicationColors = useMemo(() => {
|
const applicationColors = useMemo(() => {
|
||||||
return extractColorsFromString(DSLStringified);
|
return extractColorsFromString(widgets);
|
||||||
}, [DSLStringified]);
|
}, []);
|
||||||
const {
|
const {
|
||||||
changeColor,
|
changeColor,
|
||||||
color,
|
color,
|
||||||
|
|
@ -169,7 +182,7 @@ function ColorPickerPopup(props: ColorPickerPopupProps) {
|
||||||
<h2 className="pb-2 font-semibold border-b">Color Styles</h2>
|
<h2 className="pb-2 font-semibold border-b">Color Styles</h2>
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<h3 className="text-xs">Theme Colors</h3>
|
<h3 className="text-xs">Theme Colors</h3>
|
||||||
<div className="grid grid-cols-10 gap-2">
|
<div className="grid grid-cols-5 gap-2">
|
||||||
{Object.keys(themeColors).map((colorKey, colorIndex) => (
|
{Object.keys(themeColors).map((colorKey, colorIndex) => (
|
||||||
<div
|
<div
|
||||||
className={`${COLOR_BOX_CLASSES} ${
|
className={`${COLOR_BOX_CLASSES} ${
|
||||||
|
|
@ -199,7 +212,7 @@ function ColorPickerPopup(props: ColorPickerPopupProps) {
|
||||||
{brandColors && Object.keys(brandColors).length > 0 && (
|
{brandColors && Object.keys(brandColors).length > 0 && (
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<h3 className="text-xs">Brand Colors</h3>
|
<h3 className="text-xs">Brand Colors</h3>
|
||||||
<div className="grid grid-cols-10 gap-2">
|
<div className="grid grid-cols-5 gap-2">
|
||||||
{Object.keys(brandColors).map(
|
{Object.keys(brandColors).map(
|
||||||
(colorKey: string, colorIndex: number) => (
|
(colorKey: string, colorIndex: number) => (
|
||||||
<div
|
<div
|
||||||
|
|
@ -223,7 +236,7 @@ function ColorPickerPopup(props: ColorPickerPopupProps) {
|
||||||
{showApplicationColors && applicationColors.length > 0 && (
|
{showApplicationColors && applicationColors.length > 0 && (
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<h3 className="text-xs">Application Colors</h3>
|
<h3 className="text-xs">Application Colors</h3>
|
||||||
<div className="grid grid-cols-10 gap-2">
|
<div className="grid grid-cols-5 gap-2">
|
||||||
{Object.values(applicationColors).map(
|
{Object.values(applicationColors).map(
|
||||||
(colorCode: string, colorIndex) => (
|
(colorCode: string, colorIndex) => (
|
||||||
<div
|
<div
|
||||||
|
|
@ -246,8 +259,15 @@ function ColorPickerPopup(props: ColorPickerPopupProps) {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<section className="space-y-2">
|
<section className="space-y-2">
|
||||||
<h3 className="text-xs">All Colors</h3>
|
{(showThemeColors ||
|
||||||
<div className="grid grid-cols-10 gap-2 t--tailwind-colors">
|
(brandColors && Object.keys(brandColors).length > 0) ||
|
||||||
|
(showApplicationColors && applicationColors.length > 0)) && (
|
||||||
|
<h3 className="text-xs">All Colors</h3>
|
||||||
|
)}
|
||||||
|
<div
|
||||||
|
className="grid grid-cols-5 gap-2 t--tailwind-colors"
|
||||||
|
data-testid="t--all-colors"
|
||||||
|
>
|
||||||
{Object.keys(TAILWIND_COLORS).map((colorKey, rowIndex) =>
|
{Object.keys(TAILWIND_COLORS).map((colorKey, rowIndex) =>
|
||||||
Object.keys(get(TAILWIND_COLORS, `${colorKey}`)).map(
|
Object.keys(get(TAILWIND_COLORS, `${colorKey}`)).map(
|
||||||
(singleColorKey, colIndex) => (
|
(singleColorKey, colIndex) => (
|
||||||
|
|
@ -275,27 +295,6 @@ function ColorPickerPopup(props: ColorPickerPopupProps) {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div
|
|
||||||
className={`${COLOR_BOX_CLASSES} ${
|
|
||||||
color === "#fff" ? "ring-1" : ""
|
|
||||||
}`}
|
|
||||||
onClick={(e) => {
|
|
||||||
setColor("#fff");
|
|
||||||
changeColor("#fff", !e.isTrusted);
|
|
||||||
}}
|
|
||||||
tabIndex={-1}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
className={`${COLOR_BOX_CLASSES} diagnol-cross ${
|
|
||||||
color === "transparent" ? "ring-1" : ""
|
|
||||||
}`}
|
|
||||||
onClick={(e) => {
|
|
||||||
setColor("transparent");
|
|
||||||
changeColor("transparent", !e.isTrusted);
|
|
||||||
}}
|
|
||||||
tabIndex={-1}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</PopupContainer>
|
</PopupContainer>
|
||||||
|
|
@ -329,7 +328,7 @@ interface LeftIconProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
function LeftIcon(props: LeftIconProps) {
|
function LeftIcon(props: LeftIconProps) {
|
||||||
return props.color ? (
|
return isValidColor(props.color) ? (
|
||||||
<ColorIcon
|
<ColorIcon
|
||||||
className="rounded-full cursor-pointer"
|
className="rounded-full cursor-pointer"
|
||||||
color={props.color}
|
color={props.color}
|
||||||
|
|
@ -365,6 +364,8 @@ const ColorPickerComponent = React.forwardRef(
|
||||||
props.evaluatedColorValue || props.color,
|
props.evaluatedColorValue || props.color,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const [isFullColorPicker, setFullColorPicker] = React.useState(false);
|
||||||
|
|
||||||
const debouncedOnChange = React.useCallback(
|
const debouncedOnChange = React.useCallback(
|
||||||
debounce((color: string, isUpdatedViaKeyboard: boolean) => {
|
debounce((color: string, isUpdatedViaKeyboard: boolean) => {
|
||||||
props.changeColor(color, isUpdatedViaKeyboard);
|
props.changeColor(color, isUpdatedViaKeyboard);
|
||||||
|
|
@ -417,7 +418,6 @@ const ColorPickerComponent = React.forwardRef(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "Enter":
|
case "Enter":
|
||||||
case " ":
|
|
||||||
emitKeyPressEvent(e.key);
|
emitKeyPressEvent(e.key);
|
||||||
(document.activeElement as any)?.click();
|
(document.activeElement as any)?.click();
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -530,7 +530,9 @@ const ColorPickerComponent = React.forwardRef(
|
||||||
|
|
||||||
const handleChangeColor = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleChangeColor = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const value = event.target.value;
|
const value = event.target.value;
|
||||||
debouncedOnChange(value, true);
|
if (isValidColor(value)) {
|
||||||
|
debouncedOnChange(value, true);
|
||||||
|
}
|
||||||
setColor(value);
|
setColor(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -544,9 +546,20 @@ const ColorPickerComponent = React.forwardRef(
|
||||||
|
|
||||||
const handleInputClick = () => {
|
const handleInputClick = () => {
|
||||||
isClick.current = true;
|
isClick.current = true;
|
||||||
|
|
||||||
|
if (isFullColorPicker && isOpen) {
|
||||||
|
setIsOpen(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFullColorPickerClick = (value: boolean) => {
|
||||||
|
setFullColorPicker(value);
|
||||||
|
setIsOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnInteraction = (nextOpenState: boolean) => {
|
const handleOnInteraction = (nextOpenState: boolean) => {
|
||||||
|
if (isFullColorPicker && !isOpen) return;
|
||||||
|
|
||||||
if (isOpen !== nextOpenState) {
|
if (isOpen !== nextOpenState) {
|
||||||
if (isClick.current) setIsOpen(true);
|
if (isClick.current) setIsOpen(true);
|
||||||
else setIsOpen(nextOpenState);
|
else setIsOpen(nextOpenState);
|
||||||
|
|
@ -567,19 +580,26 @@ const ColorPickerComponent = React.forwardRef(
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
minimal
|
minimal
|
||||||
modifiers={POPOVER_MODFIER}
|
modifiers={POPOVER_MODFIER}
|
||||||
|
onClosed={props.onPopupClosed}
|
||||||
onInteraction={handleOnInteraction}
|
onInteraction={handleOnInteraction}
|
||||||
popoverClassName="color-picker-input"
|
popoverClassName="color-picker-input"
|
||||||
portalContainer={props.portalContainer}
|
portalContainer={props.portalContainer}
|
||||||
>
|
>
|
||||||
<StyledInputGroup
|
<StyledInputGroup
|
||||||
|
$isFullColorPicker={isFullColorPicker}
|
||||||
|
$isValid={isValidColor(color)}
|
||||||
autoFocus={props.autoFocus}
|
autoFocus={props.autoFocus}
|
||||||
|
data-testid="t--color-picker-input"
|
||||||
inputRef={inputGroupRef}
|
inputRef={inputGroupRef}
|
||||||
leftIcon={
|
leftIcon={
|
||||||
<LeftIcon color={color} handleInputClick={handleInputClick} />
|
!isFullColorPicker ? (
|
||||||
|
<LeftIcon color={color} handleInputClick={handleInputClick} />
|
||||||
|
) : null
|
||||||
}
|
}
|
||||||
onChange={handleChangeColor}
|
onChange={handleChangeColor}
|
||||||
onClick={handleInputClick}
|
onClick={handleInputClick}
|
||||||
placeholder={placeholderText || "enter color name or hex"}
|
placeholder={placeholderText || "enter color name or hex"}
|
||||||
|
type={isFullColorPicker ? "color" : "text"}
|
||||||
value={color}
|
value={color}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
@ -593,6 +613,14 @@ const ColorPickerComponent = React.forwardRef(
|
||||||
showThemeColors={props.showThemeColors}
|
showThemeColors={props.showThemeColors}
|
||||||
/>
|
/>
|
||||||
</Popover>
|
</Popover>
|
||||||
|
<div className="mt-2">
|
||||||
|
<Switch
|
||||||
|
isSelected={isFullColorPicker}
|
||||||
|
onChange={handleFullColorPickerClick}
|
||||||
|
>
|
||||||
|
{createMessage(FULL_COLOR_PICKER_LABEL)}
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -13,101 +13,54 @@ export type TailwindColors = {
|
||||||
|
|
||||||
export const TAILWIND_COLORS: TailwindColors = {
|
export const TAILWIND_COLORS: TailwindColors = {
|
||||||
gray: {
|
gray: {
|
||||||
50: "#fafafa",
|
|
||||||
100: "#f4f4f5",
|
100: "#f4f4f5",
|
||||||
200: "#e4e4e7",
|
|
||||||
300: "#d4d4d8",
|
300: "#d4d4d8",
|
||||||
400: "#a1a1aa",
|
|
||||||
500: "#71717a",
|
500: "#71717a",
|
||||||
600: "#52525b",
|
|
||||||
700: "#3f3f46",
|
700: "#3f3f46",
|
||||||
800: "#27272a",
|
|
||||||
900: "#18181b",
|
900: "#18181b",
|
||||||
},
|
},
|
||||||
red: {
|
red: {
|
||||||
50: "#fef2f2",
|
|
||||||
100: "#fee2e2",
|
100: "#fee2e2",
|
||||||
200: "#fecaca",
|
|
||||||
300: "#fca5a5",
|
300: "#fca5a5",
|
||||||
400: "#f87171",
|
|
||||||
500: "#ef4444",
|
500: "#ef4444",
|
||||||
600: "#dc2626",
|
|
||||||
700: "#b91c1c",
|
700: "#b91c1c",
|
||||||
800: "#991b1b",
|
|
||||||
900: "#7f1d1d",
|
900: "#7f1d1d",
|
||||||
},
|
},
|
||||||
|
|
||||||
yellow: {
|
yellow: {
|
||||||
50: "#fefce8",
|
|
||||||
100: "#fef9c3",
|
100: "#fef9c3",
|
||||||
200: "#fef08a",
|
|
||||||
300: "#fde047",
|
300: "#fde047",
|
||||||
400: "#facc15",
|
|
||||||
500: "#eab308",
|
500: "#eab308",
|
||||||
600: "#ca8a04",
|
|
||||||
700: "#a16207",
|
700: "#a16207",
|
||||||
800: "#854d0e",
|
|
||||||
900: "#713f12",
|
900: "#713f12",
|
||||||
},
|
},
|
||||||
|
|
||||||
green: {
|
green: {
|
||||||
50: "#f0fdf4",
|
|
||||||
100: "#dcfce7",
|
100: "#dcfce7",
|
||||||
200: "#bbf7d0",
|
|
||||||
300: "#86efac",
|
300: "#86efac",
|
||||||
400: "#4ade80",
|
|
||||||
500: "#22c55e",
|
500: "#22c55e",
|
||||||
600: "#16a34a",
|
|
||||||
700: "#15803d",
|
700: "#15803d",
|
||||||
800: "#166534",
|
|
||||||
900: "#14532d",
|
900: "#14532d",
|
||||||
},
|
},
|
||||||
blue: {
|
blue: {
|
||||||
50: "#eff6ff",
|
|
||||||
100: "#dbeafe",
|
100: "#dbeafe",
|
||||||
200: "#bfdbfe",
|
|
||||||
300: "#93c5fd",
|
300: "#93c5fd",
|
||||||
400: "#60a5fa",
|
|
||||||
500: "#3b82f6",
|
500: "#3b82f6",
|
||||||
600: "#2563eb",
|
|
||||||
700: "#1d4ed8",
|
700: "#1d4ed8",
|
||||||
800: "#1e40af",
|
|
||||||
900: "#1e3a8a",
|
900: "#1e3a8a",
|
||||||
},
|
},
|
||||||
indigo: {
|
|
||||||
50: "#eef2ff",
|
|
||||||
100: "#e0e7ff",
|
|
||||||
200: "#c7d2fe",
|
|
||||||
300: "#a5b4fc",
|
|
||||||
400: "#818cf8",
|
|
||||||
500: "#6366f1",
|
|
||||||
600: "#4f46e5",
|
|
||||||
700: "#4338ca",
|
|
||||||
800: "#3730a3",
|
|
||||||
900: "#312e81",
|
|
||||||
},
|
|
||||||
purple: {
|
purple: {
|
||||||
50: "#faf5ff",
|
|
||||||
100: "#f3e8ff",
|
100: "#f3e8ff",
|
||||||
200: "#e9d5ff",
|
|
||||||
300: "#d8b4fe",
|
300: "#d8b4fe",
|
||||||
400: "#c084fc",
|
|
||||||
500: "#a855f7",
|
500: "#a855f7",
|
||||||
600: "#9333ea",
|
|
||||||
700: "#7e22ce",
|
700: "#7e22ce",
|
||||||
800: "#6b21a8",
|
|
||||||
900: "#581c87",
|
900: "#581c87",
|
||||||
},
|
},
|
||||||
pink: {
|
pink: {
|
||||||
50: "#fdf2f8",
|
|
||||||
100: "#fce7f3",
|
100: "#fce7f3",
|
||||||
200: "#fbcfe8",
|
|
||||||
300: "#f9a8d4",
|
300: "#f9a8d4",
|
||||||
400: "#f472b6",
|
|
||||||
500: "#ec4899",
|
500: "#ec4899",
|
||||||
600: "#db2777",
|
|
||||||
700: "#be185d",
|
700: "#be185d",
|
||||||
800: "#9d174d",
|
|
||||||
900: "#831843",
|
900: "#831843",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,7 @@ function ThemeColorControl(props: ThemeColorControlProps) {
|
||||||
color={userDefinedColors[selectedColor]}
|
color={userDefinedColors[selectedColor]}
|
||||||
isOpen={autoFocus}
|
isOpen={autoFocus}
|
||||||
key={selectedColor}
|
key={selectedColor}
|
||||||
|
onPopupClosed={() => setAutoFocus(false)}
|
||||||
portalContainer={
|
portalContainer={
|
||||||
document.getElementById("app-settings-portal") || undefined
|
document.getElementById("app-settings-portal") || undefined
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { RenderModes } from "constants/WidgetConstants";
|
import { RenderModes } from "constants/WidgetConstants";
|
||||||
import { ValidationTypes } from "constants/WidgetValidation";
|
import { ValidationTypes } from "constants/WidgetValidation";
|
||||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||||
|
import type { CanvasWidgetsReduxState } from "../reducers/entityReducers/canvasWidgetsReducer";
|
||||||
import { AutocompleteDataType } from "./autocomplete/AutocompleteDataType";
|
import { AutocompleteDataType } from "./autocomplete/AutocompleteDataType";
|
||||||
import {
|
import {
|
||||||
flattenObject,
|
flattenObject,
|
||||||
|
|
@ -550,20 +551,30 @@ describe("#captureInvalidDynamicBindingPath", () => {
|
||||||
|
|
||||||
describe("#extractColorsFromString", () => {
|
describe("#extractColorsFromString", () => {
|
||||||
it("Check if the extractColorsFromString returns rgb, rgb, hex color strings", () => {
|
it("Check if the extractColorsFromString returns rgb, rgb, hex color strings", () => {
|
||||||
const borderWithHex = `2px solid ${Colors.GREEN}`;
|
const widgets = {
|
||||||
const borderWithRgb = "2px solid rgb(0,0,0)";
|
0: { color: `${Colors.GREEN}` },
|
||||||
const borderWithRgba = `2px solid ${Colors.BOX_SHADOW_DEFAULT_VARIANT1}`;
|
1: { color: "rgb(0,0,0)" },
|
||||||
|
2: { color: `${Colors.BOX_SHADOW_DEFAULT_VARIANT1}` },
|
||||||
|
3: { color: `LightGoldenrodYellow` },
|
||||||
|
4: { color: `lch(54.292% 106.839 40.853)` },
|
||||||
|
} as unknown as CanvasWidgetsReduxState;
|
||||||
|
|
||||||
//Check Hex value
|
//Check Hex value
|
||||||
expect(extractColorsFromString(borderWithHex)[0]).toEqual("#03b365");
|
expect(extractColorsFromString(widgets)[0]).toEqual("#03B365");
|
||||||
|
|
||||||
//Check rgba value
|
|
||||||
expect(extractColorsFromString(borderWithRgba)[0]).toEqual(
|
|
||||||
"rgba(0, 0, 0, 0.25)",
|
|
||||||
);
|
|
||||||
|
|
||||||
//Check rgb
|
//Check rgb
|
||||||
expect(extractColorsFromString(borderWithRgb)[0]).toEqual("rgb(0,0,0)");
|
expect(extractColorsFromString(widgets)[1]).toEqual("rgb(0,0,0)");
|
||||||
|
|
||||||
|
//Check rgba value
|
||||||
|
expect(extractColorsFromString(widgets)[2]).toEqual("rgba(0, 0, 0, 0.25)");
|
||||||
|
|
||||||
|
//Check name value
|
||||||
|
expect(extractColorsFromString(widgets)[3]).toEqual("LightGoldenrodYellow");
|
||||||
|
|
||||||
|
//Check lch value
|
||||||
|
expect(extractColorsFromString(widgets)[4]).toEqual(
|
||||||
|
"lch(54.292% 106.839 40.853)",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import type { ContainerWidgetProps } from "widgets/ContainerWidget/widget";
|
||||||
import type { WidgetProps } from "widgets/BaseWidget";
|
import type { WidgetProps } from "widgets/BaseWidget";
|
||||||
import { getContainerIdForCanvas } from "sagas/WidgetOperationUtils";
|
import { getContainerIdForCanvas } from "sagas/WidgetOperationUtils";
|
||||||
import scrollIntoView from "scroll-into-view-if-needed";
|
import scrollIntoView from "scroll-into-view-if-needed";
|
||||||
|
import validateColor from "validate-color";
|
||||||
|
|
||||||
export const snapToGrid = (
|
export const snapToGrid = (
|
||||||
columnWidth: number,
|
columnWidth: number,
|
||||||
|
|
@ -757,28 +758,36 @@ export function getLogToSentryFromResponse(response?: ApiResponse) {
|
||||||
return response && response?.responseMeta?.status >= 500;
|
return response && response?.responseMeta?.status >= 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BLACKLIST_COLORS = ["#ffffff"];
|
|
||||||
const HEX_REGEX = /#[0-9a-fA-F]{6}/gi;
|
|
||||||
const RGB_REGEX = /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)/gi;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* extract colors from string
|
* extract colors from string
|
||||||
*
|
*
|
||||||
* @param text
|
|
||||||
* @returns
|
* @returns
|
||||||
|
* @param widgets
|
||||||
*/
|
*/
|
||||||
export function extractColorsFromString(text: string) {
|
export function extractColorsFromString(widgets: CanvasWidgetsReduxState) {
|
||||||
const colors = new Set();
|
const colors = new Set();
|
||||||
|
|
||||||
[...(text.match(RGB_REGEX) || []), ...(text.match(HEX_REGEX) || [])]
|
Object.values(widgets).forEach((widget) => {
|
||||||
.filter((d) => BLACKLIST_COLORS.indexOf(d.toLowerCase()) === -1)
|
Object.values(widget).forEach((widgetProp) => {
|
||||||
.forEach((color) => {
|
if (isString(widgetProp) && validateColor(widgetProp)) {
|
||||||
colors.add(color.toLowerCase());
|
colors.add(widgetProp);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return Array.from(colors) as Array<string>;
|
return Array.from(colors) as Array<string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate color string
|
||||||
|
*
|
||||||
|
* @returns {boolean} true if string is valid color or includes url
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
export function isValidColor(color: string) {
|
||||||
|
return color?.includes("url") || validateColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to merge property pane config of a widget
|
* Function to merge property pane config of a widget
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -9589,6 +9589,7 @@ __metadata:
|
||||||
unescape-js: ^1.1.4
|
unescape-js: ^1.1.4
|
||||||
url-search-params-polyfill: ^8.0.0
|
url-search-params-polyfill: ^8.0.0
|
||||||
uuid: ^9.0.0
|
uuid: ^9.0.0
|
||||||
|
validate-color: ^2.2.4
|
||||||
webfontloader: ^1.6.28
|
webfontloader: ^1.6.28
|
||||||
webpack-merge: ^5.8.0
|
webpack-merge: ^5.8.0
|
||||||
webpack-retry-chunk-load-plugin: ^3.1.1
|
webpack-retry-chunk-load-plugin: ^3.1.1
|
||||||
|
|
@ -28934,6 +28935,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"validate-color@npm:^2.2.4":
|
||||||
|
version: 2.2.4
|
||||||
|
resolution: "validate-color@npm:2.2.4"
|
||||||
|
checksum: ac9109e6347797300fd0a0b08d623acaf3cc295cc2077b9041119582c632eb56dc78e94b8f7f929754508974a8a0b63d296995106a20b237b3be5e89ff2c80f1
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"validate-npm-package-license@npm:^3.0.1":
|
"validate-npm-package-license@npm:^3.0.1":
|
||||||
version: 3.0.4
|
version: 3.0.4
|
||||||
resolution: "validate-npm-package-license@npm:3.0.4"
|
resolution: "validate-npm-package-license@npm:3.0.4"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user