@hashicorp/design-system-components
Version:
Helios Design System Components
120 lines (117 loc) • 6.76 kB
JavaScript
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { or } from 'ember-truth-helpers';
import style from 'ember-style-modifier';
import PowerSelect from 'ember-power-select/components/power-select';
import { HdsFormSuperSelectHorizontalPositionValues, HdsFormSuperSelectHorizontalPositionToPlacementValues } from '../types.js';
import anchoredPositionModifier from '../../../../../modifiers/hds-anchored-position.js';
import HdsTextBody from '../../../text/body.js';
import HdsFormSuperSelectOptionGroup from '../option-group.js';
import HdsFormSuperSelectPlaceholder from '../placeholder.js';
import HdsFormSuperSelectAfterOptions from '../after-options.js';
import { precompileTemplate } from '@ember/template-compilation';
import { setComponentTemplate } from '@ember/component';
import { g, i } from 'decorator-transforms/runtime';
/**
* Copyright IBM Corp. 2021, 2025
* SPDX-License-Identifier: MPL-2.0
*/
const DEFAULT_HORIZONTAL_POSITION = HdsFormSuperSelectHorizontalPositionValues.Left;
const HORIZONTAL_POSITION_MAPPING = HdsFormSuperSelectHorizontalPositionToPlacementValues;
class HdsFormSuperSelectSingleBase extends Component {
static {
g(this.prototype, "powerSelectAPI", [tracked]);
}
#powerSelectAPI = (i(this, "powerSelectAPI"), void 0);
get horizontalPosition() {
const {
horizontalPosition = DEFAULT_HORIZONTAL_POSITION
} = this.args;
return horizontalPosition;
}
get resultCountMessageText() {
if (typeof this.args.resultCountMessage === 'string') {
return this.args.resultCountMessage;
}
return `${this.powerSelectAPI?.resultsCount || 0} total`;
}
get resultCountMessageFunction() {
if (typeof this.args.resultCountMessage === 'function') {
return this.args.resultCountMessage;
}
return undefined;
}
/**
* This action sets the powerSelectAPI property and optionally calls a registerAPI function.
*
* @param {Object} powerSelectAPI - The API object for the PowerSelect component.
*
* If a `registerAPI` function is passed in through the component's arguments,
* this function will be called with the `powerSelectAPI` as its argument.
* This allows parent components or controllers to have access to the PowerSelect API.
*
* The `powerSelectAPI` is also stored on the component instance and used in `clearSelected`
*/
setPowerSelectAPI = powerSelectAPI => {
if (typeof this.args.registerAPI === 'function') {
this.args.registerAPI(powerSelectAPI);
}
this.powerSelectAPI = powerSelectAPI;
};
calculatePosition = (trigger, content) => {
// use `hds-anchored-position` to calculate and set position
// @ts-expect-error: known issue with type of invocation
anchoredPositionModifier(content, [trigger], {
placement: HORIZONTAL_POSITION_MAPPING[this.horizontalPosition],
offsetOptions: 4,
enableCollisionDetection: true
});
// prevent PowerSelect from setting position
return {
horizontalPosition: 'auto',
verticalPosition: 'auto',
style: {}
};
};
get showAfterOptions() {
return this.args.showAfterOptions ?? this.args.afterOptionsContent ?? false;
}
get searchPlaceholder() {
return this.args.searchPlaceholder ?? 'Search';
}
get dropdownMaxWidthStyle() {
const maxWidthStyle = {};
if (this.args.dropdownMaxWidth) {
maxWidthStyle['--hds-form-super-select-dropdown-max-width'] = this.args.dropdownMaxWidth;
}
return maxWidthStyle;
}
get classNames() {
const classes = ['hds-form-super-select', 'hds-form-super-select-single'];
// add a class based on the @matchTriggerWidth argument or whether dropdownMaxWidth is set
if (this.args.matchTriggerWidth === false || this.args.dropdownMaxWidth) {
classes.push('hds-form-super-select--dropdown-content-auto-width');
}
// add a class based on the @isInvalid argument
if (this.args.isInvalid) {
classes.push(`hds-form-super-select--is-invalid`);
}
return classes.join(' ');
}
static {
setComponentTemplate(precompileTemplate("{{!-- Important: if an argument is added in base.hbs, it must also be added/processed in the Base component used in field.hbs --}}\n<div class={{this.classNames}} {{style this.dropdownMaxWidthStyle}}>\n <PowerSelect @afterOptionsComponent={{if this.showAfterOptions (or @afterOptionsComponent (component HdsFormSuperSelectAfterOptions content=@afterOptionsContent resultCountMessage=this.resultCountMessageText))}} @ariaDescribedBy={{@ariaDescribedBy}} @ariaInvalid={{@ariaInvalid}} @ariaLabel={{@ariaLabel}} @ariaLabelledBy={{@ariaLabelledBy}} @beforeOptionsComponent={{@beforeOptionsComponent}} @calculatePosition={{if @verticalPosition undefined this.calculatePosition}} @closeOnSelect={{@closeOnSelect}} @disabled={{@disabled}} @dropdownClass={{@dropdownClass}} @extra={{@extra}} @groupComponent={{HdsFormSuperSelectOptionGroup}} @horizontalPosition={{@horizontalPosition}} @initiallyOpened={{@initiallyOpened}} @labelText={{@labelText}} @loadingMessage={{@loadingMessage}} @matcher={{@matcher}} @matchTriggerWidth={{if @dropdownMaxWidth false @matchTriggerWidth}} @noMatchesMessage={{@noMatchesMessage}} @onBlur={{@onBlur}} @onChange={{@onChange}} @onClose={{@onClose}} @onFocus={{@onFocus}} @onInput={{@onInput}} @onKeydown={{@onKeydown}} @onOpen={{@onOpen}} @options={{@options}} @optionsComponent={{@optionsComponent}} @placeholder={{@placeholder}} @placeholderComponent={{HdsFormSuperSelectPlaceholder}} @preventScroll={{@preventScroll}} @registerAPI={{this.setPowerSelectAPI}} @renderInPlace={{true}} @resultCountMessage={{this.resultCountMessageFunction}} @scrollTo={{@scrollTo}} @search={{@search}} @searchEnabled={{@searchEnabled}} @searchField={{@searchField}} @searchFieldPosition=\"before-options\" @searchMessage={{@searchMessage}} @searchPlaceholder={{this.searchPlaceholder}} @selected={{@selected}} @selectedItemComponent={{@selectedItemComponent}} @tabindex={{@tabindex}} @triggerClass={{@triggerClass}} @triggerComponent={{@triggerComponent}} @triggerId={{@triggerId}} @triggerRole={{@triggerRole}} @typeAheadOptionMatcher={{@typeAheadOptionMatcher}} @verticalPosition={{@verticalPosition}} ...attributes as |option select|>\n <HdsTextBody>{{yield option select}}</HdsTextBody>\n </PowerSelect>\n</div>", {
strictMode: true,
scope: () => ({
style,
PowerSelect,
or,
HdsFormSuperSelectAfterOptions,
HdsFormSuperSelectOptionGroup,
HdsFormSuperSelectPlaceholder,
HdsTextBody
})
}), this);
}
}
export { DEFAULT_HORIZONTAL_POSITION, HORIZONTAL_POSITION_MAPPING, HdsFormSuperSelectSingleBase as default };
//# sourceMappingURL=base.js.map