Skip to content

Commit

Permalink
refactor: migrate sbb-footer
Browse files Browse the repository at this point in the history
  • Loading branch information
jeripeierSBB committed Oct 9, 2023
1 parent 4e5f193 commit d18501c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 44 deletions.
13 changes: 6 additions & 7 deletions src/components/sbb-footer/sbb-footer.e2e.ts
Original file line number Diff line number Diff line change
@@ -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('<sbb-footer></sbb-footer>');

element = await page.find('sbb-footer');
expect(element).toHaveClass('hydrated');
element = await fixture(html`<sbb-footer></sbb-footer>`);
assert.instanceOf(element, SbbFooter);
});
});
25 changes: 14 additions & 11 deletions src/components/sbb-footer/sbb-footer.spec.ts
Original file line number Diff line number Diff line change
@@ -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: '<sbb-footer accessibility-title="Footer" />',
});
const element: SbbFooter = await fixture(html`<sbb-footer accessibility-title="Footer" />`);

expect(root).toEqualHtml(`
<sbb-footer accessibility-title="Footer" variant="default">
<mock:shadow-root>
expect(element).dom.to.be.equal(
`
<sbb-footer accessibility-title="Footer" variant="default"></sbb-footer>
`,
);
expect(element).shadowDom.to.be.equal(
`
<footer class="sbb-footer">
<div class="sbb-footer-wrapper">
<h1 class="sbb-footer__title">Footer</h1>
<slot></slot>
</div>
</footer>
</mock:shadow-root>
</sbb-footer>
`);
`,
);
});
});
8 changes: 7 additions & 1 deletion src/components/sbb-footer/sbb-footer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
52 changes: 32 additions & 20 deletions src/components/sbb-footer/sbb-footer.tsx
Original file line number Diff line number Diff line change
@@ -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}</${unsafeStatic(TITLE_TAG_NAME)}>`;
/* eslint-enable lit/binding-positions */

return html`
<footer class="sbb-footer">
<div class="sbb-footer-wrapper">
{this.accessibilityTitle && (
<TITLE_TAG_NAME class="sbb-footer__title">{this.accessibilityTitle}</TITLE_TAG_NAME>
)}
${this.accessibilityTitle ? accessibilityTitle : nothing}
<slot />
</div>
</footer>
);
`;
}
}

declare global {
interface HTMLElementTagNameMap {
// eslint-disable-next-line @typescript-eslint/naming-convention
'sbb-footer': SbbFooter;
}
}
9 changes: 4 additions & 5 deletions src/global/dom/is-valid-attribute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, any>): void {
if (!attributes) {
return;
}
Expand Down

0 comments on commit d18501c

Please sign in to comment.