Soracom

Design System
  1. Home
  2. Design system
  3. Guidelines
  4. Web components

Web components

Guidelines on using SDS with html web components

Overview

When using SDS with ‘closed’ web components (where shadow root is in use), it’s recommended to use the component specific styles to prevent importing the entire SDS (including unneccessary styles) into each component.

Generally you will need to:

  1. Import the standard combined SDS into the root of the page. This allows non web component elements to use SDS, but also provides styling for slot content inside a web component.
  2. Into the web component, import a base file, which includes common styles used by all sds components (such as colors, icons etc). These are required to apply the global styles the outer web component element.
  3. Into the web component, import the component specific styles, used to style the outer web component element.

For ‘open’ web components, importing the standard combined SDS into the root of the page is all that is required, as per normal.

Component specific styles

Component CSS via assets

html
Copy
<!-- Format -->

https://assets.soracom.io/css/sds/[latest|beta|version]/[component].css

<!-- Example -->
<link
  rel="stylesheet"
  href="https://assets.soracom.io/css/sds/beta/notice.css"
/>

Component SCSS via npm

html
Copy
<!-- Format -->
@soracom/soracom-design-system/ds/src/components/[component]/build

<!-- Example -->
@import '@soracom/soracom-design-system/ds/src/components/notice/build'

Base styles

Base CSS via assets

html
Copy
<!-- Format -->
https://assets.soracom.io/css/sds/[latest|beta|version]/base.css

<!-- Example -->
<link rel="stylesheet" href="https://assets.soracom.io/css/sds/beta/base.css" />

Base SCSS via npm

html
Copy
<!-- Format -->
@soracom/soracom-design-system/ds/src/components/base

<!-- Example -->
@import '@soracom/soracom-design-system/ds/src/components/base'

Sample web component

HTML content

html
Copy
<!-- Load the full SDS on the page root -->
<link
  rel="stylesheet"
  href="https://assets.soracom.io/css/sds/beta/combined.css"
/>

<!-- Example simple notice -->
<ds-notice state="info"
  >This is plain text content inside a closed web component</ds-notice
>

<!-- Example notice with html content -->
<ds-notice state="warning">
  <p class="ds-text --label">
    This is html content inside a closed web component
  </p>
  <p class="ds-text --small">
    Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Donec sed odio
    dui. Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus
    eget urna mollis ornare vel eu leo. Lorem ipsum dolor sit amet, consectetur
    adipiscing elit. Nulla vitae elit libero, a pharetra augue. Nullam quis
    risus eget urna mollis ornare vel eu leo. Aenean lacinia bibendum nulla sed
    consectetur. Nulla vitae elit libero, a pharetra augue. Lorem ipsum dolor
    sit amet, consectetur adipiscing elit.
  </p>
</ds-notice>
const dsNoticeTemplate = document.createElement("template");
dsNoticeTemplate.innerHTML = `
<!--
Import the base (minimal global sds css), and component specific (notice) css.

Note: 
This is only required for the outer 'notice component'
HTML content INSIDE this component still uses the combined css loaded
at the root of the page. Because... reasons.
-->
<link rel="stylesheet" href="https://assets.soracom.io/css/sds/beta/base.css"/>
<link rel="stylesheet" href="https://assets.soracom.io/css/sds/beta/notice.css"/>
<div class="ds-notice">
  <slot></slot>
</div>`;

class DsNotice extends HTMLElement {
  constructor() {
    super();
  }

  // List of attributes to use
  static get observedAttributes() {
    return ["state", "loading"];
  }

  // Check for any attribute changes
  attributeChangedCallback(property, oldValue, newValue) {
    if (oldValue === newValue) return;
    this[property] = newValue;
  }

  // Connect the component and insert
  connectedCallback() {
    // Add the template to the shadowRoot
    const shadowRoot = this.attachShadow({ mode: "closed" });
    shadowRoot.appendChild(dsNoticeTemplate.content.cloneNode(true));

    // Process attributes

    // Visual states
    if (this.state) {
      shadowRoot.querySelector("div").classList.add("--" + this.state);
    }

    // Loading state
    if (typeof this.loading != "undefined") {
      shadowRoot.querySelector("div").classList.add("--loading" + this.loading);
    }
  }
}

// Register this component
customElements.define("ds-notice", DsNotice);

Example simple ds-notice webcomponent