From 041836810fbb1f0444fc33d4d59dd9dba8477b77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 8 Sep 2023 17:06:30 +1200 Subject: [PATCH 01/41] setup resizeObserver --- .../uui-tabs/lib/uui-tab-group.element.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 813a7759d..35afc8e61 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -1,6 +1,6 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration'; import { css, html, LitElement } from 'lit'; -import { queryAssignedElements } from 'lit/decorators.js'; +import { property, queryAssignedElements } from 'lit/decorators.js'; import { UUITabElement } from './uui-tab.element'; @@ -32,10 +32,21 @@ export class UUITabGroupElement extends LitElement { selector: 'uui-tab, [uui-tab], [role=tab]', }) private _slottedNodes?: HTMLElement[]; + + @property({ type: Boolean, reflect: true, attribute: 'priority-navigation' }) + priorityNavigation = false; + private _tabElements: HTMLElement[] = []; + #resizeObserver: ResizeObserver = new ResizeObserver(this.#onResize); + + #onResize(entries: ResizeObserverEntry[]) { + console.log('resize', entries); + } + private _setTabArray() { this._tabElements = this._slottedNodes ? this._slottedNodes : []; + console.log(this._tabElements); } private _onSlotChange() { @@ -71,9 +82,15 @@ export class UUITabGroupElement extends LitElement { connectedCallback() { super.connectedCallback(); + this.#resizeObserver.observe(this); if (!this.hasAttribute('role')) this.setAttribute('role', 'tablist'); } + disconnectedCallback() { + super.disconnectedCallback(); + this.#resizeObserver.unobserve(this); + } + render() { return html` `; } From f56113d2d237feca8c7875ef8222064cf78491db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 8 Sep 2023 17:39:11 +1200 Subject: [PATCH 02/41] hide tabs that overflow --- .../uui-tabs/lib/uui-tab-group.element.ts | 63 +++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 35afc8e61..589b67422 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -1,6 +1,14 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration'; import { css, html, LitElement } from 'lit'; -import { property, queryAssignedElements } from 'lit/decorators.js'; +import { + property, + query, + queryAssignedElements, + state, +} from 'lit/decorators.js'; + +import type { UUIButtonElement } from '@umbraco-ui/uui-button/lib'; +import '@umbraco-ui/uui-button/lib/uui-button.element'; import { UUITabElement } from './uui-tab.element'; @@ -27,6 +35,9 @@ export class UUITabGroupElement extends LitElement { `, ]; + @query('#more-button') + moreButtonElement!: UUIButtonElement; + @queryAssignedElements({ flatten: true, selector: 'uui-tab, [uui-tab], [role=tab]', @@ -36,17 +47,56 @@ export class UUITabGroupElement extends LitElement { @property({ type: Boolean, reflect: true, attribute: 'priority-navigation' }) priorityNavigation = false; + @state() + _hasHiddenTabs = false; + private _tabElements: HTMLElement[] = []; - #resizeObserver: ResizeObserver = new ResizeObserver(this.#onResize); + #visibleTabElements: HTMLElement[] = []; + #hiddenTabElements: HTMLElement[] = []; + #visibilityBreakpoints: number[] = []; + + #resizeObserver: ResizeObserver = new ResizeObserver( + this.#onResize.bind(this) + ); #onResize(entries: ResizeObserverEntry[]) { - console.log('resize', entries); + const containerWidth = + entries[0].contentBoxSize[0].inlineSize - + this.moreButtonElement.offsetWidth; + + this.#visibleTabElements = []; + this.#hiddenTabElements = []; + this._hasHiddenTabs = false; + + for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { + const breakpoint = this.#visibilityBreakpoints[i]; + + if (breakpoint < containerWidth) { + this.#visibleTabElements.push(this._tabElements[i]); + this._tabElements[i].style.display = 'block'; + } else { + this.#hiddenTabElements.push(this._tabElements[i]); + this._tabElements[i].style.display = 'none'; + this._hasHiddenTabs = true; + } + } + } + + #calculateBreakPoints() { + // Whenever a tab is added or removed, we need to recalculate the breakpoints + + let childrenWidth = 0; + + for (let i = 0; i < this._tabElements.length; i++) { + childrenWidth += this._tabElements[i].offsetWidth; + this.#visibilityBreakpoints[i] = childrenWidth; + } } private _setTabArray() { this._tabElements = this._slottedNodes ? this._slottedNodes : []; - console.log(this._tabElements); + this.#calculateBreakPoints(); } private _onSlotChange() { @@ -92,7 +142,10 @@ export class UUITabGroupElement extends LitElement { } render() { - return html` `; + return html` + + More + `; } } From 70c57ba911831cdb110f8780ea80c6e13930c709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:03:16 +1200 Subject: [PATCH 03/41] unset display value on visible tabs --- packages/uui-tabs/lib/uui-tab-group.element.ts | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 589b67422..a25d89542 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -1,11 +1,6 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration'; import { css, html, LitElement } from 'lit'; -import { - property, - query, - queryAssignedElements, - state, -} from 'lit/decorators.js'; +import { property, query, queryAssignedElements } from 'lit/decorators.js'; import type { UUIButtonElement } from '@umbraco-ui/uui-button/lib'; import '@umbraco-ui/uui-button/lib/uui-button.element'; @@ -47,9 +42,6 @@ export class UUITabGroupElement extends LitElement { @property({ type: Boolean, reflect: true, attribute: 'priority-navigation' }) priorityNavigation = false; - @state() - _hasHiddenTabs = false; - private _tabElements: HTMLElement[] = []; #visibleTabElements: HTMLElement[] = []; @@ -67,18 +59,18 @@ export class UUITabGroupElement extends LitElement { this.#visibleTabElements = []; this.#hiddenTabElements = []; - this._hasHiddenTabs = false; for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { const breakpoint = this.#visibilityBreakpoints[i]; if (breakpoint < containerWidth) { this.#visibleTabElements.push(this._tabElements[i]); - this._tabElements[i].style.display = 'block'; + this._tabElements[i].style.display = ''; + this.moreButtonElement.style.display = 'none'; } else { this.#hiddenTabElements.push(this._tabElements[i]); this._tabElements[i].style.display = 'none'; - this._hasHiddenTabs = true; + this.moreButtonElement.style.display = ''; } } } @@ -144,7 +136,7 @@ export class UUITabGroupElement extends LitElement { render() { return html` - More + `; } } From 7441e645f9709d5d09771d220f3e374417b98875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:06:54 +1200 Subject: [PATCH 04/41] add css var for tab horizontal padding --- packages/uui-tabs/lib/uui-tab.element.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab.element.ts b/packages/uui-tabs/lib/uui-tab.element.ts index 02506953c..000b768c9 100644 --- a/packages/uui-tabs/lib/uui-tab.element.ts +++ b/packages/uui-tabs/lib/uui-tab.element.ts @@ -16,6 +16,8 @@ import { ifDefined } from 'lit/directives/if-defined.js'; * @cssprop --uui-tab-text-active - Define the tab text active color * @cssprop --uui-tab-background - Define the tab group background color * @cssprop --uui-tab-divider - Define the tab dividers color + * @cssprop --uui-tab-padding-horizontal - Define the tab horizontal padding + * @cssprop --uui-tab-divider - Define the tab dividers color */ @defineElement('uui-tab') export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { @@ -33,7 +35,8 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { align-items: center; justify-content: center; text-align: center; - padding: var(--uui-size-2) var(--uui-size-4); + padding: var(--uui-size-2) + var(--uui-tab-padding-horizontal, var(--uui-size-4)); border: none; box-sizing: border-box; min-height: 32px; From 8edead821b5393c1b208a0bb6afff70b29f5a6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 8 Sep 2023 18:14:04 +1200 Subject: [PATCH 05/41] package lock --- package-lock.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 580594ae6..0170738f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29691,6 +29691,7 @@ "@umbraco-ui/uui-modal": "1.4.0-rc.1", "@umbraco-ui/uui-pagination": "1.4.0-rc.1", "@umbraco-ui/uui-popover": "1.4.0-rc.1", + "@umbraco-ui/uui-popover-container": "1.4.0-rc.1", "@umbraco-ui/uui-progress-bar": "1.4.0-rc.1", "@umbraco-ui/uui-radio": "1.4.0-rc.1", "@umbraco-ui/uui-range-slider": "1.4.0-rc.1", @@ -30154,7 +30155,7 @@ }, "packages/uui-popover-container": { "name": "@umbraco-ui/uui-popover-container", - "version": "0.0.0", + "version": "1.4.0-rc.1", "license": "MIT", "dependencies": { "@umbraco-ui/uui-base": "1.4.0-rc.1" From 882afd42a3e1af8fa00d6ae703985cf7f9597c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:03:20 +1200 Subject: [PATCH 06/41] add popover --- packages/uui-tabs/lib/uui-tab-group.element.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index a25d89542..93718f4a0 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -4,6 +4,7 @@ import { property, query, queryAssignedElements } from 'lit/decorators.js'; import type { UUIButtonElement } from '@umbraco-ui/uui-button/lib'; import '@umbraco-ui/uui-button/lib/uui-button.element'; +import '@umbraco-ui/uui-popover-container/lib/uui-popover-container.element'; import { UUITabElement } from './uui-tab.element'; @@ -77,7 +78,6 @@ export class UUITabGroupElement extends LitElement { #calculateBreakPoints() { // Whenever a tab is added or removed, we need to recalculate the breakpoints - let childrenWidth = 0; for (let i = 0; i < this._tabElements.length; i++) { @@ -136,7 +136,15 @@ export class UUITabGroupElement extends LitElement { render() { return html` - + + + What is going on in here + `; } } From 754494462458eb48a36a3d63b7c2696fb3980401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:45:53 +1200 Subject: [PATCH 07/41] move styles to the bottom of the file --- .../uui-tabs/lib/uui-tab-group.element.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 93718f4a0..7edbe841d 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -14,23 +14,6 @@ import { UUITabElement } from './uui-tab.element'; */ @defineElement('uui-tab-group') export class UUITabGroupElement extends LitElement { - static styles = [ - css` - :host { - display: flex; - flex-wrap: wrap; - color: var(--uui-tab-text); - background: var(--uui-tab-background, none); - height: 100%; - min-height: 48px; - } - - ::slotted(*:not(:last-of-type)) { - border-right: 1px solid var(--uui-tab-divider, none); - } - `, - ]; - @query('#more-button') moreButtonElement!: UUIButtonElement; @@ -147,6 +130,23 @@ export class UUITabGroupElement extends LitElement { `; } + + static styles = [ + css` + :host { + display: flex; + flex-wrap: wrap; + color: var(--uui-tab-text); + background: var(--uui-tab-background, none); + height: 100%; + min-height: 48px; + } + + ::slotted(*:not(:last-of-type)) { + border-right: 1px solid var(--uui-tab-divider, none); + } + `, + ]; } declare global { From 9fd31bceedd597e377d2f4aadec6e10bcc4ad9df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 16:50:15 +1200 Subject: [PATCH 08/41] work --- packages/uui-tabs/lib/uui-tab-group.element.ts | 16 ++++++++++++++-- packages/uui-tabs/lib/uui-tabs.story.ts | 3 +++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 7edbe841d..4d5384cc4 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -125,8 +125,15 @@ export class UUITabGroupElement extends LitElement { id="more-button" >... - - What is going on in here + + Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cumque aperiam + est nam ab, dolorem repellendus accusamus hic! Optio corrupti rerum + inventore, assumenda quam animi, totam atque sunt sequi numquam + exercitationem. `; } @@ -145,6 +152,11 @@ export class UUITabGroupElement extends LitElement { ::slotted(*:not(:last-of-type)) { border-right: 1px solid var(--uui-tab-divider, none); } + + #my-popover { + width: 200px; + border: 1px solid black; + } `, ]; } diff --git a/packages/uui-tabs/lib/uui-tabs.story.ts b/packages/uui-tabs/lib/uui-tabs.story.ts index c1cb35ed6..ed505c26a 100644 --- a/packages/uui-tabs/lib/uui-tabs.story.ts +++ b/packages/uui-tabs/lib/uui-tabs.story.ts @@ -47,6 +47,9 @@ export const AAAOverview: Story = props => html` Content Packages Media + Settings + Translations + Users `; AAAOverview.storyName = 'Overview'; From 27d573038cd8f55095dc12a05d9cd167f87eab6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:51:08 +1200 Subject: [PATCH 09/41] hide tabs --- .../uui-tabs/lib/uui-tab-group.element.ts | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 4d5384cc4..bef2761c5 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -1,6 +1,7 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration'; import { css, html, LitElement } from 'lit'; import { property, query, queryAssignedElements } from 'lit/decorators.js'; +import { repeat } from 'lit/directives/repeat.js'; import type { UUIButtonElement } from '@umbraco-ui/uui-button/lib'; import '@umbraco-ui/uui-button/lib/uui-button.element'; @@ -28,7 +29,6 @@ export class UUITabGroupElement extends LitElement { private _tabElements: HTMLElement[] = []; - #visibleTabElements: HTMLElement[] = []; #hiddenTabElements: HTMLElement[] = []; #visibilityBreakpoints: number[] = []; @@ -37,26 +37,44 @@ export class UUITabGroupElement extends LitElement { ); #onResize(entries: ResizeObserverEntry[]) { - const containerWidth = - entries[0].contentBoxSize[0].inlineSize - - this.moreButtonElement.offsetWidth; + this.#updateCollapsibleTabs(entries[0].contentBoxSize[0].inlineSize); + } + + #updateCollapsibleTabs(containerWidth: number) { + containerWidth = containerWidth - this.moreButtonElement.offsetWidth; - this.#visibleTabElements = []; - this.#hiddenTabElements = []; + this.#hiddenTabElements = []; //TODO - remove eventlisteners for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { const breakpoint = this.#visibilityBreakpoints[i]; if (breakpoint < containerWidth) { - this.#visibleTabElements.push(this._tabElements[i]); this._tabElements[i].style.display = ''; this.moreButtonElement.style.display = 'none'; } else { - this.#hiddenTabElements.push(this._tabElements[i]); + this.#hiddenTabElements.push( + this.#createHiddenTabElement(this._tabElements[i] as UUITabElement) + ); this._tabElements[i].style.display = 'none'; this.moreButtonElement.style.display = ''; } } + + this.requestUpdate(); + } + + #createHiddenTabElement(tab: UUITabElement) { + const hiddenTab = document.createElement('uui-button'); + hiddenTab.innerText = tab.innerText; + // hiddenTab.active = tab.active; + hiddenTab.disabled = tab.disabled; + hiddenTab.href = tab.href; + hiddenTab.target = tab.target; + hiddenTab.setAttribute('role', 'tab'); + hiddenTab.setAttribute('aria-selected', tab.active.toString()); + hiddenTab.setAttribute('aria-disabled', tab.disabled.toString()); + hiddenTab.addEventListener('click', this._onTabClicked); + return hiddenTab; } #calculateBreakPoints() { @@ -67,9 +85,13 @@ export class UUITabGroupElement extends LitElement { childrenWidth += this._tabElements[i].offsetWidth; this.#visibilityBreakpoints[i] = childrenWidth; } + + this.#updateCollapsibleTabs(this.offsetWidth); } private _setTabArray() { + console.log('set tab array'); + this._tabElements = this._slottedNodes ? this._slottedNodes : []; this.#calculateBreakPoints(); } @@ -123,17 +145,16 @@ export class UUITabGroupElement extends LitElement { popovertarget="my-popover" style="display: none" id="more-button" - >...MORE - Lorem ipsum dolor sit, amet consectetur adipisicing elit. Cumque aperiam - est nam ab, dolorem repellendus accusamus hic! Optio corrupti rerum - inventore, assumenda quam animi, totam atque sunt sequi numquam - exercitationem. + placement="bottom-end"> +
+ ${repeat(this.#hiddenTabElements, el => html`${el}`)} +
`; } @@ -153,9 +174,14 @@ export class UUITabGroupElement extends LitElement { border-right: 1px solid var(--uui-tab-divider, none); } - #my-popover { + #hidden-tabs { width: 200px; border: 1px solid black; + display: flex; + flex-direction: column; + } + #more-button { + margin-left: auto; } `, ]; From e221a5effec27571698abc495af5d9b94723131b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 17:52:22 +1200 Subject: [PATCH 10/41] cleanup --- packages/uui-tabs/lib/uui-tab-group.element.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index bef2761c5..98503804f 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -43,7 +43,11 @@ export class UUITabGroupElement extends LitElement { #updateCollapsibleTabs(containerWidth: number) { containerWidth = containerWidth - this.moreButtonElement.offsetWidth; - this.#hiddenTabElements = []; //TODO - remove eventlisteners + // Reset the hidden tabs + this.#hiddenTabElements.forEach(el => { + el.removeEventListener('click', this._onTabClicked); + }); + this.#hiddenTabElements = []; for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { const breakpoint = this.#visibilityBreakpoints[i]; From 9960eb06751407a7da5e6492a48373cfffd9b6f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 18:32:26 +1200 Subject: [PATCH 11/41] show if active tab inside dropdown --- .../uui-tabs/lib/uui-tab-group.element.ts | 83 ++++++++++++++----- 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 98503804f..215b65cae 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -36,12 +36,24 @@ export class UUITabGroupElement extends LitElement { this.#onResize.bind(this) ); + connectedCallback() { + super.connectedCallback(); + this.#resizeObserver.observe(this); + if (!this.hasAttribute('role')) this.setAttribute('role', 'tablist'); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.#resizeObserver.unobserve(this); + } + #onResize(entries: ResizeObserverEntry[]) { this.#updateCollapsibleTabs(entries[0].contentBoxSize[0].inlineSize); } #updateCollapsibleTabs(containerWidth: number) { - containerWidth = containerWidth - this.moreButtonElement.offsetWidth; + containerWidth = containerWidth; + const buttonWidth = this.moreButtonElement.offsetWidth; // Reset the hidden tabs this.#hiddenTabElements.forEach(el => { @@ -49,28 +61,43 @@ export class UUITabGroupElement extends LitElement { }); this.#hiddenTabElements = []; + let hasActiveHidden = false; + for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { const breakpoint = this.#visibilityBreakpoints[i]; - - if (breakpoint < containerWidth) { - this._tabElements[i].style.display = ''; + const tab = this._tabElements[i] as UUITabElement; + + if ( + breakpoint < + containerWidth - + (i !== this.#visibilityBreakpoints.length - 1 ? buttonWidth : 0) + ) { + tab.style.display = ''; this.moreButtonElement.style.display = 'none'; } else { this.#hiddenTabElements.push( - this.#createHiddenTabElement(this._tabElements[i] as UUITabElement) + this.#createHiddenTabElement(tab as UUITabElement) ); - this._tabElements[i].style.display = 'none'; + tab.style.display = 'none'; this.moreButtonElement.style.display = ''; + if (tab.active) { + hasActiveHidden = true; + } } } + hasActiveHidden + ? this.moreButtonElement.classList.add('active-inside') + : this.moreButtonElement.classList.remove('active-inside'); + this.requestUpdate(); } #createHiddenTabElement(tab: UUITabElement) { - const hiddenTab = document.createElement('uui-button'); + const hiddenTab = document.createElement('uui-tab'); hiddenTab.innerText = tab.innerText; - // hiddenTab.active = tab.active; + hiddenTab.classList.add('hidden-tab'); + hiddenTab.active = tab.active; hiddenTab.disabled = tab.disabled; hiddenTab.href = tab.href; hiddenTab.target = tab.target; @@ -94,8 +121,6 @@ export class UUITabGroupElement extends LitElement { } private _setTabArray() { - console.log('set tab array'); - this._tabElements = this._slottedNodes ? this._slottedNodes : []; this.#calculateBreakPoints(); } @@ -117,7 +142,10 @@ export class UUITabGroupElement extends LitElement { if (this._elementIsTabLike(selectedElement)) { selectedElement.active = true; - const filtered = this._tabElements.filter(el => el !== selectedElement); + const filtered = [ + ...this._tabElements, + ...this.#hiddenTabElements, + ].filter(el => el !== selectedElement); filtered.forEach(el => { if (this._elementIsTabLike(el)) { @@ -131,17 +159,6 @@ export class UUITabGroupElement extends LitElement { return el instanceof UUITabElement || 'active' in el; } - connectedCallback() { - super.connectedCallback(); - this.#resizeObserver.observe(this); - if (!this.hasAttribute('role')) this.setAttribute('role', 'tablist'); - } - - disconnectedCallback() { - super.disconnectedCallback(); - this.#resizeObserver.unobserve(this); - } - render() { return html` @@ -149,6 +166,7 @@ export class UUITabGroupElement extends LitElement { popovertarget="my-popover" style="display: none" id="more-button" + compact >MORE Date: Mon, 11 Sep 2023 18:33:44 +1200 Subject: [PATCH 12/41] add label --- packages/uui-tabs/lib/uui-tab-group.element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 215b65cae..f17051f7b 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -96,6 +96,7 @@ export class UUITabGroupElement extends LitElement { #createHiddenTabElement(tab: UUITabElement) { const hiddenTab = document.createElement('uui-tab'); hiddenTab.innerText = tab.innerText; + hiddenTab.label = tab.label; hiddenTab.classList.add('hidden-tab'); hiddenTab.active = tab.active; hiddenTab.disabled = tab.disabled; From 2ca68502217fdd663394ab5c03f2d29423364f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 11 Sep 2023 18:35:19 +1200 Subject: [PATCH 13/41] more labels --- packages/uui-tabs/lib/uui-tab-group.element.ts | 1 + packages/uui-tabs/lib/uui-tabs.story.ts | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index f17051f7b..7f26d5424 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -167,6 +167,7 @@ export class UUITabGroupElement extends LitElement { popovertarget="my-popover" style="display: none" id="more-button" + label="More" compact >MORE diff --git a/packages/uui-tabs/lib/uui-tabs.story.ts b/packages/uui-tabs/lib/uui-tabs.story.ts index ed505c26a..de8146957 100644 --- a/packages/uui-tabs/lib/uui-tabs.story.ts +++ b/packages/uui-tabs/lib/uui-tabs.story.ts @@ -44,12 +44,12 @@ export const AAAOverview: Story = props => html` --uui-tab-background: ${props['--uui-tab-background']}; --uui-tab-divider: ${props['--uui-tab-divider']}; ${props.inlineStyles}"> - Content - Packages - Media - Settings - Translations - Users + Content + Packages + Media + Settings + Translations + Users `; AAAOverview.storyName = 'Overview'; From 1fb1f86a41cd47ba22ef14e5a2751e3196390528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 13 Sep 2023 14:12:51 +1200 Subject: [PATCH 14/41] link proxies --- .../uui-tabs/lib/uui-tab-group.element.ts | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 7f26d5424..1e7b29b95 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -29,7 +29,9 @@ export class UUITabGroupElement extends LitElement { private _tabElements: HTMLElement[] = []; - #hiddenTabElements: HTMLElement[] = []; + #hiddenTabElements: UUITabElement[] = []; + #hiddenTabElementsMap: Map = new Map(); + #visibilityBreakpoints: number[] = []; #resizeObserver: ResizeObserver = new ResizeObserver( @@ -60,6 +62,7 @@ export class UUITabGroupElement extends LitElement { el.removeEventListener('click', this._onTabClicked); }); this.#hiddenTabElements = []; + this.#hiddenTabElementsMap.clear(); let hasActiveHidden = false; @@ -75,9 +78,12 @@ export class UUITabGroupElement extends LitElement { tab.style.display = ''; this.moreButtonElement.style.display = 'none'; } else { - this.#hiddenTabElements.push( - this.#createHiddenTabElement(tab as UUITabElement) - ); + // Make a proxy tab to put in the hidden tabs container and link it to the original tab + const proxyTab = this.#createHiddenTabElement(tab as UUITabElement); + this.#hiddenTabElementsMap.set(proxyTab, tab); + this.#hiddenTabElementsMap.set(proxyTab, tab); + this.#hiddenTabElements.push(proxyTab); + tab.style.display = 'none'; this.moreButtonElement.style.display = ''; if (tab.active) { @@ -142,17 +148,30 @@ export class UUITabGroupElement extends LitElement { const selectedElement = e.currentTarget as HTMLElement; if (this._elementIsTabLike(selectedElement)) { selectedElement.active = true; + const proxy = this.#hiddenTabElementsMap.get(selectedElement); + + if (proxy) { + proxy.active = true; + } const filtered = [ ...this._tabElements, ...this.#hiddenTabElements, - ].filter(el => el !== selectedElement); + ].filter(el => el !== selectedElement && el !== proxy); filtered.forEach(el => { if (this._elementIsTabLike(el)) { el.active = false; } }); + + const hasActiveHidden = this.#hiddenTabElements.some( + el => el.active && el !== proxy + ); + + hasActiveHidden + ? this.moreButtonElement.classList.add('active-inside') + : this.moreButtonElement.classList.remove('active-inside'); } }; @@ -164,7 +183,7 @@ export class UUITabGroupElement extends LitElement { return html` -
+
${repeat(this.#hiddenTabElements, el => html`${el}`)}
@@ -202,11 +221,12 @@ export class UUITabGroupElement extends LitElement { width: 100%; } - #hidden-tabs { + #hidden-tabs-container { width: 200px; border: 1px solid black; display: flex; flex-direction: column; + background: var(--uui-color-surface); } #more-button { margin-left: auto; From 2e9cdadda67c24ad6250090dfb8ae851c63fa211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 13 Sep 2023 14:15:20 +1200 Subject: [PATCH 15/41] dropdown styling --- packages/uui-tabs/lib/uui-tab-group.element.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 1e7b29b95..ccd8ea808 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -223,10 +223,11 @@ export class UUITabGroupElement extends LitElement { #hidden-tabs-container { width: 200px; - border: 1px solid black; display: flex; flex-direction: column; background: var(--uui-color-surface); + border-radius: var(--uui-border-radius); + box-shadow: var(--uui-shadow-depth-3); } #more-button { margin-left: auto; From f28c72c2e80bcdfc4a7f371e28f93e0e85a19f95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 13 Sep 2023 14:19:43 +1200 Subject: [PATCH 16/41] clone tab node instead of factory function --- .../uui-tabs/lib/uui-tab-group.element.ts | 37 +++++++++++-------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index ccd8ea808..bd65b8a33 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -79,7 +79,12 @@ export class UUITabGroupElement extends LitElement { this.moreButtonElement.style.display = 'none'; } else { // Make a proxy tab to put in the hidden tabs container and link it to the original tab - const proxyTab = this.#createHiddenTabElement(tab as UUITabElement); + // const proxyTab = this.#createHiddenTabElement(tab as UUITabElement); + const proxyTab = tab.cloneNode(true) as UUITabElement; + proxyTab.addEventListener('click', this._onTabClicked); + proxyTab.classList.add('hidden-tab'); + proxyTab.style.display = ''; + this.#hiddenTabElementsMap.set(proxyTab, tab); this.#hiddenTabElementsMap.set(proxyTab, tab); this.#hiddenTabElements.push(proxyTab); @@ -99,21 +104,21 @@ export class UUITabGroupElement extends LitElement { this.requestUpdate(); } - #createHiddenTabElement(tab: UUITabElement) { - const hiddenTab = document.createElement('uui-tab'); - hiddenTab.innerText = tab.innerText; - hiddenTab.label = tab.label; - hiddenTab.classList.add('hidden-tab'); - hiddenTab.active = tab.active; - hiddenTab.disabled = tab.disabled; - hiddenTab.href = tab.href; - hiddenTab.target = tab.target; - hiddenTab.setAttribute('role', 'tab'); - hiddenTab.setAttribute('aria-selected', tab.active.toString()); - hiddenTab.setAttribute('aria-disabled', tab.disabled.toString()); - hiddenTab.addEventListener('click', this._onTabClicked); - return hiddenTab; - } + // #createHiddenTabElement(tab: UUITabElement) { + // const hiddenTab = document.createElement('uui-tab'); + // hiddenTab.innerText = tab.innerText; + // hiddenTab.label = tab.label; + // hiddenTab.classList.add('hidden-tab'); + // hiddenTab.active = tab.active; + // hiddenTab.disabled = tab.disabled; + // hiddenTab.href = tab.href; + // hiddenTab.target = tab.target; + // hiddenTab.setAttribute('role', 'tab'); + // hiddenTab.setAttribute('aria-selected', tab.active.toString()); + // hiddenTab.setAttribute('aria-disabled', tab.disabled.toString()); + // hiddenTab.addEventListener('click', this._onTabClicked); + // return hiddenTab; + // } #calculateBreakPoints() { // Whenever a tab is added or removed, we need to recalculate the breakpoints From 73f86ecc7f53754fc26ba8c27f5ef46750824592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Wed, 13 Sep 2023 14:21:57 +1200 Subject: [PATCH 17/41] add comment --- packages/uui-tabs/lib/uui-tab-group.element.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index bd65b8a33..117a73774 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -57,6 +57,8 @@ export class UUITabGroupElement extends LitElement { containerWidth = containerWidth; const buttonWidth = this.moreButtonElement.offsetWidth; + //TODO: Optimize so that we only update the hidden tabs when necessary. Currently we update them every time the container is resized. + // Reset the hidden tabs this.#hiddenTabElements.forEach(el => { el.removeEventListener('click', this._onTabClicked); From 747d345caed6507174c5327a379cd47726d9c8be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Thu, 14 Sep 2023 12:52:08 +1200 Subject: [PATCH 18/41] add navigation dropdown direction --- packages/uui-tabs/lib/uui-tab-group.element.ts | 14 +++++++++++++- packages/uui-tabs/lib/uui-tabs.story.ts | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 117a73774..7e4f0e953 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -27,6 +27,13 @@ export class UUITabGroupElement extends LitElement { @property({ type: Boolean, reflect: true, attribute: 'priority-navigation' }) priorityNavigation = false; + @property({ + type: String, + reflect: true, + attribute: 'priority-navigation-dropdown-direction', + }) + priorityNavigationDropdownDirection: 'vertical' | 'horizontal' = 'vertical'; + private _tabElements: HTMLElement[] = []; #hiddenTabElements: UUITabElement[] = []; @@ -229,13 +236,18 @@ export class UUITabGroupElement extends LitElement { } #hidden-tabs-container { - width: 200px; + width: fit-content; display: flex; flex-direction: column; background: var(--uui-color-surface); border-radius: var(--uui-border-radius); box-shadow: var(--uui-shadow-depth-3); } + :host([priority-navigation-dropdown-direction='horizontal']) + #hidden-tabs-container { + flex-direction: row; + } + #more-button { margin-left: auto; position: relative; diff --git a/packages/uui-tabs/lib/uui-tabs.story.ts b/packages/uui-tabs/lib/uui-tabs.story.ts index de8146957..97883c072 100644 --- a/packages/uui-tabs/lib/uui-tabs.story.ts +++ b/packages/uui-tabs/lib/uui-tabs.story.ts @@ -96,6 +96,7 @@ export const WithIcons: Story = props => html`

Tabs with Icons

Date: Fri, 15 Sep 2023 14:23:57 +1200 Subject: [PATCH 26/41] optimize so updates only occur when necessary --- .../uui-tabs/lib/uui-tab-group.element.ts | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 1a1a99dc2..8c3f89ce5 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -6,6 +6,7 @@ import { repeat } from 'lit/directives/repeat.js'; import type { UUIButtonElement } from '@umbraco-ui/uui-button/lib'; import '@umbraco-ui/uui-button/lib/uui-button.element'; import '@umbraco-ui/uui-popover-container/lib/uui-popover-container.element'; +import '@umbraco-ui/uui-symbol-more/lib/uui-symbol-more.element'; import { UUITabElement } from './uui-tab.element'; @@ -66,6 +67,7 @@ export class UUITabGroupElement extends LitElement { #hiddenTabElementsMap: Map = new Map(); #visibilityBreakpoints: number[] = []; + #oldBreakpoint = 0; #resizeObserver: ResizeObserver = new ResizeObserver( this.#onResize.bind(this) @@ -133,8 +135,34 @@ export class UUITabGroupElement extends LitElement { containerWidth = containerWidth; const buttonWidth = this._moreButtonElement.offsetWidth; - //TODO: Optimize so that we only update the hidden tabs when necessary. Currently we update them every time the container is resized. + // Only update if the container is smaller than the last breakpoint + if ( + this.#visibilityBreakpoints.slice(-1)[0] < containerWidth && + this.#hiddenTabElements.length === 0 + ) + return; + // Only update if the new breakpoint is different from the old one + let newBreakpoint = Number.MAX_VALUE; + + for (let i = this.#visibilityBreakpoints.length - 1; i > -1; i--) { + const breakpoint = this.#visibilityBreakpoints[i]; + // Subtract the button width when we are not at the last breakpoint + const containerWidthButtonWidth = + containerWidth - + (i !== this.#visibilityBreakpoints.length - 1 ? buttonWidth : 0); + + if (breakpoint < containerWidthButtonWidth) { + newBreakpoint = i; + break; + } + } + + if (newBreakpoint === this.#oldBreakpoint) return; + console.log(newBreakpoint, this.#oldBreakpoint); + this.#oldBreakpoint = newBreakpoint; + + // Do the update // Reset the hidden tabs this.#hiddenTabElements.forEach(el => { el.removeEventListener('click', this.#onTabClicked); @@ -142,17 +170,18 @@ export class UUITabGroupElement extends LitElement { this.#hiddenTabElements = []; this.#hiddenTabElementsMap.clear(); - let hasActiveHidden = false; + let hasActiveTabInDropdown = false; for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { const breakpoint = this.#visibilityBreakpoints[i]; const tab = this._tabElements[i] as UUITabElement; - if ( - breakpoint < + // Subtract the button width when we are not at the last breakpoint + const containerWidthButtonWidth = containerWidth - - (i !== this.#visibilityBreakpoints.length - 1 ? buttonWidth : 0) - ) { + (i !== this.#visibilityBreakpoints.length - 1 ? buttonWidth : 0); + + if (breakpoint < containerWidthButtonWidth) { tab.style.display = ''; this._moreButtonElement.style.display = 'none'; } else { @@ -166,19 +195,21 @@ export class UUITabGroupElement extends LitElement { ? 'left' : 'bottom'; + // Link the proxy tab to the original tab this.#hiddenTabElementsMap.set(proxyTab, tab); - this.#hiddenTabElementsMap.set(proxyTab, tab); + this.#hiddenTabElementsMap.set(tab, proxyTab); + this.#hiddenTabElements.push(proxyTab); tab.style.display = 'none'; this._moreButtonElement.style.display = ''; if (tab.active) { - hasActiveHidden = true; + hasActiveTabInDropdown = true; } } } - hasActiveHidden + hasActiveTabInDropdown ? this._moreButtonElement.classList.add('active-inside') : this._moreButtonElement.classList.remove('active-inside'); @@ -214,9 +245,9 @@ export class UUITabGroupElement extends LitElement { style="display: none" id="more-button" label="More" - compact - >MORE + compact> + + Date: Fri, 15 Sep 2023 14:24:45 +1200 Subject: [PATCH 27/41] move tab styles to the bottom --- packages/uui-tabs/lib/uui-tab.element.ts | 154 +++++++++++------------ 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab.element.ts b/packages/uui-tabs/lib/uui-tab.element.ts index d711790fa..2d0426d38 100644 --- a/packages/uui-tabs/lib/uui-tab.element.ts +++ b/packages/uui-tabs/lib/uui-tab.element.ts @@ -21,6 +21,83 @@ import { ifDefined } from 'lit/directives/if-defined.js'; */ @defineElement('uui-tab') export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { + /** + * Reflects the disabled state of the element. True if tab is disabled. Change this to switch the state programmatically. + * @type {boolean} + * @attr + * @default false + */ + @property({ type: Boolean, reflect: true }) + public disabled = false; + + /** + * Set an href, this will turns the inner button into a anchor tag. + * @type {string} + * @attr + * @default undefined + */ + @property({ type: String }) + public href?: string; + + /** + * Set an anchor tag target, only used when using href. + * @type {string} + * @attr + * @default undefined + */ + @property({ type: String }) + public target?: '_blank' | '_parent' | '_self' | '_top'; + + /** + * Set the location of the active bar. + * @type {string} + * @attr + * @default bottom + */ + @property({ type: String, reflect: true, attribute: 'active-bar-location' }) + public activeBarLocation?: 'top' | 'bottom' | 'left' | 'right' = 'bottom'; + + constructor() { + super(); + this.addEventListener('click', this.onHostClick); + } + + private onHostClick(e: MouseEvent) { + if (this.disabled) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + } + + render() { + return this.href + ? html` + + + ${this.renderLabel()} + + + ` + : html` + + `; + } + static styles = [ css` :host { @@ -144,83 +221,6 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { } `, ]; - - /** - * Reflects the disabled state of the element. True if tab is disabled. Change this to switch the state programmatically. - * @type {boolean} - * @attr - * @default false - */ - @property({ type: Boolean, reflect: true }) - public disabled = false; - - /** - * Set an href, this will turns the inner button into a anchor tag. - * @type {string} - * @attr - * @default undefined - */ - @property({ type: String }) - public href?: string; - - /** - * Set an anchor tag target, only used when using href. - * @type {string} - * @attr - * @default undefined - */ - @property({ type: String }) - public target?: '_blank' | '_parent' | '_self' | '_top'; - - /** - * Set the location of the active bar. - * @type {string} - * @attr - * @default bottom - */ - @property({ type: String, reflect: true, attribute: 'active-bar-location' }) - public activeBarLocation?: 'top' | 'bottom' | 'left' | 'right' = 'bottom'; - - constructor() { - super(); - this.addEventListener('click', this.onHostClick); - } - - private onHostClick(e: MouseEvent) { - if (this.disabled) { - e.preventDefault(); - e.stopImmediatePropagation(); - } - } - - render() { - return this.href - ? html` - - - ${this.renderLabel()} - - - ` - : html` - - `; - } } declare global { From 52cdb4e1e4177104a602b7a3b98ad07ad0a7fa2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:38:58 +1200 Subject: [PATCH 28/41] css var for tab text alignment --- packages/uui-tabs/lib/uui-tab-group.element.ts | 13 ++++++++----- packages/uui-tabs/lib/uui-tab.element.ts | 10 +++++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 8c3f89ce5..6fbffec0a 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -43,7 +43,7 @@ export class UUITabGroupElement extends LitElement { @property({ type: String, reflect: true, - attribute: 'dropdown-direction', + attribute: 'dropdown-content-direction', }) priorityNavigationDropdownContentDirection: 'vertical' | 'horizontal' = 'vertical'; @@ -54,7 +54,11 @@ export class UUITabGroupElement extends LitElement { * @attr * @default bottom */ - @property({ type: String, reflect: true, attribute: 'active-bar-location' }) + @property({ + type: String, + reflect: true, + attribute: 'dropdown-active-bar-location', + }) public priorityNavigationDropdownActiveBarLocation?: | 'top' | 'bottom' @@ -191,9 +195,7 @@ export class UUITabGroupElement extends LitElement { proxyTab.classList.add('hidden-tab'); proxyTab.style.display = ''; proxyTab.activeBarLocation = - this.priorityNavigationDropdownContentDirection === 'vertical' - ? 'left' - : 'bottom'; + this.priorityNavigationDropdownActiveBarLocation; // Link the proxy tab to the original tab this.#hiddenTabElementsMap.set(proxyTab, tab); @@ -286,6 +288,7 @@ export class UUITabGroupElement extends LitElement { background: var(--uui-color-surface); border-radius: var(--uui-border-radius); box-shadow: var(--uui-shadow-depth-3); + --uui-tab-text-align: left; } :host([dropdown-direction='horizontal']) #hidden-tabs-container { flex-direction: row; diff --git a/packages/uui-tabs/lib/uui-tab.element.ts b/packages/uui-tabs/lib/uui-tab.element.ts index 2d0426d38..07ea4ec02 100644 --- a/packages/uui-tabs/lib/uui-tab.element.ts +++ b/packages/uui-tabs/lib/uui-tab.element.ts @@ -18,6 +18,7 @@ import { ifDefined } from 'lit/directives/if-defined.js'; * @cssprop --uui-tab-divider - Define the tab dividers color * @cssprop --uui-tab-padding-horizontal - Define the tab horizontal padding * @cssprop --uui-tab-divider - Define the tab dividers color + * @cssprop --uui-tab-text-align - Define the tab text align */ @defineElement('uui-tab') export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { @@ -113,7 +114,6 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { flex-direction: column; align-items: center; justify-content: center; - text-align: center; padding: var(--uui-size-2) var(--uui-tab-padding-horizontal, var(--uui-size-4)); border: none; @@ -219,6 +219,14 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { font-size: 20px; margin-bottom: var(--uui-size-2); } + + slot.label { + /* TODO: Find a better selector */ + text-align: var(--uui-tab-text-align, center); + display: flex; + width: 100%; + flex-direction: column; + } `, ]; } From f41a4e7c261ab0023179bc0b1fc8dcefc1ff202d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:41:56 +1200 Subject: [PATCH 29/41] change default active bar placement --- packages/uui-tabs/lib/uui-tab-group.element.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 6fbffec0a..a958e85c4 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -52,7 +52,7 @@ export class UUITabGroupElement extends LitElement { * Set the location of the active bar in the dropdown. * @type {string} * @attr - * @default bottom + * @default left */ @property({ type: String, @@ -63,7 +63,7 @@ export class UUITabGroupElement extends LitElement { | 'top' | 'bottom' | 'left' - | 'right' = 'bottom'; + | 'right' = 'left'; private _tabElements: HTMLElement[] = []; From 32d367a5220d2fb5750f187d00b733e00aec145e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:47:48 +1200 Subject: [PATCH 30/41] update story --- packages/uui-tabs/lib/uui-tabs.story.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tabs.story.ts b/packages/uui-tabs/lib/uui-tabs.story.ts index 1cf20af90..76ac2d431 100644 --- a/packages/uui-tabs/lib/uui-tabs.story.ts +++ b/packages/uui-tabs/lib/uui-tabs.story.ts @@ -66,9 +66,12 @@ export const WithBorders: Story = () => html` --uui-tab-divider: var(--uui-color-divider-standalone); "> - Content - Packages - Media + Content + Packages + Media + Settings + Translations + Users
`; @@ -85,9 +88,12 @@ export const Navbar: Story = () => html` --uui-tab-background: var(--uui-color-default); "> - Content - Packages - Media + Content + Packages + Media + Settings + Translations + Users `; From c34a49f4d31c1cc70bf3262d814610238a2ab127 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:48:39 +1200 Subject: [PATCH 31/41] cleanup --- packages/uui-tabs/lib/uui-tab.element.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab.element.ts b/packages/uui-tabs/lib/uui-tab.element.ts index 07ea4ec02..702b8f2a2 100644 --- a/packages/uui-tabs/lib/uui-tab.element.ts +++ b/packages/uui-tabs/lib/uui-tab.element.ts @@ -16,8 +16,8 @@ import { ifDefined } from 'lit/directives/if-defined.js'; * @cssprop --uui-tab-text-active - Define the tab text active color * @cssprop --uui-tab-background - Define the tab group background color * @cssprop --uui-tab-divider - Define the tab dividers color - * @cssprop --uui-tab-padding-horizontal - Define the tab horizontal padding * @cssprop --uui-tab-divider - Define the tab dividers color + * @cssprop --uui-tab-padding-horizontal - Define the tab horizontal padding * @cssprop --uui-tab-text-align - Define the tab text align */ @defineElement('uui-tab') From 326b9371169db46110b6d24ac3a1d86d012647f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:55:18 +1200 Subject: [PATCH 32/41] move styles back to the top for a cleaner PR --- packages/uui-tabs/lib/uui-tab.element.ts | 154 +++++++++++------------ 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab.element.ts b/packages/uui-tabs/lib/uui-tab.element.ts index 702b8f2a2..ddd9077db 100644 --- a/packages/uui-tabs/lib/uui-tab.element.ts +++ b/packages/uui-tabs/lib/uui-tab.element.ts @@ -22,83 +22,6 @@ import { ifDefined } from 'lit/directives/if-defined.js'; */ @defineElement('uui-tab') export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { - /** - * Reflects the disabled state of the element. True if tab is disabled. Change this to switch the state programmatically. - * @type {boolean} - * @attr - * @default false - */ - @property({ type: Boolean, reflect: true }) - public disabled = false; - - /** - * Set an href, this will turns the inner button into a anchor tag. - * @type {string} - * @attr - * @default undefined - */ - @property({ type: String }) - public href?: string; - - /** - * Set an anchor tag target, only used when using href. - * @type {string} - * @attr - * @default undefined - */ - @property({ type: String }) - public target?: '_blank' | '_parent' | '_self' | '_top'; - - /** - * Set the location of the active bar. - * @type {string} - * @attr - * @default bottom - */ - @property({ type: String, reflect: true, attribute: 'active-bar-location' }) - public activeBarLocation?: 'top' | 'bottom' | 'left' | 'right' = 'bottom'; - - constructor() { - super(); - this.addEventListener('click', this.onHostClick); - } - - private onHostClick(e: MouseEvent) { - if (this.disabled) { - e.preventDefault(); - e.stopImmediatePropagation(); - } - } - - render() { - return this.href - ? html` - - - ${this.renderLabel()} - - - ` - : html` - - `; - } - static styles = [ css` :host { @@ -229,6 +152,83 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { } `, ]; + + /** + * Reflects the disabled state of the element. True if tab is disabled. Change this to switch the state programmatically. + * @type {boolean} + * @attr + * @default false + */ + @property({ type: Boolean, reflect: true }) + public disabled = false; + + /** + * Set an href, this will turns the inner button into a anchor tag. + * @type {string} + * @attr + * @default undefined + */ + @property({ type: String }) + public href?: string; + + /** + * Set an anchor tag target, only used when using href. + * @type {string} + * @attr + * @default undefined + */ + @property({ type: String }) + public target?: '_blank' | '_parent' | '_self' | '_top'; + + /** + * Set the location of the active bar. + * @type {string} + * @attr + * @default bottom + */ + @property({ type: String, reflect: true, attribute: 'active-bar-location' }) + public activeBarLocation?: 'top' | 'bottom' | 'left' | 'right' = 'bottom'; + + constructor() { + super(); + this.addEventListener('click', this.onHostClick); + } + + private onHostClick(e: MouseEvent) { + if (this.disabled) { + e.preventDefault(); + e.stopImmediatePropagation(); + } + } + + render() { + return this.href + ? html` + + + ${this.renderLabel()} + + + ` + : html` + + `; + } } declare global { From e3062d562d12cc19e187635d12366076238153f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:00:52 +1200 Subject: [PATCH 33/41] cleanup --- packages/uui-tabs/lib/uui-tab-group.element.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index a958e85c4..3d280145f 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -65,7 +65,7 @@ export class UUITabGroupElement extends LitElement { | 'left' | 'right' = 'left'; - private _tabElements: HTMLElement[] = []; + #tabElements: HTMLElement[] = []; #hiddenTabElements: UUITabElement[] = []; #hiddenTabElementsMap: Map = new Map(); @@ -93,13 +93,13 @@ export class UUITabGroupElement extends LitElement { } #onSlotChange() { - this._tabElements.forEach(el => { + this.#tabElements.forEach(el => { el.removeEventListener('click', this.#onTabClicked); }); this.#setTabArray(); - this._tabElements.forEach(el => { + this.#tabElements.forEach(el => { el.addEventListener('click', this.#onTabClicked); }); } @@ -115,7 +115,7 @@ export class UUITabGroupElement extends LitElement { } const filtered = [ - ...this._tabElements, + ...this.#tabElements, ...this.#hiddenTabElements, ].filter(el => el !== selectedElement && el !== proxy); @@ -178,7 +178,7 @@ export class UUITabGroupElement extends LitElement { for (let i = 0; i < this.#visibilityBreakpoints.length; i++) { const breakpoint = this.#visibilityBreakpoints[i]; - const tab = this._tabElements[i] as UUITabElement; + const tab = this.#tabElements[i] as UUITabElement; // Subtract the button width when we are not at the last breakpoint const containerWidthButtonWidth = @@ -222,8 +222,8 @@ export class UUITabGroupElement extends LitElement { // Whenever a tab is added or removed, we need to recalculate the breakpoints let childrenWidth = 0; - for (let i = 0; i < this._tabElements.length; i++) { - childrenWidth += this._tabElements[i].offsetWidth; + for (let i = 0; i < this.#tabElements.length; i++) { + childrenWidth += this.#tabElements[i].offsetWidth; this.#visibilityBreakpoints[i] = childrenWidth; } @@ -231,7 +231,7 @@ export class UUITabGroupElement extends LitElement { } #setTabArray() { - this._tabElements = this._slottedNodes ? this._slottedNodes : []; + this.#tabElements = this._slottedNodes ? this._slottedNodes : []; this.#calculateBreakPoints(); } From fed1228621283776019eaebd9b24e2b971a41f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:01:49 +1200 Subject: [PATCH 34/41] move styles back to the top for a cleaner PR --- .../uui-tabs/lib/uui-tab-group.element.ts | 110 +++++++++--------- 1 file changed, 55 insertions(+), 55 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 3d280145f..e928fc66a 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -16,6 +16,61 @@ import { UUITabElement } from './uui-tab.element'; */ @defineElement('uui-tab-group') export class UUITabGroupElement extends LitElement { + static styles = [ + css` + :host { + display: flex; + flex-wrap: wrap; + color: var(--uui-tab-text); + background: var(--uui-tab-background, none); + height: 100%; + min-height: 48px; + } + + ::slotted(*:not(:last-of-type)) { + border-right: 1px solid var(--uui-tab-divider, none); + } + + .hidden-tab { + width: 100%; + } + + #hidden-tabs-container { + width: fit-content; + display: flex; + flex-direction: column; + background: var(--uui-color-surface); + border-radius: var(--uui-border-radius); + box-shadow: var(--uui-shadow-depth-3); + --uui-tab-text-align: left; + } + :host([dropdown-direction='horizontal']) #hidden-tabs-container { + flex-direction: row; + } + + #more-button { + margin-left: auto; + position: relative; + } + #more-button::before { + content: ''; + position: absolute; + bottom: 0; + width: 100%; + background-color: var(--uui-color-current); + height: 0px; + border-radius: 3px 3px 0 0; + opacity: 0; + transition: opacity ease-in 120ms, height ease-in 120ms; + } + #more-button.active-inside::before { + opacity: 1; + height: 4px; + transition: opacity 120ms, height ease-out 120ms; + } + `, + ]; + @query('#more-button') private _moreButtonElement!: UUIButtonElement; @@ -261,61 +316,6 @@ export class UUITabGroupElement extends LitElement {
`; } - - static styles = [ - css` - :host { - display: flex; - flex-wrap: wrap; - color: var(--uui-tab-text); - background: var(--uui-tab-background, none); - height: 100%; - min-height: 48px; - } - - ::slotted(*:not(:last-of-type)) { - border-right: 1px solid var(--uui-tab-divider, none); - } - - .hidden-tab { - width: 100%; - } - - #hidden-tabs-container { - width: fit-content; - display: flex; - flex-direction: column; - background: var(--uui-color-surface); - border-radius: var(--uui-border-radius); - box-shadow: var(--uui-shadow-depth-3); - --uui-tab-text-align: left; - } - :host([dropdown-direction='horizontal']) #hidden-tabs-container { - flex-direction: row; - } - - #more-button { - margin-left: auto; - position: relative; - } - #more-button::before { - content: ''; - position: absolute; - bottom: 0; - width: 100%; - background-color: var(--uui-color-current); - height: 0px; - border-radius: 3px 3px 0 0; - opacity: 0; - transition: opacity ease-in 120ms, height ease-in 120ms; - } - #more-button.active-inside::before { - opacity: 1; - height: 4px; - transition: opacity 120ms, height ease-out 120ms; - } - `, - ]; } declare global { From 8a5489104c8711e03e9f1d8ab7fc16aafab42ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:04:25 +1200 Subject: [PATCH 35/41] cleanup --- packages/uui-tabs/lib/uui-tab-group.element.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index e928fc66a..a965dc7cf 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -163,16 +163,17 @@ export class UUITabGroupElement extends LitElement { const selectedElement = e.currentTarget as HTMLElement; if (this.#isElementTabLike(selectedElement)) { selectedElement.active = true; - const proxy = this.#hiddenTabElementsMap.get(selectedElement); + const linkedElement = this.#hiddenTabElementsMap.get(selectedElement); - if (proxy) { - proxy.active = true; + if (linkedElement) { + linkedElement.active = true; } + // Reset all other tabs const filtered = [ ...this.#tabElements, ...this.#hiddenTabElements, - ].filter(el => el !== selectedElement && el !== proxy); + ].filter(el => el !== selectedElement && el !== linkedElement); filtered.forEach(el => { if (this.#isElementTabLike(el)) { @@ -180,8 +181,9 @@ export class UUITabGroupElement extends LitElement { } }); + // Check if there are any active tabs in the dropdown const hasActiveHidden = this.#hiddenTabElements.some( - el => el.active && el !== proxy + el => el.active && el !== linkedElement ); hasActiveHidden From aaccab393083963939420c61a79c89456f6b18dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:05:09 +1200 Subject: [PATCH 36/41] cleanup --- packages/uui-tabs/lib/uui-tab-group.element.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index a965dc7cf..8b986b1ac 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -193,7 +193,6 @@ export class UUITabGroupElement extends LitElement { }; #updateCollapsibleTabs(containerWidth: number) { - containerWidth = containerWidth; const buttonWidth = this._moreButtonElement.offsetWidth; // Only update if the container is smaller than the last breakpoint From a785350e448fa32cd4fd312cf9723a3602729d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 18 Sep 2023 16:21:14 +1200 Subject: [PATCH 37/41] cleanup --- packages/uui-tabs/lib/uui-tab-group.element.ts | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 8b986b1ac..e78782056 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -100,8 +100,7 @@ export class UUITabGroupElement extends LitElement { reflect: true, attribute: 'dropdown-content-direction', }) - priorityNavigationDropdownContentDirection: 'vertical' | 'horizontal' = - 'vertical'; + dropdownContentDirection: 'vertical' | 'horizontal' = 'vertical'; /** * Set the location of the active bar in the dropdown. @@ -114,11 +113,8 @@ export class UUITabGroupElement extends LitElement { reflect: true, attribute: 'dropdown-active-bar-location', }) - public priorityNavigationDropdownActiveBarLocation?: - | 'top' - | 'bottom' - | 'left' - | 'right' = 'left'; + public dropdownActiveBarLocation?: 'top' | 'bottom' | 'left' | 'right' = + 'left'; #tabElements: HTMLElement[] = []; @@ -219,7 +215,6 @@ export class UUITabGroupElement extends LitElement { } if (newBreakpoint === this.#oldBreakpoint) return; - console.log(newBreakpoint, this.#oldBreakpoint); this.#oldBreakpoint = newBreakpoint; // Do the update @@ -250,8 +245,7 @@ export class UUITabGroupElement extends LitElement { proxyTab.addEventListener('click', this.#onTabClicked); proxyTab.classList.add('hidden-tab'); proxyTab.style.display = ''; - proxyTab.activeBarLocation = - this.priorityNavigationDropdownActiveBarLocation; + proxyTab.activeBarLocation = this.dropdownActiveBarLocation; // Link the proxy tab to the original tab this.#hiddenTabElementsMap.set(proxyTab, tab); From 761c35c598d1452535b3e426d94177e5c04ca185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20M=C3=B8ller=20Jensen?= <26099018+JesmoDev@users.noreply.github.com> Date: Mon, 18 Sep 2023 18:45:39 +1200 Subject: [PATCH 38/41] remove priority navigation property --- packages/uui-tabs/lib/uui-tab-group.element.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index e78782056..0a9e0da54 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -80,15 +80,6 @@ export class UUITabGroupElement extends LitElement { }) private _slottedNodes?: HTMLElement[]; - /** - * Toggles the priority navigation mode, which will collapse tabs into a dropdown when there is not enough space. - * @type {boolean} - * @attr - * @default false - */ - @property({ type: Boolean, reflect: true, attribute: 'priority-navigation' }) - priorityNavigation = false; - /** * Set the flex direction of the content of the dropdown. * @type {string} From d7f1f2b62e813c055afa43b5717402692c1458ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 18 Sep 2023 10:46:39 +0200 Subject: [PATCH 39/41] vertical orientation --- .vscode/settings.json | 2 +- .../uui-tabs/lib/uui-tab-group.element.ts | 17 +---- packages/uui-tabs/lib/uui-tab.element.ts | 68 ++++++++----------- packages/uui-tabs/lib/uui-tabs.story.ts | 16 +++++ 4 files changed, 48 insertions(+), 55 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c8e5335b5..dcaaedc1b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "cSpell.words": ["combobox", "Umbraco"] + "cSpell.words": ["combobox", "cssprop", "noopener", "noreferrer", "Umbraco"] } diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index 0a9e0da54..ba624aa88 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -42,7 +42,6 @@ export class UUITabGroupElement extends LitElement { background: var(--uui-color-surface); border-radius: var(--uui-border-radius); box-shadow: var(--uui-shadow-depth-3); - --uui-tab-text-align: left; } :host([dropdown-direction='horizontal']) #hidden-tabs-container { flex-direction: row; @@ -93,20 +92,6 @@ export class UUITabGroupElement extends LitElement { }) dropdownContentDirection: 'vertical' | 'horizontal' = 'vertical'; - /** - * Set the location of the active bar in the dropdown. - * @type {string} - * @attr - * @default left - */ - @property({ - type: String, - reflect: true, - attribute: 'dropdown-active-bar-location', - }) - public dropdownActiveBarLocation?: 'top' | 'bottom' | 'left' | 'right' = - 'left'; - #tabElements: HTMLElement[] = []; #hiddenTabElements: UUITabElement[] = []; @@ -236,7 +221,7 @@ export class UUITabGroupElement extends LitElement { proxyTab.addEventListener('click', this.#onTabClicked); proxyTab.classList.add('hidden-tab'); proxyTab.style.display = ''; - proxyTab.activeBarLocation = this.dropdownActiveBarLocation; + proxyTab.orientation = this.dropdownContentDirection; // Link the proxy tab to the original tab this.#hiddenTabElementsMap.set(proxyTab, tab); diff --git a/packages/uui-tabs/lib/uui-tab.element.ts b/packages/uui-tabs/lib/uui-tab.element.ts index ddd9077db..4f8ff187d 100644 --- a/packages/uui-tabs/lib/uui-tab.element.ts +++ b/packages/uui-tabs/lib/uui-tab.element.ts @@ -16,9 +16,7 @@ import { ifDefined } from 'lit/directives/if-defined.js'; * @cssprop --uui-tab-text-active - Define the tab text active color * @cssprop --uui-tab-background - Define the tab group background color * @cssprop --uui-tab-divider - Define the tab dividers color - * @cssprop --uui-tab-divider - Define the tab dividers color * @cssprop --uui-tab-padding-horizontal - Define the tab horizontal padding - * @cssprop --uui-tab-text-align - Define the tab text align */ @defineElement('uui-tab') export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { @@ -32,19 +30,19 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { #button { position: relative; + box-sizing: border-box; display: flex; - width: 100%; flex-direction: column; align-items: center; justify-content: center; + width: 100%; + height: 100%; + min-height: var(--uui-size-12); + min-width: 70px; padding: var(--uui-size-2) var(--uui-tab-padding-horizontal, var(--uui-size-4)); border: none; - box-sizing: border-box; - min-height: 32px; font-size: inherit; - height: 100%; - min-width: 70px; background: none; color: inherit; cursor: pointer; @@ -55,6 +53,12 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { line-height: normal; } + :host([orientation='vertical']) #button { + min-height: var(--uui-size-14); + padding: var(--uui-size-2) + var(--uui-tab-padding-horizontal, var(--uui-size-5)); + } + :host(:not([active]):not([disabled])) #button:hover { color: var(--uui-tab-text-hover, var(--uui-color-default-emphasis)); } @@ -85,51 +89,35 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { opacity: 1; } - /* TOP AND BOTTOM */ - :host([active-bar-location='bottom']) #button::before, - :host([active-bar-location='top']) #button::before { + /* HORIZONTAL */ + :host([orientation='horizontal']) #button::before { left: auto; right: auto; border-radius: var(--borderRadius) var(--borderRadius) 0 0; height: 0px; - width: calc(100% - 16px); + width: calc(100% - 15px); + bottom: 0; transition: opacity ease-in-out var(--transitionDuration), height ease-in-out var(--transitionDuration); } - :host([active][active-bar-location='bottom']) #button::before, - :host([active][active-bar-location='top']) #button::before { + :host([active][orientation='horizontal']) #button::before { height: var(--barWidth); } - :host([active-bar-location='bottom']) #button::before { - bottom: 0; - } - :host([active-bar-location='top']) #button::before { - top: 0; - transform: rotateZ(180deg); - } - /* LEFT AND RIGHT */ - :host([active-bar-location='left']) #button::before, - :host([active-bar-location='right']) #button::before { + /* VERTICAL */ + :host([orientation='vertical']) #button::before { top: auto; bottom: auto; border-radius: 0 var(--borderRadius) var(--borderRadius) 0; - height: calc(100% - 16px); + height: calc(100% - 12px); width: 0px; + left: 0; transition: opacity ease-in-out var(--transitionDuration), width ease-in-out var(--transitionDuration); } - :host([active][active-bar-location='left']) #button::before, - :host([active][active-bar-location='right']) #button::before { + :host([active][orientation='vertical']) #button::before { width: var(--barWidth); } - :host([active-bar-location='left']) #button::before { - left: 0; - } - :host([active-bar-location='right']) #button::before { - right: 0; - transform: rotateZ(180deg); - } #button:hover::before { background-color: var(--uui-color-current-emphasis); @@ -145,11 +133,15 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { slot.label { /* TODO: Find a better selector */ - text-align: var(--uui-tab-text-align, center); + text-align: center; display: flex; width: 100%; flex-direction: column; } + + :host([orientation='vertical']) slot.label { + text-align: left; + } `, ]; @@ -181,13 +173,13 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) { public target?: '_blank' | '_parent' | '_self' | '_top'; /** - * Set the location of the active bar. + * Set the visual orientation of this tab, this changes the look and placement of the active indication. * @type {string} * @attr - * @default bottom + * @default horizontal */ - @property({ type: String, reflect: true, attribute: 'active-bar-location' }) - public activeBarLocation?: 'top' | 'bottom' | 'left' | 'right' = 'bottom'; + @property({ type: String, reflect: true }) + public orientation?: 'horizontal' | 'vertical' = 'horizontal'; constructor() { super(); diff --git a/packages/uui-tabs/lib/uui-tabs.story.ts b/packages/uui-tabs/lib/uui-tabs.story.ts index 76ac2d431..d163fa4c2 100644 --- a/packages/uui-tabs/lib/uui-tabs.story.ts +++ b/packages/uui-tabs/lib/uui-tabs.story.ts @@ -76,6 +76,22 @@ export const WithBorders: Story = () => html` `; +export const VerticalOrientation: Story = () => html` +

Vertical Orientation

+
+
+ Content + Packages + Media + Settings + + Translations + + Users +
+
+`; + export const Navbar: Story = () => html`

Navbar

Date: Mon, 18 Sep 2023 10:49:48 +0200 Subject: [PATCH 40/41] overflow: hidden; --- packages/uui-tabs/lib/uui-tab-group.element.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/uui-tabs/lib/uui-tab-group.element.ts b/packages/uui-tabs/lib/uui-tab-group.element.ts index ba624aa88..cde096957 100644 --- a/packages/uui-tabs/lib/uui-tab-group.element.ts +++ b/packages/uui-tabs/lib/uui-tab-group.element.ts @@ -42,6 +42,7 @@ export class UUITabGroupElement extends LitElement { background: var(--uui-color-surface); border-radius: var(--uui-border-radius); box-shadow: var(--uui-shadow-depth-3); + overflow: hidden; } :host([dropdown-direction='horizontal']) #hidden-tabs-container { flex-direction: row; From 4e347ce77bcea6b339e377d36aab134fac342ccb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Mon, 18 Sep 2023 10:56:28 +0200 Subject: [PATCH 41/41] remove story --- packages/uui-tabs/lib/uui-tabs.story.ts | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/packages/uui-tabs/lib/uui-tabs.story.ts b/packages/uui-tabs/lib/uui-tabs.story.ts index d163fa4c2..76ac2d431 100644 --- a/packages/uui-tabs/lib/uui-tabs.story.ts +++ b/packages/uui-tabs/lib/uui-tabs.story.ts @@ -76,22 +76,6 @@ export const WithBorders: Story = () => html`
`; -export const VerticalOrientation: Story = () => html` -

Vertical Orientation

-
-
- Content - Packages - Media - Settings - - Translations - - Users -
-
-`; - export const Navbar: Story = () => html`

Navbar