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 f400e879eeb..e4a840657ce 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'; @@ -18,6 +21,10 @@ import type Owner from '@ember/owner'; export const DEFAULT_SIZE = HdsDropdownToggleIconSizeValues.Medium; export const SIZES: string[] = Object.values(HdsDropdownToggleIconSizeValues); +export const ALLOWED_ICON_LIST: string[] = Object.values( + HdsDropdownToggleIconAllowedIconValues +); + export interface HdsDropdownToggleIconSignature { Args: { hasChevron?: boolean; @@ -105,13 +112,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 4eb658a8d10..4dc43738b71 100644 --- a/website/docs/components/dropdown/partials/code/component-api.md +++ b/website/docs/components/dropdown/partials/code/component-api.md @@ -3,96 +3,96 @@ 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 - - `Dropdown::Toggle::Button` yielded as contextual component (see below). - - - `Dropdown::Toggle::Icon` yielded as contextual component (see below). - - - `Dropdown::Header` yielded as contextual component (see below). - - - `Dropdown::ListItem::Title` yielded as contextual component (see below). - - - `Dropdown::ListItem::Description` yielded as contextual component (see below). - - - `Dropdown::ListItem::Separator` yielded as contextual component (see below). - - - `Dropdown::ListItem::Interactive` yielded as contextual component (see below). - - - `Dropdown::ListItem::CopyItem` yielded as contextual component (see below). - - - `Dropdown::ListItem::Checkmark` yielded as contextual component (see below). - - - `Dropdown::ListItem::Checkbox` yielded as contextual component (see below). - - - `Dropdown::ListItem::Radio` yielded as contextual component (see below). - - - `Dropdown::ListItem::Generic` yielded as contextual component (see below). - - - `Dropdown::Footer` yielded as contextual component (see below). - - - Function to programmatically close the Dropdown yielded to the content. -

- If this function is invoked using an `\{{on "click"}}` modifier applied to the `ListItem::Interactive` element, there is a quirky behavior of the Ember `` component which requires a workaround to have the events executed in the right order (this happens only if it has a `@route` argument). Read more about the issue and a possible solution [in this GitHub comment](https://github.com/hashicorp/design-system/pull/399#issuecomment-1171186772). -
- - _Note: If `@enableCollisionDetection` is set, the list will automatically flip position to remain visible when near the edges of the screen regardless of the starting placement._ - - - 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. - - - Controls if the list should be rendered initially opened. - - - By default, the Dropdown List has a `min-width` of `200px` and a `max-width` of `400px`, so it adapts to the content size. If a `@width` parameter is provided then the list will have a fixed width. -

We discourage the use of percentage values for this argument. The Dropdown list is [a `popover` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover), so relative units use `document` as a reference (not the parent element), meaning percentage values act similar to `vw`. - If `@matchToggleWidth` is set, `@width` is overridden. -
- - If a `@height` parameter is provided then the list will have a max-height. - - - Sets the Dropdown List’s width to match the width of the Toggle. It overrides the `@width` value if set. - - - Controls if the content is always rendered in the DOM, even when the Dropdown is closed. - - - Callback function invoked when the Dropdown is closed, if provided. - - - This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). - + +`Dropdown::Toggle::Button` yielded as contextual component (see below). + + +`Dropdown::Toggle::Icon` yielded as contextual component (see below). + + +`Dropdown::Header` yielded as contextual component (see below). + + +`Dropdown::ListItem::Title` yielded as contextual component (see below). + + +`Dropdown::ListItem::Description` yielded as contextual component (see below). + + +`Dropdown::ListItem::Separator` yielded as contextual component (see below). + + +`Dropdown::ListItem::Interactive` yielded as contextual component (see below). + + +`Dropdown::ListItem::CopyItem` yielded as contextual component (see below). + + +`Dropdown::ListItem::Checkmark` yielded as contextual component (see below). + + +`Dropdown::ListItem::Checkbox` yielded as contextual component (see below). + + +`Dropdown::ListItem::Radio` yielded as contextual component (see below). + + +`Dropdown::ListItem::Generic` yielded as contextual component (see below). + + +`Dropdown::Footer` yielded as contextual component (see below). + + +Function to programmatically close the Dropdown yielded to the content. +

+If this function is invoked using an `\{{on "click"}}` modifier applied to the `ListItem::Interactive` element, there is a quirky behavior of the Ember `` component which requires a workaround to have the events executed in the right order (this happens only if it has a `@route` argument). Read more about the issue and a possible solution [in this GitHub comment](https://github.com/hashicorp/design-system/pull/399#issuecomment-1171186772). +
+ +_Note: If `@enableCollisionDetection` is set, the list will automatically flip position to remain visible when near the edges of the screen regardless of the starting placement._ + + +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. + + +Controls if the list should be rendered initially opened. + + +By default, the Dropdown List has a `min-width` of `200px` and a `max-width` of `400px`, so it adapts to the content size. If a `@width` parameter is provided then the list will have a fixed width. +

We discourage the use of percentage values for this argument. The Dropdown list is [a `popover` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover), so relative units use `document` as a reference (not the parent element), meaning percentage values act similar to `vw`. +If `@matchToggleWidth` is set, `@width` is overridden. +
+ +If a `@height` parameter is provided then the list will have a max-height. + + +Sets the Dropdown List’s width to match the width of the Toggle. It overrides the `@width` value if set. + + +Controls if the content is always rendered in the DOM, even when the Dropdown is closed. + + +Callback function invoked when the Dropdown is closed, if provided. + + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). +
### Contextual components @@ -102,26 +102,26 @@ The Dropdown component is composed of different child components each with their The `Dropdown::Toggle::Button` component, yielded as contextual component. - - Text of the ToggleButton. If no text value is defined, an error will be thrown. - - - - - Acceptable value: any [icon](/icons/library) name. - - - Displays an optional count indicator using the [Badge Count](/components/badge-count) component. - - - Displays an optional badge indicator using the [Badge](/components/badge) component. - - - Appends an icon to the optional badge indicator. Acceptable value: any [icon](/icons/library) name. - - - This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). - + +Text of the ToggleButton. If no text value is defined, an error will be thrown. + + + + +Acceptable value: any [icon](/icons/library) name. + + +Displays an optional count indicator using the [Badge Count](/components/badge-count) component. + + +Displays an optional badge indicator using the [Badge](/components/badge) component. + + +Appends an icon to the optional badge indicator. Acceptable value: any [icon](/icons/library) name. + + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + #### [D].ToggleIcon @@ -129,19 +129,19 @@ The `Dropdown::Toggle::Button` component, yielded as contextual component. The `Dropdown::Toggle::Icon` component, yielded as contextual component. - - Value of `aria-label` for the ToggleIcon. If no text value is defined, an error will be thrown. - - - 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. - - - - This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). - + +Value of `aria-label` for the ToggleIcon. If no text value is defined, an error will be thrown. + + +Acceptable value: any [icon](/icons/library) name. + + +Per design, `false` is only currently allowed when the "more-horizontal" or "more-vertical" icons are used; it is set to `true` by default. + + + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + #### [D].Header / [D].Footer @@ -151,13 +151,13 @@ The `Dropdown::Header` / `Dropdown::Footer` components, yielded as contextual co Note: if the Dropdown content exceeds the height of the container, the header and footer remain fixed while the list of items adjusts its height. - - Elements passed as children are yielded as inner content of the Dropdown header/footer. - - - - This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). - + +Elements passed as children are yielded as inner content of the Dropdown header/footer. + + + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + #### [D].Title @@ -165,12 +165,12 @@ Note: if the Dropdown content exceeds the height of the container, the header an The `Dropdown::ListItem::Title` component, yielded as contextual component. - - Text to be used for the title. If no text value is defined, an error will be thrown. - - - This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). - + +Text to be used for the title. If no text value is defined, an error will be thrown. + + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + #### [D].Description @@ -178,12 +178,12 @@ The `Dropdown::ListItem::Title` component, yielded as contextual component. The `Dropdown::ListItem::Description` component, yielded as contextual component. - - Text to be used for the description. If no text value is defined, an error will be thrown. - - - This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). - + +Text to be used for the description. If no text value is defined, an error will be thrown. + + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + #### [D].Separator @@ -191,9 +191,9 @@ The `Dropdown::ListItem::Description` component, yielded as contextual component The `Dropdown::ListItem::Separator` 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). - + +This component supports use of [`...attributes`](https://guides.emberjs.com/release/in-depth-topics/patterns-for-components/#toc_attribute-ordering). + #### [D].Interactive @@ -203,44 +203,44 @@ The `Dropdown::ListItem::Interactive` component, yielded as contextual component It internally uses the [`Hds::Interactive`](/utilities/interactive) utility component. For more details about this component API, please refer to [its documentation page](/utilities/interactive?tab=code#component-api). - - Elements passed as children are yielded as inner content of `interactive` block. - - - The `Badge` component, yielded as contextual component inside `interactive` blocks of the `Dropdown`. It exposes the same API as the [`Badge` component](/components/badge). - - - Text to be used in the item. If no text value is defined and no content is yielded, an error will be thrown. - - - Color applied to the text and (optional) icons. - - - Leading icon. Acceptable value: any [icon](/icons/library) name. - - - Trailing icon. Acceptable value: any [icon](/icons/library) name. - - - Controls if the item is in “loading” state. When in this state, the item is not actually interactive, but you can pass the other expected arguments for the item (they’re simply ignored). - - - URL passed to the `` element. - - - Controls whether or not the `` link is external. When left `undefined` or explicitly set to `true` it adds the `target="_blank"` and `rel="noopener noreferrer"` attributes to the `` tag (for security reasons). - - - Parameters passed as arguments to the `` component. - - - Controls if the “LinkTo” is external to the Ember engine ([more details here](https://ember-engines.com/docs/link-to-external)) in which case it will use a `` instead of a simple `` for the @route. - - - 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 (`