From 4d5a490e803e44cabd13c5d91ee34603d4929880 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Fri, 8 Dec 2023 18:15:40 +0100 Subject: [PATCH] fix(core): update --- ts_web/00_commitinfo_data.ts | 2 +- ts_web/elements/dees-form.demo.ts | 15 +- ts_web/elements/dees-input-dropdown.demo.ts | 16 + ts_web/elements/dees-input-dropdown.ts | 325 ++++++++++++++------ ts_web/elements/dees-input-text.ts | 3 +- 5 files changed, 262 insertions(+), 99 deletions(-) diff --git a/ts_web/00_commitinfo_data.ts b/ts_web/00_commitinfo_data.ts index 9f6ab75..547f95c 100644 --- a/ts_web/00_commitinfo_data.ts +++ b/ts_web/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@design.estate/dees-catalog', - version: '1.0.232', + version: '1.0.233', description: 'website for lossless.com' } diff --git a/ts_web/elements/dees-form.demo.ts b/ts_web/elements/dees-form.demo.ts index f9171b3..c657982 100644 --- a/ts_web/elements/dees-form.demo.ts +++ b/ts_web/elements/dees-form.demo.ts @@ -20,9 +20,22 @@ export const demoFunc = () => html` form.setStatus('success', 'authenticated!'); }} > + - + html` {option: 'option 3', key: 'option3'} ]} > + +
+ ` \ No newline at end of file diff --git a/ts_web/elements/dees-input-dropdown.ts b/ts_web/elements/dees-input-dropdown.ts index 3db0417..d2fe722 100644 --- a/ts_web/elements/dees-input-dropdown.ts +++ b/ts_web/elements/dees-input-dropdown.ts @@ -1,6 +1,17 @@ -import { customElement, DeesElement, type TemplateResult, property, html, css, cssManager, type CSSResult, } from '@design.estate/dees-element'; +import { + customElement, + DeesElement, + type TemplateResult, + property, + state, + html, + css, + cssManager, + type CSSResult, +} from '@design.estate/dees-element'; import * as domtools from '@design.estate/dees-domtools'; import { demoFunc } from './dees-input-dropdown.demo.js'; +import { DeesWindowLayer } from './dees-windowlayer.js'; declare global { interface HTMLElementTagNameMap { @@ -10,7 +21,7 @@ declare global { @customElement('dees-input-dropdown') export class DeesInputDropdown extends DeesElement { - public static demo = demoFunc + public static demo = demoFunc; // INSTANCE public changeSubject = new domtools.plugins.smartrx.rxjs.Subject(); @@ -25,144 +36,266 @@ export class DeesInputDropdown extends DeesElement { public key: string; @property() - public options: {option: string, key: string, payload?: any}[] = []; + public options: { option: string; key: string; payload?: any }[] = []; @property() - public selectedOption: {option: string, key: string, payload?: any} = { - key: null, - option: null, - payload: null - }; + public selectedOption: { option: string; key: string; payload?: any } = null; @property({ - type: Boolean + type: Boolean, }) public required: boolean = false; @property({ - type: Boolean + type: Boolean, + }) + public enableSearch: boolean = true; + + @property({ + type: Boolean, }) public disabled: boolean = false; + @state() + public opensToTop: boolean = false; + public static styles = [ cssManager.defaultStyles, css` * { - box-sizing: border-box; - } + box-sizing: border-box; + } - :host { - position: relative; - display: block; - height: 40px; - color: ${cssManager.bdTheme('#222', '#fff')}; - } + :host { + font-family: Roboto; + position: relative; + display: block; + color: ${cssManager.bdTheme('#222', '#fff')}; + margin-bottom: 24px; + } - .maincontainer { - display: block; - } + .maincontainer { + display: block; + } - .label { - font-size: 14px; - margin-bottom: 15px; - } + .label { + font-size: 14px; + margin-bottom: 4px; + } - .selectedBox { - cursor: pointer; - position: relative; - max-width: 420px; - height: 40px; - line-height: 40px; - padding: 0px 8px; - z-index: 0px; - background: ${cssManager.bdTheme('#ffffff', '#333333')}; - box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')}; - border-radius: 3px; - border-top: 1px solid #CCCCCC00; - border-bottom: 1px solid #66666600; - } + .selectedBox { + user-select: none; + cursor: pointer; + position: relative; + max-width: 420px; + height: 40px; + line-height: 40px; + padding: 0px 8px; + background: ${cssManager.bdTheme('#fafafa', '#222')}; + box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')}; + border-radius: 3px; + border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')}; + border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #333')}; + transition: all 0.2s ease; + } - .selectedBox.show { - border-top: 1px solid ${cssManager.bdTheme('#ffffff', '#666666')}; - border-bottom: 1px solid ${cssManager.bdTheme('#fafafa', '#222222')}; - } + .accentTop { + border-top: 1px solid #e4002b; + } - .selectionBox { - will-change:transform; - pointer-events: none; - cursor: pointer; - transition: all 0.2s ease; - opacity: 0; - position: absolute; - background: ${cssManager.bdTheme('#ffffff', '#222222')}; - max-width: 420px; - box-shadow: 0px 0px 5px rgba(0,0,0,0.2); - min-height: 40px; - z-index: 100; - border-radius: 3px; - padding: 4px; - transform: scale(0.99,0.99); - } + .accentBottom { + border-bottom: 1px solid #e4002b; + } - .selectionBox.show { - pointer-events: all; - opacity: 1; - transform: scale(1,1); - } + .selectionBox { + will-change: transform; + pointer-events: none; + cursor: pointer; + transition: all 0.2s ease; + opacity: 0; + background: ${cssManager.bdTheme('#ffffff', '#222222')}; + max-width: 420px; + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + min-height: 40px; + border-radius: 3px; + padding: 4px; + transform: scale(0.99, 0.99); + position: absolute; + } - .option { - transition: all 0.1s; - line-height: 40px; - padding: 0px 4px; - border-radius: 3px; - } + .selectionBox.show { + pointer-events: all; + opacity: 1; + transform: scale(1, 1); + } - .option:hover { - color: #fff; - padding-left: 8px; - background: #0277bd; - } - ` - ] + .option { + transition: all 0.1s; + line-height: 40px; + padding: 0px 4px; + border-radius: 3px; + } + + .option:hover { + color: #fff; + padding-left: 8px; + background: #0277bd; + } + + .search { + padding: 8px; + } + .search input { + display: block; + width: 80%; + background: none; + border: none; + height: 24px; + color: inherit; + text-align: center; + font-size: 12px; + font-weight: 600; + background: ${cssManager.bdTheme('#00000010', '#ffffff08')}; + border-radius: 16px; + margin: auto; + } + + .search input:focus { + border: none; + outline: none; + } + `, + ]; public render(): TemplateResult { return html`
-
- ${this.selectedOption?.option} -
+ ${this.label ? html`
${this.label}
` : html``}
- ${this.options.map(option => { + ${this.enableSearch && !this.opensToTop + ? html` + + ` + : null} + ${this.options.map((option) => { return html` -
{this.updateSelection(option);}}>${option.option}
- ` +
{ + this.updateSelection(option); + }} + > + ${option.option} +
+ `; })} + ${this.enableSearch && this.opensToTop + ? html` + + ` + : null} +
+
+ ${this.selectedOption?.option}
`; } firstUpdated() { - this.selectedOption = this.options[0] || null; + this.selectedOption = this.selectedOption || this.options[0] || null; } public async updateSelection(selectedOption) { this.selectedOption = selectedOption; - this.dispatchEvent(new CustomEvent('selectedOption', { - detail: selectedOption, - bubbles: true - })); - this.openSelectionBox(); + this.dispatchEvent( + new CustomEvent('selectedOption', { + detail: selectedOption, + bubbles: true, + }) + ); + if (this.isElevated) { + this.toggleSelectionBox(); + } this.changeSubject.next(this); } - public openSelectionBox() { - this.shadowRoot.querySelector('.selectedBox').classList.toggle('show'); - this.shadowRoot.querySelector('.selectionBox').classList.toggle('show'); - } - - public closeSelectionBox() { - + private isElevated: boolean = false; + private windowOverlay: DeesWindowLayer; + public async toggleSelectionBox() { + const domtoolsInstance = await this.domtoolsPromise; + const selectedBox: HTMLElement = this.shadowRoot.querySelector('.selectedBox'); + const selectionBox: HTMLElement = this.shadowRoot.querySelector('.selectionBox'); + if (!this.isElevated) { + this.windowOverlay = await DeesWindowLayer.createAndShow({ + blur: false, + }); + const elevatedDropdown = new DeesInputDropdown(); + elevatedDropdown.isElevated = true; + elevatedDropdown.label = this.label; + elevatedDropdown.enableSearch = this.enableSearch; + elevatedDropdown.required = this.required; + elevatedDropdown.disabled = this.disabled; + elevatedDropdown.style.position = 'fixed'; + elevatedDropdown.style.top = this.getBoundingClientRect().top + 'px'; + elevatedDropdown.style.left = this.getBoundingClientRect().left + 'px'; + elevatedDropdown.style.width = this.clientWidth + 'px'; + elevatedDropdown.options = this.options; + elevatedDropdown.selectedOption = this.selectedOption; + console.log(elevatedDropdown.selectedOption); + this.windowOverlay.appendChild(elevatedDropdown); + await domtoolsInstance.convenience.smartdelay.delayFor(0); + elevatedDropdown.toggleSelectionBox(); + const destroyOverlay = async () => { + (elevatedDropdown.shadowRoot.querySelector('.selectionBox') as HTMLElement).style.opacity = + '0'; + elevatedDropdown.removeEventListener('selectedOption', handleSelection); + this.windowOverlay.removeEventListener('clicked', destroyOverlay); + this.windowOverlay.destroy(); + }; + const handleSelection = async (event) => { + await this.updateSelection(elevatedDropdown.selectedOption); + destroyOverlay(); + }; + elevatedDropdown.addEventListener('selectedOption', handleSelection); + this.windowOverlay.addEventListener('clicked', destroyOverlay); + } else { + if (!selectionBox.classList.contains('show')) { + selectionBox.style.width = selectedBox.clientWidth + 'px'; + selectionBox.classList.add('show'); + const spaceData = selectedBox.getBoundingClientRect(); + if (300 > window.innerHeight - spaceData.bottom) { + this.opensToTop = true; + selectedBox.classList.add('accentTop'); + selectionBox.style.bottom = selectedBox.clientHeight + 2 + 'px'; + } else { + selectedBox.classList.add('accentBottom'); + this.opensToTop = false; + const labelOffset = this.label ? 24 : 0; + selectionBox.style.top = selectedBox.clientHeight + labelOffset + 'px'; + } + await domtoolsInstance.convenience.smartdelay.delayFor(0); + const searchInput = selectionBox.querySelector('input'); + searchInput.focus(); + } else { + selectedBox.style.pointerEvents = 'none'; + selectionBox.classList.remove('show'); + selectedBox.style.opacity = '0'; + } + } } } diff --git a/ts_web/elements/dees-input-text.ts b/ts_web/elements/dees-input-text.ts index b031fa3..e416e32 100644 --- a/ts_web/elements/dees-input-text.ts +++ b/ts_web/elements/dees-input-text.ts @@ -143,6 +143,7 @@ export class DeesInputText extends DeesElement { border-radius: 7px; padding: 4px 0px; width: 40px; + z-index: 3; } .showPassword:hover { @@ -169,7 +170,7 @@ export class DeesInputText extends DeesElement { return html`