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 { + `; /* 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` diff --git a/packages/uui-button/lib/uui-button.element.ts b/packages/uui-button/lib/uui-button.element.ts index 74bd87743..b22a168c5 100644 --- a/packages/uui-button/lib/uui-button.element.ts +++ b/packages/uui-button/lib/uui-button.element.ts @@ -322,7 +322,6 @@ export class UUIButtonElement extends FormControlMixin( } #icon-check, #icon-wrong { - fill: currentColor; display: grid; place-items: center; width: 1.5em; diff --git a/packages/uui-checkbox/lib/uui-checkbox.element.ts b/packages/uui-checkbox/lib/uui-checkbox.element.ts index 40c828139..b88432f8e 100644 --- a/packages/uui-checkbox/lib/uui-checkbox.element.ts +++ b/packages/uui-checkbox/lib/uui-checkbox.element.ts @@ -100,7 +100,7 @@ export class UUICheckboxElement extends UUIBooleanInputElement { height: 1em; line-height: 0; transition: fill 120ms, opacity 120ms; - fill: var(--uui-color-selected-contrast); + color: var(--uui-color-selected-contrast); opacity: 0; } @@ -166,13 +166,13 @@ export class UUICheckboxElement extends UUIBooleanInputElement { background-color: var(--uui-color-disabled); } :host([disabled]) #ticker #icon-check { - fill: var(--uui-color-disabled-contrast); + color: var(--uui-color-disabled-contrast); } :host([disabled]) label:active #ticker { animation: ${UUIHorizontalShakeAnimationValue}; } :host([disabled]) input:checked + #ticker #icon-check { - fill: var(--uui-color-disabled-contrast); + color: var(--uui-color-disabled-contrast); } `, ]; diff --git a/packages/uui-color-swatch/lib/uui-color-swatch.element.ts b/packages/uui-color-swatch/lib/uui-color-swatch.element.ts index aaa513631..262839616 100644 --- a/packages/uui-color-swatch/lib/uui-color-swatch.element.ts +++ b/packages/uui-color-swatch/lib/uui-color-swatch.element.ts @@ -110,7 +110,7 @@ export class UUIColorSwatchElement extends LabelMixin( this.value})">
+ style="color: var(--uui-swatch-color, ${this.color ?? this.value})"> ${iconCheck}
diff --git a/packages/uui-toggle/lib/uui-toggle.element.ts b/packages/uui-toggle/lib/uui-toggle.element.ts index 4e554449d..62f62335b 100644 --- a/packages/uui-toggle/lib/uui-toggle.element.ts +++ b/packages/uui-toggle/lib/uui-toggle.element.ts @@ -6,7 +6,7 @@ import { defineElement } from '@umbraco-ui/uui-base/lib/registration'; import { UUIBooleanInputElement } from '@umbraco-ui/uui-boolean-input/lib'; import { iconCheck, - iconWrong, + iconRemove, } from '@umbraco-ui/uui-icon-registry-essential/lib/svgs'; import { css, html } from 'lit'; @@ -39,8 +39,8 @@ export class UUIToggleElement extends UUIBooleanInputElement { renderCheckbox() { return html`
-
${iconCheck}
-
${iconWrong}
+
${iconCheck}
+
${iconRemove}
`; } @@ -102,29 +102,29 @@ export class UUIToggleElement extends UUIBooleanInputElement { background-color: var(--uui-color-selected-emphasis); } - #icon-check, - #icon-wrong { + #icon-checked, + #icon-unchecked { position: absolute; vertical-align: middle; width: 1em; height: 1em; line-height: 0; - transition: fill 120ms; + transition: color 120ms; } - #icon-check { + #icon-checked { margin-left: -0.5em; left: calc(var(--uui-toggle-size) * 0.5); - fill: var(--uui-color-interactive); + color: var(--uui-color-interactive); } - #icon-wrong { + #icon-unchecked { margin-right: -0.5em; right: calc(var(--uui-toggle-size) * 0.5); - fill: var(--uui-color-interactive); + color: var(--uui-color-interactive); } - input:checked ~ #slider #icon-check { - fill: var(--uui-color-selected-contrast); + input:checked ~ #slider #icon-checked { + color: var(--uui-color-selected-contrast); } #slider::after { @@ -164,14 +164,14 @@ export class UUIToggleElement extends UUIBooleanInputElement { :host([disabled]) #slider::after { background-color: var(--uui-color-disabled); } - :host([disabled]) #slider #icon-wrong { - fill: var(--uui-color-disabled-contrast); + :host([disabled]) #slider #icon-unchecked { + color: var(--uui-color-disabled-contrast); } :host([disabled]) label:active #slider { animation: ${UUIHorizontalShakeAnimationValue}; } - :host([disabled]) input:checked #slider #icon-check { - fill: var(--uui-color-disabled-contrast); + :host([disabled]) input:checked #slider #icon-checked { + color: var(--uui-color-disabled-contrast); } :host(:not([pristine]):invalid) #slider,