Skip to content

Commit cb0414e

Browse files
authored
fix: tab group styling of dropdown (#677)
1 parent b3df44b commit cb0414e

File tree

3 files changed

+87
-73
lines changed

3 files changed

+87
-73
lines changed

packages/uui-tabs/lib/uui-tab-group.element.ts

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,24 @@ import '@umbraco-ui/uui-popover-container/lib';
99
import '@umbraco-ui/uui-symbol-more/lib';
1010

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

1314
/**
1415
* @element uui-tab-group
1516
* @slot - Default slot for the tab group
17+
* @cssprop --uui-tab-group-dropdown-tab-text - Define the tab text color in the dropdown
18+
* @cssprop --uui-tab-group-dropdown-tab-text-hover - Define the tab text hover color in the dropdown
19+
* @cssprop --uui-tab-group-dropdown-tab-text-active - Define the tab text active color in the dropdown
20+
* @cssprop --uui-tab-group-dropdown-background - Define the background color of the dropdown
1621
*/
1722
@defineElement('uui-tab-group')
1823
export class UUITabGroupElement extends LitElement {
1924
@query('#more-button')
2025
private _moreButtonElement!: UUIButtonElement;
2126

27+
@query('#popover-container')
28+
private _popoverContainerElement!: UUIPopoverContainerElement;
29+
2230
@queryAssignedElements({
2331
flatten: true,
2432
selector: 'uui-tab, [uui-tab], [role=tab]',
@@ -44,7 +52,6 @@ export class UUITabGroupElement extends LitElement {
4452
#hiddenTabElementsMap: Map<UUITabElement, UUITabElement> = new Map();
4553

4654
#visibilityBreakpoints: number[] = [];
47-
#oldBreakpoint = 0;
4855

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

116123
// Only update if the container is smaller than the last breakpoint
117-
if (
118-
this.#visibilityBreakpoints.slice(-1)[0] < containerWidth &&
119-
this.#hiddenTabElements.length === 0
120-
)
124+
const lastBreakpoint = this.#visibilityBreakpoints.slice(-1)[0];
125+
if (lastBreakpoint < containerWidth && this.#hiddenTabElements.length === 0)
121126
return;
122127

123-
// Only update if the new breakpoint is different from the old one
124-
let newBreakpoint = Number.MAX_VALUE;
125-
126-
for (let i = this.#visibilityBreakpoints.length - 1; i > -1; i--) {
127-
const breakpoint = this.#visibilityBreakpoints[i];
128-
// Subtract the button width when we are not at the last breakpoint
129-
const containerWidthButtonWidth =
130-
containerWidth -
131-
(i !== this.#visibilityBreakpoints.length - 1 ? buttonWidth : 0);
132-
133-
if (breakpoint < containerWidthButtonWidth) {
134-
newBreakpoint = i;
135-
break;
136-
}
137-
}
138-
139-
if (newBreakpoint === this.#oldBreakpoint) return;
140-
this.#oldBreakpoint = newBreakpoint;
141-
142128
// Do the update
143129
// Reset the hidden tabs
144130
this.#hiddenTabElements.forEach(el => {
@@ -183,22 +169,33 @@ export class UUITabGroupElement extends LitElement {
183169
}
184170
}
185171

172+
if (this.#hiddenTabElements.length === 0) {
173+
// close the popover
174+
this._popoverContainerElement.hidePopover();
175+
}
176+
186177
hasActiveTabInDropdown
187178
? this._moreButtonElement.classList.add('active-inside')
188179
: this._moreButtonElement.classList.remove('active-inside');
189180

190181
this.requestUpdate();
191182
}
192183

193-
#calculateBreakPoints() {
184+
async #calculateBreakPoints() {
194185
// Whenever a tab is added or removed, we need to recalculate the breakpoints
186+
187+
await this.updateComplete; // Wait for the tabs to be rendered
195188
let childrenWidth = 0;
196189

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

196+
const tolerance = 2;
197+
this.style.width = childrenWidth + tolerance + 'px';
198+
202199
this.#updateCollapsibleTabs(this.offsetWidth);
203200
}
204201

@@ -225,7 +222,6 @@ export class UUITabGroupElement extends LitElement {
225222
<uui-popover-container
226223
id="popover-container"
227224
popover
228-
margin="10"
229225
placement="bottom-end">
230226
<div id="hidden-tabs-container">
231227
${repeat(this.#hiddenTabElements, el => html`${el}`)}
@@ -238,11 +234,24 @@ export class UUITabGroupElement extends LitElement {
238234
css`
239235
:host {
240236
display: flex;
241-
flex-wrap: wrap;
237+
flex-wrap: nowrap;
242238
color: var(--uui-tab-text);
243-
background: var(--uui-tab-background, none);
244239
height: 100%;
245240
min-height: 48px;
241+
overflow: hidden;
242+
text-wrap: nowrap;
243+
}
244+
245+
#popover-container {
246+
--uui-tab-text: var(--uui-tab-group-dropdown-tab-text, unset);
247+
--uui-tab-text-hover: var(
248+
--uui-tab-group-dropdown-tab-text-hover,
249+
unset
250+
);
251+
--uui-tab-text-active: var(
252+
--uui-tab-group-dropdown-tab-text-active,
253+
unset
254+
);
246255
}
247256
248257
::slotted(*:not(:last-of-type)) {
@@ -257,7 +266,10 @@ export class UUITabGroupElement extends LitElement {
257266
width: fit-content;
258267
display: flex;
259268
flex-direction: column;
260-
background: var(--uui-color-surface);
269+
background-color: var(
270+
--uui-tab-group-dropdown-background,
271+
var(--uui-color-surface)
272+
);
261273
border-radius: var(--uui-border-radius);
262274
box-shadow: var(--uui-shadow-depth-3);
263275
overflow: hidden;
@@ -267,8 +279,12 @@ export class UUITabGroupElement extends LitElement {
267279
}
268280
269281
#more-button {
270-
margin-left: auto;
271282
position: relative;
283+
284+
--uui-button-contrast: var(--uui-tab-text);
285+
--uui-button-contrast-hover: var(--uui-tab-text-hover);
286+
--uui-button-background-color: transparent;
287+
--uui-button-background-color-hover: transparent;
272288
}
273289
#more-button::before {
274290
content: '';

packages/uui-tabs/lib/uui-tab.element.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import { ifDefined } from 'lit/directives/if-defined.js';
1414
* @cssprop --uui-tab-text - Define the tab text color
1515
* @cssprop --uui-tab-text-hover - Define the tab text hover color
1616
* @cssprop --uui-tab-text-active - Define the tab text active color
17-
* @cssprop --uui-tab-background - Define the tab group background color
1817
* @cssprop --uui-tab-divider - Define the tab dividers color
1918
* @cssprop --uui-tab-padding-horizontal - Define the tab horizontal padding
2019
*/
@@ -145,6 +144,10 @@ export class UUITabElement extends ActiveMixin(LabelMixin('', LitElement)) {
145144
0 1px 2px rgba(0, 0, 0, 0.05);
146145
}
147146
147+
:host([active]) {
148+
color: var(--uui-tab-text-active, unset);
149+
}
150+
148151
:host([active]) #button {
149152
cursor: default;
150153
}

packages/uui-tabs/lib/uui-tabs.story.ts

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,24 @@ export default {
3535
};
3636

3737
export const AAAOverview: Story = props => html`
38-
<uui-tab-group
39-
style="
38+
<div style="display: flex;">
39+
<uui-tab-group
40+
style="
4041
height: 60px;
4142
--uui-tab-text: ${props['--uui-tab-text']};
4243
--uui-tab-text-hover: ${props['--uui-tab-text-hover']};
4344
--uui-tab-text-active: ${props['--uui-tab-text-active']};
4445
--uui-tab-background: ${props['--uui-tab-background']};
4546
--uui-tab-divider: ${props['--uui-tab-divider']};
4647
${props.inlineStyles}">
47-
<uui-tab label="content" active> Content </uui-tab>
48-
<uui-tab label="Packages" ?disabled=${props.disabled}> Packages </uui-tab>
49-
<uui-tab label="Media"> Media </uui-tab>
50-
<uui-tab label="Settings"> Settings </uui-tab>
51-
<uui-tab label="Translations"> Translations </uui-tab>
52-
<uui-tab label="Users"> Users </uui-tab>
53-
</uui-tab-group>
48+
<uui-tab label="content" active> Content </uui-tab>
49+
<uui-tab label="Packages" ?disabled=${props.disabled}> Packages </uui-tab>
50+
<uui-tab label="Media"> Media </uui-tab>
51+
<uui-tab label="Settings"> Settings </uui-tab>
52+
<uui-tab label="Translations"> Translations </uui-tab>
53+
<uui-tab label="Users"> Users </uui-tab>
54+
</uui-tab-group>
55+
</div>
5456
`;
5557
AAAOverview.storyName = 'Overview';
5658

@@ -59,13 +61,10 @@ export const WithBorders: Story = () => html`
5961
<div
6062
style="
6163
height: 48px;
62-
--uui-tab-text: var(--uui-color-default);
63-
--uui-tab-text-hover: var(--uui-color-default-emphasis);
64-
--uui-tab-text-active: var(--uui-color-default-emphasis);
65-
--uui-tab-background: none;
64+
display: flex;
6665
--uui-tab-divider: var(--uui-color-divider-standalone);
6766
">
68-
<uui-tab-group>
67+
<uui-tab-group style="display: flex;">
6968
<uui-tab label="content"> Content </uui-tab>
7069
<uui-tab label="Packages"> Packages </uui-tab>
7170
<uui-tab label="Media" active> Media </uui-tab>
@@ -80,14 +79,11 @@ export const Navbar: Story = () => html`
8079
<h3>Navbar</h3>
8180
<div
8281
style="
82+
display: flex;
8383
height: 60px;
8484
font-size: 16px;
85-
--uui-tab-text: var(--uui-color-surface-alt);
86-
--uui-tab-text-hover: var(--uui-color-surface);
87-
--uui-tab-text-active: var(--uui-color-current);
88-
--uui-tab-background: var(--uui-color-default);
8985
">
90-
<uui-tab-group>
86+
<uui-tab-group style="display: flex;">
9187
<uui-tab label="content"> Content </uui-tab>
9288
<uui-tab label="Packages" active> Packages </uui-tab>
9389
<uui-tab label="Media"> Media </uui-tab>
@@ -102,12 +98,9 @@ export const UsingHref: Story = () => html`
10298
<h3>Href links</h3>
10399
<div
104100
style="
101+
display: flex;
105102
height: 60px;
106103
font-size: 16px;
107-
--uui-tab-text: var(--uui-color-surface-alt);
108-
--uui-tab-text-hover: var(--uui-color-surface);
109-
--uui-tab-text-active: var(--uui-color-current);
110-
--uui-tab-background: var(--uui-color-default);
111104
">
112105
<uui-tab-group>
113106
<uui-tab label="content" href="http://www.umbraco.com/#content">
@@ -135,25 +128,27 @@ export const UsingHref: Story = () => html`
135128
export const WithIcons: Story = props => html`
136129
<h3>Tabs with Icons</h3>
137130
<uui-icon-registry-essential>
138-
<uui-tab-group
139-
dropdown-direction="horizontal"
140-
style="
141-
height: 70px;
142-
font-size: 12px;
143-
${props.inlineStyles}">
144-
<uui-tab>
145-
<uui-icon slot="icon" name="document"></uui-icon>
146-
Content
147-
</uui-tab>
148-
<uui-tab active>
149-
<uui-icon slot="icon" name="settings"></uui-icon>
150-
Packages
151-
</uui-tab>
152-
<uui-tab>
153-
<uui-icon slot="icon" name="picture"></uui-icon>
154-
Media
155-
</uui-tab>
156-
</uui-tab-group>
131+
<div style="display: flex;">
132+
<uui-tab-group
133+
dropdown-direction="horizontal"
134+
style="
135+
height: 70px;
136+
font-size: 12px;
137+
${props.inlineStyles}">
138+
<uui-tab>
139+
<uui-icon slot="icon" name="document"></uui-icon>
140+
Content
141+
</uui-tab>
142+
<uui-tab active>
143+
<uui-icon slot="icon" name="settings"></uui-icon>
144+
Packages
145+
</uui-tab>
146+
<uui-tab>
147+
<uui-icon slot="icon" name="picture"></uui-icon>
148+
Media
149+
</uui-tab>
150+
</uui-tab-group>
151+
</div>
157152
</uui-icon-registry-essential>
158153
`;
159154
WithIcons.parameters = {

0 commit comments

Comments
 (0)