From 97aa93b63a527edd90bf9d172d4097b9aa54c3e5 Mon Sep 17 00:00:00 2001 From: Ignacio Becerra Date: Fri, 11 Feb 2022 13:47:27 -0800 Subject: [PATCH] Revert "feat(filter-panel): add view all button for filter groups" (#8252) This reverts commit 6a559927c9542dbc29d274ef75c79bb5a0d0e7f3. ### Related Ticket(s) Reverting #8188 ### Description Reverting for the time being. ### Changelog **Removed** - the changes done in the linked PR --- .../__stories__/filter-panel.stories.ts | 19 +- .../filter-panel/filter-group-item.ts | 213 +---------------- .../filter-panel/filter-panel-composite.ts | 80 ++----- .../filter-panel/filter-panel-input-select.ts | 5 +- .../components/filter-panel/filter-panel.scss | 17 +- .../filter-panel/filter-panel.e2e.js | 214 +----------------- 6 files changed, 39 insertions(+), 509 deletions(-) diff --git a/packages/web-components/src/components/filter-panel/__stories__/filter-panel.stories.ts b/packages/web-components/src/components/filter-panel/__stories__/filter-panel.stories.ts index dc2929a5ca7..b992f89db6a 100644 --- a/packages/web-components/src/components/filter-panel/__stories__/filter-panel.stories.ts +++ b/packages/web-components/src/components/filter-panel/__stories__/filter-panel.stories.ts @@ -1,30 +1,25 @@ /** * @license * - * Copyright IBM Corp. 2020, 2022 + * Copyright IBM Corp. 2020, 2021 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ import { html } from 'lit-element'; -import { text, select, number } from '@storybook/addon-knobs'; +import { text, select } from '@storybook/addon-knobs'; import '../index'; import readme from './README.stories.mdx'; export const Default = ({ parameters }) => { - const { heading, filterCutoff, maxFilters, viewAllText, gridKnobs } = parameters?.props?.FilterPanel ?? {}; + const { heading, gridKnobs } = parameters?.props?.FilterPanel ?? {}; return html`
${heading} - + API Application Data Set @@ -114,9 +109,6 @@ export default { knobs: { FilterPanel: ({ groupId }) => ({ heading: text('heading', 'Filter', groupId), - filterCutoff: number('Filter cutoff', 5, {}, groupId), - maxFilters: number('Max filters', 7, {}, groupId), - viewAllText: text('View all text', 'View all', groupId), gridKnobs: select('Grid alignment', ['3 columns', '4 columns'], '4 columns', groupId), }), }, @@ -124,9 +116,6 @@ export default { default: { FilterPanel: { heading: 'Filter', - filterCutoff: 5, - maxFilters: 7, - viewAllText: 'View all', gridKnobs: '4 columns', }, }, diff --git a/packages/web-components/src/components/filter-panel/filter-group-item.ts b/packages/web-components/src/components/filter-panel/filter-group-item.ts index 2913f341320..8c8901a7010 100644 --- a/packages/web-components/src/components/filter-panel/filter-group-item.ts +++ b/packages/web-components/src/components/filter-panel/filter-group-item.ts @@ -1,27 +1,19 @@ /** * @license * - * Copyright IBM Corp. 2020, 2022 + * Copyright IBM Corp. 2020, 2021 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ -import { customElement, property, query, state } from 'lit-element'; -import settings from 'carbon-components/es/globals/js/settings'; +import { customElement } from 'lit-element'; import ddsSettings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js'; import BXAccordionItem from 'carbon-web-components/es/components/accordion/accordion-item'; import styles from './filter-panel.scss'; import StableSelectorMixin from '../../globals/mixins/stable-selector'; -import DDSFilterPanelComposite from './filter-panel-composite'; -import DDSFilterPanelCheckbox from './filter-panel-checkbox'; -import DDSFilterPanelInputSelectItem from './filter-panel-input-select-item'; -import DDSFilterPanelInputSelect from './filter-panel-input-select'; const { stablePrefix: ddsPrefix } = ddsSettings; -const { prefix } = settings; - -const viewAllClassName = `${ddsPrefix}-filter-group-item__view-all`; /** * DDSFilterGroupItem renders each individual accordion @@ -38,207 +30,6 @@ class DDSFilterGroupItem extends StableSelectorMixin(BXAccordionItem) { } static styles = styles; // `styles` here is a `CSSResult` generated by custom WebPack loader - - static get viewAllSelector(): string { - return `button.${viewAllClassName}`; - } - - /** - * The element containing the default slot. - */ - @query(`.${prefix}--accordion__content`) - accordionContent: any; - - /** - * The text for the button that reveals all filters in the group. - */ - @property({ type: String, attribute: 'view-all-text' }) - viewAllText: string = 'View all'; - - /** - * The number of filters that can be shown without needing to hide any. - */ - @property({ type: Number, attribute: 'max-filters' }) - maxFilters: number = 7; - - /** - * The number of filters to show when not all filters are visible. - */ - @property({ type: Number, attribute: 'filter-cutoff' }) - filterCutoff: number = 5; - - /** - * Whether or not any hidden filters have been revealed. - */ - @property({ type: Boolean }) - allRevealed = false; - - /** - * An element to set focus to on reveal. - */ - @state() - _focusedElement: HTMLElement | null = null; - - /** - * Whether or not to add view all button functionality. - */ - protected _needsViewAll(): boolean { - return this.children.length > this.maxFilters; - } - - /** - * Checks if any filters beyond the cutoff point have been selected. - */ - protected _hasHiddenActiveFilter(): boolean { - const { children, filterCutoff } = this; - let result: boolean = false; - - [...children].slice(filterCutoff, children.length).forEach(elem => { - if (elem instanceof DDSFilterPanelCheckbox) { - if (elem.checked) result = true; - } - if (elem instanceof DDSFilterPanelInputSelectItem || elem instanceof DDSFilterPanelInputSelect) { - if (elem.selected) result = true; - } - }); - - return result; - } - - /** - * Hides or reveals excess filters. - */ - protected _handleAllRevealed(revealed: boolean): void { - const { children, filterCutoff, accordionContent } = this; - const hasHiddenActiveFilter = this._hasHiddenActiveFilter(); - - [...children].slice(filterCutoff, children.length).forEach(elem => { - (elem as HTMLElement).style.display = revealed || hasHiddenActiveFilter ? '' : 'none'; - }); - - if (!revealed && !hasHiddenActiveFilter) { - accordionContent.appendChild(this._renderViewAll()); - } - - this._dispatchViewAllEvent(revealed); - } - - /** - * Generates a view all button. - */ - protected _renderViewAll(): HTMLButtonElement { - const { children, filterCutoff } = this; - - const viewAll = document.createElement('button'); - viewAll.classList.add(viewAllClassName, `${prefix}--btn--ghost`); - viewAll.type = 'button'; - viewAll.innerText = this.viewAllText; - - viewAll.addEventListener( - 'click', - (e): void => { - this.allRevealed = true; - if (e.target instanceof HTMLElement) e.target.remove(); - - const firstHidden = children[filterCutoff]; - if (firstHidden instanceof HTMLElement) { - this._focusedElement = firstHidden; - } - }, - { passive: true, once: true } - ); - - return viewAll; - } - - /** - * Dispatches a custom event that notifies listeners whether or not this - * filter group has all options revealed. - */ - protected _dispatchViewAllEvent(removed: boolean): void { - const { eventViewAll } = this.constructor as typeof DDSFilterGroupItem; - this.dispatchEvent( - new CustomEvent(eventViewAll, { - bubbles: true, - cancelable: true, - composed: true, - detail: { - id: this.titleText, - value: removed, - }, - }) - ); - } - - /** - * Retrieves view all state stored in the filter panel composite. Returns - * internal value if no cache is found. - */ - protected _getCachedViewAllValue(): boolean { - const { allRevealed, titleText } = this; - let result: boolean = allRevealed; - - const filterPanel = this.closest('dds-filter-panel'); - if (filterPanel !== null) { - // Indicates this is composite's duplicated content. - let parentHost: Element | undefined; - const parent = filterPanel.parentNode; - if (parent instanceof ShadowRoot) { - parentHost = parent.host; - } - if (parentHost instanceof DDSFilterPanelComposite) { - const match = parentHost._filterGroupsAllRevealed.find(entry => { - return entry.id === titleText; - }); - if (match !== undefined) { - result = match.value; - } - } - } - - return result; - } - - protected firstUpdated(): void { - if (this._needsViewAll()) { - this.allRevealed = this._getCachedViewAllValue(); - } - } - - protected updated(_changedProperties: Map): void { - const { allRevealed, _focusedElement } = this; - if (this._needsViewAll()) { - const prevOpen = _changedProperties.get('open'); - const hasAllRevealed = _changedProperties.has('allRevealed'); - const prevAllRevealed = _changedProperties.get('allRevealed'); - - // Reset `allRevealed` on accordion close. - if (prevOpen) { - this.allRevealed = this._hasHiddenActiveFilter() || false; - } - - // Respect `allRevealed` attribute. - if (hasAllRevealed) { - if (prevAllRevealed === undefined) { - this._handleAllRevealed(this._getCachedViewAllValue()); - } else { - this._handleAllRevealed(allRevealed); - - if (allRevealed && _focusedElement instanceof HTMLElement) { - _focusedElement.focus(); - this._focusedElement = null; - } - } - } - } - } - - /** - * The name of the event that fires when the view all button is toggled. - */ - static get eventViewAll() { - return `${ddsPrefix}-filter-group-view-all-toggle`; - } } /* @__GENERATE_REACT_CUSTOM_ELEMENT_TYPE__ */ diff --git a/packages/web-components/src/components/filter-panel/filter-panel-composite.ts b/packages/web-components/src/components/filter-panel/filter-panel-composite.ts index 7e4dae02ac3..b2abf025aeb 100644 --- a/packages/web-components/src/components/filter-panel/filter-panel-composite.ts +++ b/packages/web-components/src/components/filter-panel/filter-panel-composite.ts @@ -7,7 +7,7 @@ * LICENSE file in the root directory of this source tree. */ -import { customElement, html, LitElement, property, TemplateResult } from 'lit-element'; +import { customElement, html, LitElement, property } from 'lit-element'; import ddsSettings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js'; import settings from 'carbon-components/es/globals/js/settings'; import Filter from 'carbon-web-components/es/icons/filter/16'; @@ -15,6 +15,7 @@ import HostListenerMixin from 'carbon-web-components/es/globals/mixins/host-list import './filter-group'; import './filter-panel'; import './filter-panel-modal'; +import { baseFontSize, breakpoints } from '@carbon/layout'; import { unsafeHTML } from 'lit-html/directives/unsafe-html'; import HostListener from 'carbon-web-components/es/globals/decorators/host-listener'; import StableSelectorMixin from '../../globals/mixins/stable-selector'; @@ -24,6 +25,7 @@ import DDSFilterGroupItem from './filter-group-item'; const { prefix } = settings; const { stablePrefix: ddsPrefix } = ddsSettings; +const gridBreakpoint = parseFloat(breakpoints.md.width) * baseFontSize; /** * Filter panel composite @@ -116,19 +118,6 @@ class DDSFilterPanelComposite extends HostListenerMixin(StableSelectorMixin(LitE this.renderStatus(); }; - @HostListener('document:eventFilterGroupViewAllToggle') - protected _handleFilterGroupViewAllToggle = (event: CustomEvent) => { - const match = this._filterGroupsAllRevealed.findIndex(entry => { - return entry.id === event.detail.id; - }); - - if (match !== -1) { - this._filterGroupsAllRevealed[match].value = event.detail.value; - } else { - this._filterGroupsAllRevealed.push(event.detail); - } - }; - /** * handles modal close event */ @@ -282,12 +271,6 @@ class DDSFilterPanelComposite extends HostListenerMixin(StableSelectorMixin(LitE @property() _filterButtonTitle: string = ''; - /** - * stores which filter groups have revealed filters - */ - @property({ type: Array }) - _filterGroupsAllRevealed: { id: string; value: boolean }[] = []; - /** * Handles `slotchange` event. * @@ -317,41 +300,31 @@ class DDSFilterPanelComposite extends HostListenerMixin(StableSelectorMixin(LitE this._filterButtonTitle = this._title[0].innerText; } - /** - * Renders original content into the modal and listens for changes to this - * content to then be stored in `this._content`. - */ - protected _renderModal = (): TemplateResult => html` - - - - - `; - - /** - * Renders copies of slotted elements into the desktop presentation. - */ - protected _renderDesktop = (): TemplateResult => html` - - ${this._title.map(e => { - return html` - ${unsafeHTML((e as HTMLElement).outerHTML)} - `; - })} - ${this._contents.map(e => { - return html` - ${unsafeHTML((e as HTMLElement).outerHTML)} - `; - })} - - `; + protected _renderButton = gridBreakpoint < document.body.clientHeight; render() { return html` - ${this._renderModal()} ${this._renderDesktop()} + + + + + + + + ${this._title.map(e => { + return html` + ${unsafeHTML((e as HTMLElement).outerHTML)} + `; + })} + ${this._contents.map(e => { + return html` + ${unsafeHTML((e as HTMLElement).outerHTML)} + `; + })} + `; } @@ -371,15 +344,6 @@ class DDSFilterPanelComposite extends HostListenerMixin(StableSelectorMixin(LitE return `${ddsPrefix}-filter-panel-input-select`; } - /** - * The name of the custom event captured upon activating "view all" button in - * a filter group item - */ - - static get eventFilterGroupViewAllToggle() { - return `${ddsPrefix}-filter-group-view-all-toggle`; - } - /** * The name of the custom event captured upon closing the modal */ diff --git a/packages/web-components/src/components/filter-panel/filter-panel-input-select.ts b/packages/web-components/src/components/filter-panel/filter-panel-input-select.ts index 21d73d01c06..78d74fad31c 100644 --- a/packages/web-components/src/components/filter-panel/filter-panel-input-select.ts +++ b/packages/web-components/src/components/filter-panel/filter-panel-input-select.ts @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2022 + * Copyright IBM Corp. 2020, 2021 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -11,7 +11,6 @@ import { customElement, html, property, LitElement } from 'lit-element'; import ddsSettings from '@carbon/ibmdotcom-utilities/es/utilities/settings/settings.js'; import settings from 'carbon-components/es/globals/js/settings'; import Close from 'carbon-web-components/es/icons/close/16'; -import FocusMixin from 'carbon-web-components/es/globals/mixins/focus.js'; import StableSelectorMixin from '../../globals/mixins/stable-selector'; import styles from './filter-panel.scss'; import DDSFilterPanelInputSelectItem from './filter-panel-input-select-item'; @@ -25,7 +24,7 @@ const { stablePrefix: ddsPrefix } = ddsSettings; * @element dds-filter-panel-input-select */ @customElement(`${ddsPrefix}-filter-panel-input-select`) -class DDSFilterPanelInputSelect extends FocusMixin(StableSelectorMixin(LitElement)) { +class DDSFilterPanelInputSelect extends StableSelectorMixin(LitElement) { @property() ariaLabel = ''; diff --git a/packages/web-components/src/components/filter-panel/filter-panel.scss b/packages/web-components/src/components/filter-panel/filter-panel.scss index e0dbb4a61c4..7d8e257fb74 100644 --- a/packages/web-components/src/components/filter-panel/filter-panel.scss +++ b/packages/web-components/src/components/filter-panel/filter-panel.scss @@ -1,7 +1,7 @@ /** * @license * - * Copyright IBM Corp. 2020, 2022 + * Copyright IBM Corp. 2020, 2021 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. @@ -50,21 +50,6 @@ } } -:host(#{$dds-prefix}-filter-group-item) { - .#{$dds-prefix}-filter-group-item__view-all { - width: 100%; - padding: $spacing-03 $spacing-05; - text-align: left; - cursor: pointer; - - &:focus-visible { - outline: none; - border-color: $focus; - box-shadow: inset 0 0 0 $button-outline-width $focus, inset 0 0 0 $button-border-width $ui-background; - } - } -} - :host(#{$dds-prefix}-filter-modal-footer-button) { @extend :host(#{$prefix}-modal-footer-button); diff --git a/packages/web-components/tests/e2e-storybook/cypress/integration/filter-panel/filter-panel.e2e.js b/packages/web-components/tests/e2e-storybook/cypress/integration/filter-panel/filter-panel.e2e.js index 5e494482ec4..765bd1b8fb6 100644 --- a/packages/web-components/tests/e2e-storybook/cypress/integration/filter-panel/filter-panel.e2e.js +++ b/packages/web-components/tests/e2e-storybook/cypress/integration/filter-panel/filter-panel.e2e.js @@ -103,101 +103,6 @@ describe('dds-filter-panel | (desktop)', () => { .should('have.attr', 'selected'); cy.screenshot(_screenshotOptions); }); - - it('should only add view all button when enough filters are present', () => { - let filterCount; - - cy.visit(`${_path}&knob-Filter%20cutoff_FilterPanel=1&knob-Max%20filters_FilterPanel=1`) - .get(_selector) - .shadow() - .find('dds-filter-group-item') - .first() - .as('filterGroupItem') - .click() - .find('.dds-filter-group-item__view-all') - .should('have.length', 1) - .click() - .get('@filterGroupItem') - .find('dds-filter-panel-checkbox') - .then(checkboxes => (filterCount = checkboxes.length)); - cy.visit(`${_path}&knob-Max%20filters_FilterPanel=${filterCount}`) - .get(_selector) - .shadow() - .find('dds-filter-group-item') - .first() - .click() - .find('.dds-filter-group-item__view-all') - .should('have.length', 0); - }); - - it('should support custom view all button text', () => { - let customText = 'Foo button'; - - cy.visit(`${_path}&knob-View%20all%20text_FilterPanel=${customText}`) - .get(_selector) - .shadow() - .find('dds-filter-group-item') - .first() - .click() - .find('.dds-filter-group-item__view-all') - .should('have.text', customText); - cy.screenshot(_screenshotOptions); - }); - - it('should re-hide excess elements when filter groups are closed and reopened', () => { - cy.visit(_path) - .get(_selector) - .shadow() - .find('dds-filter-group-item') - .first() - .as('filterGroupItem') - .shadow() - .find('.bx--accordion__heading') - .as('toggle') - .click() - .get('@filterGroupItem') - .find('.dds-filter-group-item__view-all') - .click() - .get('@filterGroupItem') - .find('dds-filter-panel-checkbox') - .last() - .as('lastCheckbox') - .get('@toggle') - .click() - .click() - .get('@lastCheckbox') - .should('not.be.visible'); - cy.screenshot(_screenshotOptions); - }); - - it('should not re-hide elements when an element that would be hidden has been selected', () => { - cy.visit(_path) - .get(_selector) - .shadow() - .find('dds-filter-group-item') - .first() - .as('filterGroupItem') - .shadow() - .find('.bx--accordion__heading') - .as('toggle') - .click() - .get('@filterGroupItem') - .find('.dds-filter-group-item__view-all') - .click() - .get('@filterGroupItem') - .find('dds-filter-panel-checkbox') - .last() - .as('lastCheckbox') - .shadow() - .find('input[type="checkbox') - .check(_checkOptions) - .get('@toggle') - .click() - .click() - .get('@lastCheckbox') - .should('be.visible'); - cy.screenshot(_screenshotOptions); - }); }); describe('dds-filter-panel | (mobile)', () => { @@ -206,12 +111,13 @@ describe('dds-filter-panel | (mobile)', () => { }); it('checkboxes should maintain state when transitioning to desktop', () => { - // Check box on mobile + // Visit on mobile and open modal cy.visit(_path) .get(_selector) .find('.bx--filter-button') - .click() - .get(_selector) + .click(); + // Check box on mobile + cy.get(_selector) .find('dds-filter-group-item') .first() .click() @@ -237,12 +143,13 @@ describe('dds-filter-panel | (mobile)', () => { }); it('select lists should maintain state when transitioning to desktop', () => { - // Check box on mobile + // Visit on mobile and open modal cy.visit(_path) .get(_selector) .find('.bx--filter-button') - .click() - .get(_selector) + .click(); + // Check box on mobile + cy.get(_selector) .find('dds-filter-group-item') .eq(1) .click() @@ -262,109 +169,4 @@ describe('dds-filter-panel | (mobile)', () => { .should('have.attr', 'selected'); cy.screenshot(_screenshotOptions); }); - - it('should only add view all button when enough filters are present', () => { - let filterCount; - - cy.visit(`${_path}&knob-Filter%20cutoff_FilterPanel=1&knob-Max%20filters_FilterPanel=1`) - .get(_selector) - .find('.bx--filter-button') - .click() - .get(_selector) - .find('dds-filter-group-item') - .first() - .as('filterGroupItem') - .click() - .find('.dds-filter-group-item__view-all') - .should('have.length', 1) - .click() - .get('@filterGroupItem') - .find('dds-filter-panel-checkbox') - .then(checkboxes => (filterCount = checkboxes.length)); - cy.visit(`${_path}&knob-Max%20filters_FilterPanel=${filterCount}`) - .get(_selector) - .find('.bx--filter-button') - .click() - .get(_selector) - .find('dds-filter-group-item') - .first() - .click() - .find('.dds-filter-group-item__view-all') - .should('have.length', 0); - }); - - it('should support custom view all button text', () => { - let customText = 'Foo button'; - - cy.visit(`${_path}&knob-View%20all%20text_FilterPanel=${customText}`) - .get(_selector) - .find('.bx--filter-button') - .click() - .get(_selector) - .find('dds-filter-group-item') - .first() - .click() - .find('.dds-filter-group-item__view-all') - .should('have.text', customText); - cy.screenshot(_screenshotOptions); - }); - - it('should re-hide excess elements when filter groups are closed and reopened', () => { - cy.visit(_path) - .get(_selector) - .find('.bx--filter-button') - .click() - .get(_selector) - .find('dds-filter-group-item') - .first() - .as('filterGroupItem') - .shadow() - .find('.bx--accordion__heading') - .as('toggle') - .click() - .get('@filterGroupItem') - .find('.dds-filter-group-item__view-all') - .click() - .get('@filterGroupItem') - .find('dds-filter-panel-checkbox') - .last() - .as('lastCheckbox') - .get('@toggle') - .click() - .click() - .get('@lastCheckbox') - .should('not.be.visible'); - cy.screenshot(_screenshotOptions); - }); - - it('should not re-hide elements when an element that would be hidden has been selected', () => { - cy.visit(_path) - .get(_selector) - .find('.bx--filter-button') - .click() - .get(_selector) - .find('dds-filter-group-item') - .first() - .as('filterGroupItem') - .shadow() - .find('.bx--accordion__heading') - .as('toggle') - .click() - .get('@filterGroupItem') - .find('.dds-filter-group-item__view-all') - .click() - .get('@filterGroupItem') - .find('dds-filter-panel-checkbox') - .last() - .as('lastCheckbox') - .shadow() - .find('input[type="checkbox"]') - .check(_checkOptions) - .get('@toggle') - .click() - .click() - .get('@lastCheckbox') - .should('be.visible'); - cy.screenshot(_screenshotOptions); - }); });