diff --git a/src/components/sbb-footer/sbb-footer.e2e.ts b/src/components/sbb-footer/sbb-footer.e2e.ts index 6ee43cc33f7..0a36fd84731 100644 --- a/src/components/sbb-footer/sbb-footer.e2e.ts +++ b/src/components/sbb-footer/sbb-footer.e2e.ts @@ -1,13 +1,12 @@ -import { E2EElement, E2EPage, newE2EPage } from '@stencil/core/testing'; +import { assert, fixture } from '@open-wc/testing'; +import { html } from 'lit/static-html.js'; +import { SbbFooter } from './sbb-footer'; describe('sbb-footer', () => { - let element: E2EElement, page: E2EPage; + let element: SbbFooter; it('renders', async () => { - page = await newE2EPage(); - await page.setContent(''); - - element = await page.find('sbb-footer'); - expect(element).toHaveClass('hydrated'); + element = await fixture(html``); + assert.instanceOf(element, SbbFooter); }); }); diff --git a/src/components/sbb-footer/sbb-footer.spec.ts b/src/components/sbb-footer/sbb-footer.spec.ts index 8559353b700..a88a7d751de 100644 --- a/src/components/sbb-footer/sbb-footer.spec.ts +++ b/src/components/sbb-footer/sbb-footer.spec.ts @@ -1,24 +1,27 @@ import { SbbFooter } from './sbb-footer'; -import { newSpecPage } from '@stencil/core/testing'; +import './sbb-footer'; + +import { expect, fixture } from '@open-wc/testing'; +import { html } from 'lit/static-html.js'; describe('sbb-footer', () => { it('renders', async () => { - const { root } = await newSpecPage({ - components: [SbbFooter], - html: '', - }); + const element: SbbFooter = await fixture(html``); - expect(root).toEqualHtml(` - - + expect(element).dom.to.be.equal( + ` + + `, + ); + expect(element).shadowDom.to.be.equal( + `
-
-
- `); + `, + ); }); }); diff --git a/src/components/sbb-footer/sbb-footer.stories.tsx b/src/components/sbb-footer/sbb-footer.stories.tsx index d71b12502e6..dd24d3b567e 100644 --- a/src/components/sbb-footer/sbb-footer.stories.tsx +++ b/src/components/sbb-footer/sbb-footer.stories.tsx @@ -2,8 +2,14 @@ import readme from './readme.md'; import { h, JSX } from 'jsx-dom'; import isChromatic from 'chromatic'; -import type { Meta, StoryObj, ArgTypes, Args } from '@storybook/html'; +import type { Meta, StoryObj, ArgTypes, Args } from '@storybook/web-components'; import type { InputType } from '@storybook/types'; +import '../sbb-clock'; +import '../sbb-button'; +import '../sbb-link'; +import '../sbb-link-list'; +import '../sbb-title'; +import './sbb-footer'; const variant: InputType = { control: { diff --git a/src/components/sbb-footer/sbb-footer.tsx b/src/components/sbb-footer/sbb-footer.tsx index 6b5585addc7..477013e2ac2 100644 --- a/src/components/sbb-footer/sbb-footer.tsx +++ b/src/components/sbb-footer/sbb-footer.tsx @@ -1,47 +1,59 @@ -import { Component, h, JSX, Prop } from '@stencil/core'; import { InterfaceFooterAttributes } from './sbb-footer.custom'; -import { InterfaceTitleAttributes } from '../sbb-title/sbb-title.custom'; - -@Component({ - shadow: true, - styleUrl: 'sbb-footer.scss', - tag: 'sbb-footer', -}) -export class SbbFooter { +import { CSSResult, LitElement, nothing, TemplateResult } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import Style from './sbb-footer.scss?lit&inline'; +import { html, unsafeStatic } from 'lit/static-html.js'; +import { TitleLevel } from '../sbb-title'; + +@customElement('sbb-footer') +export class SbbFooter extends LitElement { + public static override styles: CSSResult = Style; + /** * Variants to display the footer. The default, displays the content in regular block element * approach. The clock-columns, used a css-grid for displaying the content over different * breakpoints. */ - @Prop({ reflect: true }) public variant: InterfaceFooterAttributes['variant'] = 'default'; + @property({ reflect: true }) public variant: InterfaceFooterAttributes['variant'] = 'default'; /** Negative coloring variant flag. */ - @Prop({ reflect: true }) public negative = false; + @property({ reflect: true, type: Boolean }) public negative = false; /** * Whether to allow the footer content to stretch to full width. * By default, the content has the appropriate page size. */ - @Prop({ reflect: true }) public expanded = false; + @property({ reflect: true, type: Boolean }) public expanded = false; /** Footer title text, visually hidden, necessary for screen readers. */ - @Prop() public accessibilityTitle?: string; + @property({ attribute: 'accessibility-title' }) public accessibilityTitle?: string; /** Level of the accessibility title, will be rendered as heading tag (e.g. h1). Defaults to level 1. */ - @Prop() public accessibilityTitleLevel: InterfaceTitleAttributes['level'] = '1'; + @property({ attribute: 'accessibility-title-level' }) + public accessibilityTitleLevel: TitleLevel = '1'; - public render(): JSX.Element { + protected override render(): TemplateResult { const TITLE_TAG_NAME = `h${this.accessibilityTitleLevel}`; - return ( + /* eslint-disable lit/binding-positions */ + const accessibilityTitle = html`<${unsafeStatic(TITLE_TAG_NAME)} class="sbb-footer__title" + >${this.accessibilityTitle}`; + /* eslint-enable lit/binding-positions */ + + return html`
- ); + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + // eslint-disable-next-line @typescript-eslint/naming-convention + 'sbb-footer': SbbFooter; } } diff --git a/src/global/dom/is-valid-attribute.ts b/src/global/dom/is-valid-attribute.ts index c50e6195abc..451fc7ba80e 100644 --- a/src/global/dom/is-valid-attribute.ts +++ b/src/global/dom/is-valid-attribute.ts @@ -27,12 +27,11 @@ export function setAttribute(element: HTMLElement, attribute: string, value: any } /** - * Set the attribute only if value is not 'false' - * @param element The element that will have the attribute - * @param attribute The attribute name - * @param value The attribute value + * Set multiple attributes + * @param element The element that will have the attributes + * @param attributes Attributes object */ -export function setAttributes(element: HTMLElement, attributes: any): void { +export function setAttributes(element: HTMLElement, attributes: Record): void { if (!attributes) { return; }