+
${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);
">