Charcoal.mini

import

Via npm

pnpm add charcoal.mini

inside main.js

import "charcoal.mini";

Via CDN

<link
  rel="stylesheet"
  href="https://unpkg.com/charcoal.mini/dist/charcoal.mini.css"
/>
<script type="importmap">
  {
    "imports": {
      "warning": "https://esm.sh/warning@4.0.3",
      "@charcoal-ui/icon-files": "https://unpkg.com/@charcoal-ui/icon-files@3.3.0/src/index.js",
      "dompurify": "https://unpkg.com/dompurify@3.0.6/dist/purify.es.js"
    }
  }
</script>
<script
  type="module"
  src="https://unpkg.com/@charcoal-ui/icons@3.3.0/dist/index.esm.js"
></script>

.ch-button

<button class="ch-button">button</button>
<button class="ch-button" disabled>button</button>
<button class="ch-button primary">button</button>
<button class="ch-button primary" disabled>button</button>
<button class="ch-button overlay">button</button>
<button class="ch-button overlay" disabled>button</button>
<button class="ch-button danger">button</button>
<button class="ch-button danger" disabled>button</button>
<button class="ch-button navigation">button</button>
<button class="ch-button navigation" disabled>button</button>
<button class="ch-button size-s">button</button>
<button class="ch-button size-s" disabled>button</button>
<button class="ch-button primary size-s">button</button>
<button class="ch-button primary size-s" disabled>button</button>
<button class="ch-button fullwidth">button</button>
<button class="ch-button fullwidth" disabled>button</button>
<button class="ch-button fullwidth primary">button</button>
<button class="ch-button fullwidth primary" disabled>button</button>

.ch-icon-button

<button class="ch-icon-button">
  <pixiv-icon name="24/Close"></pixiv-icon>
</button>
<button class="ch-icon-button" disabled>
  <pixiv-icon name="24/Close"></pixiv-icon>
</button>
<button class="ch-icon-button size-s">
  <pixiv-icon name="24/Close"></pixiv-icon>
</button>
<button class="ch-icon-button size-xs">
  <pixiv-icon name="16/Remove"></pixiv-icon>
</button>
<button class="ch-icon-button overlay">
  <pixiv-icon name="24/Close"></pixiv-icon>
</button>
<button class="ch-icon-button overlay" disabled>
  <pixiv-icon name="24/Close"></pixiv-icon>
</button>
<button class="ch-icon-button overlay size-s">
  <pixiv-icon name="24/Close"></pixiv-icon>
</button>
<button class="ch-icon-button overlay size-xs">
  <pixiv-icon name="16/Remove"></pixiv-icon>
</button>

.ch-textfield

<div class="ch-textfield">
  <div class="ch-textfield-input-container">
    <input class="ch-textfield-input" placeholder="input..." />
  </div>
</div>
<div class="ch-textfield">
  <div class="ch-textfield-input-container">
    <input class="ch-textfield-input" disabled placeholder="input..." />
  </div>
</div>
<div class="ch-textfield">
  <div class="ch-textfield-label-container">
    <label class="ch-textfield-label"> Label </label>
    <span class="ch-textfield-required"> Required </span>
    <span class="ch-textfield-sub-label"> sub-label </span>
  </div>

  <div class="ch-textfield-input-container">
    <input class="ch-textfield-input" placeholder="input..." />
  </div>

  <span class="ch-textfield-assistive-text">Assistive text</span>
</div>
Required sub-label
Assistive text
<div class="ch-textfield">
  <div class="ch-textfield-input-container invalid">
    <input class="ch-textfield-input invalid" placeholder="input..." />
  </div>

  <span class="ch-textfield-assistive-text invalid">Assistive text</span>
</div>
Assistive text

.ch-textarea

<div class="ch-textarea">
  <div class="ch-textarea-container">
    <textarea class="ch-textarea-textarea" placeholder="input..."></textarea>
  </div>
</div>
<div class="ch-textarea">
  <div class="ch-textfield-label-container">
    <label class="ch-textfield-label"> Label </label>
    <span class="ch-textfield-required"> Required </span>
    <span class="ch-textfield-sub-label"> sub-label </span>
  </div>

  <div class="ch-textarea-container">
    <textarea class="ch-textarea-textarea" placeholder="input..."></textarea>
    <span class="ch-textarea-count">0/100</span>
  </div>

  <span class="ch-textarea-assistive-text">Assistive text</span>
</div>
Required sub-label
0/100
Assistive text
<div class="ch-textarea">
  <div class="ch-textfield-label-container">
    <label class="ch-textfield-label"> Label </label>
    <span class="ch-textfield-required"> Required </span>
    <span class="ch-textfield-sub-label"> sub-label </span>
  </div>

  <div class="ch-textarea-container invalid">
    <textarea class="ch-textarea-textarea" placeholder="input..."></textarea>
    <span class="ch-textarea-count">0/100</span>
  </div>

  <span class="ch-textarea-assistive-text invalid">Assistive text</span>
</div>
Required sub-label
0/100
Assistive text

.ch-radio-group

<div class="ch-radio-group" role="radiogroup">
  <label class="ch-radio">
    <input class="ch-radio-input" type="radio" name="radio" value="1" />
    <div class="ch-radio-text">1</div>
  </label>

  <label class="ch-radio">
    <input class="ch-radio-input" type="radio" name="radio" value="2" />
    <div class="ch-radio-text">2</div>
  </label>

  <label class="ch-radio" aria-disabled>
    <input
      class="ch-radio-input"
      disabled
      type="radio"
      name="radio"
      value="3"
    />
    <div class="ch-radio-text">3</div>
  </label>
</div>

.ch-checkbox

<label class="ch-checkbox">
  <div class="ch-checkbox-input-container">
    <input class="ch-checkbox-input" type="checkbox" name="ok" checked />
    <div class="ch-checkbox-icon">
      <pixiv-icon name="24/Check"></pixiv-icon>
    </div>
  </div>
  <div class="ch-checkbox-text">Agree to ToS</div>
</label>
<label class="ch-checkbox">
  <div class="ch-checkbox-input-container">
    <input class="ch-checkbox-input" type="checkbox" name="ok" />
    <div class="ch-checkbox-icon-hide">
      <pixiv-icon name="24/Check"></pixiv-icon>
    </div>
  </div>
  <div class="ch-checkbox-text">Agree to ToS</div>
</label>
<label class="ch-checkbox" aria-disabled>
  <div class="ch-checkbox-input-container">
    <input class="ch-checkbox-input" type="checkbox" name="ok" disabled />
    <div class="ch-checkbox-icon" aria-hidden="true">
      <pixiv-icon name="24/Check"></pixiv-icon>
    </div>
  </div>
  <div class="ch-checkbox-text">Agree to ToS</div>
</label>

.ch-switch

<label class="ch-switch">
  <input class="ch-switch-input" type="checkbox" />
  <div class="ch-switch-text">Agree to ToS</div>
</label>
<label class="ch-switch" aria-disabled>
  <input class="ch-switch-input" type="checkbox" disabled />
  <div class="ch-switch-text">Agree to ToS</div>
</label>

.ch-loading-spinner

<div class="ch-loading-spinner" role="progressbar">
  <div class="ch-loading-spinner-bubble"></div>
</div>

.ch-modal

<div>
  <button class="ch-button" id="ch-modal-button">open modal</button>

  <div class="ch-modal" style="display: none">
    <div class="ch-modal-dialog" role="dialog">
      <div class="ch-modal-body">
        <div class="ch-modal-header">
          <h3 class="ch-modal-title">title</h3>
        </div>
        <div class="ch-modal-align">
          <p>content</p>
        </div>
        <button class="ch-modal-close">
          <pixiv-icon name="24/Close"></pixiv-icon>
        </button>
      </div>
    </div>
  </div>
</div>
<script>
  // we need js for modal before invorkers.
  // https://github.com/whatwg/html/pull/9841
  // https://github.com/Fyrd/caniuse/issues/6856
  const button = document.querySelector("#ch-modal-button");
  const buttonClose = document.querySelector(".ch-modal-close");
  const modal = document.querySelector(".ch-modal");
  button.onclick = () => {
    modal.style.display = modal.style.display === "none" ? "" : "none";
  };
  buttonClose.onclick = () => (modal.style.display = "none");
</script>