smithery.ai

Web Components

Working with the ss-icon Web Component and ss-loader

Installation

$ npx skills add https://smithery.ai

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from smithery.ai · top by installs.

npx skills add https://smithery.ai

Browse all from smithery.ai

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,096 B
  • docs SUMMARY.md 74 B

History

  1. First recorded snapshot · 1 installs

SKILL.md

Web Components Skill

This skill covers the two JavaScript components that render icons.

ss-icon Web Component

Location: src/ss-icon.js

Usage

<ss-icon icon="check"></ss-icon>
<ss-icon icon="arrow-left" thickness="1.5"></ss-icon>

Attributes

Attribute Type Default Description
icon string - Icon slug from icons.json
thickness number 2 Stroke width of the icon

How It Works

class SSIcon extends HTMLElement {
  // Watch for attribute changes
  static get observedAttributes() {
    return ["icon", "thickness"];
  }

  constructor() {
    super();
    this.attachShadow({ mode: "open" });
  }

  // Re-render when attributes change
  attributeChangedCallback(name, oldValue, newValue) {
    if (name === "icon" || name === "thickness") {
      this.render();
    }
  }

  render() {
    const iconName = this.getAttribute("icon");
    const iconSvg = icons[iconName];
    // Inject SVG with custom thickness into shadow DOM
  }
}

customElements.define("ss-icon", SSIcon);

Styling

The component inherits color from parent:

.my-button {
  color: blue;
}
.my-button ss-icon {
  /* Icon will be blue */
}

Override size:

ss-icon {
  font-size: 24px; /* Icons scale with font-size */
}

ss-loader (Class-based Icons)

Location: src/ss-loader.js

Usage

<i class="ss ss-check"></i>
<i class="ss ss-arrow-left"></i>

How It Works

  1. Initial Load: On DOMContentLoaded, finds all i.ss elements
  2. Extract Icon: Looks for class starting with ss-
  3. Inject SVG: Inserts SVG content into the element
  4. Mark Loaded: Adds data-ss-loaded="true" to prevent reprocessing
  5. Observe Changes: MutationObserver watches for new icons added dynamically
function replaceIcons() {
  const elements = document.querySelectorAll("i.ss");
  elements.forEach((el) => {
    if (el.dataset.ssLoaded) return; // Skip already processed
    
    const iconClass = classes.find(c => c.startsWith("ss-"));
    const iconName = iconClass.replace("ss-", "");
    const iconSvg = icons[iconName];
    
    if (iconSvg) {
      el.innerHTML = iconSvg;
      el.dataset.ssLoaded = "true";
    }
  });
}

// Watch for dynamically added icons
const observer = new MutationObserver((mutations) => {
  // Check for added nodes or class changes
  if (shouldUpdate) replaceIcons();
});

observer.observe(document.body, {
  childList: true,
  subtree: true,
  attributes: true,
  attributeFilter: ["class"]
});

Styling Class-based Icons

.ss {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: middle;
}

/* Custom styling */
.ss-check {
  color: green;
  font-size: 2rem;
}

CSS-Only Icons (Alternative)

For environments without JavaScript, use the CSS-only approach:

<link rel="stylesheet" href="senangstart.min.css">
<i class="ss ss-check"></i>

The CSS uses mask-image with data URIs - no JavaScript required.


Extending the Components

Adding New Attributes to ss-icon

  1. Add to observedAttributes array
  2. Handle in render() method
  3. Update tests in tests/ss-icon.test.js

Example: Adding a color attribute

static get observedAttributes() {
  return ["icon", "thickness", "color"];
}

render() {
  const color = this.getAttribute("color") || "currentColor";
  this.shadowRoot.innerHTML = `
    <style>
      :host { color: ${color}; }
      /* ... */
    </style>
    ${finalSvg}
  `;
}

Adding Animation Support

render() {
  const animate = this.hasAttribute("animate");
  this.shadowRoot.innerHTML = `
    <style>
      ${animate ? `
        @keyframes spin {
          from { transform: rotate(0deg); }
          to { transform: rotate(360deg); }
        }
        svg { animation: spin 1s linear infinite; }
      ` : ""}
    </style>
    ${finalSvg}
  `;
}