diff --git a/packages/uui-box/lib/uui-box.element.ts b/packages/uui-box/lib/uui-box.element.ts
index 74777d2c0..21acf747e 100644
--- a/packages/uui-box/lib/uui-box.element.ts
+++ b/packages/uui-box/lib/uui-box.element.ts
@@ -5,11 +5,18 @@ import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import type { InterfaceHeading } from '@umbraco-ui/uui-base/lib';
import { StaticValue, html, literal, unsafeStatic } from 'lit/static-html.js';
+function slotHasContent(target: EventTarget | null): boolean {
+ return target
+ ? (target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0
+ : false;
+}
+
/**
- * A box for grouping elements
+ * A layout box for grouping elements, as well its possible to append a header, with a headline or other elements to the box.
* @element uui-box
* @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.
- * @slot header - header area, use this for things that is not the headline but located in the header.
+ * @slot header - header area, use this for things that are not the headline but are located in the header.
+ * @slot header-actions - right-side of the box header, use this to append some actions that are general for the topic of this box.
* @slot - area for the content of the box
* @cssprop --uui-box-default-padding - overwrite the box padding
*
@@ -17,7 +24,7 @@ import { StaticValue, html, literal, unsafeStatic } from 'lit/static-html.js';
@defineElement('uui-box')
export class UUIBoxElement extends LitElement {
/**
- * Headline for this box, can also be set via the 'box' slot.
+ * Headline for this box, can also be set via the `headline` slot.
* @type string
* @attr
* @default null
@@ -27,7 +34,7 @@ export class UUIBoxElement extends LitElement {
/**
* Changes the headline variant for accessibility for this box.
- * Notice this does not change the visual representation of the headline. (Umbraco does only recommend displaying a h5 sizes headline in the UUI-BOX)
+ * Notice this does not change the visual representation of the headline. (Umbraco recommends displaying a h5 size headline in the UUI-BOX)
* @type {"h1" | "h2" | "h3" | "h4" | "h5" | "h6"}
* @attr
* @default "h5"
@@ -47,19 +54,23 @@ export class UUIBoxElement extends LitElement {
@state()
private _headlineSlotHasContent = false;
private _headlineSlotChanged = (e: Event) => {
- this._headlineSlotHasContent =
- (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;
+ this._headlineSlotHasContent = slotHasContent(e.target);
};
@state()
private _headerSlotHasContent = false;
private _headerSlotChanged = (e: Event) => {
- this._headerSlotHasContent =
- (e.target as HTMLSlotElement).assignedNodes({ flatten: true }).length > 0;
+ this._headerSlotHasContent = slotHasContent(e.target);
+ };
+
+ @state()
+ private _headerActionsSlotHasContent = false;
+ private _headerActionsSlotChanged = (e: Event) => {
+ this._headerActionsSlotHasContent = slotHasContent(e.target);
};
/**
- * Renders a header with the header-slot, headline and headline-slot within
+ * Renders a header with the `header`-slot, `header-actions`-slot, headline and `headline`-slot within
* @returns {TemplateResult}
* @protected
* @method
@@ -72,6 +83,7 @@ export class UUIBoxElement extends LitElement {
style=${
this._headerSlotHasContent ||
this._headlineSlotHasContent ||
+ this._headerActionsSlotHasContent ||
this.headline !== null
? ''
: 'display: none'
@@ -88,6 +100,9 @@ export class UUIBoxElement extends LitElement {
${this._headlineVariantTag}>
+
`;
/* eslint-enable lit/no-invalid-html, lit/binding-positions */
}
@@ -110,7 +125,8 @@ export class UUIBoxElement extends LitElement {
}
#header {
- display: block;
+ display: flex;
+ column-gap: var(--uui-size-space-5);
border-bottom: 1px solid var(--uui-color-divider-standalone);
padding: var(--uui-size-space-4) var(--uui-size-space-5);
}
@@ -119,6 +135,11 @@ export class UUIBoxElement extends LitElement {
display: block;
padding: var(--uui-box-default-padding, var(--uui-size-space-5));
}
+
+ slot[name='header-actions'] {
+ display: block;
+ margin-left: auto;
+ }
`,
];
}
diff --git a/packages/uui-box/lib/uui-box.story.ts b/packages/uui-box/lib/uui-box.story.ts
index cb6687743..dc17deaaf 100644
--- a/packages/uui-box/lib/uui-box.story.ts
+++ b/packages/uui-box/lib/uui-box.story.ts
@@ -56,6 +56,9 @@ export const Slots: Story = () => html`
>Headline slot
Header slot
+ Header actions slot
Default slot
`;
diff --git a/packages/uui-box/lib/uui-box.test.ts b/packages/uui-box/lib/uui-box.test.ts
index 74f60f09f..2c96ca1a8 100644
--- a/packages/uui-box/lib/uui-box.test.ts
+++ b/packages/uui-box/lib/uui-box.test.ts
@@ -72,6 +72,13 @@ describe('UUIBox', () => {
expect(slot).to.exist;
});
+ it('renders a header-actions slot', () => {
+ const slot = element.shadowRoot!.querySelector(
+ 'slot[name=header-actions'
+ )!;
+ expect(slot).to.exist;
+ });
+
it('renders specified headline tag when headlineVariant is set', async () => {
element = await fixture(
html` Main`