Skip to content

Commit b3df44b

Browse files
Feat: header-actions slot to uui-box (#676)
Co-authored-by: Niels Lyngsø <[email protected]>
1 parent b7e71f5 commit b3df44b

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

packages/uui-box/lib/uui-box.element.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
55
import type { InterfaceHeading } from '@umbraco-ui/uui-base/lib';
66
import { StaticValue, html, literal, unsafeStatic } from 'lit/static-html.js';
77

8+
function slotHasContent(target: EventTarget | null): boolean {
9+
return target
10+
? (target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0
11+
: false;
12+
}
13+
814
/**
9-
* A box for grouping elements
15+
* A layout box for grouping elements, as well its possible to append a header, with a headline or other elements to the box.
1016
* @element uui-box
1117
* @slot headline - headline area, this area is placed within the headline tag which is located inside the header. Use this to ensure the right headline styling.
12-
* @slot header - header area, use this for things that is not the headline but located in the header.
18+
* @slot header - header area, use this for things that are not the headline but are located in the header.
19+
* @slot header-actions - right-side of the box header, use this to append some actions that are general for the topic of this box.
1320
* @slot - area for the content of the box
1421
* @cssprop --uui-box-default-padding - overwrite the box padding
1522
*
1623
*/
1724
@defineElement('uui-box')
1825
export class UUIBoxElement extends LitElement {
1926
/**
20-
* Headline for this box, can also be set via the 'box' slot.
27+
* Headline for this box, can also be set via the `headline` slot.
2128
* @type string
2229
* @attr
2330
* @default null
@@ -27,7 +34,7 @@ export class UUIBoxElement extends LitElement {
2734

2835
/**
2936
* Changes the headline variant for accessibility for this box.
30-
* Notice this does not change the visual representation of the headline. (Umbraco does only recommend displaying a h5 sizes headline in the UUI-BOX)
37+
* Notice this does not change the visual representation of the headline. (Umbraco recommends displaying a h5 size headline in the UUI-BOX)
3138
* @type {"h1" | "h2" | "h3" | "h4" | "h5" | "h6"}
3239
* @attr
3340
* @default "h5"
@@ -47,19 +54,23 @@ export class UUIBoxElement extends LitElement {
4754
@state()
4855
private _headlineSlotHasContent = false;
4956
private _headlineSlotChanged = (e: Event) => {
50-
this._headlineSlotHasContent =
51-
(e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;
57+
this._headlineSlotHasContent = slotHasContent(e.target);
5258
};
5359

5460
@state()
5561
private _headerSlotHasContent = false;
5662
private _headerSlotChanged = (e: Event) => {
57-
this._headerSlotHasContent =
58-
(e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;
63+
this._headerSlotHasContent = slotHasContent(e.target);
64+
};
65+
66+
@state()
67+
private _headerActionsSlotHasContent = false;
68+
private _headerActionsSlotChanged = (e: Event) => {
69+
this._headerActionsSlotHasContent = slotHasContent(e.target);
5970
};
6071

6172
/**
62-
* Renders a header with the header-slot, headline and headline-slot within
73+
* Renders a header with the `header`-slot, `header-actions`-slot, headline and `headline`-slot within
6374
* @returns {TemplateResult}
6475
* @protected
6576
* @method
@@ -72,6 +83,7 @@ export class UUIBoxElement extends LitElement {
7283
style=${
7384
this._headerSlotHasContent ||
7485
this._headlineSlotHasContent ||
86+
this._headerActionsSlotHasContent ||
7587
this.headline !== null
7688
? ''
7789
: 'display: none'
@@ -88,6 +100,9 @@ export class UUIBoxElement extends LitElement {
88100
<slot name="headline" @slotchange=${this._headlineSlotChanged}></slot>
89101
</${this._headlineVariantTag}>
90102
<slot name="header" @slotchange=${this._headerSlotChanged}></slot>
103+
<slot name="header-actions" @slotchange=${
104+
this._headerActionsSlotChanged
105+
}></slot>
91106
</div>`;
92107
/* eslint-enable lit/no-invalid-html, lit/binding-positions */
93108
}
@@ -110,7 +125,8 @@ export class UUIBoxElement extends LitElement {
110125
}
111126
112127
#header {
113-
display: block;
128+
display: flex;
129+
column-gap: var(--uui-size-space-5);
114130
border-bottom: 1px solid var(--uui-color-divider-standalone);
115131
padding: var(--uui-size-space-4) var(--uui-size-space-5);
116132
}
@@ -119,6 +135,11 @@ export class UUIBoxElement extends LitElement {
119135
display: block;
120136
padding: var(--uui-box-default-padding, var(--uui-size-space-5));
121137
}
138+
139+
slot[name='header-actions'] {
140+
display: block;
141+
margin-left: auto;
142+
}
122143
`,
123144
];
124145
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ export const Slots: Story = () => html`
5656
>Headline slot</uui-button
5757
>
5858
<uui-button slot="header" look="placeholder">Header slot</uui-button>
59+
<uui-button slot="header-actions" look="placeholder"
60+
>Header actions slot</uui-button
61+
>
5962
<uui-button look="placeholder">Default slot</uui-button>
6063
</uui-box>
6164
`;

packages/uui-box/lib/uui-box.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ describe('UUIBox', () => {
7272
expect(slot).to.exist;
7373
});
7474

75+
it('renders a header-actions slot', () => {
76+
const slot = element.shadowRoot!.querySelector(
77+
'slot[name=header-actions'
78+
)!;
79+
expect(slot).to.exist;
80+
});
81+
7582
it('renders specified headline tag when headlineVariant is set', async () => {
7683
element = await fixture(
7784
html` <uui-box headline="headline" headline-variant="h2">Main</uui-box>`

0 commit comments

Comments
 (0)