From 5c1e5682a1d849f809f252555001adadef3c2800 Mon Sep 17 00:00:00 2001 From: Amal K Joy <153802538+amal-k-joy@users.noreply.github.com> Date: Wed, 31 Jul 2024 13:40:20 +0530 Subject: [PATCH] feat(ConditionBuilder): design review changes (#5762) --- .../ConditionBuilder/_condition-builder.scss | 3 + .../styles/_conditionBuilderCondition.scss | 13 +++- .../styles/_conditionBuilderItem.scss | 72 +++++++++++-------- .../ConditionBlock/ConditionBlock.js | 23 +++++- .../ConditionBuilder/ConditionBuilder.test.js | 21 +++--- .../ConditionBuilderAdd.js | 6 +- .../ConditionBuilderButton.js | 6 +- .../ConditionConnector.js | 3 +- .../ConditionBuilderContent.js | 6 ++ .../translationObject.js | 5 +- .../ConditionBuilderItem.js | 28 +++++++- .../ConditionGroupBuilder.js | 29 +++++--- .../ConditionPreview/ConditionPreview.js | 11 ++- .../utils/handleKeyboardEvents.js | 21 +++++- 14 files changed, 176 insertions(+), 71 deletions(-) diff --git a/packages/ibm-products-styles/src/components/ConditionBuilder/_condition-builder.scss b/packages/ibm-products-styles/src/components/ConditionBuilder/_condition-builder.scss index e2cadeaf40..630d841a58 100644 --- a/packages/ibm-products-styles/src/components/ConditionBuilder/_condition-builder.scss +++ b/packages/ibm-products-styles/src/components/ConditionBuilder/_condition-builder.scss @@ -73,3 +73,6 @@ $block-class: #{c4p-settings.$pkg-prefix}--condition-builder; .#{$block-class}__group-separator { width: fit-content; } +.#{$block-class}__tooltip { + word-break: break-all; +} diff --git a/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderCondition.scss b/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderCondition.scss index a427821cf1..8d73a44203 100644 --- a/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderCondition.scss +++ b/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderCondition.scss @@ -36,6 +36,15 @@ $block-class: #{c4p-settings.$pkg-prefix}--condition-builder; background-color: $tag-background-red; color: $tag-color-red; } +.#{$block-class}__subgroup_deletionPreview { + .#{$block-class}__group { + /* stylelint-disable max-nesting-depth */ + button { + background-color: $tag-background-red; + color: $tag-color-red; + } + } +} .#{$block-class}__condition__deletion-preview .#{$block-class}__button:not( @@ -63,6 +72,7 @@ $block-class: #{c4p-settings.$pkg-prefix}--condition-builder; } .#{$block-class}__group-preview-animate { height: auto; + color: $text-secondary; opacity: 0.5; pointer-events: none; transition: all $duration-moderate-02 motion(exit, expressive); @@ -70,10 +80,9 @@ $block-class: #{c4p-settings.$pkg-prefix}--condition-builder; .#{$block-class}__connector--disabled { display: flex; min-width: $spacing-10; - align-items: center; background-color: $layer; color: $text-helper; - padding-inline: $spacing-03; + pointer-events: none; } .#{$block-class}__condition-wrapper > .#{$block-class}__condition-block:last-child diff --git a/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderItem.scss b/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderItem.scss index 715cedcc69..03916212e3 100644 --- a/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderItem.scss +++ b/packages/ibm-products-styles/src/components/ConditionBuilder/styles/_conditionBuilderItem.scss @@ -1,4 +1,5 @@ @use 'sass:list'; +@use 'sass:math'; @use 'sass:string'; @use '@carbon/react/scss/theme' as *; @use '../../../global/styles/project-settings' as c4p-settings; @@ -167,21 +168,11 @@ $block-class: #{c4p-settings.$pkg-prefix}--condition-builder; } //need to revamp to a simpler logic $colors: ( - ($purple-70, $purple-60, $purple-50, $purple-40, $purple-30, $purple-20), - ($cyan-70, $cyan-60, $cyan-50, $cyan-40, $cyan-30, $cyan-20), - ($teal-70, $teal-60, $teal-50, $teal-40, $teal-30, $teal-20), - ( - $magenta-70, - $magenta-60, - $magenta-50, - $magenta-40, - $magenta-30, - $magenta-20 - ), - ($red-70, $red-60, $red-50, $red-40, $red-30, $red-20), - ($orange-70, $orange-60, $orange-50, $orange-40, $orange-30, $orange-20), - ($yellow-70, $yellow-60, $yellow-50, $yellow-40, $yellow-30, $yellow-20), - ($green-70, $green-60, $green-50, $green-40, $green-30, $green-20) + ($purple-70, $purple-60, $purple-50, $purple-40, $purple-30), + ($blue-70, $blue-60, $blue-50, $blue-40, $blue-30), + ($cyan-70, $cyan-60, $cyan-50, $cyan-40, $cyan-30), + ($teal-70, $teal-60, $teal-50, $teal-40, $teal-30), + ($green-70, $green-60, $green-50, $green-40, $green-30) ); @for $i from 1 through list.length($colors) { @@ -191,10 +182,30 @@ $colors: ( ) ); $group-colors: list.nth($colors, $i); - @each $color in $group-colors { + $group-colors-length: list.length($group-colors); + + //this is to select and add color to the new group preview + .#{$block-class}__group-preview[data-color-index='#{($i%list.length($colors))}'] + button { + /* stylelint-disable-next-line carbon/theme-token-use */ + $next-group-color: list.nth($colors, ($i%list.length($colors)) +1); + /* stylelint-disable-next-line carbon/theme-token-use */ + box-shadow: inset 0 #{$spacing-01} 0 0 list.nth($next-group-color, 1); + } + + //we need to select the group color from the $colors array and need to repeat the colors after $colors.length subgroups + @for $el-index from 1 through 50 { + $item-index: $el-index; + /* stylelint-disable-next-line carbon/theme-token-use */ + $item-index: ((($item-index - 1) % $group-colors-length) +1); #{$selector} { - /* stylelint-disable-next-line carbon/theme-token-use */ - --#{$block-class}__condition-wrapper-color: #{$color}; + @if $item-index != 1 { + /* stylelint-disable-next-line carbon/theme-token-use */ + --#{$block-class}__condition-wrapper-color: #{list.nth( + $group-colors, + $item-index + )}; // stylelint-disable-line carbon/theme-token-use + } } $selector: list.append( @@ -211,13 +222,12 @@ $colors: ( .#{$block-class}__groupConnector { background-color: $layer; } - .#{$block-class}__condition-wrapper > :nth-child(1) .#{$block-class}__button, - .#{$block-class}__condition-wrapper + .#{$block-class}__condition-wrapper:not(.#{$block-class}__group-preview) + > :nth-child(1) + .#{$block-class}__button, + .#{$block-class}__condition-wrapper:not(.#{$block-class}__group-preview) > :nth-child(2) - .#{$block-class}__button:not( - .#{$block-class}__add-button, - .#{$block-class}__add-condition-sub-group - ) { + .#{$block-class}__button { /* stylelint-disable-next-line carbon/theme-token-use */ box-shadow: inset 0 #{$spacing-01} 0 0 var(--#{$block-class}__condition-wrapper-color); } @@ -237,24 +247,24 @@ $colors: ( .#{$block-class}__add-condition-sub-group-wrapper { z-index: -1; width: 0; - margin-left: -50%; - opacity: 0; pointer-events: none; + transform: translateX(-100%); // stylelint-disable-next-line carbon/motion-duration-use, carbon/motion-easing-use - transition: all linear $duration-fast-02; + transition: transform motion(exit, productive) $duration-fast-02; } .#{$block-class}__add-condition-sub-group-wrapper--show { z-index: 0; width: auto; - margin-left: 0; - opacity: 1; pointer-events: all; - // stylelint-disable-next-line carbon/motion-duration-use, carbon/motion-easing-use - transition: all linear $duration-fast-02; + transform: translateX(0); } .#{$block-class}__invalid-input { display: flex; } .#{$block-class}__invalid-input > svg { color: $support-warning; + /* stylelint-disable max-nesting-depth */ + > path:first-child { + fill: $icon-primary; + } } diff --git a/packages/ibm-products/src/components/ConditionBuilder/ConditionBlock/ConditionBlock.js b/packages/ibm-products/src/components/ConditionBuilder/ConditionBlock/ConditionBlock.js index 6b28e7e827..595cb6ab29 100644 --- a/packages/ibm-products/src/components/ConditionBuilder/ConditionBlock/ConditionBlock.js +++ b/packages/ibm-products/src/components/ConditionBuilder/ConditionBlock/ConditionBlock.js @@ -1,4 +1,4 @@ -import React, { useContext, useState } from 'react'; +import React, { useContext, useEffect, useState } from 'react'; import { Close } from '@carbon/react/icons'; import { ConditionBuilderItem } from '../ConditionBuilderItem/ConditionBuilderItem'; import PropTypes from 'prop-types'; @@ -45,6 +45,7 @@ const ConditionBlock = (props) => { hideConditionPreviewHandler, showConditionPreviewHandler, isLastCondition, + setShowDeletionPreviewForSubgroups, } = props; const { inputConfig, variant, conditionBuilderRef } = useContext( ConditionBuilderContext @@ -89,6 +90,19 @@ const ConditionBlock = (props) => { }; const ItemComponent = property ? itemComponents[type] : null; + useEffect(() => { + if ( + showDeletionPreview && + group?.conditions?.length > 1 && + group?.conditions?.[1].conditions && + group.conditions[1].id !== condition.id + ) { + setShowDeletionPreviewForSubgroups?.(true); + } else { + setShowDeletionPreviewForSubgroups?.(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [showDeletionPreview]); const onStatementChangeHandler = (v, evt) => { focusThisField(evt, conditionBuilderRef); onStatementChange(v); @@ -111,10 +125,9 @@ const ConditionBlock = (props) => { popoverToOpen: checkIsValid(newOperator) ? 'valueField' : '', }); }; - const onValueChangeHandler = (newValue, evt) => { + const onValueChangeHandler = (newValue) => { const currentCondition = { ...condition }; delete currentCondition.popoverToOpen; - focusThisField(evt, conditionBuilderRef); onChange({ ...currentCondition, @@ -363,6 +376,10 @@ ConditionBlock.propTypes = { * callback to handle the statement(if/ excl.if) change */ onStatementChange: PropTypes.func, + /** + * method to set ShowDeletionPreviewForSubgroups + */ + setShowDeletionPreviewForSubgroups: PropTypes.func, /** * handler for showing add condition preview */ diff --git a/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilder.test.js b/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilder.test.js index 7393dcaca9..8752401fad 100644 --- a/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilder.test.js +++ b/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilder.test.js @@ -974,7 +974,9 @@ describe(componentName, () => { '[role="row"][aria-level="2"][aria-posinset="3"]' ); expect(row).toHaveLength(1); - expect(row[0]).toHaveFocus(); + expect( + row[0].querySelector(`.${blockClass}__close-condition`) + ).toHaveFocus(); }); it('check the add/remove actions ', async () => { @@ -1139,7 +1141,7 @@ describe(componentName, () => { ).not.toBeInTheDocument(); }); - it(' remove all conditions in a group keeping only subgroups', async () => { + it(' remove all conditions in a group will delete subgroups as well', async () => { const sampleDataStructure = { operator: 'or', groups: [ @@ -1216,7 +1218,7 @@ describe(componentName, () => { userEvent.click(document.querySelector(`.${blockClass}__close-condition`)) ); - expect(screen.getAllByRole('button', { name: 'if' })).toHaveLength(2); + expect(screen.getByText('Add condition')); }); it('check the custom input type', async () => { @@ -1499,18 +1501,11 @@ describe(componentName, () => { await act(() => userEvent.keyboard('{Enter}')); expect( - document.querySelector(`[role="row"][aria-level="2"][aria-posinset="1"]`) + document.querySelector( + `[role="row"][aria-level="2"][aria-posinset="1"] .${blockClass}__close-condition` + ) ).toHaveFocus(); - await act(() => userEvent.keyboard('{ArrowRight}')); - expect(screen.getByRole('button', { name: 'Continent' })).toHaveFocus(); - - await act(() => userEvent.keyboard('{ArrowRight}')); - await act(() => userEvent.keyboard('{ArrowRight}')); - await act(() => userEvent.keyboard('{ArrowRight}')); - expect( - document.querySelectorAll(`.${blockClass}__close-condition`)[0] - ).toHaveFocus(); await act(() => userEvent.keyboard('{Enter}')); await act(() => userEvent.keyboard('{Tab}')); expect(screen.getByText('Add condition')).toHaveFocus(); diff --git a/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilderAdd/ConditionBuilderAdd.js b/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilderAdd/ConditionBuilderAdd.js index 70aa160ac8..b8c16a2935 100644 --- a/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilderAdd/ConditionBuilderAdd.js +++ b/packages/ibm-products/src/components/ConditionBuilder/ConditionBuilderAdd/ConditionBuilderAdd.js @@ -90,14 +90,12 @@ const ConditionBuilderAdd = ({ { + const carbonPrefix = usePrefix(); const Button = () => { const dataName = rest['data-name'] ?? ''; return (