Skip to content

Adds header-actions slot to uui-box #676

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 4 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 31 additions & 10 deletions packages/uui-box/lib/uui-box.element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,26 @@ 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
*
*/
@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
Expand All @@ -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"
Expand All @@ -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
Expand All @@ -72,6 +83,7 @@ export class UUIBoxElement extends LitElement {
style=${
this._headerSlotHasContent ||
this._headlineSlotHasContent ||
this._headerActionsSlotHasContent ||
this.headline !== null
? ''
: 'display: none'
Expand All @@ -88,6 +100,9 @@ export class UUIBoxElement extends LitElement {
<slot name="headline" @slotchange=${this._headlineSlotChanged}></slot>
</${this._headlineVariantTag}>
<slot name="header" @slotchange=${this._headerSlotChanged}></slot>
<slot name="header-actions" @slotchange=${
this._headerActionsSlotChanged
}></slot>
</div>`;
/* eslint-enable lit/no-invalid-html, lit/binding-positions */
}
Expand All @@ -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);
}
Expand All @@ -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;
}
`,
];
}
Expand Down
3 changes: 3 additions & 0 deletions packages/uui-box/lib/uui-box.story.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ export const Slots: Story = () => html`
>Headline slot</uui-button
>
<uui-button slot="header" look="placeholder">Header slot</uui-button>
<uui-button slot="header-actions" look="placeholder"
>Header actions slot</uui-button
>
<uui-button look="placeholder">Default slot</uui-button>
</uui-box>
`;
Expand Down
7 changes: 7 additions & 0 deletions packages/uui-box/lib/uui-box.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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` <uui-box headline="headline" headline-variant="h2">Main</uui-box>`
Expand Down