UNPKG

carbon-custom-elements

Version:

A Carbon Design System variant that's as easy to use as native HTML elements, with no framework tax, no framework silo.

1 lines 9.62 kB
{"version":3,"sources":["components/combo-box/combo-box.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI1C,OAAO,UAAwC,MAAM,sBAAsB,CAAC;AAC5E,OAAO,cAAc,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI3F;;;;;;;GAOG;AACH,cACM,UAAW,SAAQ,UAAU;IACjC;;OAEG;IACH,SAAS,CAAC,iBAAiB,SAAM;IAEjC,SAAS,CAAC,yBAAyB,UAAS;IAE5C;;OAEG;IAEH,OAAO,CAAC,oBAAoB,CAAe;IAE3C;;OAEG;IAEH,OAAO,CAAC,gBAAgB,CAAoB;IAE5C;;;OAGG;IACH,SAAS,CAAC,sBAAsB,CAAC,IAAI,KAAA;IAKrC;;;;;OAKG;IACH,SAAS,CAAC,mBAAmB,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAK/E;;OAEG;IACH,SAAS,CAAC,YAAY;IAYtB,SAAS,CAAC,iBAAiB,CAAC,KAAK,EAAE,UAAU;IAQ7C,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,aAAa;IAenD;;OAEG;IACH,SAAS,CAAC,8BAA8B;IAUxC,SAAS,CAAC,8BAA8B,CAAC,IAAI,CAAC,EAAE,cAAc;IAiB9D,SAAS,CAAC,qBAAqB,IAAI,cAAc;IAkBjD,SAAS,CAAC,8BAA8B,IAAI,cAAc,GAAG,IAAI;IAiBjE;;OAEG;IAEH,mBAAmB,SAAM;IAEzB;;OAEG;IAEH,UAAU,SAAM;IAEhB;;OAEG;IAEH,WAAW,EAAG,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAEnE,YAAY,CAAC,iBAAiB,KAAA;IAU9B,MAAM,CAAC,YAAY,cAAsB;IAEzC;;OAEG;IACH,MAAM,KAAK,uBAAuB,WAEjC;IAED;;OAEG;IACH,MAAM,KAAK,YAAY,WAEtB;IAED;;OAEG;IACH,MAAM,KAAK,oBAAoB,WAE9B;IAED;;;OAGG;IACH,MAAM,KAAK,iBAAiB,WAE3B;IAED;;OAEG;IACH,MAAM,KAAK,WAAW,WAErB;IAED,MAAM,CAAC,MAAM,MAAU;CACxB;AAED,eAAe,UAAU,CAAC","file":"combo-box.d.ts","sourcesContent":["/**\n * @license\n *\n * Copyright IBM Corp. 2019, 2020\n *\n * This source code is licensed under the Apache-2.0 license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nimport settings from 'carbon-components/es/globals/js/settings';\nimport { TemplateResult } from 'lit-html';\nimport { html, property, query, customElement } from 'lit-element';\nimport Close16 from '@carbon/icons/lib/close/16';\nimport { findIndex, forEach } from '../../globals/internal/collection-helpers';\nimport BXDropdown, { DROPDOWN_KEYBOARD_ACTION } from '../dropdown/dropdown';\nimport BXComboBoxItem from './combo-box-item';\nimport styles from './combo-box.scss';\n\nexport { DROPDOWN_COLOR_SCHEME, DROPDOWN_SIZE, DROPDOWN_TYPE } from '../dropdown/dropdown';\n\nconst { prefix } = settings;\n\n/**\n * Combo box.\n * @element bx-combo-box\n * @fires bx-combo-box-beingselected\n * The custom event fired before a combo box item is selected upon a user gesture.\n * Cancellation of this event stops changing the user-initiated selection.\n * @fires bx-combo-box-selected - The custom event fired after a a combo box item is selected upon a user gesture.\n */\n@customElement(`${prefix}-combo-box`)\nclass BXComboBox extends BXDropdown {\n /**\n * The text content that should be set to the `<input>` for filtering.\n */\n protected _filterInputValue = '';\n\n protected _shouldTriggerBeFocusable = false;\n\n /**\n * The selection button.\n */\n @query('#selection-button')\n private _selectionButtonNode!: HTMLElement;\n\n /**\n * The `<input>` for filtering.\n */\n @query('input')\n private _filterInputNode!: HTMLInputElement;\n\n /**\n * @param item A combo box item.\n * @returns `true` if the given combo box item matches the query text user types.\n */\n protected _testItemWithQueryText(item) {\n return (this.itemMatches || this._defaultItemMatches)(item, this._filterInputNode.value);\n }\n\n /* eslint-disable class-methods-use-this */\n /**\n * The default item matching callback.\n * @param item The combo box item.\n * @param queryText The query text user types.\n * @returns `true` if the given combo box item matches the given query text.\n */\n protected _defaultItemMatches(item: BXComboBoxItem, queryText: string): boolean {\n return item.textContent!.toLowerCase().indexOf(queryText.toLowerCase()) >= 0;\n }\n /* eslint-enable class-methods-use-this */\n\n /**\n * Handles `input` event on the `<input>` for filtering.\n */\n protected _handleInput() {\n const items = this.querySelectorAll((this.constructor as typeof BXComboBox).selectorItem);\n const index = !this._filterInputNode.value ? -1 : findIndex(items, this._testItemWithQueryText, this);\n forEach(items, (item, i) => {\n (item as BXComboBoxItem).highlighted = i === index;\n });\n const { _filterInputNode: filterInput } = this;\n this._filterInputValue = !filterInput ? '' : filterInput.value;\n this.open = true;\n this.requestUpdate(); // If the only change is to `_filterInputValue`, auto-update doesn't happen\n }\n\n protected _handleClickInner(event: MouseEvent) {\n if (this._selectionButtonNode?.contains(event.target as Node)) {\n this._handleUserInitiatedClearInput();\n } else {\n super._handleClickInner(event);\n }\n }\n\n protected _handleKeypressInner(event: KeyboardEvent) {\n const { key } = event;\n const action = (this.constructor as typeof BXDropdown).getAction(key);\n const { TRIGGERING } = DROPDOWN_KEYBOARD_ACTION;\n if (\n this._selectionButtonNode?.contains(event.target as Node) &&\n // Space key should be handled by `<input>` unless \"clear selection\" button has focus\n (action === TRIGGERING || key === ' ')\n ) {\n this._handleUserInitiatedClearInput();\n } else {\n super._handleKeypressInner(event);\n }\n }\n\n /**\n * Handles user-initiated clearing the `<input>` for filtering.\n */\n protected _handleUserInitiatedClearInput() {\n forEach(this.querySelectorAll((this.constructor as typeof BXComboBox).selectorItem), item => {\n (item as BXComboBoxItem).highlighted = false;\n });\n this._filterInputValue = '';\n this._filterInputNode.focus();\n this.open = false;\n this.requestUpdate();\n }\n\n protected _handleUserInitiatedSelectItem(item?: BXComboBoxItem) {\n if (item && !this._selectionShouldChange(item)) {\n // Escape hatch for `shouldUpdate()` logic that updates `._filterInputValue()` when selection changes,\n // given we want to update the `<input>` and close the dropdown even if selection doesn't update.\n // Use case:\n // 1. Select the 2nd item in combo box drop down\n // 2. Type some text in the `<input>`\n // 3. Re-select the 2nd item in combo box drop down,\n // the `<input>` has to updated with the 2nd item and the dropdown should be closed,\n // even if there is no change in the selected value\n this._filterInputValue = item.textContent || '';\n this.open = false;\n this.requestUpdate();\n }\n super._handleUserInitiatedSelectItem(item);\n }\n\n protected _renderTriggerContent(): TemplateResult {\n const { disabled, inputLabel, triggerContent, _filterInputValue: filterInputValue, _handleInput: handleInput } = this;\n return html`\n <input\n id=\"trigger-label\"\n class=\"${prefix}--text-input\"\n ?disabled=${disabled}\n placeholder=\"${triggerContent}\"\n .value=${filterInputValue}\n role=\"combobox\"\n aria-label=\"${inputLabel}\"\n aria-controls=\"menu-body\"\n aria-autocomplete=\"list\"\n @input=${handleInput}\n />\n `;\n }\n\n protected _renderFollowingTriggerContent(): TemplateResult | void {\n const { clearSelectionLabel, _filterInputValue: filterInputValue } = this;\n return filterInputValue.length === 0\n ? undefined\n : html`\n <div\n id=\"selection-button\"\n role=\"button\"\n class=\"${prefix}--list-box__selection\"\n tabindex=\"0\"\n title=\"${clearSelectionLabel}\"\n >\n ${Close16({ 'aria-label': clearSelectionLabel })}\n </div>\n `;\n }\n\n /**\n * The `aria-label` attribute for the icon to clear selection.\n */\n @property({ attribute: 'clear-selection-label' })\n clearSelectionLabel = '';\n\n /**\n * The `aria-label` attribute for the `<input>` for filtering.\n */\n @property({ attribute: 'input-label' })\n inputLabel = '';\n\n /**\n * The custom item matching callback.\n */\n @property({ attribute: false })\n itemMatches!: (item: BXComboBoxItem, queryText: string) => boolean;\n\n shouldUpdate(changedProperties) {\n super.shouldUpdate(changedProperties);\n const { _selectedItemContent: selectedItemContent } = this;\n if (selectedItemContent && changedProperties.has('value')) {\n this._filterInputValue = selectedItemContent?.textContent || '';\n }\n return true;\n }\n\n // For combo box, open/selection with space key is disabled given the input box should take it over\n static TRIGGER_KEYS = new Set(['Enter']);\n\n /**\n * A selector that will return highlighted items.\n */\n static get selectorItemHighlighted() {\n return `${prefix}-combo-box-item[highlighted]`;\n }\n\n /**\n * A selector that will return combo box items.\n */\n static get selectorItem() {\n return `${prefix}-combo-box-item`;\n }\n\n /**\n * A selector that will return selected items.\n */\n static get selectorItemSelected() {\n return `${prefix}-combo-box-item[selected]`;\n }\n\n /**\n * The name of the custom event fired before a combo box item is selected upon a user gesture.\n * Cancellation of this event stops changing the user-initiated selection.\n */\n static get eventBeforeSelect() {\n return `${prefix}-combo-box-beingselected`;\n }\n\n /**\n * The name of the custom event fired after a a combo box item is selected upon a user gesture.\n */\n static get eventSelect() {\n return `${prefix}-combo-box-selected`;\n }\n\n static styles = styles;\n}\n\nexport default BXComboBox;\n"]}