From bccef4896cb4e71d5e5876c1e5e2af3c02310945 Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Tue, 6 Oct 2020 17:45:42 +0200 Subject: [PATCH] chore(combobox): advanced extension demos github + whatsapp --- packages/combobox/docs/LinkMixin.js | 60 +++ packages/combobox/docs/Subclassers.md | 60 ++- .../combobox/docs/gh-combobox/gh-button.js | 69 +++ .../combobox/docs/gh-combobox/gh-combobox.js | 503 ++++++++++++++++++ .../docs/lion-combobox-selection-display.js | 197 ------- .../combobox/docs/wa-combobox/wa-combobox.js | 368 +++++++++++++ 6 files changed, 1059 insertions(+), 198 deletions(-) create mode 100644 packages/combobox/docs/LinkMixin.js create mode 100644 packages/combobox/docs/gh-combobox/gh-button.js create mode 100644 packages/combobox/docs/gh-combobox/gh-combobox.js delete mode 100644 packages/combobox/docs/lion-combobox-selection-display.js create mode 100644 packages/combobox/docs/wa-combobox/wa-combobox.js diff --git a/packages/combobox/docs/LinkMixin.js b/packages/combobox/docs/LinkMixin.js new file mode 100644 index 000000000..305abc5b5 --- /dev/null +++ b/packages/combobox/docs/LinkMixin.js @@ -0,0 +1,60 @@ +import { dedupeMixin } from '@lion/core'; + +/** + * @typedef {import('lit-element').PropertyValues } changedProperties + */ + +/** + * Designed for webcomponents that need to behave like a link. + * For instance, comboboxes that have search result options opening a webpage on click. + * Using an is not a viable alternative, because: + * - no shadow dom (and thus no style encapsulation possibilities) + * - we need to extend from LionOption (and we cannot put the anchor inside + * the focusable element (LionOption which has [role=option])) + */ +const LinkMixinImplementation = superclass => + class extends superclass { + static get properties() { + return { + href: String, + target: String, + }; + } + + constructor() { + super(); + this._nativeAnchor = document.createElement('a'); + } + + connectedCallback() { + super.connectedCallback(); + if (!this.hasAttribute('role')) { + this.setAttribute('role', 'link'); + } + } + + firstUpdated(changedProperties) { + super.firstUpdated(changedProperties); + this.addEventListener('click', this.__navigate); + this.addEventListener('keydown', ({ key }) => { + if (key === ' ' || key === 'Enter') { + this.__navigate(); + } + }); + } + + updated(changedProperties) { + super.updated(changedProperties); + if (changedProperties.has('href')) { + this._nativeAnchor.href = this.href; + } + if (changedProperties.has('target')) { + this._nativeAnchor.target = this.target; + } + } + + __navigate() { + this._nativeAnchor.click(); + } + }; +export const LinkMixin = dedupeMixin(LinkMixinImplementation); diff --git a/packages/combobox/docs/Subclassers.md b/packages/combobox/docs/Subclassers.md index aee741e59..cbd1aadb4 100644 --- a/packages/combobox/docs/Subclassers.md +++ b/packages/combobox/docs/Subclassers.md @@ -3,7 +3,8 @@ ```js script import { html } from 'lit-html'; import './md-combobox/md-combobox.js'; -import './md-combobox/md-input.js'; +import './gh-combobox/gh-combobox.js'; +import './wa-combobox/wa-combobox.js'; export default { title: 'Forms/Combobox/Extensions', @@ -21,3 +22,60 @@ export const MaterialDesign = () => html` `; ``` + +```js preview-story +export const Github = () => html` + + master + develop + release + feat/abc + feat/xyz123 + +`; +``` + +```js preview-story +export const Whatsapp = () => html` + + + + + + + +`; +``` diff --git a/packages/combobox/docs/gh-combobox/gh-button.js b/packages/combobox/docs/gh-combobox/gh-button.js new file mode 100644 index 000000000..c90190b61 --- /dev/null +++ b/packages/combobox/docs/gh-combobox/gh-button.js @@ -0,0 +1,69 @@ +import { css, html } from '@lion/core'; +import { LionButton } from '@lion/button'; + +export class GhButton extends LionButton { + static get properties() { + return { + value: String, + }; + } + + static get styles() { + return css` + :host { + outline: none; + position: relative; + display: inline-flex; + align-items: center; + padding: 5px 16px; + font-size: 14px; + font-weight: 500; + line-height: 20px; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid; + border-radius: 6px; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + + color: #24292e; + background-color: #fafbfc; + border-color: rgba(27, 31, 35, 0.15); + box-shadow: 0 1px 0 rgba(27, 31, 35, 0.04), inset 0 1px 0 hsla(0, 0%, 100%, 0.25); + transition: background-color 0.2s cubic-bezier(0.3, 0, 0.5, 1); + } + + :host(:hover) { + background-color: #f3f4f6; + transition-duration: 0.1s; + } + + :host ::slotted([slot='before']) { + margin-right: 4px; + } + + /** + * TODO: this doesn't have to be light dom anymore in LionButton, + * just spawning a hidden native button on submit would be enough + */ + :host ::slotted(button) { + position: absolute; + opacity: 0; + } + `; + } + + render() { + return html` + ${this.value} + + `; + } +} +customElements.define('gh-button', GhButton); diff --git a/packages/combobox/docs/gh-combobox/gh-combobox.js b/packages/combobox/docs/gh-combobox/gh-combobox.js new file mode 100644 index 000000000..9e8f291f8 --- /dev/null +++ b/packages/combobox/docs/gh-combobox/gh-combobox.js @@ -0,0 +1,503 @@ +import { css, html } from '@lion/core'; +import { LionOption } from '@lion/listbox'; +import { renderLitAsNode } from '@lion/helpers'; +// import { withModalDialogConfig } from '@lion/overlays'; +import { LionCombobox } from '../../src/LionCombobox.js'; +import './gh-button.js'; + +export class GhOption extends LionOption { + static get properties() { + return { + category: String, + default: { type: Boolean, reflect: true }, + }; + } + + static get styles() { + return [ + super.styles, + css` + :host { + display: flex; + align-items: center; + width: 100%; + padding: 16px; + overflow: hidden; + color: #24292e; + text-align: left; + cursor: pointer; + background-color: #fff; + border: 0; + border-bottom: 1px solid #eaecef; + box-sizing: border-box; + display: flex; + align-items: center; + } + + @media (min-width: 544px) { + :host { + padding-top: 7px; + padding-bottom: 7px; + } + } + + :host([checked]) { + background-color: white; + } + + :host(:hover), + :host([active]), + :host([focused]) { + background-color: #f6f8fa; + } + + .gh-check-icon { + visibility: hidden; + margin-right: 4px; + } + + :host([checked]) .gh-check-icon { + visibility: visible; + } + + .gh-default-badge { + visibility: hidden; + + display: inline-block; + padding: 0 7px; + font-size: 12px; + font-weight: 500; + line-height: 18px; + border-radius: 2em; + background-color: initial !important; + border: 1px solid #e1e4e8; + color: #586069; + border-color: #e1e4e8; + } + + :host([default]) .gh-default-badge { + visibility: visible; + } + + .gh-content { + flex: 1; + } + `, + ]; + } + + render() { + return html` + + + default + `; + } +} +customElements.define('gh-option', GhOption); + +export class GhCombobox extends LionCombobox { + static get properties() { + return { + category: { type: String }, + isDesktop: { type: Boolean, reflect: true, attribute: 'is-desktop' }, + }; + } + + static get styles() { + return [ + super.styles, + css` + /** @configure LionCombobox */ + + :host { + font-family: apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif, + Apple Color Emoji, Segoe UI Emoji; + font-size: 14px; + } + + .input-group__container { + display: flex; + border-bottom: none; + } + + * > ::slotted([role='listbox']) { + max-height: none; + } + + * > ::slotted([slot='input']) { + padding: 5px 12px; + font-size: 14px; + line-height: 20px; + color: #24292e; + vertical-align: middle; + background-color: #fff; + background-repeat: no-repeat; + background-position: right 8px center; + border: 1px solid #e1e4e8; + border-radius: 6px; + outline: none; + box-shadow: inset 0 1px 0 rgba(225, 228, 232, 0.2); + } + + :host([is-desktop]) { + font-size: 12px; + } + + :host([is-desktop]) ::slotted([slot='input']) { + font-size: 14px; + } + + :host([focused]) ::slotted([slot='input']) { + border-color: #0366d6; + outline: none; + box-shadow: 0 0 0 3px rgba(3, 102, 214, 0.3); + } + + .gh-combobox { + height: auto; + max-height: 480px; + margin-top: 8px; + + position: relative; + z-index: 99; + display: flex; + max-height: 66%; + margin: auto 0; + overflow: hidden; + pointer-events: auto; + flex-direction: column; + background-color: #fff; + border-radius: 12px; + box-shadow: 0 0 18px rgba(27, 31, 35, 0.4); + /* animation: SelectMenu-modal-animation 0.12s cubic-bezier(0, 0.1, 0.1, 1) backwards; */ + } + + :host([is-desktop]) .gh-combobox { + width: 300px; + height: auto; + max-height: 480px; + margin: 8px 0 16px; + font-size: 12px; + border: 1px solid #e1e4e8; + border-radius: 6px; + box-shadow: 0 8px 24px rgba(149, 157, 165, 0.2); + /* animation-name: SelectMenu-modal-animation--sm; */ + } + + .form-field__label { + font-weight: bold; + } + + /** @enhance LionCombobox */ + + .gh-categories { + display: flex; + flex-shrink: 0; + overflow-x: auto; + overflow-y: hidden; + box-shadow: inset 0 -1px 0 #eaecef; + -webkit-overflow-scrolling: touch; + } + + :host([is-desktop]) .gh-categories { + padding: 8px 8px 0; + } + + .gh-categories__btn { + flex: 1; + padding: 8px 16px; + font-size: 12px; + font-weight: 500; + color: #6a737d; + text-align: center; + background-color: initial; + border: 0; + box-shadow: inset 0 -1px 0 #eaecef; + + border-radius: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; + outline: none; + + cursor: pointer; + } + + .gh-categories__btn:focus { + background-color: #dbedff; + } + + :host([is-desktop]) .gh-categories__btn { + flex: none; + padding: 4px 16px; + border: solid transparent; + border-width: 1px 1px 0; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + } + + .gh-categories__btn[aria-pressed='true'] { + z-index: 1; + color: #24292e; + cursor: default; + box-shadow: 0 0 0 1px #eaecef; + cursor: default; + } + + :host([is-desktop]) .gh-categories__btn { + flex: none; + } + :host([is-desktop]) .gh-categories__btn[aria-pressed='true'] { + border-color: #eaecef; + box-shadow: none; + } + + .gh-section-wrapper { + padding: 16px; + margin: 0; + border-bottom: 1px solid #eaecef; + } + + :host([is-desktop]) .gh-section-wrapper { + padding: 8px; + } + `, + ]; + } + + /** + * @override LionCombobox put all content in an overlay + */ + // eslint-disable-next-line class-methods-use-this + render() { + return html` + + + + `; + } + + /** + * Wrapper with combobox role for the text input that the end user controls the listbox with. + * @type {HTMLElement} + */ + get _comboboxNode() { + if (this.__comboboxNode) { + return this.__comboboxNode; + } + const slot = this.querySelector('[slot="input"]'); + if (slot) { + this.__comboboxNode = slot; + return slot; + } + const slot2 = this._overlayCtrl?.contentWrapperNode.querySelector('[slot="input"]'); + if (slot2) { + this.__comboboxNode = slot2; + return slot2; + } + return null; + } + + /** + * @override LionCombobox: remove selection-display (place it higher up) + */ + // eslint-disable-next-line class-methods-use-this + _inputGroupInputTemplate() { + return html` +
+ +
+ `; + } + + /** + * @override LionCombobox: restore to values FormControlMixin + */ + // eslint-disable-next-line class-methods-use-this + _groupTwoTemplate() { + return html` ${this._inputGroupTemplate()} ${this._feedbackTemplate()} `; + } + + get slots() { + return { + ...super.slots, + 'selection-display': () => { + return renderLitAsNode(html` + + + + `); + }, + }; + } + + get _overlayInvokerNode() { + return this.querySelector('[slot="selection-display"]'); + } + + get _overlayReferenceNode() { + return this._overlayInvokerNode; + } + + get _categoryButtons() { + return Array.from(this.shadowRoot.querySelectorAll('.gh-categories__btn[data-category]')); + } + + constructor() { + super(); + + this.showAllOnEmpty = true; + + /** @type {'branches'|'tags'} */ + this.category = 'branches'; + + this.selectionFollowsFocus = false; + + // Capture mobile OverlayConfig + this.__mobileDropdownComboConfig = this.config; + } + + firstUpdated(changedProperties) { + super.firstUpdated(changedProperties); + + const mql = window.matchMedia('(min-width: 544px)'); + this.isDesktop = mql.matches; + mql.addListener(({ matches }) => { + this.isDesktop = matches; + }); + } + + updated(changedProperties) { + super.updated(changedProperties); + + if (changedProperties.has('category')) { + const cat = this.category; + this._categoryButtons.forEach(btn => { + btn.setAttribute( + 'aria-pressed', + btn.getAttribute('data-category') === cat ? 'true' : 'false', + ); + }); + + this._inputNode.placeholder = + cat === 'branches' ? 'Find or create a branch...' : 'Find a tag'; + + this._handleAutocompletion(); + } + + if (changedProperties.has('opened')) { + // eslint-disable-next-line no-shadow + this._selectionDisplayNode.value = this.modelValue || 'Choose a value...'; + + if (this.opened) { + setTimeout(() => { + this._inputNode.focus(); + }); + } else { + setTimeout(() => { + this._selectionDisplayNode.focus(); + }, 100); + } + } + + if (changedProperties.has('isDesktop')) { + // this.config = this.isDesktop ? this.__mobileDropdownComboConfig : withModalDialogConfig(); + } + } + + // /** + // * @enhance LionCombobox + // * @param {*} option + // * @param {...any} args + // */ + // matchCondition(option, ...args) { + // return super.matchCondition(option, ...args) && option.category === this.category; + // } + + // _defineOverlayConfig() { + // // temp + // return { ...super._defineOverlayConfig(), hidesOnOutsideClick: false }; + // } + + __handleCategory(ev) { + this.category = ev.target.getAttribute('data-category'); + } + + // TODO: overrides below are not safe for override and should be made configurable in Combobox + // basically it should be possible te create a combobox without an overlay + + /** + * @override + */ + _textboxOnKeydown() { + // if (ev.key === 'Tab') { + // this.opened = false; + // } + this.__hasSelection = this._inputNode.value.length !== this._inputNode.selectionStart; + } + + /** + * @enhance OverlayMixin + */ + _setupOpenCloseListeners() { + super._setupOpenCloseListeners(); + this.__toggleOverlay = this.__toggleOverlay.bind(this); + this._overlayInvokerNode.addEventListener('click', this.__toggleOverlay); + } + + __toggleOverlay() { + this.opened = !this.opened; + } + + /** + * @enhance OverlayMixin + */ + _teardownOpenCloseListeners() { + super._teardownOpenCloseListeners(); + this._overlayInvokerNode.removeEventListener('click', this.__toggleOverlay); + } +} +customElements.define('gh-combobox', GhCombobox); diff --git a/packages/combobox/docs/lion-combobox-selection-display.js b/packages/combobox/docs/lion-combobox-selection-display.js deleted file mode 100644 index 741938eb4..000000000 --- a/packages/combobox/docs/lion-combobox-selection-display.js +++ /dev/null @@ -1,197 +0,0 @@ -// eslint-disable-next-line max-classes-per-file -import { LitElement, html, css, nothing } from '@lion/core'; - -/** - * Disclaimer: this is just an example component demoing the selection display of LionCombobox - * It needs an 'a11y plan' and tests before it could be released - */ - -/** - * @typedef {import('../src/LionCombobox.js').LionCombobox} LionCombobox - */ - -/** - * Renders the wrapper containing the textbox that triggers the listbox with filtered options. - * Optionally, shows 'chips' that indicate the selection. - * Should be considered an internal/protected web component to be used in conjunction with - * LionCombobox - * - */ -export class LionComboboxSelectionDisplay extends LitElement { - static get properties() { - return { - comboboxElement: Object, - /** - * Can be used to visually indicate the next - */ - removeChipOnNextBackspace: Boolean, - selectedElements: Array, - }; - } - - static get styles() { - return css` - :host { - display: flex; - } - - .combobox__selection { - flex: none; - } - - .combobox__input { - display: block; - } - - .selection-chip { - border-radius: 4px; - background-color: #eee; - padding: 4px; - font-size: 10px; - } - - .selection-chip--highlighted { - background-color: #ccc; - } - - * > ::slotted([slot='_textbox']) { - outline: none; - width: 100%; - height: 100%; - box-sizing: border-box; - border: none; - border-bottom: 1px solid; - } - `; - } - - /** - * @configure FocusMixin - */ - get _inputNode() { - return this.comboboxElement._inputNode; - } - - _computeSelectedElements() { - const { formElements, checkedIndex } = /** @type {LionCombobox} */ (this.comboboxElement); - const checkedIndexes = Array.isArray(checkedIndex) ? checkedIndex : [checkedIndex]; - return formElements.filter((_, i) => checkedIndexes.includes(i)); - } - - get multipleChoice() { - return this.comboboxElement?.multipleChoice; - } - - constructor() { - super(); - - /** @type {EventListener} */ - this.__textboxOnKeyup = this.__textboxOnKeyup.bind(this); - /** @type {EventListener} */ - this.__restoreBackspace = this.__restoreBackspace.bind(this); - } - - /** - * @param {import('lit-element').PropertyValues } changedProperties - */ - firstUpdated(changedProperties) { - super.firstUpdated(changedProperties); - - if (this.multipleChoice) { - this._inputNode.addEventListener('keyup', this.__textboxOnKeyup); - this._inputNode.addEventListener('focusout', this.__restoreBackspace); - } - } - - /** - * @param {import('lit-element').PropertyValues } changedProperties - */ - onComboboxElementUpdated(changedProperties) { - if (changedProperties.has('modelValue')) { - this.selectedElements = this._computeSelectedElements(); - } - } - - /** - * Whenever selectedElements are updated, makes sure that latest added elements - * are shown latest, and deleted elements respect existing order of chips. - */ - __reorderChips() { - const { selectedElements } = this; - if (this.__prevSelectedEls) { - const addedEls = selectedElements.filter(e => !this.__prevSelectedEls.includes(e)); - const deletedEls = this.__prevSelectedEls.filter(e => !selectedElements.includes(e)); - if (addedEls.length) { - this.selectedElements = [...this.__prevSelectedEls, ...addedEls]; - } else if (deletedEls.length) { - deletedEls.forEach(delEl => { - this.__prevSelectedEls.splice(this.__prevSelectedEls.indexOf(delEl), 1); - }); - this.selectedElements = this.__prevSelectedEls; - } - } - this.__prevSelectedEls = this.selectedElements; - } - - /** - * @param {import("@lion/listbox").LionOption} option - * @param {boolean} highlight - */ - // eslint-disable-next-line class-methods-use-this - _selectedElementTemplate(option, highlight) { - return html` - - ${option.value} - - `; - } - - _selectedElementsTemplate() { - if (!this.multipleChoice) { - return nothing; - } - return html` -
- ${this.selectedElements.map((option, i) => { - const highlight = Boolean( - this.removeChipOnNextBackspace && i === this.selectedElements.length - 1, - ); - return this._selectedElementTemplate(option, highlight); - })} -
- `; - } - - render() { - return html` ${this._selectedElementsTemplate()} `; - } - - /** - * @param {{ key: string; }} ev - */ - __textboxOnKeyup(ev) { - // Why we handle here and not in LionComboboxInvoker: - // All selectedElements state truth should be kept here and should not go back - // and forth. - if (ev.key === 'Backspace') { - if (!this._inputNode.value) { - if (this.removeChipOnNextBackspace) { - this.selectedElements[this.selectedElements.length - 1].checked = false; - } - this.removeChipOnNextBackspace = true; - } - } else { - this.removeChipOnNextBackspace = false; - } - - // TODO: move to LionCombobox - if (ev.key === 'Escape') { - this._inputNode.value = ''; - } - } - - __restoreBackspace() { - this.removeChipOnNextBackspace = false; - } -} -customElements.define('lion-combobox-selection-display', LionComboboxSelectionDisplay); diff --git a/packages/combobox/docs/wa-combobox/wa-combobox.js b/packages/combobox/docs/wa-combobox/wa-combobox.js new file mode 100644 index 000000000..c876df32f --- /dev/null +++ b/packages/combobox/docs/wa-combobox/wa-combobox.js @@ -0,0 +1,368 @@ +import { html, css } from '@lion/core'; +import { renderLitAsNode } from '@lion/helpers'; +import { LionOption } from '@lion/listbox'; +import { LionCombobox } from '../../src/LionCombobox.js'; + +class WaOption extends LionOption { + static get properties() { + return { + title: String, + text: String, + time: String, + image: String, + isUserText: { attribute: 'is-user-text', reflect: true, type: Boolean }, + isUserTextRead: { attribute: 'is-user-text-read', reflect: true, type: Boolean }, + }; + } + + static get styles() { + return [ + super.styles, + css` + :host { + --background-default: white; + --background-default-active: gray; + --secondary: #777; + --secondary-lighter: #aaa; + --chatlist-icon: #aaa; + background-color: var(--background-default); + cursor: pointer; + color: rgb(74, 74, 74); + padding: 0; + transition: max-height 0.4s ease, opacity 0.3s ease; + max-height: 500px; + } + + :host([checked]) { + background-color: #eee; + } + + :host(:hover) { + background-color: #f6f6f6; + } + + .wa-option { + position: relative; + display: flex; + flex-direction: row; + height: 72px; + pointer-events: all; + } + + .wa-option__image { + display: flex; + flex: none; + align-items: center; + margin-top: -1px; + padding: 0 15px 0 13px; + } + + .wa-option__image-inner { + position: relative; + overflow: hidden; + background-color: var(--avatar-background); + border-radius: 50%; + height: 49px; + width: 49px; + } + + .wa-option__image-inner img, + .wa-option__image-inner svg { + width: 100%; + height: 100%; + } + + .wa-option__image-inner-inner { + position: absolute; + top: 0; + z-index: 1; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + } + + .wa-option__content { + display: flex; + flex-basis: auto; + flex-direction: column; + flex-grow: 1; + justify-content: center; + min-width: 0; + border-bottom: 1px solid #eee; + padding-right: 15px; + } + + .wa-option__content-row1 { + display: flex; + align-items: center; + line-height: normal; + text-align: left; + } + + .wa-option__content-row1-title { + display: flex; + flex-grow: 1; + overflow: hidden; + color: var(--primary-strong); + font-weight: 400; + font-size: 17px; + line-height: 21px; + } + + .wa-option__content-row1-time { + line-height: 14px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-left: 6px; + margin-top: 3px; + + flex: none; + max-width: 100%; + color: var(--secondary-lighter); + font-size: 12px; + line-height: 20px; + } + + .wa-option__content-row2 { + display: flex; + align-items: center; + min-height: 20px; + color: var(--secondary); + font-size: 13px; + line-height: 20px; + margin-top: 2px; + /* color: var(--secondary-stronger); */ + } + + .wa-option__content-row2-text { + flex-grow: 1; + overflow: hidden; + font-weight: 400; + font-size: 14px; + line-height: 20px; + white-space: nowrap; + text-overflow: ellipsis; + } + + .wa-option__content-row2-text-inner { + display: flex; + align-items: flex-start; + } + + .wa-option__content-row2-text-inner-icon { + display: none; + flex: none; + color: var(--chatlist-icon); + vertical-align: top; + margin-right: 2px; + } + + :host([is-user-text]) .wa-option__content-row2-text-inner-icon { + display: inline-block; + } + + :host([is-user-text-read]) .wa-option__content-row2-text-inner-icon { + color: lightblue; + } + /* + .wa-option__content-row2-menu { + } */ + `, + ]; + } + + render() { + return html``; + } + + /** + * @configure LionCombobox + * @param {string} matchingString + */ + onFilterMatch(matchingString) { + this.__originalTitle = this.title; + const newInnerHTML = this.title.replace(new RegExp(`(${matchingString})`, 'i'), `$1`); + const helperNode = document.createElement('div'); + // For Safari, we need to add a label to the element + helperNode.innerHTML = `${newInnerHTML}`; + [this.title] = helperNode.children; + this.style.cssText = ` + max-height: 500px; + opacity: 1; + `; + } + + /** + * @configure LionCombobox + * @param {string} [curValue] + * @param {string} [prevValue] + */ + // eslint-disable-next-line no-unused-vars + onFilterUnmatch() { + if (this.__originalTitle) { + this.title = this.__originalTitle; + } + this.style.cssText = ` + max-height: 0; + opacity: 0; + `; + } +} +customElements.define('wa-option', WaOption); + +class WaCombobox extends LionCombobox { + static get styles() { + return [ + super.styles, + css` + :host { + font-family: SF Pro Text, SF Pro Icons, system, -apple-system, system-ui, + BlinkMacSystemFont, Helvetica Neue, Helvetica, Lucida Grande, Kohinoor Devanagari, + sans-serif; + } + + .input-group__container { + display: flex; + border-bottom: none; + } + + * > ::slotted([role='listbox']) { + max-height: none; + } + + * > ::slotted([slot='input']) { + font-size: 14px; + } + + .input-group { + padding: 15px; + background: #f6f6f6; + } + + .input-group__prefix { + margin-right: 20px; + color: #999; + display: flex; + } + + .input-group__container { + border-radius: 18px; + background: white; + padding: 7px; + padding-left: 16px; + } + + /** Undo Popper */ + #overlay-content-node-wrapper { + position: static !important; + width: auto !important; + transform: none !important; + + /* height: 300px; + overflow: scroll; */ + } + `, + ]; + } + + get slots() { + return { + ...super.slots, + prefix: () => + renderLitAsNode( + html` + + `, + ), + }; + } + + constructor() { + super(); + + /** @configure OverlayMixin */ + this.opened = true; + /** @configure LionCombobox */ + this.showAllOnEmpty = true; + /** @configure LionCombobox */ + this.rotateKeyboardNavigation = false; + } +} +customElements.define('wa-combobox', WaCombobox);