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

@commenteme/react

v0.7.0

Published

Componentes React de commente.me (kit de marca e interface v3.3.1): os do admin da Especificaciones — campos, combobox, datas, filtros, tabela, gráficos, KPI, permissões, busca global ⌘K, status de pedido, modal, drawer, toast — e o layout com submenu e s

Downloads

622

Readme

@commenteme/react

Componentes React do admin de commente.me (app.commente.me), do kit de marca e interface v3.3.1: botões, campos, controles de escolha, badges, avisos, abas, tabela, modal, toast, stepper, configuração e o layout do admin (sidebar com submenu, drawer no celular, topbar, cabeçalho de página). Medidas, cores e estados saem do kit; nenhum hex solto.

npm install @commenteme/react

Traz junto @commenteme/tokens e @commenteme/icons. React 18 ou 19.

Estilos

Com Tailwind 4:

@import "tailwindcss";
@import "@commenteme/tokens/tailwind.css";
@import "@commenteme/react/styles.css";

Sem Tailwind, os tokens antes dos componentes:

import '@commenteme/tokens/tokens.css';
import '@commenteme/react/styles.css';

O layout raiz do app leva .ctx-admin: fonte do sistema, base 14px, fundo papel gris.

Os estilos ficam na camada components, na mesma ordem de camadas do Tailwind. Uma classe utilitária no className vence o componente: <Button className="w-full">.

Componentes

import { Button, Field, Input, Select, Badge, Alert } from '@commenteme/react';

<Button variant="primario" icon="sincronizar">Sincronizar</Button>

<Field label="RUT empresa" hint="Con guion." error={erro}>
  <Input name="rut" />
</Field>

| componente | o que é | |---|---| | Button | variant: primario (um por vista), secundario (padrão), acento (só ação comercial), fantasma, destructivo (só dentro da confirmação), peligro (contorno vermelho, o da zona de perigo). size: sm 32 · md 40 · lg 48, raio 6/8/10. icon de 16px. loading mostra o spinner e bloqueia o clique; loadingText="Guardando…" troca o texto. type="button" por padrão. | | IconButton | Só ícone, quadrado. label é obrigatório e vira aria-label e title. | | buttonClass() | As classes do botão para outro elemento: <Link className={buttonClass({ variant: 'primario' })}>. | | Field | Rótulo em cima, controle, ajuda ou erro embaixo, já ligados (for, aria-describedby, aria-invalid). error troca a ajuda e marca o controle. disabled e required passam para o controle. | | Input | 40px, raio 8. prefix e suffix (CLP $, https://, .myvtex.com), icon (buscar), shortcut (⌘K), mono (account name, SKU). | | Select | O <select> nativo com o chevron-abajo. | | Combobox | Para clientes, SKU, marketplaces: options (filtra sozinho pelo rótulo e pelo meta) ou onSearch (servidor, debounce de 250 ms, «Buscando…»). Coincidência em negrito sem acento nem caixa, até 8 visíveis, «Sin coincidencias para “zz”.». role="combobox" com aria-activedescendant; setas, Enter, Esc. Dentro de Field. | | DateRangePicker | O período da topbar e dos filtros: «28-09 — 04-10» (ano só se não for o atual) e, com comparação, «vs. 21 — 27-09». Atalhos, dois meses com a semana na segunda, o futuro bloqueado, «Comparar con» (período anterior ou ano passado); nada muda até «Aplicar». size filtro 36 ou md 40. | | DateInput | Data solta dd-mm-aaaa com os hífens entrando sozinhos e a validação ao sair (onValidityChange): o erro vai no Field. Funções formatFecha, parseFecha, formatRango, periodoComparado também para o servidor. | | Textarea | maxLength + showCount mostra 12/280; dentro do Field, na linha do rótulo. | | Checkbox | 18px, raio 5, check de 12 com traço 3,2; size="sm" é o da tabela, 16px, raio 4, check de 10 com traço 3,6. label, description, indeterminate. | | RadioGroup + Radio | Fieldset com título; name e valor marcado (value ou defaultValue, onValueChange) vão para os radios. error põe a mensagem do grupo embaixo, ligada por aria-describedby. | | RadioCard | Radio em cartão (o rol, o marketplace, o objetivo): padding 14, raio 10; selecionado com borda azul de 1,5 e --seleccion-fondo. Dentro de <RadioGroup cards>, a grade de 200px. | | Switch | 36×20, role="switch". Com label, ocupa a linha: texto à esquerda, switch à direita. | | Fieldset | Título + grupo de checkboxes ou switches. disabled desliga todos. | | Badge | status: conectado, atencion, error, pausado, borrador. Ponto + texto; o texto padrão é o nome do estado. | | OrderStatus, orderStatus(), OrderTimeline | O status de pedido do OMS: o código VTEX vira o nome em espanhol no badge certo (o mapa completo do kit; invoiced com tracking é «Despachado»); late soma o «Atrasado». A linha do tempo do detalhe: feito, atual e pendente. | | Tag | kind: nuevo (amarelo) ou proximamente (contorno). | | Counter | 20px, 11/700, vermelho. max mostra 99+. | | Chip | Filtro aplicado: «Canal: Falabella» ou «Canal: 2». 36 de altura, fundo info, borda azul, × de 12. onRemove tira (pelo × ou Backspace com foco); onEdit reabre o filtro. | | FilterButton, FilterBar | «+ Canal» com borda pontilhada, 36 de altura; a barra junta chips e botões e põe o «Limpiar» (onClear) no fim. | | Alert | tone: info, atencion (fundo --atencion-fondo, ícone --atencion-icono), error, exito. Raio 10, ícone 18. title em negrito + texto; um link dentro sai sublinhado. | | ErrorPage | 404, 500, sem permissão e sem conexão com VTEX (kind), com o texto do kit: código de 44 ou ícone na caixa de 52, título, texto e um botão secundário. | | ConnectionBanner, SuperAdminBar | As faixas de atenção: «Sin conexión con VTEX desde las 09:12…» com «Reintentar», embaixo da topbar; e «Estás en la cuenta X como super admin…» com «Salir de la cuenta». | | EmptyState | Ícone de 24, sem círculo, na caixa de 52px; title, texto até 40ch e no máximo uma action (primária no estado inicial, «Limpiar filtros» secundária sem resultados, nenhuma quando está ao dia). | | Lockup, Ladrillo | O logo em curvas — não precisa da Barlow. onBlue para fundo azul: ladrillo e logotipo brancos, ponto amarelo. | | Spinner, Icon | O spinner do botão e o <Icon> de @commenteme/icons. | | Tabs + TabPanel | Abas com painéis: altura 40, 24 entre elas, a ativa 600 em azul com --activo-tab. Setas, Home e End trocam de aba. count põe o contador cinza. Mudam o conteúdo; para ver os mesmos dados de outro jeito, o segmentado. | | NavTabs | Abas que são links (cada uma uma URL); a atual com current. | | SegmentedControl | O segmentado único (Día · Semana · Mes, 2 a 4 opções): fundo papel gris, ativo em branco com --sombra-1. Radios nativos: entra no FormData. | | Breadcrumb | Migalhas com «/» em --borde-campo, só a partir do nível 2; até 4 níveis (com mais, os do meio viram «…»); o último é a página atual, sem link. | | Pagination | «Mostrando 26–50 de 1.284», as páginas com reticências (até 7 posições) e, com onPageSizeChange, o seletor «Filas» 25 · 50 · 100. onPageChange (botão) ou hrefFor (link, ?pagina=2&filas=50). Abaixo de 960, só «‹ 2 de 52 ›». | | Table e partes | Table, TableHead, TableBody, TableRow (selected), TableHeaderCell, TableCell (variant: id, meta, num; align), TableSelectCell, TableEmpty. Uma <table> de verdade. | | Cabeçalho ordenável + useTableSort | TableHeaderCell com sort e onSort: o texto vira botão, o <th> ganha aria-sort e o ícone de 12 (ordenar, chevron-arriba, chevron-abajo) vai à direita; ordenada em azul. useTableSort() guarda uma coluna por vez e dá sortProps('total'); o clique alterna ascendente → descendente → sem ordem (nextSort). | | ActionMenu | O menu do botão «más»: items com label, icon, onSelect ou href, disabled e destructive — o destrutivo vai sempre por último, depois de um separador. 200 a 280px, itens de 36. Setas, Home, End, Enter e Esc; o foco volta ao botão. No top layer (popover), a rolagem da tabela não o corta. | | Tooltip | Envolve um elemento: <Tooltip content="Sincronizar"><IconButton … /></Tooltip>. Tinta, 12px, até 240 numa linha; 400 ms no hover, na hora com foco de teclado, some com Esc. Nunca leva ação. Num IconButton com o mesmo texto, não repete a descrição e tira o title nativo. | | SummaryList | Chave e valor do passo «Revisión» e das fichas, num <dl>: valor 14/600 à direita, missing em vermelho com o ícone («Falta API key»), «Cambiar» por onChange ou changeHref. | | LineChart | Tempo: principal em --dato-principal de 2px, comparação em --dato-comparacion pontilhada, meta em --dato-meta; grade de no máximo 5 linhas; legenda em cima; tooltip pelo ponteiro ou pelas setas, com a variação contra o comparado; «Ver datos» troca pela tabela. Entra uma vez em --t-grafico. | | BarList | Ranking em barras horizontais do maior para o menor, no máximo 10 + «Ver todo», valor à direita. | | DonutChart | Partes de um total: no máximo 5 (as 4 maiores + «Otros» em --dato-6), total no centro, legenda com o percentual. | | KpiCard | label, source (mono 11), value 28/700 e delta (value, direction, good): ▲/▼ com sinal, azul se melhora e vermelho se piora — passe good: false no CPA que sobe. Sem delta, «Sin período anterior». fullValue vira tooltip do valor abreviado; loading dá o esqueleto; error mostra «No disponible»; href torna o cartão clicável. | | FileUpload, FileUploadItem | A zona de soltar de verdade (<input type="file">): accept, maxSize, hint e onFiles(aceitos, recusados) com o motivo (tipo, tamanho). A linha do arquivo mostra o percentual e a barra, o sucesso ou o erro em vermelho. validarArquivos() para a mesma regra no servidor. | | Skeleton, SkeletonText, SkeletonGroup | Esqueletos de carga: papel gris, raio 4, pulso de 1,2 s, invisíveis nos primeiros 300 ms. SkeletonGroup dá aria-busy e o «Cargando…» para leitor de tela. Sem spinner em tabela nem cartão. | | SelectionBar + useSelection | Barra azul de 48px «3 seleccionados», que substitui a barra de filtros, com as ações à direita (no máximo 3 + «más», uma só em amarelo, fantasmas em branco); com total e onSelectAll, o link «Seleccionar los 1.284». O hook guarda os marcados e diz o estado do «selecionar todos». | | PermissionsMatrix | Módulo × Ver / Editar / Exportar / Administrar: ação liga Ver, tirar Ver limpa a linha (alternarPermissao); limit dá o teto do super admin (cadeado com «Lo habilita commente.me»); contracted: false desliga a linha; roles no segmentado, que passa a «Personalizado» ao mexer; a barra tinta conta as mudanças contra savedValue e oferece «Descartar» e «Guardar permisos». | | Modal | Até 480px (--modal-max), --sombra-modal, título + frase, footer à direita; entra com escala e opacidade e abre no primeiro campo. Para confirmar ou uma tarefa de 1 a 3 campos. dismissible={false} em passo com dados não salvos. | | ConfirmDialog | Confirmação destrutiva; abre com o foco no Cancelar; com confirmWord, só libera o botão com a palavra escrita. | | Drawer | Editar um registro sem perder a tabela: pela direita, 460px, altura toda, header de 60 com o fechar, footer fixo; abaixo de 960, a tela toda. Mesma API do Modal (open, onClose, title, description, footer, dismissible). Mais de 8 campos pedem página própria. | | ToastProvider + useToast | toast('Cambios guardados.'), com action: { label: 'Deshacer', onClick }; some em 4 s (duration: 8000 para o deshacer de ação em massa). tone: 'error': ícone vermelho, «Reintentar», não some sozinho, tem o fechar e é anunciado na hora. Um por vez; os seguintes esperam. | | Stepper | Passos do formulário longo: feito, atual, pendente, marca de 22px. | | Card | Cartão branco, raio 12, título e ações opcionais; flush para tabela de borda a borda. | | SettingsSection, DangerZone | Configuração em duas colunas e a zona de perigo com o botão peligro. | | AppShell, Sidebar, SidebarSection, SidebarItem, SidebarGroup | A moldura do admin: sidebar de 248px, fixa, com rolagem própria; itens de 38px com ícone 20 (ativo em --info-fondo, azul 700 e a barra amarela; contador vermelho só para alerta; «Pronto»); SidebarGroup é o item com submenu (subitens de 32px sobre a guia, chevron que gira, pai em azul quando um filho está ativo, soma dos alertas quando fechado). Conteúdo até 1360px. Abaixo de 960, a sidebar vira drawer de 280px com o véu. | | CommandPalette, CommandPaletteTrigger, useCommandPaletteShortcut | A busca global ⌘K: o painel de 560 a 15% do topo, campo de 52, grupos (Pedidos, Productos, Clientes, Ir a) com no máximo 5, coincidência em negrito, «Preguntar a Dante» na última linha (⌘↵). Sem texto, emptyGroups (recentes, frequentes). Quem usa faz a busca — e respeita a loja ativa. | | OnboardingChecklist | O cartão «Primeros pasos» do Inicio: «2 de 5», a barra, os passos que levam à sua tela, feitos riscados, e «Ocultar». | | StoreSwitcher | O seletor de conta e loja da topbar: botão de 44 com as iniciais da conta, popover de 300 com busca a partir de 6 opções, grupos por conta (e «Otras cuentas» para o super admin), a loja em uso com o check, a que tem erro com o badge. Digitar filtra; ↑↓, Enter, Esc. | | Topbar, StoreBadge, Avatar | Barra do topo de 60px (no celular, com o botão de menu 44×44), a loja em uso com o host do VTEX, as iniciais. | | PageHeader | Migalhas (só do nível 2) → título 24/700 com badge de estado → meta 13px → ações à direita (1 primária + 1 secundária) → abas. | | LinkProvider, AppLink | O link do app para os componentes que navegam. |

Todos aceitam className e as props do elemento HTML; os controles aceitam ref.

Layout e links

import { forwardRef } from 'react';
import { Link, Outlet } from 'react-router';
import {
  AppShell, Avatar, LinkProvider, Lockup, Sidebar, SidebarGroup, SidebarItem, SidebarSection, ToastProvider, Topbar,
  type LinkComponentProps,
} from '@commenteme/react';

const RouterLink = forwardRef<HTMLAnchorElement, LinkComponentProps>(({ href, ...props }, ref) => (
  <Link ref={ref} to={href} {...props} />
));

export default function LayoutAdmin() {
  return (
    <LinkProvider component={RouterLink}>
      <ToastProvider>
        <AppShell
          sidebar={
            <Sidebar
              logo={<Link to="/" aria-label="commente.me, Inicio"><Lockup size={24} /></Link>}
              footer={
                <SidebarSection aria-label="Cuenta">
                  <SidebarItem href="/configuracion" icon="configuracion">Configuración</SidebarItem>
                  <SidebarItem href="https://help.commente.me" icon="soporte">Soporte</SidebarItem>
                  <SidebarItem href="/salir" icon="salir" muted>Salir</SidebarItem>
                </SidebarSection>
              }
            >
              <SidebarSection aria-label="Menú principal">
                <SidebarItem href="/" icon="inicio">Inicio</SidebarItem>
                <SidebarGroup icon="oms" label="OMS" active>
                  <SidebarItem href="/oms/pedidos" active count={4}>Pedidos</SidebarItem>
                  <SidebarItem href="/oms/envios">Envíos</SidebarItem>
                </SidebarGroup>
                <SidebarGroup icon="catalogo" label="Catálogo">
                  <SidebarItem href="/catalogo/productos">Productos</SidebarItem>
                </SidebarGroup>
              </SidebarSection>
            </Sidebar>
          }
          topbar={<Topbar end={<Avatar name="María Contreras" />} />}
        >
          <Outlet />
        </AppShell>
      </ToastProvider>
    </LinkProvider>
  );
}

O AppShell já põe o .ctx-admin e liga o botão de menu da Topbar à sidebar: abaixo de 960px ela vira drawer, Esc e o véu fecham e o foco volta ao botão. O Modal e o ConfirmDialog são o <dialog> nativo: prendem o foco, fecham com Esc e devolvem o foco a quem abriu, sem biblioteca.

Os nomes do menu são os do kit: palavra comum ou sigla do ofício, só a primeira maiúscula (Inicio, OMS, Catálogo, Comparador de precios, Reportes, Conversaciones). Conexiones e Integraciones moram só em Configuración. Rotas e submenus completos na skill, em referencias/menu.md.

Por que elementos nativos

Botão é <button>, campo é <input>, select é <select>, checkbox, radio e switch são <input> com a caixa desenhada por baixo. Teclado, leitor de tela, celular e autofill funcionam sem código, e os valores entram no FormData — o <Form> do React Router e as server actions recebem tudo sem fiação extra.

Ver todos

npm run build -w @commenteme/react && npm run demo -w @commenteme/react
# abre packages/react/.demo/index.html

Um admin de mentira, montado com os próprios componentes, num HTML só que abre do disco: menu com submenus, abas, tabela com seleção, ordenação, menu de ações e drawer de edição, filtros, paginação com filas, tooltip, esqueletos, cartões de KPI, assistente por passos com radio em cartão e revisão, upload de preços, configuração com modal, confirmação destrutiva e toast de sucesso e de erro — tudo funcionando. Para comparar com a Biblioteca e a Especificaciones do kit v3.3.1 (referencias/kit-v3/reference/ na skill).

Ainda não

Os componentes do sitio (commente.me, help e support) ainda se constroem com as medidas da skill (referencias/sitio.md). Do admin, a Especificaciones inteira já está no pacote.

Versão e licença

Versionamento semântico próprio; mudanças em CHANGELOG.md. MIT para o código. A marca commente.me — nome, logotipo, ladrillo e lockup — não entra nessa licença: ver MARCA.md.