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

pgx-theme-resolver

v1.1.1

Published

Dynamic theme resolver library for PGX projects. Converts API theme tokens into CSS custom properties with a 3-layer architecture (primitives, semantic, Tailwind).

Readme

pgx-theme-resolver

Biblioteca dinâmica de resolução de temas para projetos PGX. Converte tokens de tema vindos de API ou JSON em CSS custom properties com arquitetura de 3 camadas (primitivos, semânticos, Tailwind).

Arquitetura

┌─────────────────────────────────────────────────────────────┐
│                        API / JSON                           │
│  { "Colors": { "CTA Colors": { "50": { hex: "#f5f4fe" } }} │
└──────────────────────────┬──────────────────────────────────┘
                           │
                    normalizePrimitiveTokens()
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│              Camada 1: CSS Vars Primitivos                  │
│  --cta-50: #f5f4fe   --brand-950: #0b0b0b                  │
│  --cta-op-50: rgba(245,244,254,0.5)                        │
└──────────────────────────┬──────────────────────────────────┘
                           │
                    referenciados via var()
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│              Camada 2: CSS Vars Semânticos                  │
│  --bg-page: var(--brand-950)                                │
│  --text-primary: var(--brand-50)                            │
│  --action-primary: var(--cta-600)                           │
└──────────────────────────┬──────────────────────────────────┘
                           │
                    @theme inline / config
                           │
                           ▼
┌─────────────────────────────────────────────────────────────┐
│              Camada 3: Tailwind Utilities                   │
│  bg-bg-page  text-text-primary  border-action-primary       │
└─────────────────────────────────────────────────────────────┘

Quando os primitivos mudam (via API), os semânticos atualizam automaticamente pela cascata CSS.

Instalação

# Via npm/pnpm/yarn
pnpm add pgx-theme-resolver

# Ou link local (desenvolvimento)
cd pgx-theme-resolver && pnpm install && pnpm build
cd ../seu-projeto && pnpm add ../pgx-theme-resolver

CLI — Geração de arquivos estáticos

Para projetos que preferem ter os arquivos de tema gerados estaticamente (sem resolução dinâmica), a lib oferece dois comandos CLI via npx:

npx pgx-theme generate-styles

Gera um arquivo CSS completo com :root vars (primitivos + semânticos + estáticos + fades + shadows). Se Tailwind CSS 4 for detectado no projeto (ou --tw4 for passado), inclui automaticamente o bloco @theme inline com os mapeamentos de cores.

# Gera src/styles/pgx-theme.css (detecta Tailwind automaticamente)
npx pgx-theme generate-styles

# Força Tailwind 4 (@theme inline incluído)
npx pgx-theme generate-styles --tw4

# Gera apenas :root vars, sem Tailwind
npx pgx-theme generate-styles --no-tailwind

# Output customizado
npx pgx-theme generate-styles --out=src/theme/variables.css

Arquivo gerado (com --tw4):

/* pgx-theme-resolver — Generated CSS */

:root {
  /* ── Primitivos ── */
  --cta-50: #f5f4fe;
  --cta-600: #754dda;
  --brand-950: #0b0b0b;
  /* ... 60+ primitivos ... */

  /* ── Semânticos ── */
  --bg-page: var(--brand-950);
  --text-primary: var(--brand-50);
  --action-primary: var(--cta-600);
  /* ... 50+ semânticos ... */

  /* ── Fades / Shadows ── */
  --fade-primary-default: linear-gradient(180deg, var(--cta-600) 0%, var(--cta-500) 100%);
  --shadow-primary: 0px 10px 15px var(--cta-op-700);
  /* ... */
}

/* ── Tailwind CSS 4 ── */
@theme inline {
  --color-bg-page: var(--bg-page);
  --color-text-primary: var(--text-primary);
  --color-cta-600: var(--cta-600);
  /* ... 120+ cores utilitárias ... */
}

Depois basta importar no seu globals.css:

@import "tailwindcss";
@import "./pgx-theme.css";

npx pgx-theme generate-tw-config

Gera um arquivo TypeScript (ou JavaScript) com o objeto de cores para Tailwind CSS 3. Detecta automaticamente se o projeto usa TS ou JS.

# Gera config/tailwind-theme-colors-config.ts (ou .js)
npx pgx-theme generate-tw-config

# Força JavaScript
npx pgx-theme generate-tw-config --js

# Output customizado
npx pgx-theme generate-tw-config --out=src/config/theme-colors.ts

Arquivo gerado (TypeScript):

/* pgx-theme-resolver — Tailwind CSS 3 Color Config */

export const themeColors = {
  /* ── bg ── */
  "bg-page": "var(--bg-page)",
  "bg-surface-primary": "var(--bg-surface-primary)",

  /* ── text ── */
  "text-primary": "var(--text-primary)",

  /* ── action ── */
  "action-primary": "var(--action-primary)",

  /* ── cta (primitivos) ── */
  "cta-50": "var(--cta-50)",
  "cta-600": "var(--cta-600)",
  /* ... 122 cores no total ... */
} as const;

export type ThemeColorKey = keyof typeof themeColors;

Uso no tailwind.config.ts:

import { themeColors } from "./config/tailwind-theme-colors-config";

export default {
  theme: {
    extend: {
      colors: themeColors,
    },
  },
};

npx pgx-theme apply-tokens <arquivo>

Lê um arquivo JSON de tokens e atualiza o bloco DEFAULT_PRIMITIVES em src/constants.ts com as cores extraídas. Roda do diretório raiz do projeto (process.cwd()); espera encontrar src/constants.ts ali.

# Aplica tokens (rode da raiz do projeto que contém src/constants.ts)
npx pgx-theme apply-tokens ./MULTIBET.tokens.json

# Depois rebuilda para atualizar os artefatos
pnpm build

Estruturas de arquivo suportadas

O parser aceita três combinações de envelope/token misturáveis no mesmo arquivo. O que importa é:

  1. Existir uma seção raiz "Colors" (cores sólidas) e/ou "Opacity Colors" (cores com canal alfa).
  2. Dentro de cada seção, grupos cujos nomes mapeiem para prefixos CSS via DEFAULT_GROUP_MAP ("CTA Colors"cta, "Brand Colors"brand, etc.).
  3. Dentro de cada grupo, um dicionário shade → token, onde token segue um dos formatos abaixo.
Envelope (camada raiz — obrigatório)
{
  "Colors":         { /* grupos com cores sólidas */ },
  "Opacity Colors": { /* grupos com cores translúcidas (mesmas chaves, alpha definido) */ }
}

Pelo menos uma das duas chaves precisa existir. Outras chaves de raiz são ignoradas.

Token — Formato A (DTCG, exportação direta do Figma)
{ "$type": "color", "$value": { "hex": "#191000", "alpha": 0.5 } }
Token — Formato B (API PGX / objeto plano)
{ "hex": "#191000", "alpha": 0.5 }
Token — Formato C (DTCG sem $type, só $value)
{ "$value": { "hex": "#191000" } }

Em qualquer dos formatos, alpha é opcional e só é usado dentro de "Opacity Colors" para gerar rgba(...).

Nomes de grupo aceitos (case/sufixo flexível)

Para cada chave no DEFAULT_GROUP_MAP, o resolver tenta:

  • match exato"CTA Colors"
  • match case-insensitive"cta colors", "Cta Colors"
  • com sufixo " Colors" adicionado → "CTA" resolve para "CTA Colors"
  • sem sufixo " Colors" → "Green Colors" resolve para "Green"

Ou seja, "Brand Colors", "Brand", "brand" e "BRAND COLORS" apontam todos para --brand-*.

Chaves de shade

Aceita strings numéricas ("50", "950") e formas Figma como "0% - 950", normalizadas via replace:

| Input no JSON | CSS var resultante | |---|---| | Colors / "CTA Colors" / "50" com hex | --cta-50: #... | | Opacity Colors / "CTA Colors" / "50" com hex + alpha | --cta-op-50: rgba(...) | | Opacity Colors / "Brand Colors" / "0% - 800" | --brand-op-0-800: rgba(...) |

Exemplo completo (mistura de formatos válida)
{
  "Colors": {
    "CTA Colors": {
      "50":  { "$type": "color", "$value": { "hex": "#f5f4fe" } },
      "600": { "hex": "#754dda" }
    },
    "Brand": {
      "950": { "$value": { "hex": "#0b0b0b" } }
    },
    "Green": {
      "400": { "hex": "#10b981" }
    }
  },
  "Opacity Colors": {
    "CTA Colors": {
      "600": { "hex": "#754dda", "alpha": 0.5 }
    },
    "Brand": {
      "0% - 800": { "$value": { "hex": "#272727", "alpha": 0 } }
    }
  }
}

Não suportado pelo apply-tokens (mas aceito em outras camadas): formato legado plano ({ "bg": { "page": "#080816" } }). Esse formato é processado por resolveThemeFromJson e é descrito em Formato dos dados da API → Formato legado — não passa por apply-tokens porque ele só atualiza primitivos, e o legado já vem como semânticos.

npx pgx-theme apply-tokens-local <arquivo>

Comando único que lê o JSON de tokens e gera, no projeto do usuário, todos os arquivos necessários pra usar o tema sem runtime JS:

  • src/styles/pgx-theme.css:root com primitivos do JSON + semânticos + estáticos + fades + @theme inline { ... } (se Tailwind 4 detectado).
  • config/tailwind-theme-colors-config.ts (ou .js) — export const themeColors = { ... } pronto pra tailwind.config.

Detecção automática:

  • Tailwind v4 → inclui @theme inline no CSS (não precisa de tailwind.config).
  • Tailwind v3 → CSS puro + arquivo TW config separado.
  • TS/JS → escolhe o formato do TW config conforme o tsconfig.json do projeto.

Se o JSON não trouxer algum dos grupos esperados (cta, brand, special, green, yellow, red), o comando avisa no log e preenche com DEFAULT_PRIMITIVES da lib pra evitar quebrar os semânticos. Arquivos existentes são sobrescritos sem prompt.

npx pgx-theme apply-tokens-local ./brand-tokens.json

Exemplo de saída:

  pgx-theme apply-tokens-local
  Input: /seu-projeto/brand-tokens.json

  ✓ 6 tokens extraídos do JSON

  ⚠ Grupos ausentes no JSON — preenchidos com DEFAULT_PRIMITIVES:
      • --special-*
      • --green-*
      • --yellow-*
      • --red-*

  ✓ CSS gerado: /seu-projeto/src/styles/pgx-theme.css
      Tailwind: v4 (@theme inline incluído)
  ✓ TW config gerado: /seu-projeto/config/tailwind-theme-colors-config.ts
      Formato: TypeScript • 102 cores

Depois disso o usuário só precisa de 2 coisas:

/* globals.css */
@import "tailwindcss";
@import "./styles/pgx-theme.css";
// tailwind.config.ts (apenas TW3 — TW4 não precisa)
import { themeColors } from "./config/tailwind-theme-colors-config";
export default { theme: { extend: { colors: themeColors } } };

Nenhum applyTheme(), useTheme(), <ThemeStyle> ou fetch envolvido — o tema vira asset estático.

Diferença vs. apply-tokens: apply-tokens é o workflow do dev da lib (atualiza src/constants.ts da própria pgx-theme-resolver). apply-tokens-local é o workflow do consumidor — só escreve em paths do projeto dele e nunca toca na lib.

npx pgx-theme init

Cria um arquivo pgx-theme.config.ts com o template completo de configuração.

npx pgx-theme init

Flags da CLI

| Comando | Flag | Descrição | |---------|------|-----------| | generate-styles | --out=<path> | Caminho do output (default: src/styles/pgx-theme.css) | | | --tw4 | Força inclusão do @theme inline | | | --tw3 | Não inclui @theme inline | | | --no-tailwind | Gera apenas :root vars | | generate-tw-config | --out=<path> | Caminho do output (default: config/tailwind-theme-colors-config.ts) | | | --ts | Força TypeScript | | | --js | Força JavaScript | | apply-tokens | <arquivo> | Caminho do arquivo JSON de tokens (obrigatório) | | apply-tokens-local | <arquivo> | Caminho do arquivo JSON de tokens (obrigatório) | | | --out-css=<path> | Override do CSS (default: src/styles/pgx-theme.css) | | | --out-tw=<path> | Override do TW config (default: config/tailwind-theme-colors-config.{ts,js}) | | | --no-tw-config | Não gera o arquivo de TW config (apenas o CSS) | | | --tw4 / --tw3 | Força versão do Tailwind | | | --ts / --js | Força formato do TW config |


Workflow local — tema 100% estático (sem fetch/get)

Quando você não quer depender de chamada HTTP em runtime, mantenha um JSON de tokens versionado no projeto e use um único comando: apply-tokens-local. Ele gera CSS + TW config no projeto e sobrescreve em re-runs. As cores ficam "nativas": o navegador resolve via cascata, sem JS.

Passo 1 — Crie o JSON de marca

Pode vir do Figma (DTCG) ou ser escrito à mão. Estrutura mínima:

// brand-tokens.json (na raiz do projeto)
{
  "Colors": {
    "CTA Colors":   { "50": { "hex": "#..." }, "600": { "hex": "#..." }, /* ... */ },
    "Brand Colors": { "50": { "hex": "#..." }, "950": { "hex": "#..." }, /* ... */ }
  },
  "Opacity Colors": {
    "CTA Colors":   { "600": { "hex": "#...", "alpha": 0.5 } },
    "Brand Colors": { "800": { "hex": "#...", "alpha": 0.5 } }
  }
}

(Aceita todos os formatos descritos em Estruturas de arquivo suportadas. Grupos faltantes são preenchidos com defaults — você verá um aviso no log.)

Passo 2 — Rode o comando

npx pgx-theme apply-tokens-local ./brand-tokens.json

Resultado:

brand-tokens.json
       │
       │  apply-tokens-local
       ▼
   ┌───┴──────────────────────────────────────────────────────────┐
   ▼                                                              ▼
src/styles/pgx-theme.css            config/tailwind-theme-colors-config.ts
:root { primitivos + semânticos     export const themeColors = { ... }
        + estáticos + fades }       (consumido pelo tailwind.config)
@theme inline { ... } (TW4)

Passo 3 — Plug nos arquivos do seu projeto

/* src/app/globals.css */
@import "tailwindcss";
@import "./styles/pgx-theme.css";
// tailwind.config.ts (apenas TW3 — TW4 já tem o @theme inline no CSS)
import { themeColors } from "./config/tailwind-theme-colors-config";
export default { theme: { extend: { colors: themeColors } } };

A partir daqui o uso é idêntico ao de cores nativas do Tailwind:

<div className="bg-bg-page text-text-primary">
  <button className="bg-action-primary text-action-on-primary hover:bg-action-primary-hover">
    Comprar
  </button>
</div>

Ou via CSS puro:

.card {
  background: var(--bg-surface-primary);
  color: var(--text-primary);
  border: 1px solid var(--bg-border-primary);
}

Nenhum <ThemeStyle>, applyTheme(), useTheme() ou fetch envolvido.

Automação (opcional)

// package.json
{
  "scripts": {
    "theme:apply": "pgx-theme apply-tokens-local ./brand-tokens.json"
  }
}

Rode pnpm theme:apply sempre que brand-tokens.json mudar (plugue em pre-commit ou CI).


Quick Start

1. Básico — Aplicar tema da API no DOM

import {
  resolveThemeFromApi,
  applyTheme,
} from "pgx-theme-resolver";

// Dados vindos da API (ou mock)
const apiData = {
  Colors: {
    "CTA Colors": {
      "50": { hex: "#f5f4fe" },
      "100": { hex: "#edebfc" },
      "600": { hex: "#754dda" },
      "900": { hex: "#472a88" },
    },
    "Brand Colors": {
      "50": { hex: "#fafafa" },
      "900": { hex: "#141414" },
      "950": { hex: "#0b0b0b" },
    },
  },
  "Opacity Colors": {
    "CTA Colors": {
      "600": { hex: "#754dda", alpha: 0.5 },
    },
  },
};

// Resolve → aplica
const vars = resolveThemeFromApi(apiData);
applyTheme(vars);

2. SSR (Next.js App Router)

// app/layout.tsx
import {
  fetchAndResolveTheme,
  getDefaultTheme,
} from "pgx-theme-resolver";
import { ThemeStyle } from "pgx-theme-resolver/react";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const vars =
    (await fetchAndResolveTheme({
      url: `${process.env.API_URL}/themes`,
    })) ?? getDefaultTheme();

  return (
    <html>
      <head>
        <ThemeStyle vars={vars} id="pgx-theme" />
      </head>
      <body>{children}</body>
    </html>
  );
}

3. React Hook (Client-side)

import { useTheme } from "pgx-theme-resolver/react";

function ThemeLoader() {
  const { setTheme } = useTheme();

  useEffect(() => {
    fetch("/api/themes")
      .then((r) => r.json())
      .then((data) => setTheme(data.value));
  }, [setTheme]);

  return null;
}

4. Gerar <style> tag como string (SSR genérico)

import {
  resolveThemeFromApi,
  buildStyleTag,
} from "pgx-theme-resolver";

const vars = resolveThemeFromApi(apiData);
const css = buildStyleTag(vars);
// → ":root{--cta-50:#f5f4fe;--brand-950:#0b0b0b;...}"

// Injetar no HTML:
const html = `<html><head><style>${css}</style></head>...</html>`;

5. Formato legado/simplificado (JSON plano)

import { resolveThemeFromJson, applyTheme } from "pgx-theme-resolver";

const json = {
  bg: { page: "#080816", surfacePrimary: "#1F1F40" },
  text: { primary: "#E6E6F8" },
  action: { primary: "#0062FF" },
};

const vars = resolveThemeFromJson(json);
applyTheme(vars);

6. Resposta completa da API

import {
  resolveThemeFromResponse,
  applyTheme,
} from "pgx-theme-resolver";

const response = await fetch("/api/themes").then((r) => r.json());
// response = { id, name, active, value: {...}, ... }

const vars = resolveThemeFromResponse(response);
applyTheme(vars);

Integração com Tailwind CSS

Tailwind CSS 4 (@theme inline)

import { generateTailwindThemeBlock } from "pgx-theme-resolver";

const block = generateTailwindThemeBlock();
console.log(block);

Cole o output no seu globals.css:

@import "tailwindcss";

/* ... seus :root vars ... */

@theme inline {
  /* output do generateTailwindThemeBlock() */
  --color-bg-page: var(--bg-page);
  --color-text-primary: var(--text-primary);
  --color-action-primary: var(--action-primary);
  --color-cta-600: var(--cta-600);
  /* ... */
}

Agora você pode usar: bg-bg-page, text-text-primary, bg-cta-600, etc.

Tailwind CSS 3 (tailwind.config.js)

const { generateTailwindV3Colors } = require("pgx-theme-resolver");

module.exports = {
  theme: {
    extend: {
      colors: generateTailwindV3Colors(),
    },
  },
};

API Reference

Resolvers

| Função | Input | Descrição | |--------|-------|-----------| | resolveThemeFromApi(value, options?) | ThemeApiValue | Resolve tokens do formato da API PGX | | resolveThemeFromResponse(response, options?) | ThemeApiResponse | Resolve a partir da resposta completa do endpoint | | resolveThemeFromJson(json, options?) | ThemeJson | Resolve a partir do formato legado/simplificado | | getDefaultTheme(overrides?) | — | Retorna tema padrão (fallback) |

DOM

| Função | Descrição | |--------|-----------| | applyTheme(vars, options?) | Aplica CSS vars via style.setProperty() | | clearTheme(target?) | Remove todas as CSS vars inline | | buildStyleTag(vars, selector?) | Gera string CSS (:root{...}) | | buildStyleElement(vars, id?, selector?) | Cria <style> element |

Fetch

| Função | Descrição | |--------|-----------| | fetchAndResolveTheme(options) | Busca + resolve em uma chamada | | fetchThemeValue(options) | Busca apenas o ThemeApiValue bruto |

Normalize (low-level)

| Função | Descrição | |--------|-----------| | normalizePrimitiveTokens(json, groupMap?) | Converte formato API → CSS vars | | normalizeThemeJson(json) | Converte formato legado → CSS vars |

Tailwind

| Função | Descrição | |--------|-----------| | generateTailwindThemeBlock(extra?) | Gera @theme inline { ... } para TW4 | | generateTailwindV3Colors() | Gera objeto de cores para TW3 config |

React (pgx-theme-resolver/react)

| Export | Tipo | Descrição | |--------|------|-----------| | useTheme(options?) | Hook | Resolve + aplica temas dinamicamente | | ThemeStyle | Component | <style> tag para SSR |

CLI

| Comando | Descrição | |---------|-----------| | npx pgx-theme apply-tokens-local <file> | Comando único — gera CSS + TW config no projeto a partir de um JSON (sem runtime JS) | | npx pgx-theme generate-styles | Gera CSS com :root + @theme inline (TW4) — usa DEFAULT_PRIMITIVES da lib | | npx pgx-theme generate-tw-config | Gera arquivo de cores para tailwind.config (TW3) — usa DEFAULT_PRIMITIVES da lib | | npx pgx-theme apply-tokens <file> | Workflow do dev da lib: atualiza DEFAULT_PRIMITIVES em src/constants.ts | | npx pgx-theme init | Cria pgx-theme.config.ts com template completo |

Constantes exportadas

| Constante | Descrição | |-----------|-----------| | DEFAULT_GROUP_MAP | Mapeamento de grupos API → prefixos CSS | | DEFAULT_SEMANTIC_TOKENS | Tokens semânticos padrão (camada 2) | | DEFAULT_PRIMITIVES | Cores primitivas padrão (fallback) | | STATIC_TOKENS | Tokens estáticos (gamification) | | TAILWIND_COLOR_MAP | Mapeamento semântico → Tailwind |

Customização

Mapeamento de grupos customizado

Se a sua API usa nomes de grupo diferentes:

const vars = resolveThemeFromApi(apiData, {
  groupMap: {
    "Primary Colors": "cta",    // mapeia "Primary Colors" → --cta-*
    "Neutral Colors": "brand",  // mapeia "Neutral Colors" → --brand-*
  },
});

Tokens semânticos customizados

Sobrescreva ou adicione tokens semânticos:

const vars = resolveThemeFromApi(apiData, {
  semanticTokens: {
    "--bg-page": "var(--cta-1100)",        // sobrescreve
    "--bg-custom": "var(--brand-800)",     // adiciona novo
  },
});

Aplicar em elemento específico

applyTheme(vars, {
  target: document.getElementById("my-app")!,
  cleanPrevious: true,
});

Formato dos dados da API

Formato principal (ThemeApiValue)

{
  "Colors": {
    "CTA Colors": {
      "50": { "hex": "#f5f4fe" },
      "100": { "hex": "#edebfc" },
      "600": { "hex": "#754dda" },
      "900": { "hex": "#472a88" }
    },
    "Brand Colors": {
      "50": { "hex": "#fafafa" },
      "950": { "hex": "#0b0b0b" }
    },
    "Green": {
      "400": { "hex": "#10b981" }
    }
  },
  "Opacity Colors": {
    "CTA Colors": {
      "600": { "hex": "#754dda", "alpha": 0.5 }
    }
  }
}

Formato legado (ThemeJson)

{
  "bg": {
    "page": "#080816",
    "surfacePrimary": "#1F1F40"
  },
  "text": {
    "primary": "#E6E6F8"
  },
  "action": {
    "primary": "#0062FF"
  }
}

Resposta completa (ThemeApiResponse)

{
  "id": "uuid",
  "name": "dark-purple",
  "active": true,
  "allowedUsers": null,
  "value": { /* ThemeApiValue */ },
  "createdAt": "2024-01-01T00:00:00Z",
  "updatedAt": "2024-01-01T00:00:00Z"
}

Tokens disponíveis

Primitivos (Camada 1)

| Grupo | Shades | Exemplo | |-------|--------|---------| | CTA | 50-1100 (14 shades) | --cta-600: #754dda | | Brand | 50-950 (11 shades) | --brand-950: #0b0b0b | | Green | 50, 200, 400, 800 | --green-400: #10b981 | | Yellow | 100, 300, 500, 800 | --yellow-500: #ffc801 | | Special | 100, 300, 500, 800 | --special-300: #fcbb4d | | Red | 100, 300, 500, 800 | --red-500: #ef4444 |

Cada grupo tem variantes de opacidade: --cta-op-600, --brand-op-800, etc.

Semânticos (Camada 2)

| Categoria | Tokens | |-----------|--------| | Background | --bg-page, --bg-surface-primary, --bg-surface-secondary, --bg-on-surface-primary, --bg-border-primary, --bg-border-secondary, --bg-page-border | | Text | --text-primary, --text-secondary, --text-tertiary, --text-inverse, --text-disabled, --text-special | | Icon | --icon-primary, --icon-secondary, --icon-disabled, --icon-special | | Success | --semantic-success, -container, -on-container, -border-container | | Warning | --semantic-warning, -container, -on-container, -border-container | | Error | --semantic-error, -container, -on-container, -border-container | | Info | --semantic-info, -container, -on-container, -border-container | | Action Primary | --action-primary, -on-primary, -hover, -pressed, -disabled, -border | | Action Secondary | --action-secondary, -active, -on-secondary, -hover, -pressed, -disabled, -border | | Action Special | --action-special, -on-special, -hover, -pressed, -border | | Input | --input-rest-primary, -rest-secondary, -hover, -active, -border-*, -on-container-* |

Estáticos

| Categoria | Tokens | |-----------|--------| | Gamification Bronze | --gamification-bronze, -container, -border-container, -on-container | | Gamification Prata | --gamification-prata, -container, -border-container, -on-container | | Gamification Ouro | --gamification-ouro, -container, -border-container, -on-container |

Uso com Mock (desenvolvimento)

import {
  getDefaultTheme,
  applyTheme,
  DEFAULT_PRIMITIVES,
} from "pgx-theme-resolver";

// Usa o tema padrão completo
applyTheme(getDefaultTheme());

// Ou sobrescreve apenas alguns primitivos
applyTheme({
  ...getDefaultTheme(),
  "--cta-600": "#ff0000",
  "--brand-950": "#000033",
});

TypeScript

Todos os tipos são exportados:

import type {
  ThemeApiValue,
  ThemeApiResponse,
  ThemeJson,
  CssVarMap,
  SemanticTokenMap,
  GroupMap,
  ThemeResolverOptions,
  FetchThemeOptions,
} from "pgx-theme-resolver";

Playground

O projeto inclui um playground interativo com Vite para testar os 4 temas mock em tempo real, com 3 variantes de switcher (select, tabs, radio) e preview visual de todos os tokens.

pnpm install
pnpm playground
# → http://localhost:5173

O playground mostra:

  • Select — dropdown para trocar de tema
  • Switcher (Tabs) — botões side-by-side com highlight no ativo
  • Radio Buttons — com nome e descrição de cada tema
  • Theme Preview — textos, backgrounds, paletas CTA/Brand, botões de ação, estados semânticos, gradients, shadows, inputs, icons e gamification

Todas as cores atualizam em tempo real ao trocar de tema.

Build

pnpm install
pnpm build       # Gera dist/ (CJS + ESM + types + CLI)
pnpm typecheck   # Verifica tipos
pnpm test        # Executa testes
pnpm playground  # Abre playground interativo (Vite)

License

MIT