From 69ee0823ef5dfde8626c9b7d54e97d309a0b1499 Mon Sep 17 00:00:00 2001 From: Anna Wang Date: Tue, 5 Aug 2025 15:43:10 -0700 Subject: [PATCH 1/2] HDS-5265: a11y guardrails for dropdown toggle icon feat: update enum and type names for allowed icons tests pass (#3089) Co-authored-by: Anna Wang Failing test fixed and reworked the hasChevron() function to more closely align with the syntax of other functions feat: update docs to mention more-vertical as well feat: added changeset fix: edited changeset formatting to be more consistent fix: type of allowed icons array fix: website indentation issue --- .changeset/deep-wings-arrive.md | 9 ++++++++ .../components/hds/dropdown/toggle/icon.ts | 22 +++++++++++++++++-- .../components/hds/dropdown/toggle/types.ts | 7 ++++++ .../hds/dropdown/toggle/icon-test.js | 16 +++++++++++++- .../dropdown/partials/code/component-api.md | 22 +++++++++---------- 5 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 .changeset/deep-wings-arrive.md diff --git a/.changeset/deep-wings-arrive.md b/.changeset/deep-wings-arrive.md new file mode 100644 index 00000000000..7d0365c7825 --- /dev/null +++ b/.changeset/deep-wings-arrive.md @@ -0,0 +1,9 @@ +--- +"@hashicorp/design-system-components": major +--- + + + +`Dropdown` - Added assertion to the `ToggleIcon` to provide improved developer guidance for the `hasChevron` attribute + + diff --git a/packages/components/src/components/hds/dropdown/toggle/icon.ts b/packages/components/src/components/hds/dropdown/toggle/icon.ts index b1e0d69e85e..5368b99559e 100644 --- a/packages/components/src/components/hds/dropdown/toggle/icon.ts +++ b/packages/components/src/components/hds/dropdown/toggle/icon.ts @@ -7,7 +7,10 @@ import Component from '@glimmer/component'; import { action } from '@ember/object'; import { assert } from '@ember/debug'; import { tracked } from '@glimmer/tracking'; -import { HdsDropdownToggleIconSizeValues } from './types.ts'; +import { + HdsDropdownToggleIconSizeValues, + HdsDropdownToggleIconAllowedIconValues, +} from './types.ts'; import type { HdsIconSignature } from '../../icon'; import type { HdsDropdownToggleIconSizes } from './types'; @@ -20,6 +23,9 @@ export const SIZES: HdsDropdownToggleIconSizes[] = Object.values( HdsDropdownToggleIconSizeValues ); +export const ALLOWED_ICON_LIST: HdsIconSignature['Args']['name'][] = + Object.values(HdsDropdownToggleIconAllowedIconValues); + export interface HdsDropdownToggleIconSignature { Args: { hasChevron?: boolean; @@ -107,13 +113,25 @@ export default class HdsDropdownToggleIcon extends Component`, + hbs``, ); assert.dom('.hds-icon.hds-icon-chevron-down').doesNotExist(); }); @@ -155,4 +155,18 @@ module('Integration | Component | hds/dropdown/toggle/icon', function (hooks) { throw new Error(errorMessage); }); }); + test('it should throw an assertion if an incorrect value for @icon is provided while @hasChevron is false', async function (assert) { + const errorMessage = + '@hasChevron for "Hds::Dropdown::Toggle::Icon" must be true unless the icon is one of the following: more-horizontal, more-vertical; received: apple'; + assert.expect(2); + setupOnerror(function (error) { + assert.strictEqual(error.message, `Assertion Failed: ${errorMessage}`); + }); + await render( + hbs``, + ); + assert.throws(function () { + throw new Error(errorMessage); + }); + }); }); diff --git a/website/docs/components/dropdown/partials/code/component-api.md b/website/docs/components/dropdown/partials/code/component-api.md index 79eb1a3e1d4..b940c76c800 100644 --- a/website/docs/components/dropdown/partials/code/component-api.md +++ b/website/docs/components/dropdown/partials/code/component-api.md @@ -3,16 +3,16 @@ The Dropdown component is composed of different child components each with their own APIs: - The Dropdown component - - Optional header and footer + - Optional header and footer - Toggle components to open/close the Dropdown - - ToggleButton - - ToggleIcon + - ToggleButton + - ToggleIcon - ListItem components, to build the Dropdown’s list items - - Description - - Generic - - Interactive - - Separator - - Title + - Description + - Generic + - Interactive + - Separator + - Title ### Dropdown @@ -68,7 +68,7 @@ The Dropdown component is composed of different child components each with their If an `@isInline` parameter is provided, then the element will be displayed as `inline-block` (useful to achieve specific layouts like in a container with right alignment). Otherwise, it will have a `block` layout. - Setting it to `true` will automatically flip the list position to remain visible when near the edges of the viewport. + Setting it to `true` will automatically flip the list position to remain visible when near the edges of the viewport. Controls if the list should be rendered initially opened. @@ -136,7 +136,7 @@ The `Dropdown::Toggle::Icon` component, yielded as contextual component. Acceptable value: any [icon](/icons/library) name. - Per design, `false` is only currently allowed when the "more-horizontal" icon is used; it is set to `true` by default. + Per design, `false` is only currently allowed when the "more-horizontal" or "more-vertical" icons are used; it is set to `true` by default. @@ -295,7 +295,7 @@ The `Dropdown::ListItem::Checkmark` component, yielded as contextual component. This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). -

+

In this component, the `...attributes` are not supported on the root element (an `
  • ` element) but on the underlying element/component (`