npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sxl-studio/storybook-addon

v1.1.1

Published

Storybook addon for SXL Studio — displays Figma Embed, component info and design token status for linked components

Readme

@sxl-studio/storybook-addon

Storybook addon for SXL Studio — displays Figma Embed, component info, and design token status for components linked via the SXL Studio Figma plugin.

Changelog

See CHANGELOG.md (e.g. 1.1.1 registry matching fix; 1.1.0 preset CSP, /sxl-tokens, legacy filename alias, quieter logs).

Features

  • Figma Embed — live Figma design iframe centered in the addon panel
  • Component info — name, description, node ID, direct Figma link
  • Contract — component properties and variant count
  • Statuses — token assignment and design readiness badges

Installation

npm install @sxl-studio/storybook-addon --save-dev

Setup

1. Register the addon (main)

List @sxl-studio/storybook-addon in addons. The preset ships with the package and is applied when Storybook loads the addon (no separate preset import in main unless your setup requires the explicit @sxl-studio/storybook-addon/preset entry — see troubleshooting in docs).

Minimal main.ts:

export default {
  addons: [
    '@sxl-studio/storybook-addon',
    // ...other addons
  ],
};

With a shared Storybook config (internal design-system package, monorepo): append to the shared addons array — do not drop existing entries.

import sharedMain from '@your-org/storybook-vue/main';

const config = {
  ...sharedMain,
  addons: [...(sharedMain.addons ?? []), '@sxl-studio/storybook-addon'],
};

export default config;

2. Import the registry (preview)

The SXL Studio Figma plugin generates diff-code-connect.<figmaFileKey>.json (or an exported sxl-codeconnect.json). Put it in parameters.sxl.registry. The relative import path is up to your repo (e.g. ../../tokens/tokens/diff-code-connect.xxx.json).

  • fromDiffCodeConnect(raw) — explicit normalization; use if you prefer one code path.
  • Raw import registry from '...json' — often enough for current plugin output.

Preset (automatic): when the addon preset runs, it:

  • Serves a nearby tokens/tokens folder at /sxl-tokens/… (dev + storybook build via staticDirs) so compositionFilePath in the registry resolves without extra Vite config.
  • Can resolve.alias a stable filename like diff-code-connect.SXL-Components.json to the real diff-code-connect.*.json when only one candidate exists in that folder (see CHANGELOG).

Minimal preview.ts:

import registry from '../path/to/diff-code-connect.<fileKey>.json';

export default {
  parameters: {
    sxl: { registry },
  },
};

With a shared preview — merge parameters so shared decorators/globals stay intact:

import sharedPreview from '@your-org/storybook-vue/preview';
import registry from '../../tokens/tokens/diff-code-connect.<fileKey>.json';

export default {
  ...sharedPreview,
  parameters: {
    ...sharedPreview.parameters,
    sxl: { registry },
  },
};

Alternative — converter:

import raw from '../diff-code-connect.<fileKey>.json';
import { fromDiffCodeConnect } from '@sxl-studio/storybook-addon';

export default {
  parameters: {
    sxl: { registry: fromDiffCodeConnect(raw) },
  },
};

3. Match stories to Figma components

Stories are matched to registry entries by explicit sxl.component / sxl.figmaNodeId, or by a heuristic on story title and file path. A registry with a single component is not shown on every story — unrelated stories show a “no integration” state until the story context matches or you set parameters manually.

Per-story matching:

export const Default = {
  parameters: {
    sxl: { component: 'WButton' },
  },
};

Or by Figma node ID:

export const Default = {
  parameters: {
    sxl: { figmaNodeId: '1:23' },
  },
};

You can also pass data directly without a registry:

export const Default = {
  parameters: {
    sxl: {
      figmaUrl: 'https://www.figma.com/design/abc123?node-id=1-23',
      description: 'Primary action button',
      tokenStatus: 'assigned',
      readiness: 'ready-for-dev',
    },
  },
};

Registry format (sxl-codeconnect.json)

{
  "version": 1,
  "figmaFileKey": "abc123",
  "figmaFileName": "Design System",
  "entries": [
    {
      "nodeId": "1:23",
      "displayName": "WButton",
      "description": "Primary action button",
      "figmaUrl": "https://www.figma.com/design/abc123?node-id=1-23",
      "designEmbed": true,
      "metadata": true,
      "meta": {
        "variantCount": 12,
        "componentProperties": ["size", "variant", "disabled"],
        "tokenStatus": "assigned",
        "readiness": "ready-for-dev"
      }
    }
  ]
}

Parameters reference

| Parameter | Type | Description | |-----------|------|-------------| | sxl.registry | SxlRegistry | Global registry object (set once in preview.ts) | | sxl.component | string | Match entry by displayName | | sxl.figmaNodeId | string | Match entry by Figma node ID | | sxl.figmaUrl | string | Direct Figma URL (no registry needed) | | sxl.description | string | Override description | | sxl.tokenStatus | "assigned" \| "partial" \| "none" | Override token status | | sxl.readiness | "complete" \| "ready-for-dev" \| "in-progress" \| "backlog" | Override readiness | | sxl.compositionSources | Record<string, string> | Map repo-relative composition paths → raw JSON (recommended) | | sxl.compositionFetchBaseUrl | string | Base URL to fetch() composition by path (e.g. static dir) | | sxl.compositionDevProxyPrefix | string | Same-origin prefix (e.g. Vite proxy) so fetches avoid CORS to private Git | | sxl.resolveComposition | (path) => Promise<string \| undefined> | Custom loader for composition file content | | sxl.debugFigmaEmbed | boolean | Log embed URL and iframe load to the console |

Composition JSON (repo file, not inlined in diff)

The plugin writes only compositionFilePath (and flags) into diff-code-connect. The large JSON lives in your repo; Storybook must resolve it at runtime.

Option A — glob + raw import (Vite):

// preview.ts
const sources = import.meta.glob('../packages/ds/**/*.json', {
  query: '?raw',
  import: 'default',
  eager: true,
}) as Record<string, string>;

function indexByBasename(map: Record<string, string>): Record<string, string> {
  const out: Record<string, string> = {};
  for (const [k, v] of Object.entries(map)) {
    const rel = k.replace(/^.*?\/packages\//, 'packages/'); // align with compositionFilePath in diff
    out[rel] = v;
  }
  return out;
}

export default {
  parameters: {
    sxl: {
      registry: fromDiffCodeConnect(raw),
      compositionSources: indexByBasename(sources),
    },
  },
};

Match keys to compositionFilePath from the registry (same relative path as in the monorepo).

Option B — static dir + fetch:

// main.ts
export default {
  staticDirs: [{ from: '../path/to/compositions', to: '/sxl-compositions' }],
};

// preview.ts
export default {
  parameters: {
    sxl: {
      compositionFetchBaseUrl: `${import.meta.env.BASE_URL}sxl-compositions/`,
    },
  },
};

Option C — private GitLab / CORS: the addon may build a GitLab /-/raw/... URL from registry.repository.url, but the browser cannot read cross-origin responses without Access-Control-Allow-Origin. Use a same-origin dev proxy and point the addon at it:

// preview.ts — prefix must match your Vite proxy path
export default {
  parameters: {
    sxl: {
      compositionDevProxyPrefix: `${import.meta.env.BASE_URL}__sxl_git_raw/`,
    },
  },
};
// main.ts — forward to your host; adjust target and auth as needed.
// Compose with mergeSxlFigmaFrameSrcHeader if you also need Figma iframe CSP.
import { mergeSxlFigmaFrameSrcHeader } from '@sxl-studio/storybook-addon/preset';

export default {
  async viteFinal(config) {
    const base = await mergeSxlFigmaFrameSrcHeader(config);
    return {
      ...base,
      server: {
        ...base.server,
        proxy: {
          ...base.server?.proxy,
          '/__sxl_git_raw': {
            target: 'https://git.example.com',
            changeOrigin: true,
            secure: true,
            rewrite: (path) => path.replace(/^\/__sxl_git_raw/, ''),
          },
        },
      },
    };
  },
};

The addon also avoids a common mistake when repository.url already ends at .../src/components and compositionFilePath starts with components/... (no duplicated components/components/ segment in the raw URL).

Figma embed is blank (CSP)

The addon panel runs in the Storybook manager. If the browser’s Content-Security-Policy does not allow framing https://www.figma.com, the iframe stays empty (no error in React).

  1. Set parameters.sxl.debugFigmaEmbed: true in preview and check the console for [SXL Studio addon] Figma embed with the resolved embedUrl.
  2. In .storybook/main.ts (Vite), merge dev server headers so frame-src includes Figma:
import { mergeSxlFigmaFrameSrcHeader } from '@sxl-studio/storybook-addon/preset';

export default {
  async viteFinal(config) {
    return mergeSxlFigmaFrameSrcHeader(config);
  },
};
  1. Confirm the design URL opens in a new tab via Open embed in new tab in the panel.

Figma’s embed URL format is documented at Figma — Embed; Storybook does not special-case iframes — CSP is enforced by the dev server and browser.

Requirements

  • Storybook 8+
  • React 18+ or 19+

License

MIT