From 6f2f11b40b680fb48a85cf39a1cae1f917efcd9d Mon Sep 17 00:00:00 2001 From: Pawan Kumar Date: Thu, 6 Feb 2025 13:10:25 +0530 Subject: [PATCH] chore: update select component (#38954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ![CleanShot 2025-02-03 at 13 51 45](https://github.com/user-attachments/assets/4c7a7a67-c1fc-4fe7-afbb-2342aea27fcc) Few known bugs: 1. --The placeholder value is cleared when the user is searching. This is happening cause we are using hack to put search into dropdown and it is conflicting with native behavior of rc-select-- [](https://github.com/user-attachments/assets/4d40607f-c9c9-4060-9086-cc9d8dc49553) /ok-to-test tags="@tag.All" ## Summary by CodeRabbit - **New Features** - Introduced a grouped dropdown with checkboxes for multi-select, making option organization more intuitive. - **Enhancements** - Upgraded dropdown search with auto-focus and dynamic filtering. - Improved tag display with responsive limits and an updated "info" style. - Added configuration options to control the number of visible tags. - **Documentation** - Expanded examples to showcase the new grouped and checkbox-enhanced dropdown features. - **Style** - Refined styling and animations for dropdown states, ensuring a fluid and consistent user experience. - **Bug Fixes** - Adjusted selectors in tests to improve interaction with dropdowns, enhancing test reliability. > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: > Commit: 33634093ddb9b6d699d8f9c50297c4245bea21fb > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Thu, 06 Feb 2025 07:34:34 UTC --- .../ClientSide/Binding/ChartText_spec.js | 3 +- .../Widgets/Button/ButtonGroup_spec.js | 10 +- .../CurrencyInput/CurrencyInput_spec.js | 32 +++--- .../Filepicker/FilePickerV2_CSV_spec.js | 2 +- .../Widgets/Input/Inputv2_inside_List_spec.js | 8 +- .../ClientSide/Widgets/Input/Inputv2_spec.js | 20 ++-- .../Widgets/PhoneInput/Phone_input_spec.js | 43 ++++---- app/client/cypress/locators/ViewWidgets.json | 4 +- app/client/cypress/locators/Widgets.json | 12 +- .../cypress/locators/commonlocators.json | 12 +- .../cypress/support/Pages/AggregateHelper.ts | 6 +- app/client/cypress/support/Pages/GitSync.ts | 10 +- app/client/cypress/support/widgetCommands.js | 33 +++++- app/client/package.json | 2 +- .../ads/src/Checkbox/Checkbox.tsx | 2 +- .../design-system/ads/src/Select/Select.mdx | 4 + .../ads/src/Select/Select.stories.tsx | 75 ++++++++++++- .../design-system/ads/src/Select/Select.tsx | 58 ++++++++-- .../ads/src/Select/rc-styles.css | 58 ++++++++++ .../design-system/ads/src/Select/styles.css | 103 ++++++++++++++---- .../design-system/ads/src/Tag/Tag.styles.tsx | 7 +- .../design-system/ads/src/Tag/Tag.tsx | 3 +- .../design-system/ads/src/Tag/Tag.types.tsx | 2 +- .../TableOrSpreadsheetDropdown/index.tsx | 4 - .../formControls/DropDownControl.test.tsx | 1 + .../formControls/DropDownControl.tsx | 3 + .../controls/ThemeFontControl.tsx | 2 +- 27 files changed, 399 insertions(+), 120 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js index 38f9eec51b..f44989ff37 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Binding/ChartText_spec.js @@ -28,8 +28,7 @@ describe( EditorNavigation.SelectEntityByName("Chart1", EntityType.Widget, {}, [ "Container1", ]); - cy.get(viewWidgetsPage.chartType).last().click({ force: true }); - cy.get(".t--dropdown-option").children().contains("Column chart").click(); + cy.selectDropdownValue(viewWidgetsPage.chartType, "Column chart"); cy.get( ".t--property-control-charttype span.rc-select-selection-item span", ) diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Button/ButtonGroup_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Button/ButtonGroup_spec.js index 1e64e83a5c..20e2b13be2 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Button/ButtonGroup_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Button/ButtonGroup_spec.js @@ -82,19 +82,13 @@ describe( it("Update Placement and Verify buttons alignments", function () { // check first button placement - cy.selectDropdownValue( - ".t--property-control-placement .rc-select-selection-item", - "Between", - ); + cy.selectDropdownValue(".t--property-control-placement", "Between"); // 1st btn cy.get(firstButton) .last() .should("have.css", "justify-content", "space-between"); // update dropdown value - cy.selectDropdownValue( - ".t--property-control-placement .rc-select-selection-item", - "Start", - ); + cy.selectDropdownValue(".t--property-control-placement", "Start"); cy.get(firstButton).last().should("have.css", "justify-content", "start"); // other button style stay same cy.get(menuButton).should("have.css", "justify-content", "center"); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/CurrencyInput/CurrencyInput_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/CurrencyInput/CurrencyInput_spec.js index b4fdfe4d25..61209355e1 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/CurrencyInput/CurrencyInput_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/CurrencyInput/CurrencyInput_spec.js @@ -27,12 +27,13 @@ describe( it("2. should check for type of value and widget", () => { cy.openPropertyPane(widgetName); - cy.get(".t--property-control-currency").click(); - cy.get(".t--property-control-currency").type("usd"); + cy.openSelectDropdown(".t--property-control-currency"); + cy.searchSelectDropdown("usd"); cy.selectDropdownValue( - ".t--property-control-currency input", + ".t--property-control-currency", "USD - US Dollar", ); + function enterAndTest(text, expected) { cy.get(widgetInput).clear(); cy.wait(300); @@ -53,7 +54,7 @@ describe( }); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "1"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "1"); [ //[input, {{CurrencyInput1.text}}:{{CurrencyInput1.value}}:{{CurrencyInput1.isValid}}:{{typeof CurrencyInput1.text}}:{{typeof CurrencyInput1.value}}:{{CurrencyInput1.countryCode}}:{{CurrencyInput1.currencyCode}}] @@ -66,7 +67,7 @@ describe( }); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "2"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "2"); [ //[input, {{CurrencyInput1.text}}:{{CurrencyInput1.value}}:{{CurrencyInput1.isValid}}:{{typeof CurrencyInput1.text}}:{{typeof CurrencyInput1.value}}:{{CurrencyInput1.countryCode}}:{{CurrencyInput1.currencyCode}}] @@ -80,10 +81,10 @@ describe( cy.get(".currency-change-dropdown-trigger").should("contain", "$"); cy.openPropertyPane(widgetName); - cy.get(".t--property-control-currency").click(); - cy.get(".t--property-control-currency").type("ind"); + cy.openSelectDropdown(".t--property-control-currency"); + cy.searchSelectDropdown("ind"); cy.selectDropdownValue( - ".t--property-control-currency input", + ".t--property-control-currency", "INR - Indian Rupee", ); enterAndTest("100.22", "100.22:100.22:true:string:number:IN:INR"); @@ -100,12 +101,13 @@ describe( .last() .click(); enterAndTest("100.22", "100.22:100.22:true:string:number:GB:GBP"); + enterAndTest("100.22", "100.22:100.22:true:string:number:GB:GBP"); cy.get(".t--input-currency-change").should("contain", "£"); }); it("3. should accept 0 decimal option", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "0"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "0"); cy.closePropertyPane(); cy.wait(500); cy.openPropertyPane(widgetName); @@ -142,7 +144,7 @@ describe( `{{CurrencyInput1.text}}:{{CurrencyInput1.value}}`, ); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "0"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "0"); [ //[input, {{CurrencyInput1.text}}:{{CurrencyInput1.value}}] @@ -157,7 +159,7 @@ describe( }); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "1"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "1"); [ //[input, {{CurrencyInput1.text}}:{{CurrencyInput1.value}}] ["100", "100:100"], @@ -171,7 +173,7 @@ describe( }); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "2"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "2"); [ //[input, {{CurrencyInput1.text}}:{{CurrencyInput1.value}}] ["100", "100:100"], @@ -205,7 +207,7 @@ describe( } cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "0"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "0"); [ //[input, expected] @@ -221,7 +223,7 @@ describe( }); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "1"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "1"); [ //[input, expected] ["100", "100"], @@ -238,7 +240,7 @@ describe( }); cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-decimalsallowed input", "2"); + cy.selectDropdownValue(".t--property-control-decimalsallowed", "2"); [ //[input, expected] ["100", "100"], diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Filepicker/FilePickerV2_CSV_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Filepicker/FilePickerV2_CSV_spec.js index 975f23e23f..115872c087 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Filepicker/FilePickerV2_CSV_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Filepicker/FilePickerV2_CSV_spec.js @@ -29,7 +29,7 @@ describe( ); agHelper.AssertText( - commonlocators.filePickerDataFormat, + `${commonlocators.filePickerDataFormat} .rc-select-selection-item .ads-v2-text`, "text", "Array of Objects (CSV, XLS(X), JSON, TSV)", ); diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_inside_List_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_inside_List_spec.js index 291ece7961..a69e464b32 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_inside_List_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_inside_List_spec.js @@ -52,13 +52,13 @@ describe( it("3. Validate DataType - NUMBER can be entered into Input widget", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-datatype input", "Number"); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); cy.get(".t--property-control-required label") .last() .click({ force: true }); - cy.selectDropdownValue(".t--property-control-datatype input", "Number"); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); [ { input: "invalid", @@ -101,7 +101,7 @@ describe( it("4. Validate DataType - PASSWORD can be entered into Input widget", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-datatype input", "Password"); + cy.selectDropdownValue(".t--property-control-datatype", "Password"); [ { input: "test", @@ -136,7 +136,7 @@ describe( it("5. Validate DataType - EMAIL can be entered into Input widget", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-datatype input", "Email"); + cy.selectDropdownValue(".t--property-control-datatype", "Email"); cy.get(".t--property-control-required label") .last() diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_spec.js index 3c9f53e826..d3bf289515 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/Input/Inputv2_spec.js @@ -27,7 +27,7 @@ describe( cy.wait(300); cy.get(widgetInput).should("contain.value", ""); - cy.selectDropdownValue(".t--property-control-datatype input", "Number"); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); cy.get(widgetInput).clear(); cy.get(widgetInput).type("1.0010{enter}"); //Clicking enter submits the form here @@ -37,7 +37,7 @@ describe( it("3. Validate DataType - TEXT can be entered into Input widget", () => { cy.selectDropdownValue( - ".t--property-control-datatype input", + ".t--property-control-datatype", "Single-line text", ); [ @@ -112,7 +112,7 @@ describe( it("4. Validate DataType - NUMBER can be entered into Input widget", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-datatype input", "Number"); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); [ { input: "invalid", @@ -157,7 +157,7 @@ describe( .last() .click({ force: true }); - cy.selectDropdownValue(".t--property-control-datatype input", "Number"); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); [ { input: "invalid", @@ -200,7 +200,7 @@ describe( it("5. Validate DataType - PASSWORD can be entered into Input widget", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-datatype input", "Password"); + cy.selectDropdownValue(".t--property-control-datatype", "Password"); [ { input: "test", @@ -273,7 +273,7 @@ describe( it("6. Validate DataType - EMAIL can be entered into Input widget", () => { cy.openPropertyPane(widgetName); - cy.selectDropdownValue(".t--property-control-datatype input", "Email"); + cy.selectDropdownValue(".t--property-control-datatype", "Email"); [ { input: "test", @@ -361,7 +361,7 @@ describe( it("8. onSubmit should be triggered with the whole input value", () => { cy.openPropertyPane(widgetName); cy.selectDropdownValue( - ".t--property-control-datatype input", + ".t--property-control-datatype", "Single-line text", ); cy.get(".t--property-control-required label") @@ -415,7 +415,7 @@ describe( "anotherText:anotherText:true", ); - cy.selectDropdownValue(".t--property-control-datatype input", "Number"); + cy.selectDropdownValue(".t--property-control-datatype", "Number"); cy.updateCodeInput(".t--property-control-defaultvalue", `{{1}}`); // wait for evaluations @@ -439,7 +439,7 @@ describe( // Init isDirty cy.openPropertyPane(widgetName); cy.selectDropdownValue( - ".t--property-control-datatype input", + ".t--property-control-datatype", "Single-line text", ); cy.updateCodeInput(".t--property-control-defaultvalue", "a"); @@ -490,7 +490,7 @@ describe( cy.get(widgetInput).should("have.attr", "autocomplete", "off"); //select a non email or password option - cy.selectDropdownValue(".t--property-control-datatype input", "text"); + cy.selectDropdownValue(".t--property-control-datatype", "text"); //autofill toggle should not be present as this restores autofill to be enabled cy.get(".t--property-control-allowautofill input").should("not.exist"); //autocomplete attribute should not be present in the text widget diff --git a/app/client/cypress/e2e/Regression/ClientSide/Widgets/PhoneInput/Phone_input_spec.js b/app/client/cypress/e2e/Regression/ClientSide/Widgets/PhoneInput/Phone_input_spec.js index a539adac57..cba5e7fdf3 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/Widgets/PhoneInput/Phone_input_spec.js +++ b/app/client/cypress/e2e/Regression/ClientSide/Widgets/PhoneInput/Phone_input_spec.js @@ -2,17 +2,7 @@ import * as _ from "../../../../../support/Objects/ObjectsCore"; const widgetName = "phoneinputwidget"; const widgetInput = `.t--widget-${widgetName} input`; -const searchAndSelectOption = (optionValue) => { - cy.get(".t--property-control-defaultcountrycode input") - .last() - .scrollIntoView() - .click({ force: true }) - .type(optionValue.substring(0, 3)); - cy.get(".t--dropdown-option") - .children() - .contains(optionValue) - .click({ force: true }); -}; + describe( "Phone input widget - ", { tags: ["@tag.Widget", "@tag.PhoneInput", "@tag.Binding"] }, @@ -21,7 +11,7 @@ describe( _.agHelper.AddDsl("emptyDSL"); }); - it("1. Add new dropdown widget", () => { + it("1. Add new phone input widget", () => { cy.dragAndDropToCanvas(widgetName, { x: 300, y: 300 }); cy.get(`.t--widget-${widgetName}`).should("exist"); cy.dragAndDropToCanvas("textwidget", { x: 300, y: 500 }); @@ -39,7 +29,12 @@ describe( cy.get(".t--widget-textwidget").should("contain", "(999) 999-9999:US:+1"); cy.openPropertyPane(widgetName); - searchAndSelectOption("Afghanistan (+93)"); + cy.openSelectDropdown(".t--property-control-defaultcountrycode"); + cy.searchSelectDropdown("Afg"); + cy.selectDropdownValue( + ".t--property-control-defaultcountrycode", + "Afghanistan (+93)", + ); cy.get(`.t--widget-${widgetName} input`).clear(); cy.wait(500); cy.get(`.t--widget-${widgetName} input`).type("1234567890"); @@ -62,14 +57,24 @@ describe( cy.get(".t--property-control-enableformatting label") .last() .click({ force: true }); - searchAndSelectOption("United States / Canada (+1)"); + cy.openSelectDropdown(".t--property-control-defaultcountrycode"); + cy.searchSelectDropdown("United States / Canada"); + cy.selectDropdownValue( + ".t--property-control-defaultcountrycode", + "United States / Canada (+1)", + ); cy.get(`.t--widget-${widgetName} input`).clear(); cy.wait(500); cy.get(`.t--widget-${widgetName} input`).type("9999999999"); cy.get(".t--widget-textwidget").should("contain", "9999999999:US:+1"); cy.openPropertyPane(widgetName); - searchAndSelectOption("India (+91)"); + cy.openSelectDropdown(".t--property-control-defaultcountrycode"); + cy.searchSelectDropdown("India"); + cy.selectDropdownValue( + ".t--property-control-defaultcountrycode", + "India (+91)", + ); cy.get(`.t--widget-${widgetName} input`).clear(); cy.wait(500); cy.get(`.t--widget-${widgetName} input`).type("1234567890"); @@ -131,13 +136,11 @@ describe( // Select the Currency dropdown option from property pane // and enter a value that has space and returns 0 results - cy.get(".t--property-control-defaultcountrycode input") - .first() - .click() - .type("AFDB (+93)"); + cy.openSelectDropdown(".t--property-control-defaultcountrycode"); + cy.searchSelectDropdown("AFDB"); // assert that the dropdown is still option - cy.get(".t--property-control-defaultcountrycode input").should( + cy.get(".ads-v2-select__dropdown .rc-select-item-empty").should( "be.visible", ); }); diff --git a/app/client/cypress/locators/ViewWidgets.json b/app/client/cypress/locators/ViewWidgets.json index f12eadfc45..e868e0a384 100644 --- a/app/client/cypress/locators/ViewWidgets.json +++ b/app/client/cypress/locators/ViewWidgets.json @@ -1,7 +1,7 @@ { "imageWidget": ".t--draggable-imagewidget", "chartWidget": ".t--draggable-chartwidget", - "chartType": ".t--property-control-charttype input", + "chartType": ".t--property-control-charttype", "chartTypeText": ".t--property-control-charttype", "mapType": ".t--property-control-maptype .rc-select-selection-item", "destin": ".appsmith_widget_01ewdomru7", @@ -36,4 +36,4 @@ "pickMyLocation": ".t--draggable-mapwidget div[title='Pick My Location']", "mapChartEntityLabels": ".t--draggable-mapchartwidget text", "listWidget": ".t--draggable-listwidget" -} +} \ No newline at end of file diff --git a/app/client/cypress/locators/Widgets.json b/app/client/cypress/locators/Widgets.json index 4dcb4ce330..3ebeed9d3f 100644 --- a/app/client/cypress/locators/Widgets.json +++ b/app/client/cypress/locators/Widgets.json @@ -5,7 +5,7 @@ "multiSelectWidget": ".t--draggable-multiselectwidgetv2", "togglebutton": "input[type='checkbox']", "showStepArrowsToggleCheckBox": ".t--property-control-showsteparrows input[type='checkbox']", - "inputPropsDataType": ".t--property-control-datatype input", + "inputPropsDataType": ".t--property-control-datatype", "inputdatatypeplaceholder": ".t--property-control-placeholder", "buttonWidget": ".t--draggable-buttonwidget", "buttonColor": ".t--property-control-buttoncolor [data-testid='t--color-picker-input']", @@ -31,7 +31,7 @@ "labelColor": ".t--property-control-labelcolor input", "inputval": ".t--draggable-inputwidgetv2 span.t--widget-name", "dataclass": ".bp3-input", - "datatype": ".t--property-control-datatype input", + "datatype": ".t--property-control-datatype", "rowHeight": ".t--property-control-defaultrowheight .rc-select-selection-search-input ", "innertext": ".t--draggable-inputwidgetv2 input", "defaultinput": ".t--property-control-defaultinput", @@ -232,9 +232,9 @@ "counterclockwise": ".t--property-control-counterclockwise input[type='checkbox']", "serversideFilteringInput": ".t--property-control-serversidefiltering input[type='checkbox']", "propertyPaneSaveButton": ".t--property-pane-section-collapse-savebutton", - "firstEditInput":"[data-colindex=0][data-rowindex=0] .t--inlined-cell-editor input.bp3-input", - "cellControlSwitch" : ".t--property-control-cellwrapping .ads-v2-switch", - "propertyControlLabel" : ".t--property-control-label", + "firstEditInput": "[data-colindex=0][data-rowindex=0] .t--inlined-cell-editor input.bp3-input", + "cellControlSwitch": ".t--property-control-cellwrapping .ads-v2-switch", + "propertyControlLabel": ".t--property-control-label", "todayText": "span:contains('Today')", "dayPickerToday": ".DayPicker-Day--today" -} +} \ No newline at end of file diff --git a/app/client/cypress/locators/commonlocators.json b/app/client/cypress/locators/commonlocators.json index ccdf52e485..e6750c2d4e 100644 --- a/app/client/cypress/locators/commonlocators.json +++ b/app/client/cypress/locators/commonlocators.json @@ -126,12 +126,12 @@ "filePickerRemoveButton": ".uppy-Dashboard-Item-action--remove", "AddMoreFiles": ".uppy-DashboardContent-addMoreCaption", "filePickerOnFilesSelected": ".t--property-control-onfilesselected", - "dataType": ".t--property-control-datatype input", - "recaptchaVersion": ".t--property-control-googlerecaptchaversion input", + "dataType": ".t--property-control-datatype", + "recaptchaVersion": ".t--property-control-googlerecaptchaversion", "recaptchaVersionText": ".t--property-control-googlerecaptchaversion span.rc-select-selection-item span", - "filePickerDataFormat": ".t--property-control-dataformat .rc-select-selection-item", + "filePickerDataFormat": ".t--property-control-dataformat", "helperText": ".t--property-control-helperText", - "jsonFormFieldType": ".t--property-control-fieldtype input", + "jsonFormFieldType": ".t--property-control-fieldtype", "jsonFormAddNewCustomFieldBtn": ".t--property-control-fieldconfiguration .t--add-column-btn", "evaluateMsg": ".t--evaluatedPopup-error", "globalSearchModal": "[data-testid='t--global-search-modal']", @@ -207,7 +207,7 @@ "fixed": "Fixed", "autoHeight": "Auto Height", "autoHeightWithLimits": "Auto Height with limits", - "heightDropdown": "[data-guided-tour-iid='dynamicHeight'] input", + "heightDropdown": "[data-guided-tour-iid='dynamicHeight']", "minHeight": "minheight\\(inrows\\)", "maxHeight": "maxheight\\(inrows\\)", "overlayMin": "[data-testid='t--auto-height-overlay-min']", @@ -248,4 +248,4 @@ "downloadFileType": "button[class*='t--open-dropdown-Select-file-type'] > span:first-of-type", "listToggle": "[data-testid='t--list-toggle']", "showBindingsMenu": "//*[@id='entity-properties-container']" -} +} \ No newline at end of file diff --git a/app/client/cypress/support/Pages/AggregateHelper.ts b/app/client/cypress/support/Pages/AggregateHelper.ts index 466b32c263..970192e1d9 100644 --- a/app/client/cypress/support/Pages/AggregateHelper.ts +++ b/app/client/cypress/support/Pages/AggregateHelper.ts @@ -575,12 +575,14 @@ export class AggregateHelper { }); } - public WaitUntilEleAppear(selector: string) { + // Note: isVisible is required in case where item exists but is not visible ( hidden by css ), + // For e.g - search input in select widget is not visible, + public WaitUntilEleAppear(selector: string, isVisible = true) { cy.waitUntil( () => this.GetElement(selector) .should("exist") - .should("be.visible") + .should(isVisible ? "be.visible" : "not.be.visible") .its("length") .should("be.gte", 1), { diff --git a/app/client/cypress/support/Pages/GitSync.ts b/app/client/cypress/support/Pages/GitSync.ts index db8baad24f..2d405a6396 100644 --- a/app/client/cypress/support/Pages/GitSync.ts +++ b/app/client/cypress/support/Pages/GitSync.ts @@ -450,10 +450,16 @@ export class GitSync { public CheckMergeConflicts(destinationBranch: string) { this.agHelper.AssertElementExist(this.locators.quickActionsPullBtn); this.agHelper.GetNClick(this.locators.quickActionsMergeBtn); - this.agHelper.WaitUntilEleAppear(this.locators.opsMergeBranchSelectMenu); + this.agHelper.WaitUntilEleAppear( + this.locators.opsMergeBranchSelectMenu, + false, + ); this.agHelper.WaitUntilEleDisappear(this.locators.opsMergeLoader); this.assertHelper.AssertNetworkStatus("@getBranch", 200); - this.agHelper.WaitUntilEleAppear(this.locators.opsMergeBranchSelectMenu); + this.agHelper.WaitUntilEleAppear( + this.locators.opsMergeBranchSelectMenu, + false, + ); this.agHelper.GetNClick(this.locators.opsMergeBranchSelectMenu, 0, true); this.agHelper.AssertContains(destinationBranch); this.agHelper.GetNClickByContains( diff --git a/app/client/cypress/support/widgetCommands.js b/app/client/cypress/support/widgetCommands.js index 23d1d828f6..9e42a7b359 100644 --- a/app/client/cypress/support/widgetCommands.js +++ b/app/client/cypress/support/widgetCommands.js @@ -86,14 +86,45 @@ Cypress.Commands.add("selectDateFormat", (value) => { .click({ force: true }); }); +Cypress.Commands.add("openSelectDropdown", (element) => { + let isDropdownAlreadyOpen = false; + + cy.get(element) + .invoke("html") + .then((html) => { + if (html.includes("rc-select-open")) { + isDropdownAlreadyOpen = true; + } + }) + .then(() => { + if (!isDropdownAlreadyOpen) { + cy.get(element).last().scrollIntoView().click({ force: true }); + cy.get(`${element} .rc-select-selection-search-input`) + .last() + .click({ force: true }); + } + }); +}); + Cypress.Commands.add("selectDropdownValue", (element, value) => { - cy.get(element).last().scrollIntoView().click({ force: true }); + cy.openSelectDropdown(element); + cy.get(".t--dropdown-option") .children() .contains(value) .click({ force: true }); }); +Cypress.Commands.add("searchSelectDropdown", (value) => { + cy.get(".ads-v2-select__dropdown .ads-v2-input__input-section-input").click(); + cy.get(".ads-v2-select__dropdown .ads-v2-input__input-section-input").should( + "have.focus", + ); + cy.get(".ads-v2-select__dropdown .ads-v2-input__input-section-input").type( + value, + ); +}); + Cypress.Commands.add("assertDateFormat", () => { cy.get(".t--draggable-datepickerwidget2 input") .first() diff --git a/app/client/package.json b/app/client/package.json index 8ae1f92496..9a4edfbf15 100644 --- a/app/client/package.json +++ b/app/client/package.json @@ -388,4 +388,4 @@ "@types/react": "^17.0.2", "postcss": "8.4.31" } -} +} \ No newline at end of file diff --git a/app/client/packages/design-system/ads/src/Checkbox/Checkbox.tsx b/app/client/packages/design-system/ads/src/Checkbox/Checkbox.tsx index 8e4a638873..6e2d6cb2cc 100644 --- a/app/client/packages/design-system/ads/src/Checkbox/Checkbox.tsx +++ b/app/client/packages/design-system/ads/src/Checkbox/Checkbox.tsx @@ -27,7 +27,7 @@ function Checkbox(props: CheckboxProps) { isFocusVisible={isFocusVisible} isIndeterminate={isIndeterminate} > - {children} + {children} diff --git a/app/client/packages/design-system/ads/src/Select/Select.mdx b/app/client/packages/design-system/ads/src/Select/Select.mdx index 3a939f2ba2..a1d5ee2495 100644 --- a/app/client/packages/design-system/ads/src/Select/Select.mdx +++ b/app/client/packages/design-system/ads/src/Select/Select.mdx @@ -51,6 +51,10 @@ Select allows users to make single or multiple selections from a list of options +### Grouping with Checkbox in options + + + ## Best practices The select component should: diff --git a/app/client/packages/design-system/ads/src/Select/Select.stories.tsx b/app/client/packages/design-system/ads/src/Select/Select.stories.tsx index e0daa015fd..9cda90bb39 100644 --- a/app/client/packages/design-system/ads/src/Select/Select.stories.tsx +++ b/app/client/packages/design-system/ads/src/Select/Select.stories.tsx @@ -1,9 +1,10 @@ import React, { useState } from "react"; -import { Select, Option } from "./Select"; +import { Select, Option, OptGroup } from "./Select"; import { Icon } from "../Icon"; import { Checkbox } from "../Checkbox"; import type { SelectProps } from "./Select.types"; import type { StoryObj } from "@storybook/react"; +import type { DefaultOptionType } from "rc-select/lib/Select"; export default { title: "ADS/Components/Select", @@ -970,3 +971,75 @@ export function SelectWithCheckbox() { ); } + +const groupOptions = [ + { + label: "Group 1", + options: [ + { + label: "Option 1", + value: "value 11", + }, + { + label: "Very long label to force a line break in the option", + value: "Very long label to force a line break in the option", + }, + ], + }, + { + label: "Group 2", + options: Array.from({ length: 1000 }, (_, i) => ({ + label: `Option ${i + 1}`, + value: `value ${i + 1}`, + })), + }, +]; + +export function SelectWithCheckboxAndGroup() { + const [selectedOptions, setSelectedOptions] = useState( + [], + ); + + return ( + + ); +} diff --git a/app/client/packages/design-system/ads/src/Select/Select.tsx b/app/client/packages/design-system/ads/src/Select/Select.tsx index e591525d9a..958624dceb 100644 --- a/app/client/packages/design-system/ads/src/Select/Select.tsx +++ b/app/client/packages/design-system/ads/src/Select/Select.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useRef, useState } from "react"; import RCSelect, { Option as RCOption, OptGroup as RCOptGroup, @@ -12,6 +12,7 @@ import { SelectClassName, SelectDropdownClassName } from "./Select.constants"; import { Tag } from "../Tag"; import type { SelectProps } from "./Select.types"; import { Spinner } from "../Spinner"; +import { SearchInput } from "../SearchInput"; /* TODO: @@ -29,15 +30,20 @@ function Select(props: SelectProps) { isLoading = false, isMultiSelect, isValid, - maxTagCount = 2, + maxTagCount = isMultiSelect + ? props.value?.length > 1 + ? "responsive" + : 1 + : undefined, maxTagPlaceholder, - maxTagTextLength = 5, placeholder = "Please select an option", showSearch = false, size = "md", virtual = false, ...rest } = props; + const searchRef = useRef(null); + const [searchValue, setSearchValue] = useState(""); const getMaxTagPlaceholder = (omittedValues: any[]) => { return `+${omittedValues.length}`; @@ -51,6 +57,24 @@ function Select(props: SelectProps) { return ; } + const handleDropdownVisibleChange = (open: boolean) => { + if (open) { + // this is a hack to get the search input to focus when the dropdown is opened + // the reason is, rc-select does not support putting the search input in the dropdown + // and rc-select focus its native searchinput element on dropdown open, but we need to focus the search input + // so we use a timeout to focus the search input after the dropdown is opened + setTimeout(() => { + if (!searchRef.current) return; + + searchRef.current?.focus(); + }, 200); + + return; + } + + setSearchValue(""); + }; + return ( { + return ( +
+ {showSearch && ( + + )} +
{menu}
+
+ ); + }} inputIcon={} maxTagCount={maxTagCount} maxTagPlaceholder={maxTagPlaceholder || getMaxTagPlaceholder} - maxTagTextLength={maxTagTextLength} menuItemSelectedIcon="" - mode={isMultiSelect ? "multiple" : undefined} + mode={isMultiSelect ? "tags" : undefined} + onDropdownVisibleChange={handleDropdownVisibleChange} placeholder={placeholder} + searchValue={searchValue} showArrow - showSearch={showSearch} tagRender={(props) => { + if (rest.tagRender) { + return rest.tagRender(props); + } + const { closable, label, onClose } = props; return ( - + {label} ); diff --git a/app/client/packages/design-system/ads/src/Select/rc-styles.css b/app/client/packages/design-system/ads/src/Select/rc-styles.css index fe486dddb0..fd6d8cf9c9 100644 --- a/app/client/packages/design-system/ads/src/Select/rc-styles.css +++ b/app/client/packages/design-system/ads/src/Select/rc-styles.css @@ -4,10 +4,12 @@ width: 100px; position: relative; } + .rc-select-disabled, .rc-select-disabled input { cursor: not-allowed; } + .rc-select-show-arrow.rc-select-loading .rc-select-arrow-icon::after { box-sizing: border-box; width: 12px; @@ -20,27 +22,35 @@ margin-top: 4px; animation: rcSelectLoadingIcon 0.5s infinite; } + .rc-select .rc-select-selection-placeholder { opacity: 0.4; pointer-events: none; } + .rc-select .rc-select-selection-search-input { appearance: none; + opacity: 0; } + .rc-select .rc-select-selection-search-input::-webkit-search-cancel-button { display: none; appearance: none; } + .rc-select-single .rc-select-selector { display: flex; position: relative; } + .rc-select-single .rc-select-selector .rc-select-selection-search { width: 100%; } + .rc-select-single .rc-select-selector .rc-select-selection-search-input { width: 100%; } + .rc-select-single .rc-select-selector .rc-select-selection-item, .rc-select-single .rc-select-selector .rc-select-selection-placeholder { position: absolute; @@ -48,6 +58,7 @@ left: 3px; pointer-events: none; } + /* Selects the currently selected item when in the input box*/ .rc-select-single .rc-select-selector .rc-select-selection-item, .rc-select-single .rc-select-selector .rc-select-selection-placeholder, @@ -55,6 +66,7 @@ overflow: hidden; text-overflow: ellipsis; } + .rc-select-single:not(.rc-select-customize-input) .rc-select-selector .rc-select-selection-search-input { @@ -63,12 +75,14 @@ width: 100%; padding: 0; } + .rc-select-multiple .rc-select-selector { display: flex; flex-wrap: wrap; padding: 1px; border: 1px solid #000; } + .rc-select-multiple .rc-select-selector .rc-select-selection-item { flex: none; background: #bbb; @@ -76,28 +90,34 @@ margin-right: 2px; padding: 0 8px; } + .rc-select-multiple .rc-select-selector .rc-select-selection-item-disabled { cursor: not-allowed; opacity: 0.5; } + .rc-select-multiple .rc-select-selector .rc-select-selection-overflow { display: flex; flex-wrap: wrap; width: 100%; } + .rc-select-multiple .rc-select-selector .rc-select-selection-overflow-item { flex: none; max-width: 100%; } + .rc-select-multiple .rc-select-selector .rc-select-selection-search { position: relative; max-width: 100%; } + .rc-select-multiple .rc-select-selector .rc-select-selection-search-input, .rc-select-multiple .rc-select-selector .rc-select-selection-search-mirror { padding: 1px; font-family: var(--ads-v2-font-family); } + .rc-select-multiple .rc-select-selector .rc-select-selection-search-mirror { position: absolute; z-index: 999; @@ -107,29 +127,35 @@ top: 0; visibility: hidden; } + .rc-select-multiple .rc-select-selector .rc-select-selection-search-input { border: none; outline: none; background: rgba(255, 0, 0, 0.2); width: 100%; } + .rc-select-allow-clear.rc-select-multiple .rc-select-selector { padding-right: 20px; } + .rc-select-allow-clear .rc-select-clear { position: absolute; right: 20px; top: 0; } + .rc-select-show-arrow.rc-select-multiple .rc-select-selector { padding-right: 20px; } + .rc-select-show-arrow .rc-select-arrow { pointer-events: none; position: absolute; right: 5px; top: 0; } + .rc-select-show-arrow .rc-select-arrow-icon::after { content: ""; border: 5px solid transparent; @@ -145,60 +171,75 @@ position: absolute; background: #fff; } + .rc-select-dropdown-hidden { display: none; } + .rc-select-item { font-size: 16px; line-height: 1.5; padding: 4px 16px; } + .rc-select-item-group { color: #999; font-weight: bold; font-size: 80%; } + .rc-select-item-option { position: relative; } + .rc-select-item-option-grouped { padding-left: 24px; } + .rc-select-item-option .rc-select-item-option-state { position: absolute; right: 0; top: 4px; pointer-events: none; } + .rc-select-item-option-active { background: #ddd; } + .rc-select-item-option-disabled { color: #999; } + .rc-select-item-empty { text-align: center; color: #999; } + .rc-select-selection__choice-zoom { transition: all 0.3s; } + .rc-select-selection__choice-zoom-appear { opacity: 0; transform: scale(0.5); } + .rc-select-selection__choice-zoom-appear.rc-select-selection__choice-zoom-appear-active { opacity: 1; transform: scale(1); } + .rc-select-selection__choice-zoom-leave { opacity: 1; transform: scale(1); } + .rc-select-selection__choice-zoom-leave.rc-select-selection__choice-zoom-leave-active { opacity: 0; transform: scale(0.5); } + .rc-select-dropdown-slide-up-enter, .rc-select-dropdown-slide-up-appear { animation-duration: 0.3s; @@ -208,6 +249,7 @@ animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1); animation-play-state: paused; } + .rc-select-dropdown-slide-up-leave { animation-duration: 0.3s; animation-fill-mode: both; @@ -216,6 +258,7 @@ animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34); animation-play-state: paused; } + .rc-select-dropdown-slide-up-enter.rc-select-dropdown-slide-up-enter-active.rc-select-dropdown-placement-bottomLeft, .rc-select-dropdown-slide-up-appear.rc-select-dropdown-slide-up-appear-active.rc-select-dropdown-placement-bottomLeft, .rc-select-dropdown-slide-up-enter.rc-select-dropdown-slide-up-enter-active.rc-select-dropdown-placement-bottomRight, @@ -223,11 +266,13 @@ animation-name: rcSelectDropdownSlideUpIn; animation-play-state: running; } + .rc-select-dropdown-slide-up-leave.rc-select-dropdown-slide-up-leave-active.rc-select-dropdown-placement-bottomLeft, .rc-select-dropdown-slide-up-leave.rc-select-dropdown-slide-up-leave-active.rc-select-dropdown-placement-bottomRight { animation-name: rcSelectDropdownSlideUpOut; animation-play-state: running; } + .rc-select-dropdown-slide-up-enter.rc-select-dropdown-slide-up-enter-active.rc-select-dropdown-placement-topLeft, .rc-select-dropdown-slide-up-appear.rc-select-dropdown-slide-up-appear-active.rc-select-dropdown-placement-topLeft, .rc-select-dropdown-slide-up-enter.rc-select-dropdown-slide-up-enter-active.rc-select-dropdown-placement-topRight, @@ -235,71 +280,84 @@ animation-name: rcSelectDropdownSlideDownIn; animation-play-state: running; } + .rc-select-dropdown-slide-up-leave.rc-select-dropdown-slide-up-leave-active.rc-select-dropdown-placement-topLeft, .rc-select-dropdown-slide-up-leave.rc-select-dropdown-slide-up-leave-active.rc-select-dropdown-placement-topRight { animation-name: rcSelectDropdownSlideDownOut; animation-play-state: running; } + .rc-virtual-list-scrollbar { width: 5px !important; height: 5px !important; } + .rc-virtual-list-scrollbar .rc-virtual-list-scrollbar-thumb { background-color: var(--ads-v2-color-bg-emphasis) !important; border-radius: 36px; } + @keyframes rcSelectDropdownSlideUpIn { 0% { opacity: 0; transform-origin: 0% 0%; transform: scaleY(0); } + 100% { opacity: 1; transform-origin: 0% 0%; transform: scaleY(1); } } + @keyframes rcSelectDropdownSlideUpOut { 0% { opacity: 1; transform-origin: 0% 0%; transform: scaleY(1); } + 100% { opacity: 0; transform-origin: 0% 0%; transform: scaleY(0); } } + @keyframes rcSelectDropdownSlideDownIn { 0% { transform: scaleY(0); transform-origin: 100% 100%; opacity: 0; } + 100% { transform: scaleY(1); transform-origin: 100% 100%; opacity: 1; } } + @keyframes rcSelectDropdownSlideDownOut { 0% { transform: scaleY(1); transform-origin: 100% 100%; opacity: 1; } + 100% { transform: scaleY(0); transform-origin: 100% 100%; opacity: 0; } } + @keyframes rcSelectLoadingIcon { 0% { transform: rotate(0); } + 100% { transform: rotate(360deg); } diff --git a/app/client/packages/design-system/ads/src/Select/styles.css b/app/client/packages/design-system/ads/src/Select/styles.css index 723192f68a..9210c3bedc 100644 --- a/app/client/packages/design-system/ads/src/Select/styles.css +++ b/app/client/packages/design-system/ads/src/Select/styles.css @@ -19,7 +19,7 @@ } .ads-v2-select.rc-select-show-search * { - cursor: text; + cursor: unset; } /* size sm */ @@ -187,7 +187,10 @@ display: flex; font-size: 12px; align-items: center; - background: var(--ads-v2-colors-control-pill-default-bg); + background: var(--ads-v2-colors-content-surface-info-bg); + border: 1px solid var(--ads-v2-colors-content-surface-info-border); + color: var(--ads-v2-colors-content-label-info-fg); + line-height: normal; } /* typing space */ @@ -208,11 +211,10 @@ border-radius: var(--ads-v2-border-radius); border: 1px solid var(--ads-v2-colors-content-container-default-border); box-shadow: var(--ads-v2-shadow-popovers); - padding: var(--ads-v2-spaces-2); + padding: 0; animation-duration: 400ms; animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1); will-change: transform, opacity; - overflow: auto; z-index: 1001; pointer-events: auto; } @@ -226,15 +228,29 @@ --select-option-height: 36px; padding: var(--select-option-padding); - margin-bottom: var(--ads-v2-spaces-1); + margin-inline: var(--ads-v2-spaces-2); border-radius: var(--ads-v2-border-radius); cursor: pointer; - /* TODO: remove !important after WDS fix their issue in tree select */ - background-color: var(--select-option-color-bg) !important; position: relative; color: var(--ads-v2-colors-content-label-default-fg); min-height: var(--select-option-height); box-sizing: border-box; + display: flex; + align-items: center; + background-color: var(--select-option-color-bg); +} + +.ads-v2-select__dropdown .rc-virtual-list { + padding-top: var(--ads-v2-spaces-2); + padding-bottom: var(--ads-v2-spaces-2); +} + +/* if the dropdown first item is a group, dont add padding-top to virtual list */ +.ads-v2-select__dropdown:has( + .rc-select-item:first-child:is(.rc-select-item-group) + ) + .rc-virtual-list { + padding-top: 0; } /* Option group */ @@ -249,8 +265,6 @@ border-radius: var(--ads-v2-border-radius); font-weight: 500; font-size: var(--ads-v2-font-size-4); - /* TODO: remove !important after WDS fix their issue in tree select */ - background-color: var(--select-option-color-bg) !important; position: relative; color: var(--ads-v2-colors-content-label-default-fg); min-height: var(--select-option-height); @@ -267,12 +281,9 @@ --select-option-height: 36px; padding: var(--select-option-padding); - padding-left: var(--ads-v2-spaces-5); - margin-bottom: var(--ads-v2-spaces-1); + margin-left: var(--ads-v2-spaces-2); border-radius: var(--ads-v2-border-radius); cursor: pointer; - /* TODO: remove !important after WDS fix their issue in tree select */ - background-color: var(--select-option-color-bg) !important; position: relative; color: var(--ads-v2-colors-content-label-default-fg); min-height: var(--select-option-height); @@ -306,6 +317,18 @@ font-size: var(--select-option-font-size); overflow: hidden; overflow-wrap: break-word; + width: 100%; +} + +.ads-v2-select__dropdown + .rc-select-item.rc-select-item-option + .rc-select-item-option-content + > label + > span { + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; } /* Option hover */ @@ -314,6 +337,13 @@ .rc-select-item.rc-select-item-option.rc-select-item-option-active { --select-option-color-bg: var(--ads-v2-colors-content-surface-hover-bg); outline: none; + --select-option-color-bg: var(--ads-v2-colors-content-surface-hover-bg); +} + +/* selected */ +.ads-v2-select__dropdown + .rc-select-item.rc-select-item-option.rc-select-item-option-selected { + --select-option-color-bg: var(--ads-v2-colors-content-surface-active-bg); } /* Option focus */ @@ -328,11 +358,6 @@ outline-offset: var(--ads-v2-offset-outline); } -/* Option active */ -.ads-v2-select__dropdown .rc-select-item.rc-select-item-option:active { - --select-option-color-bg: var(--ads-v2-colors-content-surface-active-bg); -} - /* Option disabled */ .ads-v2-select__dropdown .rc-select-item.rc-select-item-option.rc-select-item-option-disabled { @@ -348,8 +373,42 @@ color: var(--ads-v2-colors-content-helper-default-fg); } -/* Selected option */ -.ads-v2-select__dropdown - .rc-select-item.rc-select-item-option.rc-select-item-option-selected { - --select-option-color-bg: var(--ads-v2-colors-content-surface-active-bg); +/* search input */ +.ads-v2-select__dropdown .ads-v2-search-input input { + border-top: none; + border-left: none; + border-right: none; + border-bottom: 1px solid var(--ads-v2-color-border-emphasis); + border-radius: 0; + outline: none !important; +} + +/* this is required because we want to set the max width of first tag around 60% of the container width */ +.ads-v2-select .rc-select-selector { + container-type: inline-size; +} + +/* tags */ +.ads-v2-select + .rc-select-selection-overflow-item:first-child + .ads-v2-tag + > span { + max-width: calc(60cqw - 16px); +} + +.ads-v2-select .rc-select-selection-overflow-item .ads-v2-tag > span { + display: -webkit-box; + -webkit-line-clamp: 1; + -webkit-box-orient: vertical; + overflow: hidden; + max-width: calc(100% - 16px); +} + +.ads-v2-select .rc-select-selection-overflow-item-suffix { + display: none; +} + +.ads-v2-select__dropdown .rc-virtual-list { + padding-top: var(--ads-v2-spaces-2); + padding-bottom: var(--ads-v2-spaces-2); } diff --git a/app/client/packages/design-system/ads/src/Tag/Tag.styles.tsx b/app/client/packages/design-system/ads/src/Tag/Tag.styles.tsx index 19ca130441..fc786df527 100644 --- a/app/client/packages/design-system/ads/src/Tag/Tag.styles.tsx +++ b/app/client/packages/design-system/ads/src/Tag/Tag.styles.tsx @@ -78,6 +78,10 @@ export const StyledTag = styled.span<{ display: flex; align-items: center; + & > span { + line-height: normal; + } + ${({ isClosed }) => isClosed && `display: none;`} `; @@ -85,9 +89,8 @@ export const StyledButton = styled(Button)` --button-color-fg: var(--tag-color-fg); --button-color-bg: inherit; - margin-left: var(--ads-v2-spaces-1); + margin-left: var(--ads-v2-spaces-2); position: relative; - top: 1px; // align with text cursor: pointer; &:hover:not([data-disabled="true"]):not([data-loading="true"]) { diff --git a/app/client/packages/design-system/ads/src/Tag/Tag.tsx b/app/client/packages/design-system/ads/src/Tag/Tag.tsx index de430670ec..d2b13f51a3 100644 --- a/app/client/packages/design-system/ads/src/Tag/Tag.tsx +++ b/app/client/packages/design-system/ads/src/Tag/Tag.tsx @@ -24,7 +24,7 @@ function Tag({ }; return ( - + {children} @@ -36,6 +36,7 @@ function Tag({ isIconButton kind="tertiary" onClick={closeHandler} + onMouseDown={(e) => e.stopPropagation()} size="sm" startIcon="close-line" /> diff --git a/app/client/packages/design-system/ads/src/Tag/Tag.types.tsx b/app/client/packages/design-system/ads/src/Tag/Tag.types.tsx index 5416ff7ec3..ade342c078 100644 --- a/app/client/packages/design-system/ads/src/Tag/Tag.types.tsx +++ b/app/client/packages/design-system/ads/src/Tag/Tag.types.tsx @@ -4,7 +4,7 @@ import type { Sizes } from "../__config__/types"; export type TagSizes = Extract; // TODO: Update this to include "Kind" from __config__/types -export type TagKind = "neutral" | "special" | "premium"; +export type TagKind = "neutral" | "special" | "premium" | "info"; export type TagProps = { /** the size of the tag */ diff --git a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/TableOrSpreadsheetDropdown/index.tsx b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/TableOrSpreadsheetDropdown/index.tsx index 801e23a135..ae9d6a6803 100644 --- a/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/TableOrSpreadsheetDropdown/index.tsx +++ b/app/client/src/components/editorComponents/WidgetQueryGeneratorForm/CommonControls/TableOrSpreadsheetDropdown/index.tsx @@ -35,10 +35,6 @@ function TableOrSpreadsheetDropdown() {