UNPKG

@hashicorp/design-system-components

Version:
115 lines (112 loc) 6.05 kB
import Component from '@glimmer/component'; import { assert } from '@ember/debug'; import { hash } from '@ember/helper'; import { or } from 'ember-truth-helpers'; import style from 'ember-style-modifier'; import didInsert from '@ember/render-modifiers/modifiers/did-insert'; import { HdsDropdownPositionValues, HdsDropdownPositionToPlacementValues } from './types.js'; import HdsPopoverPrimitive from '../popover-primitive/index.js'; import HdsDropdownToggleButton from './toggle/button.js'; import HdsDropdownToggleIcon from './toggle/icon.js'; import HdsDropdownHeader from './header.js'; import HdsDropdownListItemCheckbox from './list-item/checkbox.js'; import HdsDropdownListItemCheckmark from './list-item/checkmark.js'; import HdsDropdownListItemCopyItem from './list-item/copy-item.js'; import HdsDropdownListItemDescription from './list-item/description.js'; import HdsDropdownListItemGeneric from './list-item/generic.js'; import HdsDropdownListItemInteractive from './list-item/interactive.js'; import HdsDropdownListItemRadio from './list-item/radio.js'; import HdsDropdownListItemSeparator from './list-item/separator.js'; import HdsDropdownListItemTitle from './list-item/title.js'; import HdsDropdownFooter from './footer.js'; import { precompileTemplate } from '@ember/template-compilation'; import { setComponentTemplate } from '@ember/component'; /** * Copyright IBM Corp. 2021, 2025 * SPDX-License-Identifier: MPL-2.0 */ const DEFAULT_POSITION = HdsDropdownPositionValues.BottomRight; const POSITIONS = Object.values(HdsDropdownPositionValues); class HdsDropdown extends Component { get listPosition() { const { listPosition = DEFAULT_POSITION } = this.args; assert(`@listPosition for "Hds::Dropdown::Index" must be one of the following: ${POSITIONS.join(', ')}; received: ${listPosition}`, POSITIONS.includes(listPosition)); return listPosition; } get enableCollisionDetection() { return this.args.enableCollisionDetection ?? false; } get matchToggleWidth() { return this.args.matchToggleWidth ?? false; } get anchoredPositionOptions() { // custom options specific for the `RichTooltip` component // for details see the `hds-anchored-position` modifier return { placement: HdsDropdownPositionToPlacementValues[this.listPosition], offsetOptions: 4, enableCollisionDetection: this.enableCollisionDetection ? 'flip' : false, matchToggleWidth: this.matchToggleWidth, boundary: this.args.boundary }; } get classNames() { const classes = ['hds-dropdown']; // add a class based on the @isInline argument if (this.args.isInline) { classes.push('hds-dropdown--is-inline'); } return classes.join(' '); } get classNamesContent() { const classes = ['hds-dropdown__content']; // add a class based on the @listPosition argument // TODO: we preserved these classes to avoid introducing breaking changes for consumers who rely on these classes for tests, but we aim to remove them in the next major release // context: https://github.com/hashicorp/design-system/pull/2309#discussion_r1706941892 classes.push(`hds-dropdown__content--position-${this.listPosition}`); // add a class based on the @width or @matchToggleWidth arguments if (this.args.width || this.args.matchToggleWidth) { classes.push('hds-dropdown__content--fixed-width'); } return classes.join(' '); } didInsertList = element => { const checkmarkItems = element.querySelectorAll(`[role="option"]`); if (checkmarkItems.length) { const toggleButtonId = element.closest('.hds-dropdown')?.querySelector('.hds-dropdown-toggle-button')?.getAttribute('id'); element.setAttribute('role', 'listbox'); if (toggleButtonId) { element.setAttribute('aria-labelledby', toggleButtonId); } } }; static { setComponentTemplate(precompileTemplate("<HdsPopoverPrimitive @isOpen={{@isOpen}} @onClose={{@onClose}} @onFocusOut={{@onFocusOut}} @boundary={{@boundary}} @enableClickEvents={{true}} as |PP|>\n <div class={{this.classNames}} ...attributes {{PP.setupPrimitiveContainer}}>\n {{yield (hash ToggleButton=(component HdsDropdownToggleButton isOpen=PP.isOpen setupPrimitiveToggle=PP.setupPrimitiveToggle) ToggleIcon=(component HdsDropdownToggleIcon isOpen=PP.isOpen setupPrimitiveToggle=PP.setupPrimitiveToggle) close=PP.hidePopover)}}\n <div tabindex=\"-1\" class={{this.classNamesContent}} {{style width=@width max-height=@height}} {{PP.setupPrimitivePopover anchoredPositionOptions=this.anchoredPositionOptions}}>\n {{#if (or PP.isOpen @preserveContentInDom)}}\n {{yield (hash Header=HdsDropdownHeader close=PP.hidePopover)}}\n <ul class=\"hds-dropdown__list\" {{didInsert this.didInsertList}}>\n {{yield (hash close=PP.hidePopover Checkbox=HdsDropdownListItemCheckbox Checkmark=HdsDropdownListItemCheckmark CopyItem=HdsDropdownListItemCopyItem Description=HdsDropdownListItemDescription Generic=HdsDropdownListItemGeneric Interactive=HdsDropdownListItemInteractive Radio=HdsDropdownListItemRadio Separator=HdsDropdownListItemSeparator Title=HdsDropdownListItemTitle)}}\n </ul>\n {{yield (hash close=PP.hidePopover Footer=HdsDropdownFooter)}}\n {{/if}}\n </div>\n </div>\n</HdsPopoverPrimitive>", { strictMode: true, scope: () => ({ HdsPopoverPrimitive, hash, HdsDropdownToggleButton, HdsDropdownToggleIcon, style, or, HdsDropdownHeader, didInsert, HdsDropdownListItemCheckbox, HdsDropdownListItemCheckmark, HdsDropdownListItemCopyItem, HdsDropdownListItemDescription, HdsDropdownListItemGeneric, HdsDropdownListItemInteractive, HdsDropdownListItemRadio, HdsDropdownListItemSeparator, HdsDropdownListItemTitle, HdsDropdownFooter }) }), this); } } export { DEFAULT_POSITION, POSITIONS, HdsDropdown as default }; //# sourceMappingURL=index.js.map