Skip to content

Bugfix/tab group #677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
Dec 1, 2023
Merged
76 changes: 46 additions & 30 deletions packages/uui-tabs/lib/uui-tab-group.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,24 @@ import '@umbraco-ui/uui-popover-container/lib';
import '@umbraco-ui/uui-symbol-more/lib';

import { UUITabElement } from './uui-tab.element';
import { UUIPopoverContainerElement } from '@umbraco-ui/uui-popover-container/lib';

/**
* @element uui-tab-group
* @slot - Default slot for the tab group
* @cssprop --uui-tab-group-dropdown-tab-text - Define the tab text color in the dropdown
* @cssprop --uui-tab-group-dropdown-tab-text-hover - Define the tab text hover color in the dropdown
* @cssprop --uui-tab-group-dropdown-tab-text-active - Define the tab text active color in the dropdown
* @cssprop --uui-tab-group-dropdown-background - Define the background color of the dropdown
*/
@defineElement('uui-tab-group')
export class UUITabGroupElement extends LitElement {
@query('#more-button')
private _moreButtonElement!: UUIButtonElement;

@query('#popover-container')
private _popoverContainerElement!: UUIPopoverContainerElement;

@queryAssignedElements({
flatten: true,
selector: 'uui-tab, [uui-tab], [role=tab]',
Expand All @@ -44,7 +52,6 @@ export class UUITabGroupElement extends LitElement {
#hiddenTabElementsMap: Map<UUITabElement, UUITabElement> = new Map();

#visibilityBreakpoints: number[] = [];
#oldBreakpoint = 0;

#resizeObserver: ResizeObserver = new ResizeObserver(
this.#onResize.bind(this)
Expand Down Expand Up @@ -114,31 +121,10 @@ export class UUITabGroupElement extends LitElement {
const buttonWidth = this._moreButtonElement.offsetWidth;

// Only update if the container is smaller than the last breakpoint
if (
this.#visibilityBreakpoints.slice(-1)[0] < containerWidth &&
this.#hiddenTabElements.length === 0
)
const lastBreakpoint = this.#visibilityBreakpoints.slice(-1)[0];
if (lastBreakpoint < 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;
this.#oldBreakpoint = newBreakpoint;

// Do the update
// Reset the hidden tabs
this.#hiddenTabElements.forEach(el => {
Expand Down Expand Up @@ -183,22 +169,33 @@ export class UUITabGroupElement extends LitElement {
}
}

if (this.#hiddenTabElements.length === 0) {
// close the popover
this._popoverContainerElement.hidePopover();
}

hasActiveTabInDropdown
? this._moreButtonElement.classList.add('active-inside')
: this._moreButtonElement.classList.remove('active-inside');

this.requestUpdate();
}

#calculateBreakPoints() {
async #calculateBreakPoints() {
// Whenever a tab is added or removed, we need to recalculate the breakpoints

await this.updateComplete; // Wait for the tabs to be rendered
let childrenWidth = 0;

for (let i = 0; i < this.#tabElements.length; i++) {
this.#tabElements[i].style.display = '';
childrenWidth += this.#tabElements[i].offsetWidth;
this.#visibilityBreakpoints[i] = childrenWidth;
}

const tolerance = 2;
this.style.width = childrenWidth + tolerance + 'px';

this.#updateCollapsibleTabs(this.offsetWidth);
}

Expand All @@ -225,7 +222,6 @@ export class UUITabGroupElement extends LitElement {
<uui-popover-container
id="popover-container"
popover
margin="10"
placement="bottom-end">
<div id="hidden-tabs-container">
${repeat(this.#hiddenTabElements, el => html`${el}`)}
Expand All @@ -238,11 +234,24 @@ export class UUITabGroupElement extends LitElement {
css`
:host {
display: flex;
flex-wrap: wrap;
flex-wrap: nowrap;
color: var(--uui-tab-text);
background: var(--uui-tab-background, none);
height: 100%;
min-height: 48px;
overflow: hidden;
text-wrap: nowrap;
}

#popover-container {
--uui-tab-text: var(--uui-tab-group-dropdown-tab-text, unset);
--uui-tab-text-hover: var(
--uui-tab-group-dropdown-tab-text-hover,
unset
);
--uui-tab-text-active: var(
--uui-tab-group-dropdown-tab-text-active,
unset
);
}

::slotted(*:not(:last-of-type)) {
Expand All @@ -257,7 +266,10 @@ export class UUITabGroupElement extends LitElement {
width: fit-content;
display: flex;
flex-direction: column;
background: var(--uui-color-surface);
background-color: var(
--uui-tab-group-dropdown-background,
var(--uui-color-surface)
);
border-radius: var(--uui-border-radius);
box-shadow: var(--uui-shadow-depth-3);
overflow: hidden;
Expand All @@ -267,8 +279,12 @@ export class UUITabGroupElement extends LitElement {
}

#more-button {
margin-left: auto;
position: relative;

--uui-button-contrast: var(--uui-tab-text);
--uui-button-contrast-hover: var(--uui-tab-text-hover);
--uui-button-background-color: transparent;
--uui-button-background-color-hover: transparent;
}
#more-button::before {
content: '';
Expand Down
5 changes: 4 additions & 1 deletion packages/uui-tabs/lib/uui-tab.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { ifDefined } from 'lit/directives/if-defined.js';
* @cssprop --uui-tab-text - Define the tab text color
* @cssprop --uui-tab-text-hover - Define the tab text hover color
* @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
*/
Expand Down Expand Up @@ -145,6 +144,10 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) {
0 1px 2px rgba(0, 0, 0, 0.05);
}

:host([active]) {
color: var(--uui-tab-text-active, unset);
}

:host([active]) #button {
cursor: default;
}
Expand Down
79 changes: 37 additions & 42 deletions packages/uui-tabs/lib/uui-tabs.story.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,24 @@ export default {
};

export const AAAOverview: Story = props => html`
<uui-tab-group
style="
<div style="display: flex;">
<uui-tab-group
style="
height: 60px;
--uui-tab-text: ${props['--uui-tab-text']};
--uui-tab-text-hover: ${props['--uui-tab-text-hover']};
--uui-tab-text-active: ${props['--uui-tab-text-active']};
--uui-tab-background: ${props['--uui-tab-background']};
--uui-tab-divider: ${props['--uui-tab-divider']};
${props.inlineStyles}">
<uui-tab label="content" active> Content </uui-tab>
<uui-tab label="Packages" ?disabled=${props.disabled}> Packages </uui-tab>
<uui-tab label="Media"> Media </uui-tab>
<uui-tab label="Settings"> Settings </uui-tab>
<uui-tab label="Translations"> Translations </uui-tab>
<uui-tab label="Users"> Users </uui-tab>
</uui-tab-group>
<uui-tab label="content" active> Content </uui-tab>
<uui-tab label="Packages" ?disabled=${props.disabled}> Packages </uui-tab>
<uui-tab label="Media"> Media </uui-tab>
<uui-tab label="Settings"> Settings </uui-tab>
<uui-tab label="Translations"> Translations </uui-tab>
<uui-tab label="Users"> Users </uui-tab>
</uui-tab-group>
</div>
`;
AAAOverview.storyName = 'Overview';

Expand All @@ -59,13 +61,10 @@ export const WithBorders: Story = () => html`
<div
style="
height: 48px;
--uui-tab-text: var(--uui-color-default);
--uui-tab-text-hover: var(--uui-color-default-emphasis);
--uui-tab-text-active: var(--uui-color-default-emphasis);
--uui-tab-background: none;
display: flex;
--uui-tab-divider: var(--uui-color-divider-standalone);
">
<uui-tab-group>
<uui-tab-group style="display: flex;">
<uui-tab label="content"> Content </uui-tab>
<uui-tab label="Packages"> Packages </uui-tab>
<uui-tab label="Media" active> Media </uui-tab>
Expand All @@ -80,14 +79,11 @@ export const Navbar: Story = () => html`
<h3>Navbar</h3>
<div
style="
display: flex;
height: 60px;
font-size: 16px;
--uui-tab-text: var(--uui-color-surface-alt);
--uui-tab-text-hover: var(--uui-color-surface);
--uui-tab-text-active: var(--uui-color-current);
--uui-tab-background: var(--uui-color-default);
">
<uui-tab-group>
<uui-tab-group style="display: flex;">
<uui-tab label="content"> Content </uui-tab>
<uui-tab label="Packages" active> Packages </uui-tab>
<uui-tab label="Media"> Media </uui-tab>
Expand All @@ -102,12 +98,9 @@ export const UsingHref: Story = () => html`
<h3>Href links</h3>
<div
style="
display: flex;
height: 60px;
font-size: 16px;
--uui-tab-text: var(--uui-color-surface-alt);
--uui-tab-text-hover: var(--uui-color-surface);
--uui-tab-text-active: var(--uui-color-current);
--uui-tab-background: var(--uui-color-default);
">
<uui-tab-group>
<uui-tab label="content" href="http://www.umbraco.com/#content">
Expand Down Expand Up @@ -135,25 +128,27 @@ export const UsingHref: Story = () => html`
export const WithIcons: Story = props => html`
<h3>Tabs with Icons</h3>
<uui-icon-registry-essential>
<uui-tab-group
dropdown-direction="horizontal"
style="
height: 70px;
font-size: 12px;
${props.inlineStyles}">
<uui-tab>
<uui-icon slot="icon" name="document"></uui-icon>
Content
</uui-tab>
<uui-tab active>
<uui-icon slot="icon" name="settings"></uui-icon>
Packages
</uui-tab>
<uui-tab>
<uui-icon slot="icon" name="picture"></uui-icon>
Media
</uui-tab>
</uui-tab-group>
<div style="display: flex;">
<uui-tab-group
dropdown-direction="horizontal"
style="
height: 70px;
font-size: 12px;
${props.inlineStyles}">
<uui-tab>
<uui-icon slot="icon" name="document"></uui-icon>
Content
</uui-tab>
<uui-tab active>
<uui-icon slot="icon" name="settings"></uui-icon>
Packages
</uui-tab>
<uui-tab>
<uui-icon slot="icon" name="picture"></uui-icon>
Media
</uui-tab>
</uui-tab-group>
</div>
</uui-icon-registry-essential>
`;
WithIcons.parameters = {
Expand Down