{"v":0,"components":{"blocos-bannerdecookies":{"id":"blocos-bannerdecookies","name":"BannerDeCookies","path":"./src/blocks/BannerDeCookies/BannerDeCookies.stories.tsx","jsDocTags":{},"description":"Aviso de cookies com aceite rápido e painel de preferências por categoria. Copie para o seu hotsite.","reactDocgenTypescript":{"tags":{"example":"const salvo = localStorage.getItem('consentimento')\n{!salvo && (\n  <BannerDeCookies\n    policyHref=\"/politica-de-cookies\"\n    onSave={(consent) => localStorage.setItem('consentimento', JSON.stringify(consent))}\n  />\n)}"},"filePath":"src/blocks/BannerDeCookies/BannerDeCookies.tsx","description":"Bloco de campanha \"Banner de cookies\": aviso fixo no rodapé com o link da política, \"Aceitar todos\" e\n\"Personalizar\". Personalizar abre o painel de preferências com uma chave por categoria; a categoria obrigatória\nfica sempre ativa. Depois da escolha, o aviso some.\n\nO bloco não grava cookies nem carrega scripts: guarde o consentimento e só ative as ferramentas de cada categoria\ndepois dele. Mostre o bloco apenas enquanto não houver uma escolha salva. Fica fora do pacote: copie para o seu\nhotsite.","displayName":"BannerDeCookies","methods":[],"props":{"policyHref":{"defaultValue":null,"description":"Endereço da política de cookies.","name":"policyHref","parent":{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"}],"required":true,"type":{"name":"string"}},"categories":{"defaultValue":{"value":"[\n  { id: 'necessarios', label: 'Necessários', description: 'Essenciais para o site funcionar.', required: true },\n  { id: 'desempenho', label: 'Desempenho', description: 'Mostram como o site é usado, para melhorá-lo.' },\n  { id: 'funcionais', label: 'Funcionais', description: 'Lembram suas preferências.' },\n  { id: 'marketing', label: 'Marketing', description: 'Personalizam conteúdos e ofertas.' },\n]"},"description":"Categorias do painel de preferências. Padrão: Necessários (sempre ativos), Desempenho, Funcionais e Marketing.","name":"categories","parent":{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"}],"required":false,"type":{"name":"CookieCategory[]"}},"onSave":{"defaultValue":null,"description":"Recebe a escolha da pessoa, com uma chave por categoria.","name":"onSave","parent":{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"}],"required":true,"type":{"name":"(consent: CookieConsent) => void"}},"message":{"defaultValue":{"value":"Usamos cookies para o site funcionar e para melhorar sua experiência."},"description":"Texto do aviso.","name":"message","parent":{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/BannerDeCookies/BannerDeCookies.tsx","name":"BannerDeCookiesProps"}],"required":false,"type":{"name":"string"}}},"exportName":"BannerDeCookies"},"stories":[{"id":"blocos-bannerdecookies--default","name":"Default","snippet":"const Default = () => <BannerDeCookies policyHref=\"#politica-de-cookies\" />;","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-bannerdecookies--preferencias","name":"Preferencias","snippet":"const Preferencias = () => <BannerDeCookies policyHref=\"#politica-de-cookies\" />;","exportName":"Preferencias","tags":["dev","test","manifest","play-fn"]},{"id":"blocos-bannerdecookies--celular","name":"Celular","snippet":"const Celular = () => <BannerDeCookies policyHref=\"#politica-de-cookies\" />;","exportName":"Celular","tags":["dev","test","manifest"]}],"import":"import { BannerDeCookies } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Blocos/BannerDeCookies"},"blocos-cadastro-de-cupom":{"id":"blocos-cadastro-de-cupom","name":"CadastroCupom","path":"./src/blocks/CadastroCupom/CadastroCupom.stories.tsx","jsDocTags":{},"description":"Bloco de campanha fora do pacote npm: card de cadastro de cupom fiscal com CPF (com máscara), número da\nnota e botão de envio. Valida os campos obrigatórios e mostra uma mensagem de sucesso. Copie para o seu hotsite e\nligue o `onSubmit` à API da campanha.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/CadastroCupom/CadastroCupom.tsx","description":"Bloco de campanha \"Cadastro de cupom\": card com CPF, número da nota fiscal e botão de envio, com validação de\ncampos obrigatórios e mensagem de sucesso. Copie para o seu hotsite e ligue o\n`onSubmit` à API da campanha; não faz parte do pacote.","displayName":"CadastroCupom","methods":[],"props":{"title":{"defaultValue":null,"description":"Título do card.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"}],"required":true,"type":{"name":"string"}},"description":{"defaultValue":null,"description":"Texto de apoio abaixo do título.","name":"description","parent":{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"}],"required":true,"type":{"name":"string"}},"submitLabel":{"defaultValue":null,"description":"Texto do botão de envio.","name":"submitLabel","parent":{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"}],"required":true,"type":{"name":"string"}},"successMessage":{"defaultValue":null,"description":"Mensagem exibida depois de um envio válido.","name":"successMessage","parent":{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"}],"required":true,"type":{"name":"string"}},"onSubmit":{"defaultValue":null,"description":"Recebe CPF (só dígitos) e número da nota depois da validação.","name":"onSubmit","parent":{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/CadastroCupom/CadastroCupom.tsx","name":"CadastroCupomProps"}],"required":false,"type":{"name":"((values: CadastroCupomValues) => void)"}}},"exportName":"CadastroCupom"},"stories":[{"id":"blocos-cadastro-de-cupom--default","name":"Default","snippet":"const Default = () => <CadastroCupom\n    title=\"Cadastre seu cupom\"\n    description=\"Preencha os dados da nota para receber seus números da sorte.\"\n    submitLabel=\"Participar\"\n    successMessage=\"Cupom cadastrado! Seus números da sorte chegam por e-mail.\" />;","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-cadastro-de-cupom--validacao","name":"Validacao","snippet":"const Validacao = () => <CadastroCupom\n    title=\"Cadastre seu cupom\"\n    description=\"Preencha os dados da nota para receber seus números da sorte.\"\n    submitLabel=\"Participar\"\n    successMessage=\"Cupom cadastrado! Seus números da sorte chegam por e-mail.\" />;","description":"Envio vazio mostra os erros; CPF com máscara e nota preenchida enviam só os dígitos.","exportName":"Validacao","tags":["dev","test","manifest","play-fn"]}],"import":"import { CadastroCupom } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Blocos/Cadastro de cupom"},"blocos-como-participar":{"id":"blocos-como-participar","name":"ComoParticipar","path":"./src/blocks/ComoParticipar/ComoParticipar.stories.tsx","jsDocTags":{},"description":"Bloco de campanha fora do pacote npm: seção \"Como participar\" de um hotsite promocional,\npromo.idplugger.com — título, introdução, quatro passos (Compre, Cadastre, Vale brinde, Concorra) e o botão\n\"Quero Participar\". Copie para o seu hotsite e troque os textos.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/ComoParticipar/ComoParticipar.tsx","description":"Bloco de campanha \"Como participar\": título, introdução, passos numerados em grade e botão de ação.\nCopie para o seu hotsite; não faz parte do pacote.","displayName":"ComoParticipar","methods":[],"props":{"title":{"defaultValue":null,"description":"Título da seção.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"}],"required":true,"type":{"name":"string"}},"intro":{"defaultValue":null,"description":"Texto de introdução abaixo do título.","name":"intro","parent":{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"}],"required":true,"type":{"name":"ReactNode"}},"steps":{"defaultValue":null,"description":"Passos numerados, na ordem de exibição.","name":"steps","parent":{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"}],"required":true,"type":{"name":"ComoParticiparStep[]"}},"ctaLabel":{"defaultValue":null,"description":"Texto do botão de ação.","name":"ctaLabel","parent":{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"}],"required":true,"type":{"name":"string"}},"onCtaClick":{"defaultValue":null,"description":"Chamado ao clicar no botão de ação.","name":"onCtaClick","parent":{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ComoParticipar/ComoParticipar.tsx","name":"ComoParticiparProps"}],"required":false,"type":{"name":"(() => void)"}}},"exportName":"ComoParticipar"},"stories":[{"id":"blocos-como-participar--default","name":"Default","snippet":"const Default = () => <ComoParticipar\n    title=\"Como participar\"\n    intro={(<>Veja como é fácil participar da <strong>“Sua promo é um sucesso”</strong>, seguindo os passos abaixo. Vamos\n              conectar sua empresa na melhor plataforma de promoção.\n            </>)}\n    steps={[\n      {\n        title: 'Compre',\n        description: 'R$650,00 em produtos da Linha Promo quero Mais da idPlugger',\n        icon: <IconShoppingCart size={36} />,\n      },\n      {\n        title: 'Cadastre',\n        description: 'O cupom fiscal aqui no site da promoção da idPlugger',\n        icon: <IconReceiptLong size={36} />,\n      },\n      {\n        title: 'Vale brinde',\n        description: 'Aos sorteios semanais, além de um mega prêmio final',\n        icon: <IconCardGiftcard size={36} />,\n      },\n      {\n        title: 'Concorra',\n        description: 'Aos sorteios semanais, além de um mega prêmio final',\n        icon: <IconEmojiEvents size={36} />,\n      },\n    ]}\n    ctaLabel=\"Quero Participar\" />;","exportName":"Default","tags":["dev","test","manifest","play-fn"]}],"import":"import { ComoParticipar } from '@handsondigital/idplugger-ui';\nimport { IconCardGiftcard, IconEmojiEvents, IconReceiptLong, IconShoppingCart } from '@handsondigital/idplugger-ui/icons';","title":"Blocos/Como participar"},"blocos-confirmacao":{"id":"blocos-confirmacao","name":"Confirmacao","path":"./src/blocks/Confirmacao/Confirmacao.stories.tsx","jsDocTags":{},"description":"Card de fim de fluxo: cupom, conferência de dados, atendimento e senha. Copie para o seu hotsite.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/Confirmacao/Confirmacao.tsx","description":"Bloco de campanha \"Confirmação\": card de fim de fluxo com ícone de status, título, mensagem, dados para conferir,\naviso e ações. Serve para cupom cadastrado, conferência de dados antes de confirmar, atendimento registrado e senha\nalterada. O título é o `h1` da página. Fica fora do pacote: copie para o seu hotsite.","displayName":"Confirmacao","methods":[],"props":{"status":{"defaultValue":null,"description":"`success` (concluído), `info` (recebido, em análise) ou `warning` (confira antes de confirmar).","name":"status","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":true,"type":{"name":"enum","raw":"\"success\" | \"info\" | \"warning\"","value":[{"value":"\"success\""},{"value":"\"info\""},{"value":"\"warning\""}]}},"title":{"defaultValue":null,"description":"Título da confirmação; é o `h1` da página.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":true,"type":{"name":"string"}},"message":{"defaultValue":null,"description":"Mensagem principal abaixo do título.","name":"message","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":true,"type":{"name":"ReactNode"}},"details":{"defaultValue":null,"description":"Dados para conferir, em pares rótulo/valor (CNPJ, valor da compra, data, número do cupom).","name":"details","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":false,"type":{"name":"ConfirmacaoDetail[]"}},"notice":{"defaultValue":null,"description":"Aviso exibido antes das ações (ex.: as informações não poderão ser alteradas).","name":"notice","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":false,"type":{"name":"ReactNode"}},"primaryAction":{"defaultValue":null,"description":"Ação principal.","name":"primaryAction","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":false,"type":{"name":"ConfirmacaoAction"}},"secondaryAction":{"defaultValue":null,"description":"Ação secundária.","name":"secondaryAction","parent":{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Confirmacao/Confirmacao.tsx","name":"ConfirmacaoProps"}],"required":false,"type":{"name":"ConfirmacaoAction"}}},"exportName":"Confirmacao"},"stories":[{"id":"blocos-confirmacao--cupom-cadastrado","name":"Cupom Cadastrado","snippet":"const CupomCadastrado = () => <Confirmacao\n    status=\"success\"\n    title=\"Cupom cadastrado!\"\n    message=\"Seus números da sorte já estão na sua conta. Boa sorte!\"\n    primaryAction={{ label: 'Ver meus números', href: '#numeros' }}\n    secondaryAction={{ label: 'Cadastrar outro cupom', href: '#cadastro' }} />;","exportName":"CupomCadastrado","tags":["dev","test","manifest"]},{"id":"blocos-confirmacao--confirmar-dados","name":"Confirmar Dados","snippet":"const ConfirmarDados = () => <Confirmacao\n    status=\"warning\"\n    title=\"Confira os dados do cupom\"\n    message=\"As informações abaixo estão corretas?\"\n    details={[\n      { label: 'CNPJ', value: '00.000.000/0001-00' },\n      { label: 'Valor da compra', value: 'R$ 150,00' },\n      { label: 'Data da compra', value: '15/10/2026' },\n      { label: 'Número do cupom', value: '000123456' },\n    ]}\n    notice=\"Estas informações não poderão ser alteradas após a confirmação.\"\n    primaryAction={{ label: 'Confirmar', onClick: fn() }}\n    secondaryAction={{ label: 'Corrigir', onClick: fn() }} />;","exportName":"ConfirmarDados","tags":["dev","test","manifest"]},{"id":"blocos-confirmacao--atendimento-registrado","name":"Atendimento Registrado","snippet":"const AtendimentoRegistrado = () => <Confirmacao\n    status=\"info\"\n    title=\"Atendimento registrado\"\n    message=\"Recebemos sua solicitação. Nossa equipe responde em até 2 dias úteis pelo e-mail cadastrado.\"\n    primaryAction={{ label: 'Acompanhar atendimento', href: '#atendimentos' }} />;","exportName":"AtendimentoRegistrado","tags":["dev","test","manifest"]},{"id":"blocos-confirmacao--senha-alterada","name":"Senha Alterada","snippet":"const SenhaAlterada = () => <Confirmacao\n    status=\"success\"\n    title=\"Senha alterada\"\n    message=\"Sua senha foi alterada. Use a nova senha no próximo acesso.\"\n    primaryAction={{ label: 'Acessar', href: '#login' }} />;","exportName":"SenhaAlterada","tags":["dev","test","manifest"]}],"import":"import { Confirmacao } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Blocos/Confirmacao"},"blocos-faq":{"id":"blocos-faq","name":"Faq","path":"./src/blocks/Faq/Faq.stories.tsx","jsDocTags":{},"description":"Bloco de campanha fora do pacote npm: perguntas frequentes em acordeão, uma aberta por vez. Serve como\nseção da home ou como a página de FAQ do hotsite. Copie para o seu hotsite e troque as perguntas.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/Faq/Faq.tsx","description":"Bloco de campanha \"Perguntas frequentes\": título e acordeão com uma pergunta aberta por vez (abrir uma fecha a\nanterior). Cada pergunta é um botão com `aria-expanded`/`aria-controls` dentro de um `h3`, e a resposta é uma\nregião rotulada pela pergunta. Copie para o seu hotsite; não faz parte do pacote.","displayName":"Faq","methods":[],"props":{"title":{"defaultValue":null,"description":"Título da seção.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/Faq/Faq.tsx","name":"FaqProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Faq/Faq.tsx","name":"FaqProps"}],"required":true,"type":{"name":"string"}},"items":{"defaultValue":null,"description":"Perguntas e respostas, na ordem de exibição.","name":"items","parent":{"fileName":"idplugger-ui/src/blocks/Faq/Faq.tsx","name":"FaqProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Faq/Faq.tsx","name":"FaqProps"}],"required":true,"type":{"name":"FaqItem[]"}}},"exportName":"Faq"},"stories":[{"id":"blocos-faq--default","name":"Default","snippet":"const Default = () => <Faq\n    title=\"Perguntas frequentes\"\n    items={[\n      {\n        question: 'Como faço para participar?',\n        answer: (\n          <p style={{ margin: 0 }}>\n            Compre os produtos participantes, cadastre o cupom fiscal no site da promoção e acompanhe seus números da\n            sorte na área do participante.\n          </p>\n        ),\n      },\n      {\n        question: 'Quem pode participar da promoção?',\n        answer: <p style={{ margin: 0 }}>Pessoas físicas maiores de 18 anos, residentes e domiciliadas no Brasil.</p>,\n      },\n      {\n        question: 'Qual é o prazo para participar?',\n        answer: <p style={{ margin: 0 }}>Os cupons podem ser cadastrados até a data final informada no regulamento.</p>,\n      },\n      {\n        question: 'Quais são os prêmios?',\n        answer: (\n          <ul style={{ margin: 0, paddingInlineStart: 20 }}>\n            <li>Sorteios semanais de vale-compras;</li>\n            <li>Um prêmio final entre todos os participantes.</li>\n          </ul>\n        ),\n      },\n      {\n        question: 'Não encontrei minha dúvida, o que eu faço?',\n        answer: <p style={{ margin: 0 }}>Fale com o atendimento pelo formulário de contato do site da promoção.</p>,\n      },\n    ]} />;","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-faq--uma-aberta-por-vez","name":"Uma Aberta Por Vez","snippet":"const UmaAbertaPorVez = () => <Faq\n    title=\"Perguntas frequentes\"\n    items={[\n      {\n        question: 'Como faço para participar?',\n        answer: (\n          <p style={{ margin: 0 }}>\n            Compre os produtos participantes, cadastre o cupom fiscal no site da promoção e acompanhe seus números da\n            sorte na área do participante.\n          </p>\n        ),\n      },\n      {\n        question: 'Quem pode participar da promoção?',\n        answer: <p style={{ margin: 0 }}>Pessoas físicas maiores de 18 anos, residentes e domiciliadas no Brasil.</p>,\n      },\n      {\n        question: 'Qual é o prazo para participar?',\n        answer: <p style={{ margin: 0 }}>Os cupons podem ser cadastrados até a data final informada no regulamento.</p>,\n      },\n      {\n        question: 'Quais são os prêmios?',\n        answer: (\n          <ul style={{ margin: 0, paddingInlineStart: 20 }}>\n            <li>Sorteios semanais de vale-compras;</li>\n            <li>Um prêmio final entre todos os participantes.</li>\n          </ul>\n        ),\n      },\n      {\n        question: 'Não encontrei minha dúvida, o que eu faço?',\n        answer: <p style={{ margin: 0 }}>Fale com o atendimento pelo formulário de contato do site da promoção.</p>,\n      },\n    ]} />;","description":"Abrir uma pergunta fecha a anterior; clicar de novo fecha; o teclado (Enter/Espaço) abre como o clique.","exportName":"UmaAbertaPorVez","tags":["dev","test","manifest","play-fn"]}],"import":"import { Faq } from '@handsondigital/idplugger-ui';","title":"Blocos/FAQ"},"blocos-footer":{"id":"blocos-footer","name":"Footer","path":"./src/blocks/Footer/Footer.stories.tsx","jsDocTags":{},"description":"Bloco de campanha fora do pacote npm: rodapé com logo, redes sociais, texto legal, links legais e a\nfaixa final de crédito. Copie para o seu hotsite e troque o logo e o conteúdo legal.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/Footer/Footer.tsx","description":"Bloco de campanha \"Rodapé\": logo, redes sociais, texto legal, links legais e a faixa final de crédito.\nCentralizado em uma coluna no celular; em telas largas, três colunas (logo + redes | texto legal | links).\nCopie para o seu hotsite; não faz parte do pacote.","displayName":"Footer","methods":[],"props":{"logo":{"defaultValue":null,"description":"Logo da campanha (ex.: `<img src=\"...\" alt=\"Nome da campanha\" />`).","name":"logo","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":true,"type":{"name":"ReactNode"}},"social":{"defaultValue":null,"description":"Redes sociais da campanha.","name":"social","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":false,"type":{"name":"FooterSocialLink[]"}},"socialTitle":{"defaultValue":{"value":"Nas redes"},"description":"Título da coluna de redes. Padrão: `'Nas redes'`.","name":"socialTitle","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":false,"type":{"name":"string"}},"legalText":{"defaultValue":null,"description":"Período da campanha, certificado SPA/MF etc.","name":"legalText","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":false,"type":{"name":"ReactNode"}},"links":{"defaultValue":null,"description":"Regulamento, Política de privacidade, Termos de uso.","name":"links","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":false,"type":{"name":"FooterLink[]"}},"credit":{"defaultValue":{"value":"(\n    <>\n      Desenvolvido por{' '}\n      <a href=\"https://idplugger.com.br\" target=\"_blank\" rel=\"noopener noreferrer\">\n        idPlugger\n      </a>\n    </>\n  )"},"description":"Padrão: \"Desenvolvido por idPlugger\" com link para `https://idplugger.com.br`.","name":"credit","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":false,"type":{"name":"ReactNode"}},"tone":{"defaultValue":{"value":"navy"},"description":"`navy` (padrão, como nas referências) ou `surface`.","name":"tone","parent":{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Footer/Footer.tsx","name":"FooterProps"}],"required":false,"type":{"name":"enum","raw":"\"navy\" | \"surface\"","value":[{"value":"\"navy\""},{"value":"\"surface\""}]}}},"exportName":"Footer"},"stories":[{"id":"blocos-footer--default","name":"Default","snippet":"const Default = () => <Footer\n    logo={<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>}\n    social={[\n      { network: 'facebook', href: 'https://facebook.com' },\n      { network: 'instagram', href: 'https://instagram.com' },\n      { network: 'youtube', href: 'https://youtube.com' },\n      { network: 'whatsapp', href: 'https://wa.me/550000000000' },\n    ]}\n    legalText={(<p style={{ margin: 0 }}>Promoção válida de 01/01/2026 a 31/03/2026, mediante cadastro no site. Certificado de autorização SPA/MF\n              00.000000/0000.\n            </p>)}\n    links={[\n      { label: 'Regulamento', href: '#regulamento' },\n      { label: 'Política de privacidade', href: '#privacidade' },\n      { label: 'Termos de uso', href: '#termos' },\n    ]} />;","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-footer--surface","name":"Surface","snippet":"const Surface = () => <Footer\n    logo={<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>}\n    social={[\n      { network: 'facebook', href: 'https://facebook.com' },\n      { network: 'instagram', href: 'https://instagram.com' },\n      { network: 'youtube', href: 'https://youtube.com' },\n      { network: 'whatsapp', href: 'https://wa.me/550000000000' },\n    ]}\n    legalText={(<p style={{ margin: 0 }}>Promoção válida de 01/01/2026 a 31/03/2026, mediante cadastro no site. Certificado de autorização SPA/MF\n              00.000000/0000.\n            </p>)}\n    links={[\n      { label: 'Regulamento', href: '#regulamento' },\n      { label: 'Política de privacidade', href: '#privacidade' },\n      { label: 'Termos de uso', href: '#termos' },\n    ]}\n    tone=\"surface\" />;","exportName":"Surface","tags":["dev","test","manifest"]},{"id":"blocos-footer--celular","name":"Celular","snippet":"const Celular = () => <Footer\n    logo={<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>}\n    social={[\n      { network: 'facebook', href: 'https://facebook.com' },\n      { network: 'instagram', href: 'https://instagram.com' },\n      { network: 'youtube', href: 'https://youtube.com' },\n      { network: 'whatsapp', href: 'https://wa.me/550000000000' },\n    ]}\n    legalText={(<p style={{ margin: 0 }}>Promoção válida de 01/01/2026 a 31/03/2026, mediante cadastro no site. Certificado de autorização SPA/MF\n              00.000000/0000.\n            </p>)}\n    links={[\n      { label: 'Regulamento', href: '#regulamento' },\n      { label: 'Política de privacidade', href: '#privacidade' },\n      { label: 'Termos de uso', href: '#termos' },\n    ]} />;","description":"360px: colunas empilham e tudo fica centralizado.","exportName":"Celular","tags":["dev","test","manifest"]}],"import":"import { Footer } from '@handsondigital/idplugger-ui';","title":"Blocos/Footer"},"blocos-header":{"id":"blocos-header","name":"Header","path":"./src/blocks/Header/Header.stories.tsx","jsDocTags":{},"description":"Bloco de campanha fora do pacote npm: cabeçalho com logo, navegação, CTA ou saudação da área logada e\nmenu móvel acessível. Copie para o seu hotsite e troque o logo e os itens.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/Header/Header.tsx","description":"Bloco de campanha \"Cabeçalho\": logo, navegação, CTA ou saudação da área logada. Em telas estreitas a navegação vira\num painel suspenso aberto pelo hambúrguer (Escape fecha e devolve o foco; clicar num item fecha; a rolagem da\npágina trava enquanto está aberto). Copie para o seu hotsite; não faz parte\ndo pacote.","displayName":"Header","methods":[],"props":{"logo":{"defaultValue":null,"description":"Logo da campanha (ex.: `<img src=\"...\" alt=\"Nome da campanha\" />`).","name":"logo","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":true,"type":{"name":"ReactNode"}},"logoHref":{"defaultValue":{"value":"/"},"description":"Link do logo. Padrão: `'/'`.","name":"logoHref","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"string"}},"items":{"defaultValue":null,"description":"Itens de navegação (âncoras ou páginas).","name":"items","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":true,"type":{"name":"HeaderNavItem[]"}},"currentHref":{"defaultValue":null,"description":"Marca o item atual com `aria-current=\"page\"`.","name":"currentHref","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"string"}},"cta":{"defaultValue":null,"description":"Ação de destaque (ex.: \"Cadastre-se\"); ignorada quando `user` é informado.","name":"cta","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"HeaderCta"}},"user":{"defaultValue":null,"description":"Área logada: mostra \"Olá, {primeiro nome}\" no lugar do `cta`.","name":"user","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"HeaderUser"}},"tone":{"defaultValue":{"value":"surface"},"description":"`surface` (fundo claro) ou `navy` (fundo `--color-brand-navy`, texto claro). Padrão: `surface`.","name":"tone","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"enum","raw":"\"navy\" | \"surface\"","value":[{"value":"\"navy\""},{"value":"\"surface\""}]}},"sticky":{"defaultValue":{"value":"true"},"description":"Fixa o cabeçalho no topo ao rolar. Padrão: `true`.","name":"sticky","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"boolean"}},"skipToHref":{"defaultValue":{"value":"#conteudo"},"description":"Alvo do link \"Pular para o conteúdo\". Padrão: `'#conteudo'`.","name":"skipToHref","parent":{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Header/Header.tsx","name":"HeaderProps"}],"required":false,"type":{"name":"string"}}},"exportName":"Header"},"stories":[{"id":"blocos-header--default","name":"Default","snippet":"const Default = () => <Header\n    logo={(<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>)}\n    items={[\n      { label: 'Como participar', href: '#como-participar' },\n      { label: 'Produtos', href: '#produtos' },\n      { label: 'Prêmios', href: '#premios' },\n      { label: 'Dúvidas', href: '#faq' },\n    ]}\n    cta={{ label: 'Cadastre-se', href: '#cadastro' }} />;","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-header--navy","name":"Navy","snippet":"const Navy = () => <Header\n    logo={(<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>)}\n    items={[\n      { label: 'Como participar', href: '#como-participar' },\n      { label: 'Produtos', href: '#produtos' },\n      { label: 'Prêmios', href: '#premios' },\n      { label: 'Dúvidas', href: '#faq' },\n    ]}\n    cta={{ label: 'Cadastre-se', href: '#cadastro' }}\n    tone=\"navy\" />;","exportName":"Navy","tags":["dev","test","manifest"]},{"id":"blocos-header--logado","name":"Logado","snippet":"const Logado = () => <Header\n    logo={(<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>)}\n    items={[\n      { label: 'Como participar', href: '#como-participar' },\n      { label: 'Produtos', href: '#produtos' },\n      { label: 'Prêmios', href: '#premios' },\n      { label: 'Dúvidas', href: '#faq' },\n    ]}\n    cta={{ label: 'Cadastre-se', href: '#cadastro' }}\n    user={{ name: 'Maria Oliveira', href: '#perfil' }} />;","exportName":"Logado","tags":["dev","test","manifest"]},{"id":"blocos-header--celular","name":"Celular","snippet":"const Celular = () => <Header\n    logo={(<span style={{ font: '700 1.25rem/1 var(--font-brand-heading)', color: 'inherit' }}>Campanha</span>)}\n    items={[\n      { label: 'Como participar', href: '#como-participar' },\n      { label: 'Produtos', href: '#produtos' },\n      { label: 'Prêmios', href: '#premios' },\n      { label: 'Dúvidas', href: '#faq' },\n    ]}\n    cta={{ label: 'Cadastre-se', href: '#cadastro' }} />;","description":"360px: o menu vira um painel suspenso aberto pelo hambúrguer.","exportName":"Celular","tags":["dev","test","manifest","play-fn"]}],"import":"import { Header } from '@handsondigital/idplugger-ui';","title":"Blocos/Header"},"blocos-hero":{"id":"blocos-hero","name":"Hero","path":"./src/blocks/Hero/Hero.stories.tsx","jsDocTags":{},"description":"Hero de campanha em card com mídia e ações ou banner com arte e sobreposição para leitura do título.\n\n**Quando usar:** abrir uma página de campanha com sua mensagem e ação principal.\n\n**Quando não usar:** introduzir seções internas sem ação de destaque; use um título de seção.","reactDocgenTypescript":{"tags":{"example":"<Hero title=\"Participe e concorra\" description=\"Cadastre sua compra.\" primaryAction={{ label: 'Participar', href: '#cadastro' }} />"},"filePath":"src/blocks/Hero/Hero.tsx","description":"Hero de campanha em card com mídia e ações ou banner com arte e sobreposição para leitura do título.\n\n**Quando usar:** abrir uma página de campanha com sua mensagem e ação principal.\n\n**Quando não usar:** introduzir seções internas sem ação de destaque; use um título de seção.","displayName":"Hero","methods":[],"props":{"title":{"defaultValue":null,"description":"Título principal; renderizado como o único `h1` do bloco.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":true,"type":{"name":"string"}},"description":{"defaultValue":null,"description":"Texto de apoio ao título.","name":"description","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"ReactNode"}},"primaryAction":{"defaultValue":null,"description":"Ação principal.","name":"primaryAction","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"HeroAction"}},"secondaryAction":{"defaultValue":null,"description":"Ação secundária.","name":"secondaryAction","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"HeroAction"}},"media":{"defaultValue":null,"description":"Mídia do hero. Padrão: `AppThumb` em proporção 1:1 sem imagem.","name":"media","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"ReactNode"}},"disclaimer":{"defaultValue":null,"description":"Aviso curto sob a mídia, ex.: \"*Imagem meramente ilustrativa\".","name":"disclaimer","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"string"}},"layout":{"defaultValue":{"value":"card"},"description":"Composição em card ou banner de campanha. Padrão: `'card'`.","name":"layout","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"enum","raw":"\"card\" | \"banner\"","value":[{"value":"\"card\""},{"value":"\"banner\""}]}},"backgroundImage":{"defaultValue":null,"description":"Imagem de fundo opcional no layout banner.","name":"backgroundImage","parent":{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Hero/Hero.tsx","name":"HeroProps"}],"required":false,"type":{"name":"string"}}},"exportName":"Hero"},"stories":[{"id":"blocos-hero--card","name":"Card","snippet":"const Card = () => <Hero\n    title=\"Participe da campanha e concorra a prêmios\"\n    description=\"Cadastre sua compra e acompanhe sua participação de forma simples e segura.\"\n    primaryAction={{ label: 'Participar', href: '#cadastro' }}\n    secondaryAction={{ label: 'Saiba mais', href: '#como-participar' }}\n    disclaimer=\"*Imagem meramente ilustrativa\" />;","exportName":"Card","tags":["dev","test","manifest"]},{"id":"blocos-hero--banner","name":"Banner","snippet":"const Banner = () => <Hero\n    title=\"Uma campanha feita para você\"\n    description=\"Participe e descubra experiências incríveis.\"\n    primaryAction={{ label: 'Quero participar', href: '#cadastro' }}\n    secondaryAction={undefined}\n    disclaimer={undefined}\n    layout=\"banner\"\n    backgroundImage={`data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1600\" height=\"700\"><rect width=\"1600\" height=\"700\" fill=\"#0a223c\"/><circle cx=\"1300\" cy=\"300\" r=\"360\" fill=\"#ec2474\"/><circle cx=\"1000\" cy=\"650\" r=\"260\" fill=\"#f6dae5\"/></svg>')}`} />;","exportName":"Banner","tags":["dev","test","manifest"]},{"id":"blocos-hero--celular","name":"Celular","snippet":"const Celular = () => <Hero\n    title=\"Participe da campanha e concorra a prêmios\"\n    description=\"Cadastre sua compra e acompanhe sua participação de forma simples e segura.\"\n    primaryAction={{ label: 'Participar', href: '#cadastro' }}\n    secondaryAction={{ label: 'Saiba mais', href: '#como-participar' }}\n    disclaimer=\"*Imagem meramente ilustrativa\" />;","exportName":"Celular","tags":["dev","test","manifest"]}],"import":"import { Hero } from '@handsondigital/idplugger-ui';","title":"Blocos/Hero"},"blocos-login":{"id":"blocos-login","name":"Login","path":"./src/blocks/Login/Login.stories.tsx","jsDocTags":{},"description":"Acesso do participante ao lado do convite para cadastro. Copie para o seu hotsite.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/Login/Login.tsx","description":"Bloco de campanha \"Login\": painel \"Já sou cadastrado\" (identificação, senha com mostrar/ocultar, link para\nrecuperar a senha e \"Entrar\") ao lado do painel \"Não sou cadastrado\", com o convite para o cadastro. Lado a lado\na partir de 720px de largura do bloco; empilhado abaixo disso. Campos vazios mostram erro no próprio campo; o erro\ndo acesso (`error`) aparece acima do formulário e é anunciado. Fica fora do pacote: copie para o seu hotsite.","displayName":"Login","methods":[],"props":{"identifierLabel":{"defaultValue":{"value":"CPF ou e-mail"},"description":"Rótulo do campo de identificação. Padrão: `'CPF ou e-mail'`.","name":"identifierLabel","parent":{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"}],"required":false,"type":{"name":"string"}},"forgotHref":{"defaultValue":null,"description":"Página de recuperação de senha.","name":"forgotHref","parent":{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"}],"required":true,"type":{"name":"string"}},"registerHref":{"defaultValue":null,"description":"Página de cadastro.","name":"registerHref","parent":{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"}],"required":true,"type":{"name":"string"}},"onSubmit":{"defaultValue":null,"description":"Recebe identificação e senha depois da validação de campos obrigatórios.","name":"onSubmit","parent":{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"}],"required":true,"type":{"name":"(values: LoginValues) => void"}},"error":{"defaultValue":null,"description":"Erro do acesso (ex.: dados não conferem), mostrado acima do formulário.","name":"error","parent":{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"}],"required":false,"type":{"name":"string"}},"loading":{"defaultValue":{"value":"false"},"description":"Enquanto a tentativa de acesso está em andamento.","name":"loading","parent":{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/Login/Login.tsx","name":"LoginProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"Login"},"stories":[{"id":"blocos-login--default","name":"Default","snippet":"const Default = () => <Login forgotHref=\"#esqueci-a-senha\" registerHref=\"#cadastro\" />;","exportName":"Default","tags":["dev","test","manifest","play-fn"]},{"id":"blocos-login--com-erro","name":"Com Erro","snippet":"const ComErro = () => <Login\n    forgotHref=\"#esqueci-a-senha\"\n    registerHref=\"#cadastro\"\n    error=\"CPF ou senha não conferem. Confira os dados ou recupere sua senha.\" />;","exportName":"ComErro","tags":["dev","test","manifest"]},{"id":"blocos-login--carregando","name":"Carregando","snippet":"const Carregando = () => <Login\n    forgotHref=\"#esqueci-a-senha\"\n    registerHref=\"#cadastro\"\n    loading />;","exportName":"Carregando","tags":["dev","test","manifest"]},{"id":"blocos-login--celular","name":"Celular","snippet":"const Celular = () => <Login forgotHref=\"#esqueci-a-senha\" registerHref=\"#cadastro\" />;","exportName":"Celular","tags":["dev","test","manifest"]}],"import":"import { Login } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Blocos/Login"},"blocos-numerosdasorte":{"id":"blocos-numerosdasorte","name":"NumerosDaSorte","path":"./src/blocks/NumerosDaSorte/NumerosDaSorte.stories.tsx","jsDocTags":{},"description":"Números da sorte do participante, com status, estado vazio e paginação. Copie para o seu hotsite.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","description":"Bloco de campanha \"Números da sorte\": os números do participante em formato de bilhete, com a data do sorteio e o\nstatus escrito (Concorrendo, Sorteado, Premiado). Pagina a partir de `pageSize` números e, sem números, mostra o\nconvite para cadastrar um cupom. Fica fora do pacote: copie para o seu hotsite.","displayName":"NumerosDaSorte","methods":[],"props":{"title":{"defaultValue":null,"description":"Título da seção.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"}],"required":true,"type":{"name":"string"}},"numbers":{"defaultValue":null,"description":"Números do participante, com status e data do sorteio.","name":"numbers","parent":{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"}],"required":true,"type":{"name":"LuckyNumber[]"}},"pageSize":{"defaultValue":{"value":"30"},"description":"Números por página antes da paginação. Padrão: 30.","name":"pageSize","parent":{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"}],"required":false,"type":{"name":"number"}},"emptyAction":{"defaultValue":null,"description":"Ação do estado vazio (ex.: cadastrar cupom).","name":"emptyAction","parent":{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/NumerosDaSorte/NumerosDaSorte.tsx","name":"NumerosDaSorteProps"}],"required":false,"type":{"name":"{ label: string; href: string; }"}}},"exportName":"NumerosDaSorte"},"stories":[{"id":"blocos-numerosdasorte--default","name":"Default","snippet":"const Default = () => <NumerosDaSorte title=\"Meus números da sorte\" numbers={numbers(6)} />;","warning":"Incomplete snippet: `numbers` could not be resolved statically.","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-numerosdasorte--com-status","name":"Com Status","snippet":"const ComStatus = () => <NumerosDaSorte\n    title=\"Meus números da sorte\"\n    numbers={[\n      { value: '12.340', drawDate: '30/10/2026', status: 'ativo' },\n      { value: '12.347', drawDate: '30/10/2026', status: 'ativo' },\n      { value: '08.112', drawDate: '15/10/2026', status: 'sorteado' },\n      { value: '08.119', drawDate: '15/10/2026', status: 'premiado' },\n    ]} />;","exportName":"ComStatus","tags":["dev","test","manifest"]},{"id":"blocos-numerosdasorte--vazio","name":"Vazio","snippet":"const Vazio = () => <NumerosDaSorte\n    title=\"Meus números da sorte\"\n    numbers={[]}\n    emptyAction={{ label: 'Cadastrar cupom', href: '#cadastro' }} />;","exportName":"Vazio","tags":["dev","test","manifest"]},{"id":"blocos-numerosdasorte--paginado","name":"Paginado","snippet":"const Paginado = () => <NumerosDaSorte title=\"Meus números da sorte\" numbers={numbers(45)} pageSize={30} />;","warning":"Incomplete snippet: `numbers` could not be resolved statically.","exportName":"Paginado","tags":["dev","test","manifest","play-fn"]},{"id":"blocos-numerosdasorte--celular","name":"Celular","snippet":"const Celular = () => <NumerosDaSorte title=\"Meus números da sorte\" numbers={numbers(6)} />;","warning":"Incomplete snippet: `numbers` could not be resolved statically.","exportName":"Celular","tags":["dev","test","manifest"]}],"import":"import { NumerosDaSorte } from '@handsondigital/idplugger-ui';","title":"Blocos/NumerosDaSorte"},"blocos-produtos-participantes":{"id":"blocos-produtos-participantes","name":"ProdutosParticipantes","path":"./src/blocks/ProdutosParticipantes/ProdutosParticipantes.stories.tsx","jsDocTags":{},"description":"Bloco de campanha fora do pacote npm: produtos participantes em carrossel (1 por vez em espaços\nestreitos, 3 a partir de 880px de largura do bloco), com setas, rolagem por toque e botão de ação. Copie para o seu hotsite e troque os produtos.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","description":"Bloco de campanha \"Produtos participantes\": título, introdução, carrossel de produtos (1 por vez em espaços\nestreitos, 3 a partir de 880px de largura do bloco; setas e rolagem por toque/trackpad, sem autoplay) e botão de ação. O carrossel usa rolagem nativa\ncom `scroll-snap`, sem biblioteca. Copie para o seu hotsite; não faz parte do pacote.","displayName":"ProdutosParticipantes","methods":[],"props":{"title":{"defaultValue":null,"description":"Título da seção.","name":"title","parent":{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"}],"required":true,"type":{"name":"string"}},"intro":{"defaultValue":null,"description":"Texto de introdução abaixo do título.","name":"intro","parent":{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"}],"required":true,"type":{"name":"ReactNode"}},"products":{"defaultValue":null,"description":"Produtos do carrossel.","name":"products","parent":{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"}],"required":true,"type":{"name":"ProdutoParticipante[]"}},"disclaimer":{"defaultValue":null,"description":"Aviso sobre a mídia de cada produto, ex.: \"*Imagem meramente ilustrativa\".","name":"disclaimer","parent":{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"}],"required":false,"type":{"name":"string"}},"ctaLabel":{"defaultValue":null,"description":"Texto do botão de ação.","name":"ctaLabel","parent":{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"}],"required":true,"type":{"name":"string"}},"onCtaClick":{"defaultValue":null,"description":"Chamado ao clicar no botão de ação.","name":"onCtaClick","parent":{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/ProdutosParticipantes/ProdutosParticipantes.tsx","name":"ProdutosParticipantesProps"}],"required":false,"type":{"name":"(() => void)"}}},"exportName":"ProdutosParticipantes"},"stories":[{"id":"blocos-produtos-participantes--default","name":"Default","snippet":"const Default = () => <ProdutosParticipantes\n    title=\"Produtos participantes\"\n    intro=\"Confira abaixo os produtos participantes da promoção e aproveite as ofertas exclusivas para quem participa.\"\n    products={CORES.map((cor, index) => ({\n      image: produto(`Produto ${index + 1}`, cor),\n      imageAlt: `Embalagem do produto ${index + 1}`,\n      name: `Produto ${index + 1}`,\n      reference: `Ref. 00${index + 1}-PROMO`,\n    }))}\n    disclaimer=\"*Imagem meramente ilustrativa\"\n    ctaLabel=\"Quero Participar\" />;","warning":"Incomplete snippet: `CORES`, `produto` could not be resolved statically.","exportName":"Default","tags":["dev","test","manifest"]},{"id":"blocos-produtos-participantes--navegacao","name":"Navegacao","snippet":"const Navegacao = () => <ProdutosParticipantes\n    title=\"Produtos participantes\"\n    intro=\"Confira abaixo os produtos participantes da promoção e aproveite as ofertas exclusivas para quem participa.\"\n    products={CORES.map((cor, index) => ({\n      image: produto(`Produto ${index + 1}`, cor),\n      imageAlt: `Embalagem do produto ${index + 1}`,\n      name: `Produto ${index + 1}`,\n      reference: `Ref. 00${index + 1}-PROMO`,\n    }))}\n    disclaimer=\"*Imagem meramente ilustrativa\"\n    ctaLabel=\"Quero Participar\" />;","description":"As setas avançam uma página de produtos; a anterior fica desabilitada no início e a próxima, no fim.","warning":"Incomplete snippet: `CORES`, `produto` could not be resolved statically.","exportName":"Navegacao","tags":["dev","test","manifest","play-fn"]}],"import":"import { ProdutosParticipantes } from '@handsondigital/idplugger-ui';","title":"Blocos/Produtos participantes"},"blocos-recuperarsenha":{"id":"blocos-recuperarsenha","name":"RecuperarSenha","path":"./src/blocks/RecuperarSenha/RecuperarSenha.stories.tsx","jsDocTags":{},"description":"Os passos de recuperação de senha. Copie para o seu hotsite.","reactDocgenTypescript":{"tags":{},"filePath":"src/blocks/RecuperarSenha/RecuperarSenha.tsx","description":"Bloco de campanha \"Recuperar senha\": os quatro passos da recuperação num só card, escolhidos por `step` —\npedir o link por e-mail, aviso de envio, nova senha (com requisitos visíveis e confirmação) e conclusão. Erros\naparecem no próprio campo. Fica fora do pacote: copie para o seu hotsite.","displayName":"RecuperarSenha","methods":[],"props":{"step":{"defaultValue":null,"description":"Passo exibido; quem usa avança o passo depois de cada chamada à API.","name":"step","parent":{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"}],"required":true,"type":{"name":"enum","raw":"RecuperarSenhaStep","value":[{"value":"\"solicitar\""},{"value":"\"enviado\""},{"value":"\"redefinir\""},{"value":"\"concluido\""}]}},"onRequest":{"defaultValue":null,"description":"Recebe o e-mail informado no passo `solicitar`.","name":"onRequest","parent":{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"}],"required":false,"type":{"name":"((email: string) => void)"}},"onReset":{"defaultValue":null,"description":"Recebe a nova senha no passo `redefinir`, depois de atender os requisitos e conferir a confirmação.","name":"onReset","parent":{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"}],"required":false,"type":{"name":"((password: string) => void)"}},"email":{"defaultValue":null,"description":"E-mail mostrado no passo `enviado`.","name":"email","parent":{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"}],"required":false,"type":{"name":"string"}},"loginHref":{"defaultValue":null,"description":"Página de login, usada em `enviado` e `concluido`.","name":"loginHref","parent":{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"}],"required":true,"type":{"name":"string"}},"passwordRules":{"defaultValue":{"value":"[\n  { label: 'Pelo menos 8 caracteres', test: (value) => value.length >= 8 },\n  { label: 'Uma letra maiúscula', test: (value) => /[A-Z]/.test(value) },\n  { label: 'Um número', test: (value) => /\\d/.test(value) },\n]"},"description":"Requisitos da nova senha. Padrão: 8 caracteres, uma letra maiúscula e um número.","name":"passwordRules","parent":{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"},"declarations":[{"fileName":"idplugger-ui/src/blocks/RecuperarSenha/RecuperarSenha.tsx","name":"RecuperarSenhaProps"}],"required":false,"type":{"name":"{ label: string; test: (password: string) => boolean; }[]"}}},"exportName":"RecuperarSenha"},"stories":[{"id":"blocos-recuperarsenha--solicitar","name":"Solicitar","snippet":"const Solicitar = () => <RecuperarSenha step=\"solicitar\" loginHref=\"#login\" />;","exportName":"Solicitar","tags":["dev","test","manifest","play-fn"]},{"id":"blocos-recuperarsenha--enviado","name":"Enviado","snippet":"const Enviado = () => <RecuperarSenha\n    step=\"enviado\"\n    loginHref=\"#login\"\n    email=\"maria@exemplo.com\" />;","exportName":"Enviado","tags":["dev","test","manifest"]},{"id":"blocos-recuperarsenha--redefinir","name":"Redefinir","snippet":"const Redefinir = () => <RecuperarSenha step=\"redefinir\" loginHref=\"#login\" />;","exportName":"Redefinir","tags":["dev","test","manifest","play-fn"]},{"id":"blocos-recuperarsenha--concluido","name":"Concluido","snippet":"const Concluido = () => <RecuperarSenha step=\"concluido\" loginHref=\"#login\" />;","exportName":"Concluido","tags":["dev","test","manifest"]}],"import":"import { RecuperarSenha } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Blocos/RecuperarSenha"},"molecules-appalert":{"id":"molecules-appalert","name":"AppAlert","path":"./src/components/AppAlert/AppAlert.stories.tsx","jsDocTags":{},"description":"Aviso em linha com ícone, título opcional, mensagem e ação.\n\n**Quando usar:** instruções antes de um formulário (onde encontrar o CNPJ e o número do cupom), aviso antes de uma\nconfirmação definitiva, erro geral de um envio ou sucesso de uma etapa.\n\n**Quando não usar:** erro de um campo específico (use o `error` do campo) ou confirmação passageira de uma ação\n(use `AppToast`).","reactDocgenTypescript":{"tags":{"example":"<AppAlert tone=\"warning\" title=\"Atenção\">\n  Estas informações não poderão ser alteradas após a confirmação.\n</AppAlert>"},"filePath":"src/components/AppAlert/AppAlert.tsx","description":"Aviso em linha com ícone, título opcional, mensagem e ação.\n\n**Quando usar:** instruções antes de um formulário (onde encontrar o CNPJ e o número do cupom), aviso antes de uma\nconfirmação definitiva, erro geral de um envio ou sucesso de uma etapa.\n\n**Quando não usar:** erro de um campo específico (use o `error` do campo) ou confirmação passageira de uma ação\n(use `AppToast`).","displayName":"AppAlert","methods":[],"props":{"tone":{"defaultValue":{"value":"info"},"description":"Tom da mensagem: muda cor e ícone. Padrão: `'info'`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":false,"type":{"name":"enum","raw":"AppAlertTone","value":[{"value":"\"success\""},{"value":"\"info\""},{"value":"\"warning\""},{"value":"\"danger\""}]}},"title":{"defaultValue":null,"description":"Título curto em destaque, acima da mensagem.","name":"title","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":false,"type":{"name":"ReactNode"}},"children":{"defaultValue":null,"description":"Mensagem do aviso.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":true,"type":{"name":"ReactNode"}},"icon":{"defaultValue":null,"description":"Ícone à esquerda. Padrão: um ícone por tom; `false` remove o ícone. Decorativo.","name":"icon","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":false,"type":{"name":"ReactNode"}},"action":{"defaultValue":null,"description":"Ação abaixo da mensagem, como um link ou botão.","name":"action","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":false,"type":{"name":"ReactNode"}},"onDismiss":{"defaultValue":null,"description":"Mostra o botão \"Fechar aviso\" e é chamado ao clicar nele. Quem usa remove o aviso (o fechamento é controlado):\nassim o mesmo aviso volta a aparecer se a condição se repetir, como um novo erro no envio.","name":"onDismiss","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":false,"type":{"name":"(() => void)"}},"live":{"defaultValue":{"value":"false"},"description":"Anuncia o aviso para leitores de tela quando ele aparece depois de uma ação (`danger`/`warning` como alerta,\nos demais como status). Deixe `false` para avisos que já estão na página ao carregar. Padrão: `false`.","name":"live","parent":{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAlert/AppAlert.tsx","name":"AppAlertProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"AppAlert"},"stories":[{"id":"molecules-appalert--tons","name":"Tons","snippet":"const Tons = () => (\n  <div style={{ display: 'grid', gap: 12 }}>\n    <AppAlert tone=\"info\">Informação para você.</AppAlert>\n    <AppAlert tone=\"success\">Operação concluída.</AppAlert>\n    <AppAlert tone=\"warning\">Confira os dados informados.</AppAlert>\n    <AppAlert tone=\"danger\">Não foi possível concluir.</AppAlert>\n  </div>\n);","exportName":"Tons","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appalert--com-titulo","name":"Com Titulo","snippet":"const ComTitulo = () => <AppAlert tone=\"success\" title=\"Tudo certo\">Seu cadastro foi confirmado.</AppAlert>;","exportName":"ComTitulo","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appalert--com-acao","name":"Com Acao","snippet":"const ComAcao = () => <AppAlert\n    action={<a href=\"#orientacoes\">Clique aqui para saber onde encontrar o CNPJ e o número do cupom fiscal</a>}>Para saber onde encontrar o CNPJ e o número do cupom fiscal, consulte as orientações.</AppAlert>;","exportName":"ComAcao","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appalert--dispensavel","name":"Dispensavel","snippet":"const Dispensavel = () => <Dismissible />;","exportName":"Dispensavel","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appalert--confirmacao-de-cupom","name":"Confirmacao De Cupom","snippet":"const ConfirmacaoDeCupom = () => <AppAlert tone=\"warning\" title=\"Atenção\">Estas informações não poderão ser alteradas após a confirmação.</AppAlert>;","exportName":"ConfirmacaoDeCupom","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppAlert } from '@handsondigital/idplugger-ui';","title":"Molecules/AppAlert"},"atoms-appavatar":{"id":"atoms-appavatar","name":"AppAvatar","path":"./src/components/AppAvatar/AppAvatar.stories.tsx","jsDocTags":{},"description":"Representa uma pessoa, empresa ou ausência de imagem com foto, iniciais ou placeholder.\n\n**Quando usar:** identificar visualmente uma pessoa, equipe ou empresa em listas, cabeçalhos e comentários.\n\n**Quando não usar:** a imagem é decorativa sem representar uma entidade; nesse caso, use um ícone ou ilustração.","reactDocgenTypescript":{"tags":{"example":"<AppAvatar name=\"João Carlos\" status=\"online\" />"},"filePath":"src/components/AppAvatar/AppAvatar.tsx","description":"Representa uma pessoa, empresa ou ausência de imagem com foto, iniciais ou placeholder.\n\n**Quando usar:** identificar visualmente uma pessoa, equipe ou empresa em listas, cabeçalhos e comentários.\n\n**Quando não usar:** a imagem é decorativa sem representar uma entidade; nesse caso, use um ícone ou ilustração.","displayName":"AppAvatar","methods":[],"props":{"src":{"defaultValue":null,"description":"URL da imagem exibida no avatar. Ao falhar, exibe as iniciais ou o placeholder.","name":"src","parent":{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"}],"required":false,"type":{"name":"string"}},"alt":{"defaultValue":null,"description":"Texto alternativo da imagem. Por padrão, usa `name`.","name":"alt","parent":{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"}],"required":false,"type":{"name":"string"}},"name":{"defaultValue":null,"description":"Nome usado para gerar as iniciais e o nome acessível do avatar.","name":"name","parent":{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":{"value":"md"},"description":"Diâmetro do avatar. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"}],"required":false,"type":{"name":"enum","raw":"AppAvatarSize","value":[{"value":"\"xs\""},{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""},{"value":"\"xl\""},{"value":"\"2xl\""}]}},"status":{"defaultValue":null,"description":"Estado de presença exibido no canto inferior direito.","name":"status","parent":{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"}],"required":false,"type":{"name":"enum","raw":"AppAvatarStatus","value":[{"value":"\"online\""},{"value":"\"offline\""}]}},"badge":{"defaultValue":null,"description":"Selo no canto inferior direito. `verified` exibe a verificação; um nó permite o logo de uma empresa.","name":"badge","parent":{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatar/AppAvatar.tsx","name":"AppAvatarProps"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"AppAvatar"},"stories":[{"id":"atoms-appavatar--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n    <AppAvatar size=\"xs\" name=\"João Carlos\" />\n    <AppAvatar size=\"sm\" name=\"João Carlos\" />\n    <AppAvatar size=\"md\" name=\"João Carlos\" />\n    <AppAvatar size=\"lg\" name=\"João Carlos\" />\n    <AppAvatar size=\"xl\" name=\"João Carlos\" />\n    <AppAvatar size=\"2xl\" name=\"João Carlos\" />\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appavatar--iniciais","name":"Iniciais","snippet":"const Iniciais = () => <AppAvatar name=\"João Carlos\" />;","exportName":"Iniciais","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appavatar--placeholder","name":"Placeholder","snippet":"const Placeholder = () => <AppAvatar name={undefined} />;","exportName":"Placeholder","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appavatar--status","name":"Status","snippet":"const Status = () => (\n  <div style={{ display: 'flex', gap: 12 }}>\n    <AppAvatar name=\"João Carlos\" status=\"online\" />\n    <AppAvatar name=\"Ana Souza\" status=\"offline\" />\n  </div>\n);","exportName":"Status","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appavatar--verificado","name":"Verificado","snippet":"const Verificado = () => <AppAvatar name=\"João Carlos\" src={avatarSvg('#E6F9F9', '#005450')} badge=\"verified\" />;","warning":"Incomplete snippet: `avatarSvg` could not be resolved statically.","exportName":"Verificado","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appavatar--empresa","name":"Empresa","snippet":"const Empresa = () => <AppAvatar\n    name=\"João Carlos\"\n    src={avatarSvg('#E6F2FF', '#00336B')}\n    badge={<span style={{ display: 'grid', width: '100%', height: '100%', placeItems: 'center', background: '#E6F9F9', color: '#005450', fontSize: 8 }}>H</span>} />;","warning":"Incomplete snippet: `avatarSvg` could not be resolved statically.","exportName":"Empresa","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appavatar--imagem-quebrada","name":"Imagem Quebrada","snippet":"const ImagemQuebrada = () => <AppAvatar name=\"João Carlos\" src=\"/avatar-inexistente.svg\" />;","exportName":"ImagemQuebrada","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { AppAvatar } from '@handsondigital/idplugger-ui';","title":"Atoms/AppAvatar"},"molecules-appavatargroup":{"id":"molecules-appavatargroup","name":"AppAvatarGroup","path":"./src/components/AppAvatarGroup/AppAvatarGroup.stories.tsx","jsDocTags":{},"description":"Agrupa avatares sobrepostos e informa quantas pessoas não estão visíveis.\n\n**Quando usar:** representar participantes, membros de uma equipe ou pessoas associadas a uma entidade.\n\n**Quando não usar:** identificar uma única pessoa; use `AppAvatar` ou `AppAvatarLabel`.","reactDocgenTypescript":{"tags":{"example":"<AppAvatarGroup max={3}><AppAvatar name=\"João\" /></AppAvatarGroup>"},"filePath":"src/components/AppAvatarGroup/AppAvatarGroup.tsx","description":"Agrupa avatares sobrepostos e informa quantas pessoas não estão visíveis.\n\n**Quando usar:** representar participantes, membros de uma equipe ou pessoas associadas a uma entidade.\n\n**Quando não usar:** identificar uma única pessoa; use `AppAvatar` ou `AppAvatarLabel`.","displayName":"AppAvatarGroup","methods":[],"props":{"children":{"defaultValue":null,"description":"Avatares que serão exibidos sobrepostos.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"}],"required":true,"type":{"name":"ReactNode"}},"max":{"defaultValue":null,"description":"Máximo de avatares visíveis antes de exibir o indicador \"+N\".","name":"max","parent":{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"}],"required":false,"type":{"name":"number"}},"size":{"defaultValue":{"value":"md"},"description":"Tamanho repassado aos avatares filhos. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"}],"required":false,"type":{"name":"enum","raw":"AppAvatarGroupSize","value":[{"value":"\"xs\""},{"value":"\"sm\""},{"value":"\"md\""}]}},"onAdd":{"defaultValue":null,"description":"Ação chamada pelo botão para adicionar uma pessoa. Quando ausente, o botão não é exibido.","name":"onAdd","parent":{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"}],"required":false,"type":{"name":"(() => void)"}},"addLabel":{"defaultValue":{"value":"Adicionar pessoa"},"description":"Nome acessível e título do botão de adicionar. Padrão: `Adicionar pessoa`.","name":"addLabel","parent":{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarGroup/AppAvatarGroup.tsx","name":"AppAvatarGroupProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppAvatarGroup"},"stories":[{"id":"molecules-appavatargroup--default","name":"Default","snippet":"const Default = () => <AppAvatarGroup max={5}>{people.map(([name, background, hair]) => <AppAvatar key={name} name={name} src={avatarSvg(background, hair)} />)}</AppAvatarGroup>;","warning":"Incomplete snippet: `people`, `avatarSvg` could not be resolved statically.","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appavatargroup--com-adicionar","name":"Com Adicionar","snippet":"const ComAdicionar = () => <AppAvatarGroup max={5}>{people.map(([name, background, hair]) => <AppAvatar key={name} name={name} src={avatarSvg(background, hair)} />)}</AppAvatarGroup>;","warning":"Incomplete snippet: `people`, `avatarSvg` could not be resolved statically.","exportName":"ComAdicionar","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appavatargroup--tamanhos","name":"Tamanhos","snippet":"const Tamanhos = () => (\n  <div style={{ display: 'grid', gap: 16 }}>\n    <AppAvatarGroup size=\"xs\" max={3}>{avatars}</AppAvatarGroup>\n    <AppAvatarGroup size=\"sm\" max={3}>{avatars}</AppAvatarGroup>\n    <AppAvatarGroup size=\"md\" max={3}>{avatars}</AppAvatarGroup>\n  </div>\n);","exportName":"Tamanhos","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppAvatar, AppAvatarGroup } from '@handsondigital/idplugger-ui';\nimport { AppAvatar } from '../AppAvatar/AppAvatar';\nimport { fn } from 'storybook/test';","title":"Molecules/AppAvatarGroup"},"molecules-appavatarlabel":{"id":"molecules-appavatarlabel","name":"AppAvatarLabel","path":"./src/components/AppAvatarLabel/AppAvatarLabel.stories.tsx","jsDocTags":{},"description":"Exibe um avatar decorativo acompanhado do nome e de uma informação complementar.\n\n**Quando usar:** apresentar uma pessoa ou empresa em listas, tabelas e campos de responsável.\n\n**Quando não usar:** o nome não está disponível ou a informação precisa caber em um cartão mais completo.","reactDocgenTypescript":{"tags":{"example":"<AppAvatarLabel name=\"João Carlos\" supportingText=\"joao@empresa.com.br\" />"},"filePath":"src/components/AppAvatarLabel/AppAvatarLabel.tsx","description":"Exibe um avatar decorativo acompanhado do nome e de uma informação complementar.\n\n**Quando usar:** apresentar uma pessoa ou empresa em listas, tabelas e campos de responsável.\n\n**Quando não usar:** o nome não está disponível ou a informação precisa caber em um cartão mais completo.","displayName":"AppAvatarLabel","methods":[],"props":{"name":{"defaultValue":null,"description":"Nome visível da pessoa ou empresa.","name":"name","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":true,"type":{"name":"string"}},"supportingText":{"defaultValue":null,"description":"Informação complementar, como cargo ou e-mail.","name":"supportingText","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":{"value":"md"},"description":"Tamanho do avatar e da tipografia. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":false,"type":{"name":"enum","raw":"AppAvatarLabelSize","value":[{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""},{"value":"\"xl\""}]}},"src":{"defaultValue":null,"description":"URL da imagem exibida no avatar.","name":"src","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":false,"type":{"name":"string"}},"alt":{"defaultValue":null,"description":"Texto alternativo da imagem do avatar.","name":"alt","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":false,"type":{"name":"string"}},"status":{"defaultValue":null,"description":"Estado de presença exibido no avatar.","name":"status","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":false,"type":{"name":"enum","raw":"AppAvatarStatus","value":[{"value":"\"online\""},{"value":"\"offline\""}]}},"badge":{"defaultValue":null,"description":"Selo exibido no avatar.","name":"badge","parent":{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppAvatarLabel/AppAvatarLabel.tsx","name":"AppAvatarLabelProps"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"AppAvatarLabel"},"stories":[{"id":"molecules-appavatarlabel--nome-e-email","name":"Nome E Email","snippet":"const NomeEEmail = () => <AppAvatarLabel\n    name=\"João Carlos\"\n    src={`data:image/svg+xml,${encodeURIComponent(`\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\">\n        <rect width=\"64\" height=\"64\" fill=\"#E6F2FF\"/>\n        <circle cx=\"32\" cy=\"27\" r=\"13\" fill=\"#F5C9A9\"/>\n        <path d=\"M18 27c0-12 28-15 28 0v-6c0-15-28-15-28 0z\" fill=\"#00336B\"/>\n        <path d=\"M12 64c2-16 13-24 20-24s18 8 20 24\" fill=\"#E6F9F9\"/>\n      </svg>\n    `)}`}\n    supportingText=\"joaocarlos@handson-ti.com.br\" />;","exportName":"NomeEEmail","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appavatarlabel--so-nome","name":"So Nome","snippet":"const SoNome = () => <AppAvatarLabel\n    name=\"João Carlos\"\n    src={`data:image/svg+xml,${encodeURIComponent(`\n      <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 64 64\">\n        <rect width=\"64\" height=\"64\" fill=\"#E6F2FF\"/>\n        <circle cx=\"32\" cy=\"27\" r=\"13\" fill=\"#F5C9A9\"/>\n        <path d=\"M18 27c0-12 28-15 28 0v-6c0-15-28-15-28 0z\" fill=\"#00336B\"/>\n        <path d=\"M12 64c2-16 13-24 20-24s18 8 20 24\" fill=\"#E6F9F9\"/>\n      </svg>\n    `)}`} />;","exportName":"SoNome","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appavatarlabel--tamanhos","name":"Tamanhos","snippet":"const Tamanhos = () => (\n  <div style={{ display: 'grid', gap: 16 }}>\n    <AppAvatarLabel size=\"sm\" name=\"João Carlos\" supportingText=\"joaocarlos@handson-ti.com.br\" src={avatarSvg} />\n    <AppAvatarLabel size=\"md\" name=\"João Carlos\" supportingText=\"joaocarlos@handson-ti.com.br\" src={avatarSvg} />\n    <AppAvatarLabel size=\"lg\" name=\"João Carlos\" supportingText=\"joaocarlos@handson-ti.com.br\" src={avatarSvg} />\n    <AppAvatarLabel size=\"xl\" name=\"João Carlos\" supportingText=\"joaocarlos@handson-ti.com.br\" src={avatarSvg} />\n  </div>\n);","exportName":"Tamanhos","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppAvatarLabel } from '@handsondigital/idplugger-ui';","title":"Molecules/AppAvatarLabel"},"atoms-appbadge":{"id":"atoms-appbadge","name":"AppBadge","path":"./src/components/AppBadge/AppBadge.stories.tsx","jsDocTags":{},"description":"Selo compacto para comunicar status, contagens ou destaques breves.\n\n**Quando usar:** `success` para status ativo ou aprovado; `warning` para avisos; `danger` para erro ou queda;\n`info` para informação; `neutral` para contagens como \"+N\" e rótulos neutros; `primary` para destaque de campanha.\n\n**Quando não usar:** o conteúdo precisa de ação, descrição longa ou prioridade suficiente para merecer um alerta.","reactDocgenTypescript":{"tags":{"example":"<AppBadge tone=\"success\">Ativo</AppBadge>"},"filePath":"src/components/AppBadge/AppBadge.tsx","description":"Selo compacto para comunicar status, contagens ou destaques breves.\n\n**Quando usar:** `success` para status ativo ou aprovado; `warning` para avisos; `danger` para erro ou queda;\n`info` para informação; `neutral` para contagens como \"+N\" e rótulos neutros; `primary` para destaque de campanha.\n\n**Quando não usar:** o conteúdo precisa de ação, descrição longa ou prioridade suficiente para merecer um alerta.","displayName":"AppBadge","methods":[],"props":{"children":{"defaultValue":null,"description":"Conteúdo curto que identifica o status, a contagem ou o destaque.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppBadge/AppBadge.tsx","name":"AppBadgeProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppBadge/AppBadge.tsx","name":"AppBadgeProps"}],"required":true,"type":{"name":"ReactNode"}},"icon":{"defaultValue":null,"description":"Ícone decorativo exibido antes do conteúdo.","name":"icon","parent":{"fileName":"idplugger-ui/src/components/AppBadge/AppBadge.tsx","name":"AppBadgeProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppBadge/AppBadge.tsx","name":"AppBadgeProps"}],"required":false,"type":{"name":"ReactNode"}},"tone":{"defaultValue":{"value":"neutral"},"description":"Significado visual do selo. Padrão: `neutral`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppBadge/AppBadge.tsx","name":"AppBadgeProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppBadge/AppBadge.tsx","name":"AppBadgeProps"}],"required":false,"type":{"name":"enum","raw":"AppBadgeTone","value":[{"value":"\"success\""},{"value":"\"info\""},{"value":"\"warning\""},{"value":"\"danger\""},{"value":"\"neutral\""},{"value":"\"primary\""}]}}},"exportName":"AppBadge"},"stories":[{"id":"atoms-appbadge--default","name":"Default","snippet":"const Default = () => <AppBadge>Novo</AppBadge>;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbadge--tons","name":"Tons","snippet":"const Tons = () => (\n  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>\n    <AppBadge tone=\"neutral\">Neutro</AppBadge>\n    <AppBadge tone=\"primary\">Campanha</AppBadge>\n    <AppBadge tone=\"success\">Aprovado</AppBadge>\n    <AppBadge tone=\"info\">Informação</AppBadge>\n    <AppBadge tone=\"warning\">Atenção</AppBadge>\n    <AppBadge tone=\"danger\">Erro</AppBadge>\n  </div>\n);","exportName":"Tons","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbadge--com-icone","name":"Com Icone","snippet":"const ComIcone = () => (\n  <div style={{ display: 'flex', gap: 8 }}>\n    <AppBadge tone=\"success\" icon={<IconArrowUpward />}>20%</AppBadge>\n    <AppBadge tone=\"danger\" icon={<IconArrowDownward />}>20%</AppBadge>\n  </div>\n);","exportName":"ComIcone","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbadge--grupo","name":"Grupo","snippet":"const Grupo = () => (\n  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>\n    <AppBadge tone=\"primary\">Label</AppBadge>\n    <AppBadge tone=\"info\">Label</AppBadge>\n    <AppBadge tone=\"success\">Label</AppBadge>\n    <AppBadge tone=\"neutral\">+4</AppBadge>\n  </div>\n);","exportName":"Grupo","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbadge--status","name":"Status","snippet":"const Status = () => <AppBadge tone=\"success\">Active</AppBadge>;","exportName":"Status","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppBadge } from '@handsondigital/idplugger-ui';\nimport { IconArrowDownward, IconArrowUpward } from '@handsondigital/idplugger-ui/icons';","title":"Atoms/AppBadge"},"atoms-appbutton":{"id":"atoms-appbutton","name":"AppButton","path":"./src/components/AppButton/AppButton.stories.tsx","jsDocTags":{},"description":"Botão de ação com variações de aparência, tom e tamanho, ícones, estado de carregamento e modo só-ícone.\n\n**Quando usar:** ações primárias e secundárias (enviar formulário, \"Participar\", confirmar, cancelar), ações destrutivas (`tone=\"danger\"`) e ações só com ícone.\n\n**Quando não usar:** navegação entre páginas (use um link `<a>` estilizado); rótulos informativos ou removíveis (use `AppTag`); controle de paginação (use `AppPagination`).\n\nAcessibilidade: botão só com ícone (`icon`) exige `aria-label` ou `aria-labelledby`.","reactDocgenTypescript":{"tags":{"example":"<AppButton tone=\"primary\" onClick={participar}>Participar</AppButton>"},"filePath":"src/components/AppButton/AppButton.tsx","description":"Botão de ação com variações de aparência, tom e tamanho, ícones, estado de carregamento e modo só-ícone.\n\n**Quando usar:** ações primárias e secundárias (enviar formulário, \"Participar\", confirmar, cancelar), ações destrutivas (`tone=\"danger\"`) e ações só com ícone.\n\n**Quando não usar:** navegação entre páginas (use um link `<a>` estilizado); rótulos informativos ou removíveis (use `AppTag`); controle de paginação (use `AppPagination`).\n\nAcessibilidade: botão só com ícone (`icon`) exige `aria-label` ou `aria-labelledby`.","displayName":"AppButton","methods":[],"props":{"appearance":{"defaultValue":null,"description":"Estilo visual: `solid` (destaque), `soft` (fundo suave), `outline` (borda), `ghost` (sem fundo) ou `link` (texto sublinhado). Padrão: `solid`.","name":"appearance","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonBaseProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonBaseProps"}],"required":false,"type":{"name":"enum","raw":"ButtonAppearance","value":[{"value":"\"link\""},{"value":"\"solid\""},{"value":"\"soft\""},{"value":"\"outline\""},{"value":"\"ghost\""}]}},"tone":{"defaultValue":null,"description":"Cor semântica: `primary`, `secondary`, `success`, `info`, `warning`, `danger` ou `white` (neutro: fundo branco, borda e texto cinza). Padrão: `primary`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonBaseProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonBaseProps"}],"required":false,"type":{"name":"enum","raw":"ButtonTone","value":[{"value":"\"success\""},{"value":"\"info\""},{"value":"\"warning\""},{"value":"\"danger\""},{"value":"\"primary\""},{"value":"\"secondary\""},{"value":"\"white\""}]}},"isLoading":{"defaultValue":{"value":"false"},"description":"Mostra um spinner no lugar do ícone/ponto à esquerda, desabilita o botão e marca `aria-busy`. Padrão: `false`.","name":"isLoading","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonBaseProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonBaseProps"}],"required":false,"type":{"name":"boolean"}},"children":{"defaultValue":null,"description":"Texto do botão; vira o nome acessível. Não use junto com `icon`.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}},"size":{"defaultValue":null,"description":"Tamanho: `sm` 36px, `md` 40px, `lg` 44px, `xl` 48px, `2xl` 60px ou `full` (largura total, só com texto). Padrão: `lg`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"ButtonSize","value":[{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""},{"value":"\"xl\""},{"value":"\"2xl\""},{"value":"\"full\""}]}},"leadingIcon":{"defaultValue":null,"description":"Ícone antes do texto, decorativo (`aria-hidden`). Não use junto com `icon`.","name":"leadingIcon","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}},"trailingIcon":{"defaultValue":null,"description":"Ícone depois do texto, decorativo (`aria-hidden`). Não use junto com `icon`.","name":"trailingIcon","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}},"dot":{"defaultValue":null,"description":"Ponto de status antes do texto, decorativo. Não use junto com `icon`.","name":"dot","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"boolean"}},"icon":{"defaultValue":null,"description":"Botão quadrado só com ícone. Exige `aria-label` ou `aria-labelledby`; não aceita `children`, `leadingIcon`, `trailingIcon`, `dot` nem `size=\"full\"`.","name":"icon","parent":{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"AppButtonTextProps"},{"fileName":"idplugger-ui/src/components/AppButton/AppButton.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"AppButton"},"stories":[{"id":"atoms-appbutton--default","name":"Default","snippet":"const Default = () => <AppButton>Participar</AppButton>;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appbutton--secondary","name":"Secondary","snippet":"const Secondary = () => <AppButton tone=\"secondary\">Ver regulamento</AppButton>;","exportName":"Secondary","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--soft","name":"Soft","snippet":"const Soft = () => <AppButton appearance=\"soft\">Saiba mais</AppButton>;","exportName":"Soft","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--outline","name":"Outline","snippet":"const Outline = () => <AppButton appearance=\"outline\">Cancelar</AppButton>;","exportName":"Outline","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--ghost","name":"Ghost","snippet":"const Ghost = () => <AppButton appearance=\"ghost\">Voltar</AppButton>;","exportName":"Ghost","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--link","name":"Link","snippet":"const Link = () => <AppButton appearance=\"link\">Termos de uso</AppButton>;","exportName":"Link","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--destructive","name":"Destructive","snippet":"const Destructive = () => <AppButton tone=\"danger\">Excluir cadastro</AppButton>;","exportName":"Destructive","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--sizes","name":"Sizes","snippet":"const Sizes = (args) => (\n  <div style={{ display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>\n    {(['sm', 'md', 'lg', 'xl', '2xl'] as const).map((size) => (\n      <AppButton key={size} {...args} size={size}>{`Tamanho ${size}`}</AppButton>\n    ))}\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--full-width","name":"Full Width","snippet":"const FullWidth = () => <AppButton size=\"full\">Enviar nota fiscal</AppButton>;","exportName":"FullWidth","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--with-leading-icon","name":"With Leading Icon","snippet":"const WithLeadingIcon = () => <AppButton leadingIcon={<IconCheck />}>Confirmar participação</AppButton>;","exportName":"WithLeadingIcon","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--with-trailing-icon","name":"With Trailing Icon","snippet":"const WithTrailingIcon = () => <AppButton trailingIcon={<IconArrowForward />}>Continuar</AppButton>;","exportName":"WithTrailingIcon","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--with-dot","name":"With Dot","snippet":"const WithDot = () => <AppButton dot appearance=\"outline\">Em andamento</AppButton>;","exportName":"WithDot","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appbutton--icon-only","name":"Icon Only","snippet":"const IconOnly = () => <AppButton icon={<IconAdd />} aria-label=\"Adicionar nota fiscal\">{undefined}</AppButton>;","exportName":"IconOnly","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appbutton--loading","name":"Loading","snippet":"const Loading = () => <AppButton isLoading>Enviando...</AppButton>;","exportName":"Loading","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appbutton--disabled","name":"Disabled","snippet":"const Disabled = () => <AppButton disabled>Participar</AppButton>;","exportName":"Disabled","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appbutton--tone-appearance-matrix","name":"Tone Appearance Matrix","snippet":"const ToneAppearanceMatrix = () => (\n  <div style={{ display: 'grid', gridTemplateColumns: `repeat(${appearances.length}, max-content)`, gap: 12, background: 'var(--color-surface)', padding: 16 }}>\n    {tones.flatMap((tone) =>\n      appearances.map((appearance) => (\n        <AppButton key={`${tone}-${appearance}`} tone={tone} appearance={appearance} size=\"md\" leadingIcon={tone === 'danger' ? <IconDelete /> : undefined}>\n          {`${tone} ${appearance}`}\n        </AppButton>\n      )),\n    )}\n  </div>\n);","exportName":"ToneAppearanceMatrix","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppButton } from '@handsondigital/idplugger-ui';\nimport { IconAdd, IconArrowForward, IconCheck, IconDelete } from '@handsondigital/idplugger-ui/icons';\nimport { fn } from 'storybook/test';","title":"Atoms/AppButton"},"molecules-appcard":{"id":"molecules-appcard","name":"AppCard","path":"./src/components/AppCard/AppCard.stories.tsx","jsDocTags":{},"description":"Superfície de conteúdo composta com `AppCardMedia`, `AppCardBody` e `AppCardFooter`.\n\n**Quando usar:** agrupar mídia, texto e ações relacionadas (produto, plano, prêmio) numa superfície elevada.\n\n**Quando não usar:** uma lista simples de texto sem mídia ou ação própria; use `Typography` direto.","reactDocgenTypescript":{"tags":{"example":"<AppCard interactive>\n  <AppCardMedia><AppThumb alt=\"Produto\" /></AppCardMedia>\n  <AppCardBody>\n    <Typography variant=\"h5\">Plano Básico</Typography>\n    <a href=\"/planos/basico\">Ver mais</a>\n  </AppCardBody>\n</AppCard>"},"filePath":"src/components/AppCard/AppCard.tsx","description":"Superfície de conteúdo composta com `AppCardMedia`, `AppCardBody` e `AppCardFooter`.\n\n**Quando usar:** agrupar mídia, texto e ações relacionadas (produto, plano, prêmio) numa superfície elevada.\n\n**Quando não usar:** uma lista simples de texto sem mídia ou ação própria; use `Typography` direto.","displayName":"AppCard","methods":[],"props":{"as":{"defaultValue":{"value":"div"},"description":"Elemento raiz renderizado. Padrão: `'div'`.","name":"as","parent":{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"}],"required":false,"type":{"name":"enum","raw":"AppCardAs","value":[{"value":"\"article\""},{"value":"\"div\""},{"value":"\"li\""}]}},"tone":{"defaultValue":{"value":"default"},"description":"`'brand'` usa o fundo suave da marca. Padrão: `'default'`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"}],"required":false,"type":{"name":"enum","raw":"AppCardTone","value":[{"value":"\"default\""},{"value":"\"brand\""}]}},"elevation":{"defaultValue":{"value":"raised"},"description":"`'flat'` remove a sombra, mantendo só a borda. Padrão: `'raised'`.","name":"elevation","parent":{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"}],"required":false,"type":{"name":"enum","raw":"AppCardElevation","value":[{"value":"\"raised\""},{"value":"\"flat\""}]}},"interactive":{"defaultValue":{"value":"false"},"description":"Transforma o primeiro link/botão do card na área clicável do card inteiro (stretched link), com hover elevado\ne foco visível da marca.","name":"interactive","parent":{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCard/AppCard.tsx","name":"AppCardProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"AppCard"},"stories":[{"id":"molecules-appcard--default","name":"Default","snippet":"const Default = () => (\n  <div style={{ width: 298 }}>\n    <AppCard>\n      <AppCardMedia>\n        <AppThumb alt=\"Produto\" />\n      </AppCardMedia>\n      <AppCardBody>\n        <Typography variant=\"h5\" as=\"h3\" style={{ margin: 0 }}>Nome do produto</Typography>\n        <Typography variant=\"body\" style={{ margin: 0, color: 'var(--color-foreground-muted)' }}>\n          Descrição curta do produto participante da campanha.\n        </Typography>\n      </AppCardBody>\n      <AppCardFooter>\n        <AppButton size=\"full\">Ver mais</AppButton>\n      </AppCardFooter>\n    </AppCard>\n  </div>\n);","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appcard--planos","name":"Planos","snippet":"const Planos = () => (\n  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(0, 260px))', gap: 24 }}>\n    <AppCard>\n      <AppCardMedia>\n        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 155, background: 'var(--color-surface-muted)' }}>\n          <AppBadge>Básico</AppBadge>\n        </div>\n      </AppCardMedia>\n      <AppCardBody>\n        <Typography variant=\"h4\" as=\"h3\" style={{ margin: 0 }}>Básico</Typography>\n        <ul style={{ margin: 0, paddingInlineStart: 20, display: 'grid', gap: 8 }}>\n          <li>1 participação por mês</li>\n          <li>Suporte por e-mail</li>\n        </ul>\n      </AppCardBody>\n      <AppCardFooter>\n        <AppButton appearance=\"outline\" size=\"full\">Escolher</AppButton>\n      </AppCardFooter>\n    </AppCard>\n    <AppCard tone=\"brand\">\n      <AppCardMedia>\n        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 155 }}>\n          <AppBadge tone=\"primary\">Enterprise</AppBadge>\n        </div>\n      </AppCardMedia>\n      <AppCardBody>\n        <Typography variant=\"h4\" as=\"h3\" style={{ margin: 0 }}>Enterprise</Typography>\n        <ul style={{ margin: 0, paddingInlineStart: 20, display: 'grid', gap: 8 }}>\n          <li>Participações ilimitadas</li>\n          <li>Suporte prioritário</li>\n          <li>Relatórios mensais</li>\n        </ul>\n      </AppCardBody>\n      <AppCardFooter>\n        <AppButton tone=\"white\" size=\"full\">Escolher</AppButton>\n      </AppCardFooter>\n    </AppCard>\n    <AppCard>\n      <AppCardMedia>\n        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 155, background: 'var(--color-surface-muted)' }}>\n          <AppBadge>Intermediário</AppBadge>\n        </div>\n      </AppCardMedia>\n      <AppCardBody>\n        <Typography variant=\"h4\" as=\"h3\" style={{ margin: 0 }}>Intermediário</Typography>\n        <ul style={{ margin: 0, paddingInlineStart: 20, display: 'grid', gap: 8 }}>\n          <li>5 participações por mês</li>\n          <li>Suporte por chat</li>\n        </ul>\n      </AppCardBody>\n      <AppCardFooter>\n        <AppButton appearance=\"outline\" size=\"full\">Escolher</AppButton>\n      </AppCardFooter>\n    </AppCard>\n  </div>\n);","exportName":"Planos","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appcard--carregando","name":"Carregando","snippet":"const Carregando = () => (\n  <div style={{ width: 298 }} aria-busy=\"true\">\n    <AppCard>\n      <AppCardMedia>\n        <AppThumb alt=\"\" />\n      </AppCardMedia>\n      <AppCardBody>\n        <AppSkeleton variant=\"title\" />\n        <AppSkeleton variant=\"text\" lines={2} />\n      </AppCardBody>\n      <AppCardFooter>\n        <AppSkeleton variant=\"rect\" height={44} />\n      </AppCardFooter>\n    </AppCard>\n  </div>\n);","exportName":"Carregando","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appcard--interativo","name":"Interativo","snippet":"const Interativo = () => (\n  <div style={{ width: 298 }}>\n    <AppCard interactive>\n      <AppCardMedia>\n        <AppThumb alt=\"\" />\n      </AppCardMedia>\n      <AppCardBody>\n        <Typography variant=\"h5\" as=\"h3\" style={{ margin: 0 }}>Plano Básico</Typography>\n        <a href=\"#plano-basico\">Ver mais</a>\n      </AppCardBody>\n    </AppCard>\n  </div>\n);","exportName":"Interativo","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appcard--grade","name":"Grade","snippet":"const Grade = () => (\n  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 220px), 1fr))', gap: 16, maxWidth: 960 }}>\n    {['Produto A', 'Produto B', 'Produto C', 'Produto D'].map((name) => (\n      <AppCard key={name}>\n        <AppCardMedia>\n          <AppThumb alt={name} />\n        </AppCardMedia>\n        <AppCardBody>\n          <Typography variant=\"h6\" as=\"h3\" style={{ margin: 0 }}>{name}</Typography>\n        </AppCardBody>\n        <AppCardFooter>\n          <AppButton size=\"full\" appearance=\"outline\">Ver mais</AppButton>\n        </AppCardFooter>\n      </AppCard>\n    ))}\n  </div>\n);","exportName":"Grade","tags":["dev","test","manifest","autodocs"]}],"import":"import {\n  AppBadge,\n  AppButton,\n  AppCard,\n  AppCardBody,\n  AppCardFooter,\n  AppCardMedia,\n  AppSkeleton,\n  AppThumb,\n  Typography,\n} from '@handsondigital/idplugger-ui';","title":"Molecules/AppCard"},"atoms-appcheckbox":{"id":"atoms-appcheckbox","name":"AppCheckbox","path":"./src/components/AppCheckbox/AppCheckbox.stories.tsx","jsDocTags":{},"description":"Caixa de seleção nativa com rótulo, mensagem de apoio e estado indeterminado opcional.\n\n**Quando usar:** seleção independente de uma ou mais opções, inclusive o estado parcial de um conjunto.\n\n**Quando não usar:** escolha exclusiva entre opções (use `AppRadio` ou `AppRadioGroup`).\n\nO `ref` e todas as props HTML são repassados ao `<input>` nativo.","reactDocgenTypescript":{"tags":{"example":"<AppCheckbox label=\"Aceito os termos\" />"},"filePath":"src/components/AppCheckbox/AppCheckbox.tsx","description":"Caixa de seleção nativa com rótulo, mensagem de apoio e estado indeterminado opcional.\n\n**Quando usar:** seleção independente de uma ou mais opções, inclusive o estado parcial de um conjunto.\n\n**Quando não usar:** escolha exclusiva entre opções (use `AppRadio` ou `AppRadioGroup`).\n\nO `ref` e todas as props HTML são repassados ao `<input>` nativo.","displayName":"AppCheckbox","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível. Informe `label` ou `aria-label` para dar nome acessível ao controle.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"}],"required":false,"type":{"name":"ReactNode"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do rótulo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro que marca o controle como inválido.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":{"value":"md"},"description":"Tamanho do controle e da tipografia. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\"","value":[{"value":"\"sm\""},{"value":"\"md\""}]}},"indeterminate":{"defaultValue":{"value":"false"},"description":"Exibe o estado parcialmente selecionado no controle nativo.","name":"indeterminate","parent":{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckbox/AppCheckbox.tsx","name":"AppCheckboxProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"AppCheckbox"},"stories":[{"id":"atoms-appcheckbox--default","name":"Default","snippet":"const Default = () => <AppCheckbox label=\"Receber novidades\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appcheckbox--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'grid', gap: 16 }}>\n    <AppCheckbox size=\"sm\" label=\"Pequeno\" />\n    <AppCheckbox size=\"md\" label=\"Médio\" defaultChecked />\n    <AppCheckbox size=\"md\" label=\"Parcial\" indeterminate />\n    <AppCheckbox size=\"md\" label=\"Indisponível\" disabled defaultChecked />\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appcheckbox--with-hint","name":"With Hint","snippet":"const WithHint = () => <AppCheckbox\n    label=\"Receber novidades\"\n    hint=\"Você pode alterar esta preferência depois.\" />;","exportName":"WithHint","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appcheckbox--with-error","name":"With Error","snippet":"const WithError = () => <AppCheckbox\n    label=\"Receber novidades\"\n    error=\"Confirme o recebimento de novidades.\" />;","exportName":"WithError","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appcheckbox--indeterminate","name":"Indeterminate","snippet":"const Indeterminate = () => <AppCheckbox label=\"Selecionar todos\" indeterminate />;","exportName":"Indeterminate","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appcheckbox--disabled","name":"Disabled","snippet":"const Disabled = () => <AppCheckbox label=\"Receber novidades\" disabled defaultChecked />;","exportName":"Disabled","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppCheckbox } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Atoms/AppCheckbox"},"molecules-appcheckboxgroup":{"id":"molecules-appcheckboxgroup","name":"AppCheckboxGroup","path":"./src/components/AppCheckboxGroup/AppCheckboxGroup.stories.tsx","jsDocTags":{},"description":"Agrupa caixas de seleção relacionadas em um `<fieldset>` com legenda e feedback do grupo.\n\n**Quando usar:** várias escolhas que pertencem à mesma pergunta ou preferência.\n\n**Quando não usar:** uma única caixa de seleção isolada (use `AppCheckbox`) ou escolha exclusiva (use `AppRadioGroup`).\n\nO grupo não controla o estado das opções: passe as props nativas a cada `AppCheckbox` filho.","reactDocgenTypescript":{"tags":{"example":"<AppCheckboxGroup legend=\"Interesses\"><AppCheckbox label=\"Eventos\" /></AppCheckboxGroup>"},"filePath":"src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","description":"Agrupa caixas de seleção relacionadas em um `<fieldset>` com legenda e feedback do grupo.\n\n**Quando usar:** várias escolhas que pertencem à mesma pergunta ou preferência.\n\n**Quando não usar:** uma única caixa de seleção isolada (use `AppCheckbox`) ou escolha exclusiva (use `AppRadioGroup`).\n\nO grupo não controla o estado das opções: passe as props nativas a cada `AppCheckbox` filho.","displayName":"AppCheckboxGroup","methods":[],"props":{"legend":{"defaultValue":null,"description":"Legenda visível que dá nome acessível ao grupo.","name":"legend","parent":{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"}],"required":true,"type":{"name":"ReactNode"}},"children":{"defaultValue":null,"description":"Opções `AppCheckbox` do grupo.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"}],"required":true,"type":{"name":"ReactNode"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo das opções. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro que marca o grupo como inválido.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"}],"required":false,"type":{"name":"string"}},"orientation":{"defaultValue":{"value":"vertical"},"description":"Disposição das opções. Padrão: `vertical`.","name":"orientation","parent":{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppCheckboxGroup/AppCheckboxGroup.tsx","name":"AppCheckboxGroupProps"}],"required":false,"type":{"name":"enum","raw":"\"horizontal\" | \"vertical\"","value":[{"value":"\"horizontal\""},{"value":"\"vertical\""}]}}},"exportName":"AppCheckboxGroup"},"stories":[{"id":"molecules-appcheckboxgroup--default","name":"Default","snippet":"const Default = () => <AppCheckboxGroup legend=\"Interesses\" hint=\"Escolha todas as opções que desejar.\">(<>\n      <AppCheckbox label=\"Eventos\" />\n      <AppCheckbox label=\"Novidades do produto\" />\n      <AppCheckbox label=\"Conteúdos educativos\" />\n    </>)</AppCheckboxGroup>;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appcheckboxgroup--with-error","name":"With Error","snippet":"const WithError = () => <AppCheckboxGroup legend=\"Preferências\" error=\"Escolha ao menos uma opção.\"><AppCheckbox label=\"Eventos\" /></AppCheckboxGroup>;","exportName":"WithError","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppCheckbox, AppCheckboxGroup } from '@handsondigital/idplugger-ui';\nimport { AppCheckbox } from '../AppCheckbox/AppCheckbox';","title":"Molecules/AppCheckboxGroup"},"atoms-appfeaturedicon":{"id":"atoms-appfeaturedicon","name":"AppFeaturedIcon","path":"./src/components/AppFeaturedIcon/AppFeaturedIcon.stories.tsx","jsDocTags":{},"description":"Ícone decorativo destacado em um círculo com cor semântica.\n\n**Quando usar:** identificar visualmente um arquivo, etapa ou resumo curto ao lado de um texto já nomeado.\n\n**Quando não usar:** o ícone precisa ser a única forma de comunicar uma ação ou informação; nesse caso, forneça\num nome acessível no controle que o contém.","reactDocgenTypescript":{"tags":{"example":"<AppFeaturedIcon icon={<IconFilePresent />} />"},"filePath":"src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","description":"Ícone decorativo destacado em um círculo com cor semântica.\n\n**Quando usar:** identificar visualmente um arquivo, etapa ou resumo curto ao lado de um texto já nomeado.\n\n**Quando não usar:** o ícone precisa ser a única forma de comunicar uma ação ou informação; nesse caso, forneça\num nome acessível no controle que o contém.","displayName":"AppFeaturedIcon","methods":[],"props":{"icon":{"defaultValue":null,"description":"Ícone decorativo exibido dentro do círculo.","name":"icon","parent":{"fileName":"idplugger-ui/src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","name":"AppFeaturedIconProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","name":"AppFeaturedIconProps"}],"required":true,"type":{"name":"ReactNode"}},"size":{"defaultValue":{"value":"md"},"description":"Diâmetro do círculo: 32px, 40px ou 48px. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","name":"AppFeaturedIconProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","name":"AppFeaturedIconProps"}],"required":false,"type":{"name":"enum","raw":"AppFeaturedIconSize","value":[{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""}]}},"tone":{"defaultValue":{"value":"primary"},"description":"Intenção visual do ícone. Padrão: `primary`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","name":"AppFeaturedIconProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFeaturedIcon/AppFeaturedIcon.tsx","name":"AppFeaturedIconProps"}],"required":false,"type":{"name":"enum","raw":"AppFeaturedIconTone","value":[{"value":"\"success\""},{"value":"\"warning\""},{"value":"\"danger\""},{"value":"\"neutral\""},{"value":"\"primary\""}]}}},"exportName":"AppFeaturedIcon"},"stories":[{"id":"atoms-appfeaturedicon--default","name":"Default","snippet":"const Default = () => <AppFeaturedIcon icon={<IconFilePresent />} />;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appfeaturedicon--tons","name":"Tons","snippet":"const Tons = () => (\n  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12 }}>\n    <AppFeaturedIcon tone=\"primary\" icon={<IconFilePresent />} />\n    <AppFeaturedIcon tone=\"success\" icon={<IconFilePresent />} />\n    <AppFeaturedIcon tone=\"warning\" icon={<IconFilePresent />} />\n    <AppFeaturedIcon tone=\"danger\" icon={<IconFilePresent />} />\n    <AppFeaturedIcon tone=\"neutral\" icon={<IconFilePresent />} />\n  </div>\n);","exportName":"Tons","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appfeaturedicon--tamanhos","name":"Tamanhos","snippet":"const Tamanhos = () => (\n  <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n    <AppFeaturedIcon size=\"sm\" icon={<IconFilePresent />} />\n    <AppFeaturedIcon size=\"md\" icon={<IconFilePresent />} />\n    <AppFeaturedIcon size=\"lg\" icon={<IconFilePresent />} />\n  </div>\n);","exportName":"Tamanhos","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppFeaturedIcon } from '@handsondigital/idplugger-ui';\nimport { IconFilePresent } from '@handsondigital/idplugger-ui/icons';","title":"Atoms/AppFeaturedIcon"},"molecules-appfileupload":{"id":"molecules-appfileupload","name":"AppFileUpload","path":"./src/components/AppFileUpload/AppFileUpload.stories.tsx","jsDocTags":{},"description":"Campo para enviar arquivos: área de soltar (arrastar e soltar) e seleção pelo explorador de arquivos, com\nvalidação de formato e tamanho e a lista dos arquivos escolhidos (miniatura para imagens, nome, tamanho e\nbotão de remover).\n\n**Quando usar:** foto do cupom fiscal, anexos de um atendimento, foto do participante.\n\n**Quando não usar:** quando o arquivo precisa ser recortado ou editado antes do envio.\n\nO controle acessível é o próprio `<input type=\"file\">` (um só ponto de foco). Arquivos fora de `accept` ou acima\nde `maxSize` não entram na lista e geram a mensagem de erro do campo; a entrada e a saída de arquivos são\nanunciadas para leitores de tela. O campo não envia nada: quem usa recebe os `File` em `onChange`.","reactDocgenTypescript":{"tags":{"example":"<AppFileUpload\n  label=\"Foto do cupom fiscal\"\n  hint=\"JPG, PNG ou PDF até 5 MB\"\n  accept=\"image/jpeg,image/png,.pdf\"\n  maxSize={5 * 1024 * 1024}\n  onChange={setArquivos}\n/>"},"filePath":"src/components/AppFileUpload/AppFileUpload.tsx","description":"Campo para enviar arquivos: área de soltar (arrastar e soltar) e seleção pelo explorador de arquivos, com\nvalidação de formato e tamanho e a lista dos arquivos escolhidos (miniatura para imagens, nome, tamanho e\nbotão de remover).\n\n**Quando usar:** foto do cupom fiscal, anexos de um atendimento, foto do participante.\n\n**Quando não usar:** quando o arquivo precisa ser recortado ou editado antes do envio.\n\nO controle acessível é o próprio `<input type=\"file\">` (um só ponto de foco). Arquivos fora de `accept` ou acima\nde `maxSize` não entram na lista e geram a mensagem de erro do campo; a entrada e a saída de arquivos são\nanunciadas para leitores de tela. O campo não envia nada: quem usa recebe os `File` em `onChange`.","displayName":"AppFileUpload","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível; vira o nome acessível do campo.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":true,"type":{"name":"string"}},"hint":{"defaultValue":null,"description":"Texto de apoio (ex.: formatos e tamanho aceitos). Some enquanto houver erro.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Erro vindo de quem usa (ex.: do servidor). Tem precedência sobre o erro de validação do próprio campo.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"string"}},"accept":{"defaultValue":null,"description":"Tipos aceitos, como no `<input type=\"file\">`: `\"image/*\"`, `\".pdf\"`, `\"image/png,.pdf\"`.","name":"accept","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"string"}},"multiple":{"defaultValue":{"value":"false"},"description":"Permite vários arquivos. Sem `multiple`, um arquivo novo substitui o anterior.","name":"multiple","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"boolean"}},"maxSize":{"defaultValue":null,"description":"Tamanho máximo de cada arquivo, em bytes.","name":"maxSize","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"number"}},"value":{"defaultValue":null,"description":"Arquivos selecionados (controlado).","name":"value","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"File[]"}},"onChange":{"defaultValue":null,"description":"Chamado com a lista nova sempre que um arquivo entra ou sai.","name":"onChange","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"((files: File[]) => void)"}},"disabled":{"defaultValue":{"value":"false"},"description":"","name":"disabled","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"boolean"}},"name":{"defaultValue":null,"description":"`name` do `<input type=\"file\">`, para envio em formulário.","name":"name","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"string"}},"id":{"defaultValue":null,"description":"","name":"id","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"string"}},"className":{"defaultValue":null,"description":"","name":"className","parent":{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppFileUpload/AppFileUpload.tsx","name":"AppFileUploadProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppFileUpload"},"stories":[{"id":"molecules-appfileupload--cupom-fiscal","name":"Cupom Fiscal","snippet":"const CupomFiscal = () => <AppFileUpload\n    label=\"Foto do cupom fiscal\"\n    hint=\"JPG, PNG ou PDF até 5 MB\"\n    accept=\"image/jpeg,image/png,.pdf\"\n    maxSize={5 * MB} />;","warning":"Incomplete snippet: `MB` could not be resolved statically.","exportName":"CupomFiscal","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appfileupload--anexos-de-atendimento","name":"Anexos De Atendimento","snippet":"const AnexosDeAtendimento = () => <AppFileUpload\n    label=\"Anexos\"\n    hint=\"Até 3 arquivos de 5 MB\"\n    accept=\"image/jpeg,image/png,.pdf\"\n    maxSize={5 * MB}\n    multiple />;","warning":"Incomplete snippet: `MB` could not be resolved statically.","exportName":"AnexosDeAtendimento","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appfileupload--foto","name":"Foto","snippet":"const Foto = () => <AppFileUpload\n    label=\"Sua foto\"\n    hint=\"JPG ou PNG até 5 MB\"\n    accept=\"image/jpeg,image/png\"\n    maxSize={5 * MB} />;","warning":"Incomplete snippet: `MB` could not be resolved statically.","exportName":"Foto","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appfileupload--com-erro","name":"Com Erro","snippet":"const ComErro = () => <AppFileUpload\n    label=\"Foto do cupom fiscal\"\n    hint=\"JPG, PNG ou PDF até 5 MB\"\n    accept=\"image/jpeg,image/png,.pdf\"\n    maxSize={5 * MB} />;","warning":"Incomplete snippet: `MB` could not be resolved statically.","exportName":"ComErro","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appfileupload--desabilitado","name":"Desabilitado","snippet":"const Desabilitado = () => <AppFileUpload\n    label=\"Foto do cupom fiscal\"\n    hint=\"JPG, PNG ou PDF até 5 MB\"\n    accept=\"image/jpeg,image/png,.pdf\"\n    maxSize={5 * MB}\n    disabled />;","warning":"Incomplete snippet: `MB` could not be resolved statically.","exportName":"Desabilitado","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppFileUpload } from '@handsondigital/idplugger-ui';","title":"Molecules/AppFileUpload"},"atoms-appinput":{"id":"atoms-appinput","name":"AppInput","path":"./src/components/AppInput/AppInput.stories.tsx","jsDocTags":{},"description":"Campo de texto de uma linha com rótulo, texto de apoio, mensagem de erro, ícones e slots laterais.\n\n**Quando usar:** formulários (nome, CPF, e-mail, número da nota fiscal, busca) que precisam de rótulo e feedback de validação.\n\n**Quando não usar:** texto de várias linhas (use `AppTextarea`) ou escolha entre opções fixas (use um `<select>` nativo).\n\nO `ref` e o `className` são repassados ao `<input>`; as demais props HTML também.","reactDocgenTypescript":{"tags":{"example":"<AppInput label=\"CPF\" hint=\"Somente números\" inputMode=\"numeric\" />"},"filePath":"src/components/AppInput/AppInput.tsx","description":"Campo de texto de uma linha com rótulo, texto de apoio, mensagem de erro, ícones e slots laterais.\n\n**Quando usar:** formulários (nome, CPF, e-mail, número da nota fiscal, busca) que precisam de rótulo e feedback de validação.\n\n**Quando não usar:** texto de várias linhas (use `AppTextarea`) ou escolha entre opções fixas (use um `<select>` nativo).\n\nO `ref` e o `className` são repassados ao `<input>`; as demais props HTML também.","displayName":"AppInput","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível do campo (obrigatório): vira o nome acessível via `<label htmlFor>`.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":true,"type":{"name":"string"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do campo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro: troca o hint, pinta o campo de vermelho e marca `aria-invalid`.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":null,"description":"Altura do campo: `sm` ou `md`. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\"","value":[{"value":"\"sm\""},{"value":"\"md\""}]}},"leadingIcon":{"defaultValue":null,"description":"Ícone de 20px antes do texto. Decorativo (`aria-hidden`).","name":"leadingIcon","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"trailingIcon":{"defaultValue":null,"description":"Ícone de 16px no fim do campo (ex.: ajuda). Com `error`, o ícone de erro toma o lugar. Decorativo.","name":"trailingIcon","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"startContent":{"defaultValue":null,"description":"Conteúdo livre antes do texto, na própria caixa: selos de pagamento, tags etc.","name":"startContent","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"leadingAddon":{"defaultValue":null,"description":"Segmento à esquerda: texto fixo (\"http://\", com divisor) ou `<select>` (\"R$\", sem divisor, com seta).","name":"leadingAddon","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"trailingAddon":{"defaultValue":null,"description":"Segmento à direita: `AppButton` (com divisor) ou `<select>` de moeda (sem divisor, com seta).","name":"trailingAddon","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"endAction":{"defaultValue":null,"description":"Ação interativa no fim do campo, antes do segmento direito (ex.: alternar a visibilidade da senha). Ao\ncontrário de `trailingIcon`, que é decorativo, o elemento deve ser focável e descrever a própria ação\n(ex.: `aria-label`).","name":"endAction","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"AppInput"},"stories":[{"id":"atoms-appinput--default","name":"Default","snippet":"const Default = () => <AppInput label=\"CPF\" placeholder=\"000.000.000-00\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appinput--with-hint","name":"With Hint","snippet":"const WithHint = () => <AppInput\n    label=\"Número da nota fiscal\"\n    placeholder=\"\"\n    hint=\"Está no topo do cupom fiscal.\" />;","exportName":"WithHint","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appinput--with-error","name":"With Error","snippet":"const WithError = () => <AppInput\n    label=\"CPF\"\n    placeholder=\"000.000.000-00\"\n    error=\"CPF inválido. Confira os números.\"\n    defaultValue=\"123\" />;","exportName":"WithError","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appinput--disabled","name":"Disabled","snippet":"const Disabled = () => <AppInput\n    label=\"CPF\"\n    placeholder=\"000.000.000-00\"\n    disabled\n    defaultValue=\"123.456.789-00\" />;","exportName":"Disabled","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--sizes","name":"Sizes","snippet":"const Sizes = () => <div style={{ display: 'grid', gap: 16 }}>\n    <AppInput placeholder=\"000.000.000-00\" label=\"Pequeno\" size=\"sm\" />\n    <AppInput\n        placeholder=\"000.000.000-00\"\n        label=\"Médio (padrão)\"\n        size=\"md\" />\n</div>;","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--leading-icon","name":"Leading Icon","snippet":"const LeadingIcon = () => <AppInput\n    label=\"E-mail\"\n    placeholder=\"nome@email.com\"\n    type=\"email\"\n    leadingIcon={<IconMail />}\n    trailingIcon={<IconHelpOutline />} />;","exportName":"LeadingIcon","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--payment","name":"Payment","snippet":"const Payment = () => <AppInput\n    label=\"Número do cartão\"\n    placeholder=\"0000 0000 0000 0000\"\n    inputMode=\"numeric\"\n    startContent={<AppPaymentIcon method=\"visa\" />} />;","exportName":"Payment","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--tags","name":"Tags","snippet":"const Tags = () => <AppInput\n    label=\"Buscar\"\n    placeholder=\"Digite…\"\n    leadingIcon={<IconSearch />}\n    startContent={<AppTag removeLabel=\"Remover Marketing\">Marketing</AppTag>} />;","exportName":"Tags","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--leading-text-addon","name":"Leading Text Addon","snippet":"const LeadingTextAddon = () => <AppInput\n    label=\"Site\"\n    placeholder=\"www.exemplo.com.br\"\n    leadingAddon=\"http://\" />;","exportName":"LeadingTextAddon","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--trailing-select-addon","name":"Trailing Select Addon","snippet":"const TrailingSelectAddon = () => <AppInput\n    label=\"Valor\"\n    placeholder=\"0,00\"\n    inputMode=\"decimal\"\n    trailingAddon={(<select aria-label=\"Moeda\" defaultValue=\"BRL\">\n      <option value=\"BRL\">R$</option>\n      <option value=\"USD\">US$</option>\n    </select>)} />;","exportName":"TrailingSelectAddon","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appinput--trailing-button-addon","name":"Trailing Button Addon","snippet":"const TrailingButtonAddon = () => <AppInput\n    label=\"Link de indicação\"\n    placeholder=\"000.000.000-00\"\n    defaultValue=\"https://exemplo.com.br/promo/abc\"\n    readOnly\n    trailingAddon={<AppButton appearance=\"ghost\" size=\"sm\">Copiar</AppButton>} />;","exportName":"TrailingButtonAddon","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppButton, AppInput, AppPaymentIcon, AppTag } from '@handsondigital/idplugger-ui';\nimport { IconHelpOutline, IconMail, IconSearch } from '@handsondigital/idplugger-ui/icons';\nimport { fn } from 'storybook/test';\nimport { AppPaymentIcon } from '../AppPaymentIcon/AppPaymentIcon';\nimport { AppTag } from '../AppTag/AppTag';\nimport { AppButton } from '../AppButton/AppButton';","title":"Atoms/AppInput"},"organisms-appmodal":{"id":"organisms-appmodal","name":"AppModal","path":"./src/components/AppModal/AppModal.stories.tsx","jsDocTags":{},"description":"Diálogo modal (Radix Dialog) renderizado em portal sobre um overlay.\n\nPrende o foco dentro do diálogo (focus trap), bloqueia a rolagem da página enquanto aberto,\nfecha com Escape e devolve o foco ao elemento que o abriu.\n\nO portal fica no fim do `<body>`, fora da seção que abriu o modal; por isso o modal copia o `data-brand` e o\n`data-theme` do escopo do elemento focado ao abrir (o gatilho). Aberto sem gatilho (ex.: ao carregar a página),\nsegue a marca e o modo do `<html>`.\n\n**Quando usar:** confirmações, formulários curtos e avisos que exigem decisão antes de continuar.\n\n**Quando não usar:** feedback passageiro (use `AppToast`) ou conteúdo que deve ficar na página.","reactDocgenTypescript":{"tags":{"example":"<AppModal isOpen={open} onClose={() => setOpen(false)} title=\"Regulamento\">\n  <p>Leia as regras da promoção.</p>\n</AppModal>"},"filePath":"src/components/AppModal/AppModal.tsx","description":"Diálogo modal (Radix Dialog) renderizado em portal sobre um overlay.\n\nPrende o foco dentro do diálogo (focus trap), bloqueia a rolagem da página enquanto aberto,\nfecha com Escape e devolve o foco ao elemento que o abriu.\n\nO portal fica no fim do `<body>`, fora da seção que abriu o modal; por isso o modal copia o `data-brand` e o\n`data-theme` do escopo do elemento focado ao abrir (o gatilho). Aberto sem gatilho (ex.: ao carregar a página),\nsegue a marca e o modo do `<html>`.\n\n**Quando usar:** confirmações, formulários curtos e avisos que exigem decisão antes de continuar.\n\n**Quando não usar:** feedback passageiro (use `AppToast`) ou conteúdo que deve ficar na página.","displayName":"AppModal","methods":[],"props":{"isOpen":{"defaultValue":null,"description":"Controla a visibilidade. Componente controlado: o pai decide quando abrir e fechar.","name":"isOpen","parent":{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"}],"required":true,"type":{"name":"boolean"}},"onClose":{"defaultValue":null,"description":"Chamado ao pedir o fechamento (botão \"Fechar modal\" ou Escape). Atualize `isOpen` para `false` aqui. O clique fora não fecha.","name":"onClose","parent":{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"}],"required":true,"type":{"name":"() => void"}},"title":{"defaultValue":null,"description":"Título do diálogo; vira o nome acessível (`aria-labelledby`). Obrigatório.","name":"title","parent":{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"}],"required":true,"type":{"name":"string"}},"children":{"defaultValue":null,"description":"Conteúdo do corpo do modal.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"}],"required":true,"type":{"name":"ReactNode"}},"footer":{"defaultValue":null,"description":"Rodapé opcional, normalmente com os botões de ação. Omitido quando não informado.","name":"footer","parent":{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"}],"required":false,"type":{"name":"ReactNode"}},"className":{"defaultValue":null,"description":"Classe CSS extra aplicada ao diálogo.","name":"className","parent":{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppModal/AppModal.tsx","name":"AppModalProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppModal"},"stories":[{"id":"organisms-appmodal--default","name":"Default","snippet":"const Default = () => <ModalWithTrigger />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"organisms-appmodal--with-footer","name":"With Footer","snippet":"const WithFooter = () => <AppModal\n    isOpen\n    title=\"Regulamento da promoção\"\n    footer={<AppButton>Participar</AppButton>}>Para participar, informe seu CPF e o número da nota fiscal.</AppModal>;","exportName":"WithFooter","tags":["dev","test","manifest","autodocs","sem-portal"]},{"id":"organisms-appmodal--close-button","name":"Close Button","snippet":"const CloseButton = () => <AppModal isOpen title=\"Regulamento da promoção\">Para participar, informe seu CPF e o número da nota fiscal.</AppModal>;","exportName":"CloseButton","tags":["dev","test","manifest","autodocs","sem-portal","play-fn"]}],"import":"import { AppButton, AppModal } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';\nimport { AppButton } from '../AppButton/AppButton';","title":"Organisms/AppModal"},"molecules-apppagination":{"id":"molecules-apppagination","name":"AppPagination","path":"./src/components/AppPagination/AppPagination.stories.tsx","jsDocTags":{},"description":"Navegação entre páginas de uma lista, controlada por `page` e `onPageChange`.\n\n**Quando usar:** listas longas divididas em páginas (ganhadores, notas fiscais, resultados), no rodapé da página ou de um card.\n\n**Quando não usar:** passos de um fluxo sequencial ou carregamento infinito; use o componente de etapas ou um botão \"Ver mais\" (`AppButton`).\n\nAcessibilidade: é um `<nav>` com `aria-label` \"Paginação\" (sobrescreva se houver mais de uma) e a página atual recebe `aria-current=\"page\"`. Em telas estreitas o CSS reduz os números exibidos.","reactDocgenTypescript":{"tags":{"example":"const [page, setPage] = useState(1)\n<AppPagination page={page} pageCount={10} onPageChange={setPage} />"},"filePath":"src/components/AppPagination/AppPagination.tsx","description":"Navegação entre páginas de uma lista, controlada por `page` e `onPageChange`.\n\n**Quando usar:** listas longas divididas em páginas (ganhadores, notas fiscais, resultados), no rodapé da página ou de um card.\n\n**Quando não usar:** passos de um fluxo sequencial ou carregamento infinito; use o componente de etapas ou um botão \"Ver mais\" (`AppButton`).\n\nAcessibilidade: é um `<nav>` com `aria-label` \"Paginação\" (sobrescreva se houver mais de uma) e a página atual recebe `aria-current=\"page\"`. Em telas estreitas o CSS reduz os números exibidos.","displayName":"AppPagination","methods":[],"props":{"page":{"defaultValue":null,"description":"Página atual, a partir de 1 (controlado).","name":"page","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":true,"type":{"name":"number"}},"pageCount":{"defaultValue":null,"description":"Total de páginas (mínimo 1).","name":"pageCount","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":true,"type":{"name":"number"}},"onPageChange":{"defaultValue":null,"description":"Chamada com o número da nova página ao navegar; não dispara para a página atual nem fora do intervalo.","name":"onPageChange","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":true,"type":{"name":"(page: number) => void"}},"appearance":{"defaultValue":{"value":"page"},"description":"`page`: rodapé da página (borda no topo). `card`: dentro de um card, com padding.","name":"appearance","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"enum","raw":"PaginationAppearance","value":[{"value":"\"card\""},{"value":"\"page\""}]}},"layout":{"defaultValue":{"value":"numbers"},"description":"`numbers`: anterior, números e próxima. `details`: \"Página 1 de 10\" e os dois botões. `group`: botões unidos.","name":"layout","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"enum","raw":"PaginationLayout","value":[{"value":"\"group\""},{"value":"\"details\""},{"value":"\"numbers\""}]}},"align":{"defaultValue":{"value":"right"},"description":"Onde ficam os botões (`details`) ou o grupo (`group`). Padrão: `right`.","name":"align","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"enum","raw":"PaginationAlign","value":[{"value":"\"center\""},{"value":"\"left\""},{"value":"\"right\""}]}},"shape":{"defaultValue":{"value":"square"},"description":"Forma dos números do layout `numbers`.","name":"shape","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"enum","raw":"\"circle\" | \"square\"","value":[{"value":"\"circle\""},{"value":"\"square\""}]}},"nav":{"defaultValue":null,"description":"Estilo de anterior/próxima no layout `numbers`: `link` (padrão em `page`) ou `button` (padrão em `card`).","name":"nav","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"enum","raw":"\"button\" | \"link\"","value":[{"value":"\"button\""},{"value":"\"link\""}]}},"previousLabel":{"defaultValue":{"value":"Anterior"},"description":"Texto do botão \"anterior\". Padrão: `Anterior`.","name":"previousLabel","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"string"}},"nextLabel":{"defaultValue":{"value":"Próxima"},"description":"Texto do botão \"próxima\". Padrão: `Próxima`.","name":"nextLabel","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"string"}},"pageLabel":{"defaultValue":{"value":"(number) => `Página ${number}`"},"description":"Nome acessível de cada número. Padrão: `Página N`.","name":"pageLabel","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"((page: number) => string)"}},"detailsLabel":{"defaultValue":{"value":"(current, total) => `Página ${current} de ${total}`"},"description":"Texto de `details`. Padrão: `Página N de M`.","name":"detailsLabel","parent":{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPagination/AppPagination.tsx","name":"AppPaginationProps"}],"required":false,"type":{"name":"((page: number, pageCount: number) => string)"}}},"exportName":"AppPagination"},"stories":[{"id":"molecules-apppagination--default","name":"Default","snippet":"const Default = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-apppagination--card","name":"Card","snippet":"const Card = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            appearance=\"card\"\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"Card","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apppagination--circle","name":"Circle","snippet":"const Circle = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            shape=\"circle\"\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"Circle","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apppagination--details-right","name":"Details Right","snippet":"const DetailsRight = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            layout=\"details\"\n            align=\"right\"\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"DetailsRight","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-apppagination--details-center","name":"Details Center","snippet":"const DetailsCenter = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            layout=\"details\"\n            align=\"center\"\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"DetailsCenter","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apppagination--details-left","name":"Details Left","snippet":"const DetailsLeft = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            layout=\"details\"\n            align=\"left\"\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"DetailsLeft","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apppagination--group","name":"Group","snippet":"const Group = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            layout=\"group\"\n            align=\"right\"\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"Group","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-apppagination--last-page","name":"Last Page","snippet":"const LastPage = () => {\n    const [page, setPage] = useState(initialPage)\n\n    return (\n        <AppPagination\n            pageCount={10}\n            page={page}\n            onPageChange={(next) => {\n              setPage(next)\n              onPageChange(next)\n            }} />\n    );\n};","exportName":"LastPage","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { AppPagination } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Molecules/AppPagination"},"atoms-apppasswordinput":{"id":"atoms-apppasswordinput","name":"AppPasswordInput","path":"./src/components/AppPasswordInput/AppPasswordInput.stories.tsx","jsDocTags":{},"description":"Campo de senha com botão para mostrar ou ocultar o texto digitado. Aceita as mesmas props de campo do\n`AppInput` (rótulo, dica, erro, tamanho) e, opcionalmente, a lista de requisitos da senha com o estado de cada um.\n\n**Quando usar:** login, cadastro e redefinição de senha.\n\n**Quando não usar:** códigos curtos que a pessoa precisa conferir (ex.: código de validação por e-mail); use\n`AppInput` com `inputMode=\"numeric\"`.\n\nO botão \"Mostrar senha\" indica o estado com `aria-pressed` e devolve o foco ao campo quando clicado com o mouse.","reactDocgenTypescript":{"tags":{"example":"<AppPasswordInput\n  label=\"Nova senha\"\n  autoComplete=\"new-password\"\n  rules={[{ label: 'Pelo menos 8 caracteres', met: senha.length >= 8 }]}\n/>"},"filePath":"src/components/AppPasswordInput/AppPasswordInput.tsx","description":"Campo de senha com botão para mostrar ou ocultar o texto digitado. Aceita as mesmas props de campo do\n`AppInput` (rótulo, dica, erro, tamanho) e, opcionalmente, a lista de requisitos da senha com o estado de cada um.\n\n**Quando usar:** login, cadastro e redefinição de senha.\n\n**Quando não usar:** códigos curtos que a pessoa precisa conferir (ex.: código de validação por e-mail); use\n`AppInput` com `inputMode=\"numeric\"`.\n\nO botão \"Mostrar senha\" indica o estado com `aria-pressed` e devolve o foco ao campo quando clicado com o mouse.","displayName":"AppPasswordInput","methods":[],"props":{"rules":{"defaultValue":null,"description":"Requisitos da senha, mostrados abaixo do campo e lidos junto com ele por leitores de tela.","name":"rules","parent":{"fileName":"idplugger-ui/src/components/AppPasswordInput/AppPasswordInput.tsx","name":"AppPasswordInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPasswordInput/AppPasswordInput.tsx","name":"AppPasswordInputProps"}],"required":false,"type":{"name":"AppPasswordRule[]"}},"label":{"defaultValue":null,"description":"Rótulo visível do campo (obrigatório): vira o nome acessível via `<label htmlFor>`.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":true,"type":{"name":"string"}},"size":{"defaultValue":null,"description":"Altura do campo: `sm` ou `md`. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\"","value":[{"value":"\"sm\""},{"value":"\"md\""}]}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do campo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro: troca o hint, pinta o campo de vermelho e marca `aria-invalid`.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"string"}},"leadingIcon":{"defaultValue":null,"description":"Ícone de 20px antes do texto. Decorativo (`aria-hidden`).","name":"leadingIcon","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"startContent":{"defaultValue":null,"description":"Conteúdo livre antes do texto, na própria caixa: selos de pagamento, tags etc.","name":"startContent","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}},"leadingAddon":{"defaultValue":null,"description":"Segmento à esquerda: texto fixo (\"http://\", com divisor) ou `<select>` (\"R$\", sem divisor, com seta).","name":"leadingAddon","parent":{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppInput/AppInput.tsx","name":"AppInputProps"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"AppPasswordInput"},"stories":[{"id":"atoms-apppasswordinput--default","name":"Default","snippet":"const Default = () => <AppPasswordInput label=\"Senha\" placeholder=\"Digite sua senha\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apppasswordinput--com-regras","name":"Com Regras","snippet":"const ComRegras = () => <NewPassword />;","exportName":"ComRegras","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apppasswordinput--com-erro","name":"Com Erro","snippet":"const ComErro = () => <AppPasswordInput\n    label=\"Senha\"\n    placeholder=\"Digite sua senha\"\n    error=\"Senha incorreta. Tente de novo ou recupere sua senha.\" />;","exportName":"ComErro","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apppasswordinput--desabilitado","name":"Desabilitado","snippet":"const Desabilitado = () => <AppPasswordInput label=\"Senha\" placeholder=\"Digite sua senha\" disabled />;","exportName":"Desabilitado","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppPasswordInput } from '@handsondigital/idplugger-ui';","title":"Atoms/AppPasswordInput"},"atoms-apppaymenticon":{"id":"atoms-apppaymenticon","name":"AppPaymentIcon","path":"./src/components/AppPaymentIcon/AppPaymentIcon.stories.tsx","jsDocTags":{},"description":"Ícone da bandeira de um cartão de pagamento (Visa, Mastercard, Amex, Diners, Discover).\n\n**Quando usar:** indicar bandeiras aceitas ou a bandeira detectada em um formulário de pagamento.\n\n**Quando não usar:** ícones de interface genéricos (use os de `Foundations/Ícones`); métodos de pagamento sem bandeira, como Pix ou boleto.","reactDocgenTypescript":{"tags":{"example":"<AppPaymentIcon method=\"visa\" size=\"md\" />"},"filePath":"src/components/AppPaymentIcon/AppPaymentIcon.tsx","description":"Ícone da bandeira de um cartão de pagamento (Visa, Mastercard, Amex, Diners, Discover).\n\n**Quando usar:** indicar bandeiras aceitas ou a bandeira detectada em um formulário de pagamento.\n\n**Quando não usar:** ícones de interface genéricos (use os de `Foundations/Ícones`); métodos de pagamento sem bandeira, como Pix ou boleto.","displayName":"AppPaymentIcon","methods":[],"props":{"method":{"defaultValue":null,"description":"Bandeira do cartão: `visa`, `mastercard`, `amex`, `diners` ou `discover`.","name":"method","parent":{"fileName":"idplugger-ui/src/components/AppPaymentIcon/AppPaymentIcon.tsx","name":"AppPaymentIconProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPaymentIcon/AppPaymentIcon.tsx","name":"AppPaymentIconProps"}],"required":true,"type":{"name":"enum","raw":"\"visa\" | \"mastercard\" | \"amex\" | \"diners\" | \"discover\"","value":[{"value":"\"visa\""},{"value":"\"mastercard\""},{"value":"\"amex\""},{"value":"\"diners\""},{"value":"\"discover\""}]}},"size":{"defaultValue":null,"description":"34×24 (`sm`), 46×32 (`md`) ou 58×40 (`lg`). Padrão: `sm`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppPaymentIcon/AppPaymentIcon.tsx","name":"AppPaymentIconProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPaymentIcon/AppPaymentIcon.tsx","name":"AppPaymentIconProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\" | \"lg\"","value":[{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""}]}},"label":{"defaultValue":null,"description":"Nome acessível. Padrão: nome da bandeira (ex.: `Visa`).","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppPaymentIcon/AppPaymentIcon.tsx","name":"AppPaymentIconProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppPaymentIcon/AppPaymentIcon.tsx","name":"AppPaymentIconProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppPaymentIcon"},"stories":[{"id":"atoms-apppaymenticon--default","name":"Default","snippet":"const Default = () => <AppPaymentIcon method=\"visa\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apppaymenticon--mastercard","name":"Mastercard","snippet":"const Mastercard = () => <AppPaymentIcon method=\"mastercard\" />;","exportName":"Mastercard","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apppaymenticon--custom-label","name":"Custom Label","snippet":"const CustomLabel = () => <AppPaymentIcon method=\"amex\" label=\"Cartão American Express aceito\" />;","exportName":"CustomLabel","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apppaymenticon--all-methods","name":"All Methods","snippet":"const AllMethods = () => (\n  <div style={{ display: 'flex', gap: 12 }}>\n    {methods.map((method) => <AppPaymentIcon key={method} method={method} />)}\n  </div>\n);","exportName":"AllMethods","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apppaymenticon--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>\n    {(['sm', 'md', 'lg'] as const).map((size) => <AppPaymentIcon key={size} method=\"mastercard\" size={size} />)}\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apppaymenticon--methods-by-size","name":"Methods By Size","snippet":"const MethodsBySize = () => (\n  <div style={{ display: 'grid', gap: 12 }}>\n    {(['sm', 'md', 'lg'] as const).map((size) => (\n      <div key={size} style={{ display: 'flex', gap: 12 }}>\n        {methods.map((method) => <AppPaymentIcon key={method} method={method} size={size} />)}\n      </div>\n    ))}\n  </div>\n);","exportName":"MethodsBySize","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppPaymentIcon } from '@handsondigital/idplugger-ui';","title":"Atoms/AppPaymentIcon"},"atoms-appprogress":{"id":"atoms-appprogress","name":"AppProgress","path":"./src/components/AppProgress/AppProgress.stories.tsx","jsDocTags":{},"description":"Indicador de progresso para uma tarefa, meta ou processamento mensurável.\n\n**Quando usar:** há um valor atual e um máximo conhecidos, como envio de arquivo ou avaliações concluídas.\n\n**Quando não usar:** a duração é indeterminada; nesse caso, use um indicador de carregamento.","reactDocgenTypescript":{"tags":{"example":"<AppProgress value={45} max={70} label=\"45/70 avaliações\" tone=\"success\" />"},"filePath":"src/components/AppProgress/AppProgress.tsx","description":"Indicador de progresso para uma tarefa, meta ou processamento mensurável.\n\n**Quando usar:** há um valor atual e um máximo conhecidos, como envio de arquivo ou avaliações concluídas.\n\n**Quando não usar:** a duração é indeterminada; nesse caso, use um indicador de carregamento.","displayName":"AppProgress","methods":[],"props":{"value":{"defaultValue":null,"description":"Valor atual, limitado visualmente e semanticamente ao intervalo de `0` a `max`.","name":"value","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"}],"required":true,"type":{"name":"number"}},"max":{"defaultValue":{"value":"100"},"description":"Maior valor possível. Padrão: `100`.","name":"max","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"}],"required":false,"type":{"name":"number"}},"label":{"defaultValue":null,"description":"Texto exibido acima da barra e usado como nome acessível.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"TypeLiteral"},{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}},"showValue":{"defaultValue":{"value":"false"},"description":"Exibe a porcentagem calculada à direita da barra.","name":"showValue","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"}],"required":false,"type":{"name":"boolean"}},"icon":{"defaultValue":null,"description":"Ícone decorativo exibido antes do rótulo.","name":"icon","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"}],"required":false,"type":{"name":"ReactNode"}},"tone":{"defaultValue":{"value":"navy"},"description":"Cor do preenchimento. Padrão: `navy`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"}],"required":false,"type":{"name":"enum","raw":"AppProgressTone","value":[{"value":"\"success\""},{"value":"\"navy\""},{"value":"\"primary\""}]}},"size":{"defaultValue":{"value":"md"},"description":"Altura da barra. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"AppProgressCommonProps"}],"required":false,"type":{"name":"enum","raw":"AppProgressSize","value":[{"value":"\"sm\""},{"value":"\"md\""}]}},"aria-label":{"defaultValue":null,"description":"Nome acessível obrigatório quando não há `label`.","name":"aria-label","declarations":[{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"TypeLiteral"},{"fileName":"idplugger-ui/src/components/AppProgress/AppProgress.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}}},"exportName":"AppProgress"},"stories":[{"id":"atoms-appprogress--default","name":"Default","snippet":"const Default = () => <AppProgress value={60} aria-label=\"Progresso da tarefa\" showValue />;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appprogress--estilo-navy","name":"Estilo Navy","snippet":"const EstiloNavy = () => <AppProgress value={60} aria-label=\"Utilização\" showValue />;","exportName":"EstiloNavy","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appprogress--estilo-success-com-rotulo","name":"Estilo Success Com Rotulo","snippet":"const EstiloSuccessComRotulo = () => <AppProgress\n    value={45}\n    aria-label=\"Progresso da tarefa\"\n    showValue\n    max={70}\n    label=\"45/70 avaliações\"\n    icon={<IconCheckCircle />}\n    tone=\"success\"\n    size=\"sm\" />;","exportName":"EstiloSuccessComRotulo","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appprogress--estilo-success-com-valor","name":"Estilo Success Com Valor","snippet":"const EstiloSuccessComValor = () => <AppProgress\n    value={6}\n    aria-label=\"Progresso da tarefa\"\n    showValue\n    max={10}\n    label=\"05/10\"\n    icon={<IconCheckCircle size={20} />}\n    tone=\"success\" />;","exportName":"EstiloSuccessComValor","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appprogress--primary","name":"Primary","snippet":"const Primary = () => <AppProgress value={70} aria-label=\"Progresso da campanha\" showValue tone=\"primary\" />;","exportName":"Primary","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppProgress } from '@handsondigital/idplugger-ui';\nimport { IconCheckCircle } from '@handsondigital/idplugger-ui/icons';","title":"Atoms/AppProgress"},"atoms-appradio":{"id":"atoms-appradio","name":"AppRadio","path":"./src/components/AppRadio/AppRadio.stories.tsx","jsDocTags":{},"description":"Botão de opção nativo com rótulo e mensagem de apoio opcional.\n\n**Quando usar:** escolha exclusiva entre opções relacionadas, normalmente dentro de `AppRadioGroup`.\n\n**Quando não usar:** múltiplas escolhas independentes (use `AppCheckbox`).\n\nO `ref` e todas as props HTML são repassados ao `<input>` nativo.","reactDocgenTypescript":{"tags":{"example":"<AppRadio name=\"plano\" value=\"mensal\" label=\"Mensal\" />"},"filePath":"src/components/AppRadio/AppRadio.tsx","description":"Botão de opção nativo com rótulo e mensagem de apoio opcional.\n\n**Quando usar:** escolha exclusiva entre opções relacionadas, normalmente dentro de `AppRadioGroup`.\n\n**Quando não usar:** múltiplas escolhas independentes (use `AppCheckbox`).\n\nO `ref` e todas as props HTML são repassados ao `<input>` nativo.","displayName":"AppRadio","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível. Informe `label` ou `aria-label` para dar nome acessível ao controle.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"}],"required":false,"type":{"name":"ReactNode"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do rótulo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro que marca o controle como inválido.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":{"value":"md"},"description":"Tamanho do controle e da tipografia. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadio/AppRadio.tsx","name":"AppRadioProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\"","value":[{"value":"\"sm\""},{"value":"\"md\""}]}}},"exportName":"AppRadio"},"stories":[{"id":"atoms-appradio--default","name":"Default","snippet":"const Default = () => <AppRadio label=\"Mensal\" name=\"plano\" value=\"mensal\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appradio--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'grid', gap: 16 }}>\n    <AppRadio size=\"sm\" label=\"Pequeno\" name=\"tamanho\" value=\"sm\" />\n    <AppRadio size=\"md\" label=\"Médio\" name=\"tamanho\" value=\"md\" defaultChecked />\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appradio--disabled","name":"Disabled","snippet":"const Disabled = () => <AppRadio label=\"Mensal\" name=\"plano\" value=\"mensal\" disabled defaultChecked />;","exportName":"Disabled","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppRadio } from '@handsondigital/idplugger-ui';","title":"Atoms/AppRadio"},"molecules-appradiogroup":{"id":"molecules-appradiogroup","name":"AppRadioGroup","path":"./src/components/AppRadioGroup/AppRadioGroup.stories.tsx","jsDocTags":{},"description":"Grupo de escolha exclusiva que renderiza radios nativos a partir de uma lista de opções.\n\n**Quando usar:** uma opção deve ser escolhida entre alternativas relacionadas.\n\n**Quando não usar:** múltiplas escolhas independentes (use `AppCheckboxGroup`) ou um radio isolado (use `AppRadio`).\n\nA API usa `options` em vez de filhos para garantir que todos os radios compartilhem `name`, seleção e teclado nativos.","reactDocgenTypescript":{"tags":{"example":"<AppRadioGroup legend=\"Plano\" options={[{ value: 'mensal', label: 'Mensal' }]} />"},"filePath":"src/components/AppRadioGroup/AppRadioGroup.tsx","description":"Grupo de escolha exclusiva que renderiza radios nativos a partir de uma lista de opções.\n\n**Quando usar:** uma opção deve ser escolhida entre alternativas relacionadas.\n\n**Quando não usar:** múltiplas escolhas independentes (use `AppCheckboxGroup`) ou um radio isolado (use `AppRadio`).\n\nA API usa `options` em vez de filhos para garantir que todos os radios compartilhem `name`, seleção e teclado nativos.","displayName":"AppRadioGroup","methods":[],"props":{"legend":{"defaultValue":null,"description":"Legenda visível que dá nome acessível ao grupo.","name":"legend","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":true,"type":{"name":"ReactNode"}},"options":{"defaultValue":null,"description":"Opções renderizadas como `AppRadio`.","name":"options","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":true,"type":{"name":"AppRadioOption[]"}},"name":{"defaultValue":null,"description":"Nome comum dos radios. Quando omitido, um nome estável é gerado.","name":"name","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"string"}},"value":{"defaultValue":null,"description":"Valor selecionado no modo controlado.","name":"value","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"string"}},"defaultValue":{"defaultValue":null,"description":"Valor inicialmente selecionado no modo não controlado.","name":"defaultValue","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"string"}},"onChange":{"defaultValue":null,"description":"Recebe o valor da opção selecionada.","name":"onChange","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"((value: string) => void)"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo das opções. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro que marca o grupo como inválido.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"string"}},"orientation":{"defaultValue":{"value":"vertical"},"description":"Disposição das opções. Padrão: `vertical`.","name":"orientation","parent":{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRadioGroup/AppRadioGroup.tsx","name":"AppRadioGroupProps"}],"required":false,"type":{"name":"enum","raw":"\"horizontal\" | \"vertical\"","value":[{"value":"\"horizontal\""},{"value":"\"vertical\""}]}}},"exportName":"AppRadioGroup"},"stories":[{"id":"molecules-appradiogroup--default","name":"Default","snippet":"const Default = () => <ControlledGroup\n    legend=\"Plano\"\n    options={[\n      { value: 'mensal', label: 'Mensal' },\n      { value: 'anual', label: 'Anual', hint: 'Economize no pagamento anual.' },\n      { value: 'vitalicio', label: 'Vitalício' },\n    ]} />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-appradiogroup--with-error","name":"With Error","snippet":"const WithError = () => <AppRadioGroup\n    legend=\"Plano\"\n    options={[\n      { value: 'mensal', label: 'Mensal' },\n      { value: 'anual', label: 'Anual', hint: 'Economize no pagamento anual.' },\n      { value: 'vitalicio', label: 'Vitalício' },\n    ]}\n    error=\"Escolha um plano para continuar.\" />;","exportName":"WithError","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-appradiogroup--horizontal","name":"Horizontal","snippet":"const Horizontal = () => <AppRadioGroup\n    legend=\"Plano\"\n    options={[\n      { value: 'mensal', label: 'Mensal' },\n      { value: 'anual', label: 'Anual', hint: 'Economize no pagamento anual.' },\n      { value: 'vitalicio', label: 'Vitalício' },\n    ]}\n    orientation=\"horizontal\"\n    defaultValue=\"anual\" />;","exportName":"Horizontal","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppRadioGroup } from '@handsondigital/idplugger-ui';","title":"Molecules/AppRadioGroup"},"atoms-apprating":{"id":"atoms-apprating","name":"AppRating","path":"./src/components/AppRating/AppRating.stories.tsx","jsDocTags":{},"description":"Exibe uma nota em estrelas, inclusive com meia estrela, sem permitir interação.\n\n**Quando usar:** apresentar uma avaliação consolidada ou a nota de um item já calculada.\n\n**Quando não usar:** a pessoa precisa informar ou editar uma nota; use um controle de formulário apropriado.","reactDocgenTypescript":{"tags":{"example":"<AppRating value={4.5} />"},"filePath":"src/components/AppRating/AppRating.tsx","description":"Exibe uma nota em estrelas, inclusive com meia estrela, sem permitir interação.\n\n**Quando usar:** apresentar uma avaliação consolidada ou a nota de um item já calculada.\n\n**Quando não usar:** a pessoa precisa informar ou editar uma nota; use um controle de formulário apropriado.","displayName":"AppRating","methods":[],"props":{"value":{"defaultValue":null,"description":"Nota exibida, limitada entre `0` e `max` e arredondada para o incremento de 0,5.","name":"value","parent":{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"}],"required":true,"type":{"name":"number"}},"max":{"defaultValue":{"value":"5"},"description":"Maior nota possível. Padrão: `5`.","name":"max","parent":{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"}],"required":false,"type":{"name":"number"}},"size":{"defaultValue":{"value":"md"},"description":"Tamanho de cada estrela: 16px ou 20px. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"}],"required":false,"type":{"name":"enum","raw":"AppRatingSize","value":[{"value":"\"sm\""},{"value":"\"md\""}]}},"label":{"defaultValue":null,"description":"Nome acessível. Padrão: \"Nota {valor} de {max}\".","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppRating/AppRating.tsx","name":"AppRatingProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppRating"},"stories":[{"id":"atoms-apprating--default","name":"Default","snippet":"const Default = () => <AppRating value={4.5} />;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apprating--valores","name":"Valores","snippet":"const Valores = () => (\n  <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>\n    <AppRating value={0} />\n    <AppRating value={2.5} />\n    <AppRating value={4} />\n    <AppRating value={5} />\n  </div>\n);","exportName":"Valores","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apprating--tamanhos","name":"Tamanhos","snippet":"const Tamanhos = () => (\n  <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>\n    <AppRating value={4.5} size=\"sm\" />\n    <AppRating value={4.5} size=\"md\" />\n  </div>\n);","exportName":"Tamanhos","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppRating } from '@handsondigital/idplugger-ui';","title":"Atoms/AppRating"},"atoms-appselect":{"id":"atoms-appselect","name":"AppSelect","path":"./src/components/AppSelect/AppSelect.stories.tsx","jsDocTags":{},"description":"Campo de seleção com rótulo, texto de apoio e mensagem de erro, na mesma caixa do `AppInput` e com a seta\n`arrow_drop_down`. Usa o `<select>` nativo: teclado, leitores de tela e a lista do celular funcionam sem\nscript.\n\n**Quando usar:** escolher uma opção de uma lista média ou longa (estado, loja, categoria de produto).\n\n**Quando não usar:** poucas opções sempre visíveis (use `AppRadioGroup`), várias escolhas (use `AppCheckboxGroup`)\nou busca com digitação.\n\nO `ref` e as props HTML são repassados ao `<select>`.","reactDocgenTypescript":{"tags":{"example":"<AppSelect label=\"Estado\" placeholder=\"Selecione\">\n  <option value=\"sp\">São Paulo</option>\n</AppSelect>"},"filePath":"src/components/AppSelect/AppSelect.tsx","description":"Campo de seleção com rótulo, texto de apoio e mensagem de erro, na mesma caixa do `AppInput` e com a seta\n`arrow_drop_down`. Usa o `<select>` nativo: teclado, leitores de tela e a lista do celular funcionam sem\nscript.\n\n**Quando usar:** escolher uma opção de uma lista média ou longa (estado, loja, categoria de produto).\n\n**Quando não usar:** poucas opções sempre visíveis (use `AppRadioGroup`), várias escolhas (use `AppCheckboxGroup`)\nou busca com digitação.\n\nO `ref` e as props HTML são repassados ao `<select>`.","displayName":"AppSelect","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível do campo (obrigatório): vira o nome acessível via `<label htmlFor>`.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"}],"required":true,"type":{"name":"string"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do campo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro: troca o hint, pinta o campo de vermelho e marca `aria-invalid`.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":null,"description":"Altura do campo: `sm` (40px) ou `md` (44px). Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\"","value":[{"value":"\"sm\""},{"value":"\"md\""}]}},"placeholder":{"defaultValue":null,"description":"Texto exibido enquanto nada foi escolhido (primeira opção, vazia e desabilitada, em cinza).","name":"placeholder","parent":{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"}],"required":false,"type":{"name":"string"}},"children":{"defaultValue":null,"description":"As opções: elementos `<option>` (e `<optgroup>`).","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSelect/AppSelect.tsx","name":"AppSelectProps"}],"required":true,"type":{"name":"ReactNode"}}},"exportName":"AppSelect"},"stories":[{"id":"atoms-appselect--default","name":"Default","snippet":"const Default = () => <AppSelect label=\"Estado\" placeholder=\"Selecione\">{ESTADOS.map(([value, name]) => (\n      <option key={value} value={value}>\n        {name}\n      </option>\n    ))}</AppSelect>;","description":"Sem escolha: mostra o placeholder em cinza; escolher pelo teclado ou pelo clique troca o valor.","warning":"Incomplete snippet: `ESTADOS` could not be resolved statically.","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appselect--sizes","name":"Sizes","snippet":"const Sizes = () => <div style={{ display: 'grid', gap: 16 }}>\n    <AppSelect placeholder=\"Selecione\" label=\"Pequeno (sm)\" size=\"sm\">{ESTADOS.map(([value, name]) => (\n          <option key={value} value={value}>\n            {name}\n          </option>\n        ))}</AppSelect>\n    <AppSelect\n        label=\"Médio (md)\"\n        size=\"md\"\n        defaultValue=\"sp\"\n        placeholder={undefined}>{ESTADOS.map(([value, name]) => (\n          <option key={value} value={value}>\n            {name}\n          </option>\n        ))}</AppSelect>\n</div>;","warning":"Incomplete snippet: `ESTADOS` could not be resolved statically.","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appselect--with-hint","name":"With Hint","snippet":"const WithHint = () => <AppSelect\n    label=\"Estado\"\n    placeholder=\"Selecione\"\n    hint=\"Onde você comprou o produto.\">{ESTADOS.map(([value, name]) => (\n      <option key={value} value={value}>\n        {name}\n      </option>\n    ))}</AppSelect>;","warning":"Incomplete snippet: `ESTADOS` could not be resolved statically.","exportName":"WithHint","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appselect--with-error","name":"With Error","snippet":"const WithError = () => <AppSelect\n    label=\"Estado\"\n    placeholder=\"Selecione\"\n    error=\"Escolha o estado da compra.\">{ESTADOS.map(([value, name]) => (\n      <option key={value} value={value}>\n        {name}\n      </option>\n    ))}</AppSelect>;","warning":"Incomplete snippet: `ESTADOS` could not be resolved statically.","exportName":"WithError","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appselect--disabled","name":"Disabled","snippet":"const Disabled = () => <AppSelect label=\"Estado\" placeholder=\"Selecione\" disabled>{ESTADOS.map(([value, name]) => (\n      <option key={value} value={value}>\n        {name}\n      </option>\n    ))}</AppSelect>;","warning":"Incomplete snippet: `ESTADOS` could not be resolved statically.","exportName":"Disabled","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppSelect } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Atoms/AppSelect"},"atoms-appskeleton":{"id":"atoms-appskeleton","name":"AppSkeleton","path":"./src/components/AppSkeleton/AppSkeleton.stories.tsx","jsDocTags":{},"description":"Indicador de carregamento em forma de barra ou forma arredondada, no lugar de texto ou mídia ainda não disponíveis.\n\n**Quando usar:** no lugar de conteúdo (texto, título, imagem) enquanto ele carrega; ponha `aria-busy=\"true\"` no\ncontêiner que está carregando para avisar tecnologias assistivas.\n\n**Quando não usar:** para indicar o progresso de uma ação já iniciada pela pessoa (use `AppSpinner` ou `AppProgress`).","reactDocgenTypescript":{"tags":{"example":"<AppSkeleton variant=\"title\" /><AppSkeleton lines={3} />"},"filePath":"src/components/AppSkeleton/AppSkeleton.tsx","description":"Indicador de carregamento em forma de barra ou forma arredondada, no lugar de texto ou mídia ainda não disponíveis.\n\n**Quando usar:** no lugar de conteúdo (texto, título, imagem) enquanto ele carrega; ponha `aria-busy=\"true\"` no\ncontêiner que está carregando para avisar tecnologias assistivas.\n\n**Quando não usar:** para indicar o progresso de uma ação já iniciada pela pessoa (use `AppSpinner` ou `AppProgress`).","displayName":"AppSkeleton","methods":[],"props":{"variant":{"defaultValue":{"value":"text"},"description":"Forma da barra: texto, título, retângulo livre ou círculo. Padrão: `'text'`.","name":"variant","parent":{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"}],"required":false,"type":{"name":"enum","raw":"AppSkeletonVariant","value":[{"value":"\"title\""},{"value":"\"text\""},{"value":"\"rect\""},{"value":"\"circle\""}]}},"lines":{"defaultValue":{"value":"1"},"description":"Número de linhas (só se aplica a `variant=\"text\"`). A última linha fica com 60% de largura. Padrão: `1`.","name":"lines","parent":{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"}],"required":false,"type":{"name":"number"}},"width":{"defaultValue":null,"description":"Largura: número em px ou string CSS.","name":"width","parent":{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"}],"required":false,"type":{"name":"string | number"}},"height":{"defaultValue":null,"description":"Altura: número em px ou string CSS.","name":"height","parent":{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"}],"required":false,"type":{"name":"string | number"}},"tone":{"defaultValue":{"value":"neutral"},"description":"Tom neutro (padrão) ou tom suave da marca, para usar sobre superfícies de marca. Padrão: `'neutral'`.","name":"tone","parent":{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"}],"required":false,"type":{"name":"enum","raw":"AppSkeletonTone","value":[{"value":"\"neutral\""},{"value":"\"brand\""}]}},"animated":{"defaultValue":{"value":"true"},"description":"Liga a animação de brilho. Desligada automaticamente com `prefers-reduced-motion: reduce`. Padrão: `true`.","name":"animated","parent":{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSkeleton/AppSkeleton.tsx","name":"AppSkeletonProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"AppSkeleton"},"stories":[{"id":"atoms-appskeleton--default","name":"Default","snippet":"const Default = () => <AppSkeleton variant=\"text\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appskeleton--variantes","name":"Variantes","snippet":"const Variantes = () => (\n  <div style={{ display: 'grid', gap: 16, width: 240 }}>\n    <AppSkeleton variant=\"title\" />\n    <AppSkeleton variant=\"text\" lines={3} />\n    <AppSkeleton variant=\"rect\" height={96} />\n    <AppSkeleton variant=\"circle\" />\n  </div>\n);","exportName":"Variantes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appskeleton--tom-de-marca","name":"Tom De Marca","snippet":"const TomDeMarca = () => (\n  <div style={{ display: 'grid', gap: 12, width: 240, padding: 16, background: 'var(--color-action-primary)', borderRadius: 16 }}>\n    <AppSkeleton variant=\"title\" tone=\"brand\" />\n    <AppSkeleton variant=\"text\" lines={2} tone=\"brand\" />\n  </div>\n);","exportName":"TomDeMarca","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appskeleton--sem-animacao","name":"Sem Animacao","snippet":"const SemAnimacao = () => <AppSkeleton variant=\"text\" lines={2} animated={false} />;","exportName":"SemAnimacao","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppSkeleton } from '@handsondigital/idplugger-ui';","title":"Atoms/AppSkeleton"},"atoms-appspinner":{"id":"atoms-appspinner","name":"AppSpinner","path":"./src/components/AppSpinner/AppSpinner.stories.tsx","jsDocTags":{},"description":"Indicador circular de carregamento com `role=\"status\"`.\n\n**Quando usar:** espera curta de uma ação ou região da página (envio de formulário, carregamento de lista).\n\n**Quando não usar:** dentro de `AppButton` (use `isLoading`, que já inclui o spinner); quando o progresso é conhecido (use uma barra de progresso).","reactDocgenTypescript":{"tags":{"example":"<AppSpinner size=\"lg\" label=\"Validando nota fiscal...\" />"},"filePath":"src/components/AppSpinner/AppSpinner.tsx","description":"Indicador circular de carregamento com `role=\"status\"`.\n\n**Quando usar:** espera curta de uma ação ou região da página (envio de formulário, carregamento de lista).\n\n**Quando não usar:** dentro de `AppButton` (use `isLoading`, que já inclui o spinner); quando o progresso é conhecido (use uma barra de progresso).","displayName":"AppSpinner","methods":[],"props":{"size":{"defaultValue":null,"description":"Tamanho do indicador: `sm`, `md` ou `lg`. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppSpinner/AppSpinner.tsx","name":"AppSpinnerProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSpinner/AppSpinner.tsx","name":"AppSpinnerProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\" | \"lg\"","value":[{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""}]}},"className":{"defaultValue":null,"description":"Classe CSS adicional.","name":"className","parent":{"fileName":"idplugger-ui/src/components/AppSpinner/AppSpinner.tsx","name":"AppSpinnerProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSpinner/AppSpinner.tsx","name":"AppSpinnerProps"}],"required":false,"type":{"name":"string"}},"label":{"defaultValue":{"value":"Carregando..."},"description":"Nome acessível anunciado a leitores de tela (`role=\"status\"`). Padrão: `Carregando...`.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppSpinner/AppSpinner.tsx","name":"AppSpinnerProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppSpinner/AppSpinner.tsx","name":"AppSpinnerProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppSpinner"},"stories":[{"id":"atoms-appspinner--default","name":"Default","snippet":"const Default = () => <AppSpinner />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-appspinner--custom-label","name":"Custom Label","snippet":"const CustomLabel = () => <AppSpinner label=\"Validando nota fiscal...\" />;","exportName":"CustomLabel","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appspinner--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'flex', gap: 16, alignItems: 'center' }}>\n    <AppSpinner size=\"sm\" />\n    <AppSpinner size=\"md\" />\n    <AppSpinner size=\"lg\" />\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppSpinner } from '@handsondigital/idplugger-ui';","title":"Atoms/AppSpinner"},"organisms-apptable":{"id":"organisms-apptable","name":"AppTable","path":"./src/components/AppTable/AppTable.stories.tsx","jsDocTags":{},"description":"Contêiner semântico para tabelas de dados compostas com as peças `AppTable*`.\n\n**Quando usar:** comparar dados tabulares com cabeçalhos e células em colunas estáveis.\n\n**Quando não usar:** apresentar poucos pares de rótulo e valor ou conteúdo que vira cartão no celular.","reactDocgenTypescript":{"tags":{"example":"<AppTable caption=\"Pessoas\"><AppTableHead>...</AppTableHead><AppTableBody>...</AppTableBody></AppTable>"},"filePath":"src/components/AppTable/AppTable.tsx","description":"Contêiner semântico para tabelas de dados compostas com as peças `AppTable*`.\n\n**Quando usar:** comparar dados tabulares com cabeçalhos e células em colunas estáveis.\n\n**Quando não usar:** apresentar poucos pares de rótulo e valor ou conteúdo que vira cartão no celular.","displayName":"AppTable","methods":[],"props":{"caption":{"defaultValue":null,"description":"Descrição curta da tabela, exibida apenas para tecnologias assistivas. Também nomeia a região rolável.","name":"caption","parent":{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"}],"required":false,"type":{"name":"string"}},"footer":{"defaultValue":null,"description":"Conteúdo exibido abaixo da área rolável, como uma paginação.","name":"footer","parent":{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"}],"required":false,"type":{"name":"ReactNode"}},"loading":{"defaultValue":{"value":"false"},"description":"Substitui o corpo por um indicador de carregamento e marca a tabela como ocupada.","name":"loading","parent":{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"}],"required":false,"type":{"name":"boolean"}},"stickyFirstColumn":{"defaultValue":{"value":"false"},"description":"Mantém a primeira coluna visível durante a rolagem horizontal.","name":"stickyFirstColumn","parent":{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"}],"required":false,"type":{"name":"boolean"}},"children":{"defaultValue":null,"description":"Cabeçalho e corpo da tabela.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTable/AppTable.tsx","name":"AppTableProps"}],"required":true,"type":{"name":"ReactNode"}}},"exportName":"AppTable"},"stories":[{"id":"organisms-apptable--default","name":"Default","snippet":"const Default = () => (\n  <AppTable\n    caption=\"Utilização\"\n    footer={<AppPagination page={1} pageCount={10} onPageChange={() => {}} />}\n  >\n    <AppTableHead>\n      <AppTableRow>\n        <AppTableHeaderCell>Nome</AppTableHeaderCell>\n        <AppTableHeaderCell>Status</AppTableHeaderCell>\n        <AppTableHeaderCell>Cargo</AppTableHeaderCell>\n        <AppTableHeaderCell>E-mail</AppTableHeaderCell>\n        <AppTableHeaderCell>Equipes</AppTableHeaderCell>\n        <AppTableHeaderCell align=\"end\">Ações</AppTableHeaderCell>\n      </AppTableRow>\n    </AppTableHead>\n    <AppTableBody>\n      <AppTableRow>\n        <AppTableCell><AppAvatarLabel size=\"sm\" name=\"João Carlos\" supportingText=\"joao@idplugger.com.br\" src={avatars[0]} /></AppTableCell>\n        <AppTableCell><AppBadge tone=\"success\">Ativo</AppBadge></AppTableCell>\n        <AppTableCell>Designer de produto</AppTableCell>\n        <AppTableCell>joao@idplugger.com.br</AppTableCell>\n        <AppTableCell><div style={{ display: 'flex', gap: 4 }}><AppBadge tone=\"primary\">Produto</AppBadge><AppBadge tone=\"info\">Design</AppBadge><AppBadge>+4</AppBadge></div></AppTableCell>\n        <AppTableCell align=\"end\"><ActionButtons /></AppTableCell>\n      </AppTableRow>\n      <AppTableRow>\n        <AppTableCell><AppAvatarLabel size=\"sm\" name=\"Ana Souza\" supportingText=\"ana@idplugger.com.br\" src={avatars[1]} /></AppTableCell>\n        <AppTableCell><AppBadge tone=\"success\">Ativo</AppBadge></AppTableCell>\n        <AppTableCell>Gerente comercial</AppTableCell>\n        <AppTableCell>ana@idplugger.com.br</AppTableCell>\n        <AppTableCell><div style={{ display: 'flex', gap: 4 }}><AppBadge tone=\"primary\">Vendas</AppBadge><AppBadge>+2</AppBadge></div></AppTableCell>\n        <AppTableCell align=\"end\"><ActionButtons /></AppTableCell>\n      </AppTableRow>\n    </AppTableBody>\n  </AppTable>\n);","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"organisms-apptable--ordenacao","name":"Ordenacao","snippet":"const Ordenacao = () => <OrdenacaoExemplo />;","exportName":"Ordenacao","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"organisms-apptable--selecao","name":"Selecao","snippet":"const Selecao = () => <SelecaoExemplo />;","exportName":"Selecao","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"organisms-apptable--estilos-de-celula","name":"Estilos De Celula","snippet":"const EstilosDeCelula = () => (\n  <AppTable caption=\"Estilos de célula\">\n    <AppTableHead><AppTableRow><AppTableHeaderCell>Estilo</AppTableHeaderCell><AppTableHeaderCell>Exemplo</AppTableHeaderCell></AppTableRow></AppTableHead>\n    <AppTableBody>\n      <AppTableRow><AppTableCell>Texto</AppTableCell><AppTableCell>Conteúdo regular</AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Texto destacado</AppTableCell><AppTableCell supportingText=\"Detalhe complementar\">Conteúdo principal</AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Badge</AppTableCell><AppTableCell><AppBadge tone=\"success\">Ativo</AppBadge></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Badges</AppTableCell><AppTableCell><div style={{ display: 'flex', gap: 4 }}><AppBadge tone=\"primary\">Produto</AppBadge><AppBadge tone=\"info\">Design</AppBadge><AppBadge>+4</AppBadge></div></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Grupo de avatares</AppTableCell><AppTableCell><AppAvatarGroup size=\"xs\" max={3}><AppAvatar name=\"Ana\" src={avatars[0]} /><AppAvatar name=\"Bruna\" src={avatars[1]} /><AppAvatar name=\"João\" src={avatars[2]} /><AppAvatar name=\"Lia\" /></AppAvatarGroup></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Forma de pagamento</AppTableCell><AppTableCell supportingText=\"Validade 06/2024\"><div style={{ display: 'flex', alignItems: 'center', gap: 12 }}><AppPaymentIcon method=\"visa\" size=\"md\" />Visa final 1234</div></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Tendência</AppTableCell><AppTableCell><div style={{ display: 'flex', alignItems: 'center', gap: 12 }}><strong>R$ 1.800</strong><AppBadge tone=\"success\" icon={<IconArrowUpward />}>20%</AppBadge><AppBadge tone=\"danger\" icon={<IconArrowDownward />}>20%</AppBadge></div></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Progresso</AppTableCell><AppTableCell><div style={{ display: 'grid', gap: 12 }}><AppProgress value={60} aria-label=\"Progresso de receita\" showValue /><AppProgress value={45} max={70} label=\"45/70 avaliações\" icon={<IconCheckCircle />} tone=\"success\" size=\"sm\" /><AppProgress value={5} max={10} label=\"05/10\" icon={<IconCheckCircle />} tone=\"success\" showValue /></div></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Arquivo</AppTableCell><AppTableCell supportingText=\"200 KB\"><div style={{ display: 'flex', alignItems: 'center', gap: 12 }}><AppFeaturedIcon icon={<IconFilePresent />} />Regulamento.pdf</div></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Toggle</AppTableCell><AppTableCell><AppToggle size=\"sm\" aria-label=\"Notificações ativas\" defaultChecked /></AppTableCell></AppTableRow>\n      <AppTableRow><AppTableCell>Avaliação</AppTableCell><AppTableCell><AppRating value={4.5} /></AppTableCell></AppTableRow>\n    </AppTableBody>\n  </AppTable>\n);","exportName":"EstilosDeCelula","tags":["dev","test","manifest","autodocs"]},{"id":"organisms-apptable--vazio","name":"Vazio","snippet":"const Vazio = () => (\n  <AppTable caption=\"Pessoas\">\n    <AppTableHead><AppTableRow><AppTableHeaderCell>Nome</AppTableHeaderCell></AppTableRow></AppTableHead>\n    <AppTableBody><AppTableEmpty colSpan={1}>Nenhuma pessoa encontrada.</AppTableEmpty></AppTableBody>\n  </AppTable>\n);","exportName":"Vazio","tags":["dev","test","manifest","autodocs"]},{"id":"organisms-apptable--carregando","name":"Carregando","snippet":"const Carregando = () => (\n  <AppTable caption=\"Pessoas\" loading>\n    <AppTableHead><AppTableRow><AppTableHeaderCell>Nome</AppTableHeaderCell></AppTableRow></AppTableHead>\n    <AppTableBody><AppTableRow><AppTableCell>Conteúdo substituído pelo carregamento</AppTableCell></AppTableRow></AppTableBody>\n  </AppTable>\n);","exportName":"Carregando","tags":["dev","test","manifest","autodocs"]},{"id":"organisms-apptable--celular","name":"Celular","snippet":"const Celular = () => (\n  <AppTable caption=\"Pessoas no celular\" stickyFirstColumn>\n    <AppTableHead><AppTableRow><AppTableHeaderCell>Nome</AppTableHeaderCell><AppTableHeaderCell>Cargo</AppTableHeaderCell><AppTableHeaderCell>E-mail</AppTableHeaderCell></AppTableRow></AppTableHead>\n    <AppTableBody><AppTableRow><AppTableCell><AppAvatarLabel size=\"sm\" name=\"João Carlos\" supportingText=\"joao@idplugger.com.br\" src={avatars[0]} /></AppTableCell><AppTableCell>Designer de produto</AppTableCell><AppTableCell>joao@idplugger.com.br</AppTableCell></AppTableRow></AppTableBody>\n  </AppTable>\n);","description":"Em telas estreitas a tabela rola na horizontal dentro do contêiner, com a primeira coluna fixa.","exportName":"Celular","tags":["dev","test","manifest","autodocs"]}],"import":"import {\n  AppAvatar,\n  AppAvatarGroup,\n  AppAvatarLabel,\n  AppBadge,\n  AppButton,\n  AppCheckbox,\n  AppFeaturedIcon,\n  AppPagination,\n  AppPaymentIcon,\n  AppProgress,\n  AppRating,\n  AppTable,\n  AppTableBody,\n  AppTableCell,\n  AppTableEmpty,\n  AppTableHead,\n  AppTableHeaderCell,\n  AppTableRow,\n  AppToggle,\n} from '@handsondigital/idplugger-ui';\nimport {\n  IconArrowDownward,\n  IconArrowUpward,\n  IconCheckCircle,\n  IconFilePresent,\n  IconMoreVert,\n} from '@handsondigital/idplugger-ui/icons';","title":"Organisms/AppTable"},"molecules-apptabs":{"id":"molecules-apptabs","name":"AppTabs","path":"./src/components/AppTabs/AppTabs.stories.tsx","jsDocTags":{},"description":"Abas para alternar entre painéis de conteúdo na mesma página, compostas com `AppTabList`, `AppTab` e `AppTabPanel`.\nAs setas ←/→ (e Home/End) trocam de aba; só a aba ativa entra na ordem do Tab. No celular, a lista rola na\nhorizontal.\n\n**Quando usar:** área do participante (Números da sorte, Cupons, Atendimentos, Perfil), modalidades de um\nregulamento, detalhes e acompanhamento de um atendimento.\n\n**Quando não usar:** navegação entre páginas (use links) ou conteúdo que a pessoa precisa ver junto (use seções).","reactDocgenTypescript":{"tags":{"example":"<AppTabs defaultValue=\"numeros\">\n  <AppTabList aria-label=\"Minha conta\">\n    <AppTab value=\"numeros\">Números da sorte</AppTab>\n    <AppTab value=\"cupons\" badge={2}>Cupons</AppTab>\n  </AppTabList>\n  <AppTabPanel value=\"numeros\">…</AppTabPanel>\n  <AppTabPanel value=\"cupons\">…</AppTabPanel>\n</AppTabs>"},"filePath":"src/components/AppTabs/AppTabs.tsx","description":"Abas para alternar entre painéis de conteúdo na mesma página, compostas com `AppTabList`, `AppTab` e `AppTabPanel`.\nAs setas ←/→ (e Home/End) trocam de aba; só a aba ativa entra na ordem do Tab. No celular, a lista rola na\nhorizontal.\n\n**Quando usar:** área do participante (Números da sorte, Cupons, Atendimentos, Perfil), modalidades de um\nregulamento, detalhes e acompanhamento de um atendimento.\n\n**Quando não usar:** navegação entre páginas (use links) ou conteúdo que a pessoa precisa ver junto (use seções).","displayName":"AppTabs","methods":[],"props":{"onValueChange":{"defaultValue":null,"description":"Chamado ao trocar de aba, por clique ou pelas setas do teclado.","name":"onValueChange","parent":{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"AppTabsBaseProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"AppTabsBaseProps"}],"required":false,"type":{"name":"((value: string) => void)"}},"variant":{"defaultValue":{"value":"underline"},"description":"`underline`: linha da marca sob a aba ativa. `pill`: fundo suave da marca na aba ativa. Padrão: `'underline'`.","name":"variant","parent":{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"AppTabsBaseProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"AppTabsBaseProps"}],"required":false,"type":{"name":"enum","raw":"AppTabsVariant","value":[{"value":"\"underline\""},{"value":"\"pill\""}]}},"fullWidth":{"defaultValue":{"value":"false"},"description":"As abas dividem a largura disponível.","name":"fullWidth","parent":{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"AppTabsBaseProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"AppTabsBaseProps"}],"required":false,"type":{"name":"boolean"}},"value":{"defaultValue":null,"description":"Aba selecionada (controlado).","name":"value","declarations":[{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"TypeLiteral"},{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"defaultValue":{"defaultValue":null,"description":"Aba selecionada ao montar (não controlado).","name":"defaultValue","declarations":[{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"TypeLiteral"},{"fileName":"idplugger-ui/src/components/AppTabs/AppTabs.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}}},"exportName":"AppTabs"},"stories":[{"id":"molecules-apptabs--area-do-participante","name":"Area Do Participante","snippet":"const AreaDoParticipante = () => <ParticipantTabs />;","exportName":"AreaDoParticipante","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"molecules-apptabs--regulamento","name":"Regulamento","snippet":"const Regulamento = () => (\n  <AppTabs defaultValue=\"geral\">\n    <AppTabList aria-label=\"Modalidades do regulamento\">\n      <AppTab value=\"geral\">Geral</AppTab>\n      <AppTab value=\"sorteio\">Sorteio</AppTab>\n      <AppTab value=\"premios\">Prêmios</AppTab>\n    </AppTabList>\n    <AppTabPanel value=\"geral\">Regras gerais da promoção</AppTabPanel>\n    <AppTabPanel value=\"sorteio\">Como funciona o sorteio</AppTabPanel>\n    <AppTabPanel value=\"premios\">Prêmios da campanha</AppTabPanel>\n  </AppTabs>\n);","exportName":"Regulamento","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apptabs--atendimento","name":"Atendimento","snippet":"const Atendimento = () => (\n  <AppTabs defaultValue=\"detalhes\">\n    <AppTabList aria-label=\"Informações do atendimento\">\n      <AppTab value=\"detalhes\">Detalhes</AppTab>\n      <AppTab value=\"acompanhamento\">Acompanhamento</AppTab>\n    </AppTabList>\n    <AppTabPanel value=\"detalhes\">Detalhes do atendimento</AppTabPanel>\n    <AppTabPanel value=\"acompanhamento\">Acompanhe sua solicitação</AppTabPanel>\n  </AppTabs>\n);","exportName":"Atendimento","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apptabs--pill","name":"Pill","snippet":"const Pill = () => (\n  <AppTabs defaultValue=\"cupons\" variant=\"pill\">\n    <AppTabList aria-label=\"Seções\">\n      <AppTab value=\"numeros\">Números da sorte</AppTab>\n      <AppTab value=\"cupons\">Cupons</AppTab>\n    </AppTabList>\n    <AppTabPanel value=\"numeros\">Números</AppTabPanel>\n    <AppTabPanel value=\"cupons\">Cupons</AppTabPanel>\n  </AppTabs>\n);","exportName":"Pill","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apptabs--celular","name":"Celular","snippet":"const Celular = () => (\n  <div style={{ width: 360 }}>\n    <ParticipantTabs />\n  </div>\n);","exportName":"Celular","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppTab, AppTabList, AppTabPanel, AppTabs } from '@handsondigital/idplugger-ui';","title":"Molecules/AppTabs"},"atoms-apptag":{"id":"atoms-apptag","name":"AppTag","path":"./src/components/AppTag/AppTag.stories.tsx","jsDocTags":{},"description":"Etiqueta compacta para rotular, categorizar ou exibir um valor selecionado, opcionalmente removível.\n\n**Quando usar:** categorias, filtros aplicados, valores escolhidos que o usuário pode remover.\n\n**Quando não usar:** ações (use `AppButton`); mensagens de feedback temporárias (use `AppToast`).\n\nAcessibilidade: o botão \"x\" é um `<button>` focável; personalize `removeLabel` para dizer o que será removido.","reactDocgenTypescript":{"tags":{"example":"<AppTag onRemove={() => remover('Marketing')} removeLabel=\"Remover Marketing\">Marketing</AppTag>"},"filePath":"src/components/AppTag/AppTag.tsx","description":"Etiqueta compacta para rotular, categorizar ou exibir um valor selecionado, opcionalmente removível.\n\n**Quando usar:** categorias, filtros aplicados, valores escolhidos que o usuário pode remover.\n\n**Quando não usar:** ações (use `AppButton`); mensagens de feedback temporárias (use `AppToast`).\n\nAcessibilidade: o botão \"x\" é um `<button>` focável; personalize `removeLabel` para dizer o que será removido.","displayName":"AppTag","methods":[],"props":{"children":{"defaultValue":null,"description":"Rótulo da tag.","name":"children","parent":{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"}],"required":true,"type":{"name":"ReactNode"}},"icon":{"defaultValue":null,"description":"Ícone ou avatar de 16px antes do rótulo. Decorativo (`aria-hidden`).","name":"icon","parent":{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"}],"required":false,"type":{"name":"ReactNode"}},"onRemove":{"defaultValue":null,"description":"Quando informado, mostra o botão \"x\" que chama esta função.","name":"onRemove","parent":{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"}],"required":false,"type":{"name":"(() => void)"}},"removeLabel":{"defaultValue":{"value":"Remover"},"description":"Nome acessível do botão \"x\" (ex.: `Remover Marketing`). Padrão: `Remover`.","name":"removeLabel","parent":{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTag/AppTag.tsx","name":"AppTagProps"}],"required":false,"type":{"name":"string"}}},"exportName":"AppTag"},"stories":[{"id":"atoms-apptag--default","name":"Default","snippet":"const Default = () => <AppTag>Marketing</AppTag>;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apptag--removable","name":"Removable","snippet":"const Removable = () => <AppTag removeLabel=\"Remover Marketing\">Marketing</AppTag>;","exportName":"Removable","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apptag--removable-by-keyboard","name":"Removable By Keyboard","snippet":"const RemovableByKeyboard = () => <AppTag removeLabel=\"Remover Marketing\">Marketing</AppTag>;","exportName":"RemovableByKeyboard","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apptag--with-icon","name":"With Icon","snippet":"const WithIcon = () => <AppTag icon={<IconCheck />}>Nota validada</AppTag>;","exportName":"WithIcon","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apptag--with-icon-removable","name":"With Icon Removable","snippet":"const WithIconRemovable = () => <AppTag icon={<IconCheck />} removeLabel=\"Remover Nota validada\">Nota validada</AppTag>;","exportName":"WithIconRemovable","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppTag } from '@handsondigital/idplugger-ui';\nimport { IconCheck } from '@handsondigital/idplugger-ui/icons';\nimport { fn } from 'storybook/test';","title":"Atoms/AppTag"},"atoms-apptextarea":{"id":"atoms-apptextarea","name":"AppTextarea","path":"./src/components/AppTextarea/AppTextarea.stories.tsx","jsDocTags":{},"description":"Campo de texto de várias linhas com rótulo, texto de apoio, mensagem de erro e tags opcionais.\n\n**Quando usar:** mensagens, comentários e descrições longas; use `tags` para exibir seleções dentro da caixa.\n\n**Quando não usar:** texto curto de uma linha (use `AppInput`).\n\nO `ref` e o `className` são repassados ao `<textarea>`. Altura inicial: `rows` (Padrão: 3).","reactDocgenTypescript":{"tags":{"example":"<AppTextarea label=\"Mensagem\" hint=\"Máximo de 500 caracteres\" />"},"filePath":"src/components/AppTextarea/AppTextarea.tsx","description":"Campo de texto de várias linhas com rótulo, texto de apoio, mensagem de erro e tags opcionais.\n\n**Quando usar:** mensagens, comentários e descrições longas; use `tags` para exibir seleções dentro da caixa.\n\n**Quando não usar:** texto curto de uma linha (use `AppInput`).\n\nO `ref` e o `className` são repassados ao `<textarea>`. Altura inicial: `rows` (Padrão: 3).","displayName":"AppTextarea","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível do campo (obrigatório): vira o nome acessível via `<label htmlFor>`.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"}],"required":true,"type":{"name":"string"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do campo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro: troca o hint, pinta o campo de vermelho e marca `aria-invalid`.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"}],"required":false,"type":{"name":"string"}},"tags":{"defaultValue":null,"description":"Tags (`AppTag`) exibidas dentro da caixa, acima do texto.","name":"tags","parent":{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppTextarea/AppTextarea.tsx","name":"AppTextareaProps"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"AppTextarea"},"stories":[{"id":"atoms-apptextarea--default","name":"Default","snippet":"const Default = () => <AppTextarea label=\"Mensagem\" placeholder=\"Escreva sua mensagem\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apptextarea--with-hint","name":"With Hint","snippet":"const WithHint = () => <AppTextarea\n    label=\"Mensagem\"\n    placeholder=\"Escreva sua mensagem\"\n    hint=\"Máximo de 500 caracteres.\" />;","exportName":"WithHint","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apptextarea--with-error","name":"With Error","snippet":"const WithError = () => <AppTextarea\n    label=\"Mensagem\"\n    placeholder=\"Escreva sua mensagem\"\n    error=\"Escreva ao menos 10 caracteres.\" />;","exportName":"WithError","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apptextarea--disabled","name":"Disabled","snippet":"const Disabled = () => <AppTextarea\n    label=\"Mensagem\"\n    placeholder=\"Escreva sua mensagem\"\n    disabled\n    defaultValue=\"Campo indisponível\" />;","exportName":"Disabled","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apptextarea--with-tags","name":"With Tags","snippet":"const WithTags = () => <TextareaWithTags label=\"Mensagem\" placeholder=\"Escreva sua mensagem\" />;","exportName":"WithTags","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { AppTag, AppTextarea } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Atoms/AppTextarea"},"atoms-appthumb":{"id":"atoms-appthumb","name":"AppThumb","path":"./src/components/AppThumb/AppThumb.stories.tsx","jsDocTags":{},"description":"Imagem com proporção fixa e placeholder automático quando não há `src` ou o carregamento falha.\n\n**Quando usar:** mídia de produtos, prêmios ou qualquer imagem de conteúdo variável em cards e grades.\n\n**Quando não usar:** avatares de pessoas (use `AppAvatar`) ou ícones decorativos isolados.","reactDocgenTypescript":{"tags":{"example":"<AppThumb src=\"/produto.jpg\" alt=\"Caixa do produto\" ratio=\"4:3\" />"},"filePath":"src/components/AppThumb/AppThumb.tsx","description":"Imagem com proporção fixa e placeholder automático quando não há `src` ou o carregamento falha.\n\n**Quando usar:** mídia de produtos, prêmios ou qualquer imagem de conteúdo variável em cards e grades.\n\n**Quando não usar:** avatares de pessoas (use `AppAvatar`) ou ícones decorativos isolados.","displayName":"AppThumb","methods":[],"props":{"src":{"defaultValue":null,"description":"URL da imagem. Sem valor, ou se a imagem falhar ao carregar, mostra o placeholder.","name":"src","parent":{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"}],"required":false,"type":{"name":"string"}},"alt":{"defaultValue":null,"description":"Texto alternativo da imagem. Obrigatório; use `\"\"` quando a imagem é puramente decorativa.","name":"alt","parent":{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"}],"required":true,"type":{"name":"string"}},"ratio":{"defaultValue":{"value":"1:1"},"description":"Proporção fixa do contêiner. Padrão: `'1:1'`.","name":"ratio","parent":{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"}],"required":false,"type":{"name":"enum","raw":"AppThumbRatio","value":[{"value":"\"1:1\""},{"value":"\"4:3\""},{"value":"\"3:2\""},{"value":"\"16:9\""},{"value":"\"3:4\""}]}},"fit":{"defaultValue":{"value":"cover"},"description":"Ajuste da imagem dentro do contêiner. Padrão: `'cover'`.","name":"fit","parent":{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"}],"required":false,"type":{"name":"enum","raw":"AppThumbFit","value":[{"value":"\"cover\""},{"value":"\"contain\""}]}},"rounded":{"defaultValue":{"value":"true"},"description":"Arredonda os cantos no raio do card. Padrão: `true`.","name":"rounded","parent":{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppThumb/AppThumb.tsx","name":"AppThumbProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"AppThumb"},"stories":[{"id":"atoms-appthumb--default","name":"Default","snippet":"const Default = () => <div style={{ width: 220 }}>\n    <AppThumb\n        alt=\"Caixa do produto\"\n        src={`data:image/svg+xml,${encodeURIComponent('<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"600\" height=\"600\" viewBox=\"0 0 600 600\"><rect width=\"600\" height=\"600\" fill=\"#edf0f4\"/><rect x=\"160\" y=\"140\" width=\"280\" height=\"340\" rx=\"24\" fill=\"#0a223c\"/><path d=\"M160 210h280v90H160z\" fill=\"#ec2474\"/><text x=\"300\" y=\"375\" text-anchor=\"middle\" font-family=\"sans-serif\" font-size=\"32\" fill=\"white\">PRODUTO</text></svg>')}`} />\n</div>;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appthumb--sem-imagem","name":"Sem Imagem","snippet":"const SemImagem = () => <div style={{ width: 220 }}>\n    <AppThumb alt=\"Imagem do prêmio\" src={undefined} />\n</div>;","exportName":"SemImagem","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appthumb--erro-de-carregamento","name":"Erro De Carregamento","snippet":"const ErroDeCarregamento = () => <div style={{ width: 220 }}>\n    <AppThumb alt=\"Imagem do prêmio\" src=\"data:image/png;base64,invalid\" />\n</div>;","exportName":"ErroDeCarregamento","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appthumb--proporcoes","name":"Proporcoes","snippet":"const Proporcoes = () => (\n  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(min(100%, 160px), 1fr))', gap: 16, maxWidth: 520 }}>\n    <AppThumb alt=\"1:1\" ratio=\"1:1\" src={sampleImage} />\n    <AppThumb alt=\"4:3\" ratio=\"4:3\" src={sampleImage} />\n    <AppThumb alt=\"3:2\" ratio=\"3:2\" src={sampleImage} />\n    <AppThumb alt=\"16:9\" ratio=\"16:9\" src={sampleImage} />\n    <AppThumb alt=\"3:4\" ratio=\"3:4\" src={sampleImage} />\n  </div>\n);","exportName":"Proporcoes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-appthumb--decorativa","name":"Decorativa","snippet":"const Decorativa = () => <div style={{ width: 220 }}>\n    <AppThumb alt=\"\" src={undefined} />\n</div>;","exportName":"Decorativa","tags":["dev","test","manifest","autodocs"]}],"import":"import { AppThumb } from '@handsondigital/idplugger-ui';","title":"Atoms/AppThumb"},"molecules-apptoast":{"id":"molecules-apptoast","name":"AppToast","path":"./src/components/AppToast/AppToast.stories.tsx","jsDocTags":{},"description":"Notificação temporária (posição fixa) com botão de fechar e anúncio para leitores de tela.\n\n**Quando usar:** confirmar ou informar o resultado de uma ação (\"Participação enviada!\").\n\n**Quando não usar:** decisões que bloqueiam o fluxo (use `AppModal`) ou erros de campo (use a mensagem de erro do campo).","reactDocgenTypescript":{"tags":{"example":"<AppToast type=\"success\" message=\"Participação enviada!\" onDismiss={() => setToast(null)} />"},"filePath":"src/components/AppToast/AppToast.tsx","description":"Notificação temporária (posição fixa) com botão de fechar e anúncio para leitores de tela.\n\n**Quando usar:** confirmar ou informar o resultado de uma ação (\"Participação enviada!\").\n\n**Quando não usar:** decisões que bloqueiam o fluxo (use `AppModal`) ou erros de campo (use a mensagem de erro do campo).","displayName":"AppToast","methods":[],"props":{"type":{"defaultValue":null,"description":"Tipo da notificação. `error` usa `role=\"alert\"`; `success` e `info` usam `role=\"status\"`.","name":"type","parent":{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"}],"required":true,"type":{"name":"enum","raw":"\"success\" | \"info\" | \"error\"","value":[{"value":"\"success\""},{"value":"\"info\""},{"value":"\"error\""}]}},"message":{"defaultValue":null,"description":"Texto exibido.","name":"message","parent":{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"}],"required":true,"type":{"name":"string"}},"duration":{"defaultValue":{"value":"5000"},"description":"Tempo em ms até fechar sozinho; `0` mantém o toast até o usuário fechar. Padrão: 5000.","name":"duration","parent":{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"}],"required":false,"type":{"name":"number"}},"onDismiss":{"defaultValue":null,"description":"Chamado uma única vez quando o toast é fechado (botão ou fim do tempo).","name":"onDismiss","parent":{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToast/AppToast.tsx","name":"AppToastProps"}],"required":false,"type":{"name":"(() => void)"}}},"exportName":"AppToast"},"stories":[{"id":"molecules-apptoast--success","name":"Success","snippet":"const Success = () => <AppToast\n    type=\"success\"\n    message=\"Participação enviada com sucesso!\"\n    duration={0} />;","exportName":"Success","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apptoast--error","name":"Error","snippet":"const Error = () => <AppToast\n    type=\"error\"\n    message=\"Não foi possível validar a nota fiscal.\"\n    duration={0} />;","exportName":"Error","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apptoast--info","name":"Info","snippet":"const Info = () => <AppToast\n    type=\"info\"\n    message=\"O resultado sai em até 48 horas.\"\n    duration={0} />;","exportName":"Info","tags":["dev","test","manifest","autodocs"]},{"id":"molecules-apptoast--dismiss-with-close-button","name":"Dismiss With Close Button","snippet":"const DismissWithCloseButton = () => <AppToast\n    type=\"success\"\n    message=\"Participação enviada com sucesso!\"\n    duration={0} />;","exportName":"DismissWithCloseButton","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { AppToast } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Molecules/AppToast"},"atoms-apptoggle":{"id":"atoms-apptoggle","name":"AppToggle","path":"./src/components/AppToggle/AppToggle.stories.tsx","jsDocTags":{},"description":"Interruptor nativo para ativar ou desativar uma preferência imediatamente.\n\n**Quando usar:** uma configuração binária tem efeito imediato e os estados ligado e desligado são claros.\n\n**Quando não usar:** a pessoa precisa confirmar a escolha antes de aplicá-la ou escolher entre várias opções.\n\nO `ref` e todas as props HTML são repassados ao `<input>` nativo.","reactDocgenTypescript":{"tags":{"example":"<AppToggle label=\"Receber novidades\" />"},"filePath":"src/components/AppToggle/AppToggle.tsx","description":"Interruptor nativo para ativar ou desativar uma preferência imediatamente.\n\n**Quando usar:** uma configuração binária tem efeito imediato e os estados ligado e desligado são claros.\n\n**Quando não usar:** a pessoa precisa confirmar a escolha antes de aplicá-la ou escolher entre várias opções.\n\nO `ref` e todas as props HTML são repassados ao `<input>` nativo.","displayName":"AppToggle","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível. Informe `label` ou `aria-label` para dar nome acessível ao controle.","name":"label","parent":{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"}],"required":false,"type":{"name":"ReactNode"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do rótulo. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro que marca o controle como inválido.","name":"error","parent":{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"}],"required":false,"type":{"name":"string"}},"size":{"defaultValue":{"value":"md"},"description":"Tamanho do trilho. Padrão: `md`.","name":"size","parent":{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"},"declarations":[{"fileName":"idplugger-ui/src/components/AppToggle/AppToggle.tsx","name":"AppToggleProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\"","value":[{"value":"\"sm\""},{"value":"\"md\""}]}}},"exportName":"AppToggle"},"stories":[{"id":"atoms-apptoggle--default","name":"Default","snippet":"const Default = () => <AppToggle label=\"Receber novidades\" />;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apptoggle--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'grid', gap: 16 }}>\n    <AppToggle size=\"sm\" label=\"Pequeno\" />\n    <AppToggle size=\"md\" label=\"Médio\" defaultChecked />\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apptoggle--with-hint","name":"With Hint","snippet":"const WithHint = () => <AppToggle\n    label=\"Receber novidades\"\n    hint=\"Você pode alterar esta preferência depois.\" />;","exportName":"WithHint","tags":["dev","test","manifest","autodocs"]},{"id":"atoms-apptoggle--with-error","name":"With Error","snippet":"const WithError = () => <AppToggle\n    label=\"Receber novidades\"\n    error=\"Confirme o recebimento de novidades.\" />;","exportName":"WithError","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"atoms-apptoggle--disabled","name":"Disabled","snippet":"const Disabled = () => <AppToggle label=\"Receber novidades\" disabled defaultChecked />;","exportName":"Disabled","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { AppToggle } from '@handsondigital/idplugger-ui';\nimport { fn } from 'storybook/test';","title":"Atoms/AppToggle"},"layout-container":{"id":"layout-container","name":"Container","path":"./src/components/Container/Container.stories.tsx","jsDocTags":{},"description":"Contêiner de página que centraliza e limita a largura do conteúdo.\n\n**Quando usar:** envolver seções inteiras do hotsite.\n\n**Quando não usar:** para alinhar itens em colunas (use `Grid`).","reactDocgenTypescript":{"tags":{"example":"<Container><Typography variant=\"h2\">Participe</Typography></Container>"},"filePath":"src/components/Container/Container.tsx","description":"Contêiner de página que centraliza e limita a largura do conteúdo.\n\n**Quando usar:** envolver seções inteiras do hotsite.\n\n**Quando não usar:** para alinhar itens em colunas (use `Grid`).","displayName":"Container","methods":[],"props":{"fluid":{"defaultValue":null,"description":"`true` ocupa toda a largura; `false` limita à largura máxima centralizada. Padrão: `false`.","name":"fluid","parent":{"fileName":"idplugger-ui/src/components/Container/Container.tsx","name":"ContainerProps"},"declarations":[{"fileName":"idplugger-ui/src/components/Container/Container.tsx","name":"ContainerProps"}],"required":false,"type":{"name":"boolean"}}},"exportName":"Container"},"stories":[{"id":"layout-container--default","name":"Default","snippet":"const Default = () => <Container>(<>\n      <Typography variant=\"h2\">Concorra a prêmios</Typography>\n      <Typography>Cadastre sua nota fiscal e participe.</Typography>\n    </>)</Container>;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"layout-container--fluid","name":"Fluid","snippet":"const Fluid = () => <Container fluid>(<>\n      <Typography variant=\"h2\">Concorra a prêmios</Typography>\n      <Typography>Cadastre sua nota fiscal e participe.</Typography>\n    </>)</Container>;","exportName":"Fluid","tags":["dev","test","manifest","autodocs"]}],"import":"import { Container, Typography } from '@handsondigital/idplugger-ui';\nimport { Typography } from '../Typography/Typography';","title":"Layout/Container"},"molecules-formfield":{"id":"molecules-formfield","name":"FormField","path":"./src/components/FormField/FormField.stories.tsx","jsDocTags":{},"description":"Estrutura de campo com rótulo, controle fornecido pelo consumidor e feedback acessível.\n\n**Quando usar:** controles próprios (data nativa, máscara ou componente de terceiros) que precisam seguir o padrão\nde rótulo, dica e erro da biblioteca. Para a mesma caixa do `AppInput`, envolva o controle em\n`<div className=\"app-input-group app-input-group--md\">` e use a classe `app-input` nele.\n\n**Quando não usar:** `AppInput`, `AppTextarea` e `AppSelect`, que já incluem essa estrutura; controles de escolha com\nrótulo ao lado.","reactDocgenTypescript":{"tags":{"example":"<FormField label=\"Data da compra\">\n  {(field) => (\n    <div className=\"app-input-group app-input-group--md\">\n      <input type=\"date\" className=\"app-input\" {...field} />\n    </div>\n  )}\n</FormField>"},"filePath":"src/components/FormField/FormField.tsx","description":"Estrutura de campo com rótulo, controle fornecido pelo consumidor e feedback acessível.\n\n**Quando usar:** controles próprios (data nativa, máscara ou componente de terceiros) que precisam seguir o padrão\nde rótulo, dica e erro da biblioteca. Para a mesma caixa do `AppInput`, envolva o controle em\n`<div className=\"app-input-group app-input-group--md\">` e use a classe `app-input` nele.\n\n**Quando não usar:** `AppInput`, `AppTextarea` e `AppSelect`, que já incluem essa estrutura; controles de escolha com\nrótulo ao lado.","displayName":"FormField","methods":[],"props":{"label":{"defaultValue":null,"description":"Rótulo visível do controle.","name":"label","parent":{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"},"declarations":[{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"}],"required":true,"type":{"name":"ReactNode"}},"hint":{"defaultValue":null,"description":"Texto de apoio abaixo do controle. Some enquanto houver `error`.","name":"hint","parent":{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"},"declarations":[{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"}],"required":false,"type":{"name":"string"}},"error":{"defaultValue":null,"description":"Mensagem de erro que marca o controle como inválido.","name":"error","parent":{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"},"declarations":[{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"}],"required":false,"type":{"name":"string"}},"id":{"defaultValue":null,"description":"Id estável do controle. Quando omitido, um id acessível é gerado.","name":"id","parent":{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"},"declarations":[{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"}],"required":false,"type":{"name":"string"}},"children":{"defaultValue":null,"description":"Função que recebe os atributos a aplicar ao controle próprio.","name":"children","parent":{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"},"declarations":[{"fileName":"idplugger-ui/src/components/FormField/FormField.tsx","name":"FormFieldProps"}],"required":true,"type":{"name":"(props: FormFieldControlProps) => ReactNode"}}},"exportName":"FormField"},"stories":[{"id":"molecules-formfield--default","name":"Default","snippet":"const Default = () => <FormField label=\"Data da compra\" hint=\"A mesma do cupom fiscal.\">{(field) => (\n      <div className=\"app-input-group app-input-group--md\">\n        <input type=\"date\" className=\"app-input\" {...field} />\n      </div>\n    )}</FormField>;","exportName":"Default","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { FormField } from '@handsondigital/idplugger-ui';","title":"Molecules/FormField"},"layout-grid":{"id":"layout-grid","name":"Grid","path":"./src/components/Grid/Grid.stories.tsx","jsDocTags":{},"description":"Grade CSS com 1 a 4 colunas e espaçamento configurável.\n\n**Quando usar:** listas de cards, prêmios ou campos lado a lado.\n\n**Quando não usar:** para limitar a largura da página (use `Container`).","reactDocgenTypescript":{"tags":{"example":"<Grid columns={3} gap=\"lg\"><Card /><Card /><Card /></Grid>"},"filePath":"src/components/Grid/Grid.tsx","description":"Grade CSS com 1 a 4 colunas e espaçamento configurável.\n\n**Quando usar:** listas de cards, prêmios ou campos lado a lado.\n\n**Quando não usar:** para limitar a largura da página (use `Container`).","displayName":"Grid","methods":[],"props":{"columns":{"defaultValue":null,"description":"Número de colunas. Padrão: 1.","name":"columns","parent":{"fileName":"idplugger-ui/src/components/Grid/Grid.tsx","name":"GridProps"},"declarations":[{"fileName":"idplugger-ui/src/components/Grid/Grid.tsx","name":"GridProps"}],"required":false,"type":{"name":"enum","raw":"3 | 1 | 2 | 4","value":[{"value":"3"},{"value":"1"},{"value":"2"},{"value":"4"}]}},"gap":{"defaultValue":null,"description":"Espaçamento entre itens. Padrão: `md`.","name":"gap","parent":{"fileName":"idplugger-ui/src/components/Grid/Grid.tsx","name":"GridProps"},"declarations":[{"fileName":"idplugger-ui/src/components/Grid/Grid.tsx","name":"GridProps"}],"required":false,"type":{"name":"enum","raw":"\"sm\" | \"md\" | \"lg\"","value":[{"value":"\"sm\""},{"value":"\"md\""},{"value":"\"lg\""}]}}},"exportName":"Grid"},"stories":[{"id":"layout-grid--default","name":"Default","snippet":"const Default = () => <Grid columns={3} gap=\"md\">{prizes.slice(0, 3).map((prize) => (\n      <Typography key={prize} variant=\"h5\">\n        {prize}\n      </Typography>\n    ))}</Grid>;","warning":"Incomplete snippet: `prizes` could not be resolved statically.","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"layout-grid--two-columns","name":"Two Columns","snippet":"const TwoColumns = () => <Grid columns={2} gap=\"md\">{prizes.map((p) => <Typography key={p}>{p}</Typography>)}</Grid>;","warning":"Incomplete snippet: `prizes` could not be resolved statically.","exportName":"TwoColumns","tags":["dev","test","manifest","autodocs"]},{"id":"layout-grid--four-columns-large-gap","name":"Four Columns Large Gap","snippet":"const FourColumnsLargeGap = () => <Grid columns={4} gap=\"lg\">{prizes.map((p) => <Typography key={p}>{p}</Typography>)}</Grid>;","warning":"Incomplete snippet: `prizes` could not be resolved statically.","exportName":"FourColumnsLargeGap","tags":["dev","test","manifest","autodocs"]},{"id":"layout-grid--single-column","name":"Single Column","snippet":"const SingleColumn = () => <Grid columns={1} gap=\"sm\">{prizes.slice(0, 3).map((prize) => (\n      <Typography key={prize} variant=\"h5\">\n        {prize}\n      </Typography>\n    ))}</Grid>;","warning":"Incomplete snippet: `prizes` could not be resolved statically.","exportName":"SingleColumn","tags":["dev","test","manifest","autodocs"]}],"import":"import { Grid, Typography } from '@handsondigital/idplugger-ui';\nimport { Typography } from '../Typography/Typography';","title":"Layout/Grid"},"foundations-typography":{"id":"foundations-typography","name":"Typography","path":"./src/components/Typography/Typography.stories.tsx","jsDocTags":{},"description":"Texto com a escala tipográfica do design system.\n\n**Quando usar:** todo título e texto corrido, para manter fontes e tamanhos consistentes.\n\n**Quando não usar:** rótulos de campos (use o `label` do `AppInput`/`AppTextarea`) ou ações (use `AppButton`).","reactDocgenTypescript":{"tags":{"example":"<Typography variant=\"h2\" as=\"h1\">Concorra a prêmios</Typography>"},"filePath":"src/components/Typography/Typography.tsx","description":"Texto com a escala tipográfica do design system.\n\n**Quando usar:** todo título e texto corrido, para manter fontes e tamanhos consistentes.\n\n**Quando não usar:** rótulos de campos (use o `label` do `AppInput`/`AppTextarea`) ou ações (use `AppButton`).","displayName":"Typography","methods":[],"props":{"as":{"defaultValue":null,"description":"Elemento HTML renderizado. Padrão: definido pela variante (h1–h6, `p`, `small`). Use para manter a semântica sem mudar o visual.","name":"as","declarations":[{"fileName":"idplugger-ui/src/components/Typography/Typography.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ElementType"}},"variant":{"defaultValue":{"value":"body"},"description":"Estilo tipográfico. Padrão: `body`.","name":"variant","declarations":[{"fileName":"idplugger-ui/src/components/Typography/Typography.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"TypographyVariant","value":[{"value":"\"small\""},{"value":"\"body\""},{"value":"\"caption\""},{"value":"\"h1\""},{"value":"\"h2\""},{"value":"\"h3\""},{"value":"\"h4\""},{"value":"\"h5\""},{"value":"\"h6\""},{"value":"\"body-large\""},{"value":"\"footnote\""}]}},"weight":{"defaultValue":null,"description":"Só tem efeito nas variantes em Poppins; os títulos h1–h5 (VAG Rundschrift D) têm peso único. Padrão: `regular`.","name":"weight","declarations":[{"fileName":"idplugger-ui/src/components/Typography/Typography.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"enum","raw":"\"regular\" | \"medium\"","value":[{"value":"\"regular\""},{"value":"\"medium\""}]}},"className":{"defaultValue":null,"description":"Classe CSS extra.","name":"className","declarations":[{"fileName":"idplugger-ui/src/components/Typography/Typography.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"string"}},"children":{"defaultValue":null,"description":"Conteúdo do texto.","name":"children","declarations":[{"fileName":"idplugger-ui/src/components/Typography/Typography.tsx","name":"TypeLiteral"}],"required":false,"type":{"name":"ReactNode"}}},"exportName":"Typography"},"stories":[{"id":"foundations-typography--default","name":"Default","snippet":"const Default = () => <Typography variant=\"body\">Cadastre sua nota fiscal e participe</Typography>;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-typography--heading","name":"Heading","snippet":"const Heading = () => <Typography variant=\"h2\">Cadastre sua nota fiscal e participe</Typography>;","exportName":"Heading","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-typography--medium-weight","name":"Medium Weight","snippet":"const MediumWeight = () => <Typography variant=\"body\" weight=\"medium\">Cadastre sua nota fiscal e participe</Typography>;","exportName":"MediumWeight","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-typography--as-different-element","name":"As Different Element","snippet":"const AsDifferentElement = () => <Typography variant=\"h2\" as=\"h1\">Título da página</Typography>;","exportName":"AsDifferentElement","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-typography--all-variants","name":"All Variants","snippet":"const AllVariants = () => (\n  // `caption` e `small` renderizam <small> (inline): a coluna flex mantem uma variante por linha.\n  <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 8 }}>\n    {variants.map((variant) => (\n      <Typography key={variant} variant={variant}>\n        {variant}: Participe da promoção\n      </Typography>\n    ))}\n  </div>\n);","exportName":"AllVariants","tags":["dev","test","manifest","autodocs"]}],"import":"import { Typography } from '@handsondigital/idplugger-ui';","title":"Foundations/Typography"},"theming-contraste":{"id":"theming-contraste","name":"Contraste","path":"./src/docs/Contraste.stories.tsx","jsDocTags":{},"error":{"name":"No component found","message":"We could not detect the component from your story file. Specify meta.component.\n  78 |  * os pares controlados pela biblioteca atingem o mínimo. Bordas, anéis de foco e ícones não entram na medição.\n  79 |  */\n> 80 | const meta = {\n     | ^\n  81 |   title: 'Theming/Contraste',\n  82 |   parameters: {\n  83 |     layout: 'padded',\n\n./src/docs/Contraste.stories.tsx:\nimport type { Meta, StoryObj } from '@storybook/react-vite'\nimport { useLayoutEffect, useRef, useState } from 'react'\nimport { expect, waitFor } from 'storybook/test'\nimport { CONTRAST_PAIRS, measurePair } from './contrast'\n\n// Um preset por arquivo em src/themes: uma marca nova entra no teste sem mudar esta story.\nconst BRANDS = Object.keys(import.meta.glob('../themes/*.css')).map((path) => path.replace(/^.*\\/(.+)\\.css$/, '$1'))\nconst THEMES = ['light', 'dark'] as const\n\ntype Status = 'ok' | 'aviso' | 'falha'\n\nfunction ContrastTable({ brand, theme }: { brand: string; theme: (typeof THEMES)[number] }) {\n  const scope = useRef<HTMLElement>(null)\n  const [ratios, setRatios] = useState<Record<string, number>>({})\n\n  useLayoutEffect(() => {\n    const section = scope.current!\n    const measured: Record<string, number> = {}\n    for (const sample of section.querySelectorAll<HTMLElement>('[data-sample]')) {\n      measured[sample.dataset.sample!] = measurePair(section, sample)\n    }\n    setRatios(measured)\n  }, [])\n\n  return (\n    <section\n      ref={scope}\n      data-brand={brand}\n      data-theme={theme}\n      aria-label={`${brand} · ${theme}`}\n      style={{ background: 'var(--color-surface)', color: 'var(--color-foreground)', padding: 16, borderRadius: 8 }}\n    >\n      <h2 style={{ margin: '0 0 8px', fontSize: 16 }}>\n        {brand} · {theme === 'light' ? 'claro' : 'escuro'}\n      </h2>\n      <table style={{ borderCollapse: 'collapse', fontSize: 13 }}>\n        <thead>\n          <tr>\n            <th scope=\"col\" style={{ textAlign: 'left' }}>Par</th>\n            <th scope=\"col\">Amostra</th>\n            <th scope=\"col\">Razão</th>\n            <th scope=\"col\">Escopo</th>\n            <th scope=\"col\">Situação</th>\n          </tr>\n        </thead>\n        <tbody>\n          {CONTRAST_PAIRS.map((pair) => {\n            const ratio = ratios[pair.id]\n            const status: Status | undefined =\n              ratio === undefined ? undefined : ratio >= pair.min ? 'ok' : pair.scope === 'marca' ? 'aviso' : 'falha'\n            return (\n              <tr key={pair.id} data-pair={pair.id} data-ratio={ratio?.toFixed(2)} data-status={status}>\n                <td style={{ padding: '2px 8px 2px 0' }}>{pair.label}</td>\n                <td style={{ padding: '2px 8px' }}>\n                  <span\n                    data-sample={pair.id}\n                    style={{ background: `var(${pair.background})`, color: `var(${pair.foreground})`, padding: '0 8px', fontWeight: 600 }}\n                  >\n                    Aa\n                  </span>\n                </td>\n                <td style={{ padding: '2px 8px', textAlign: 'right' }}>{ratio?.toFixed(2)}</td>\n                <td style={{ padding: '2px 8px' }}>{pair.scope}</td>\n                <td style={{ padding: '2px 8px' }}>{status === 'ok' ? '✓' : status === 'aviso' ? `⚠ < ${pair.min} (cor da marca)` : status ? `✗ < ${pair.min}` : ''}</td>\n              </tr>\n            )\n          })}\n        </tbody>\n      </table>\n    </section>\n  )\n}\n\n/**\n * Contraste WCAG (texto ≥ 4,5:1) dos pares de tokens renderizados pelos componentes, em cada marca e modo de cor.\n * As cores são resolvidas pelo navegador. Pares da marca aparecem com aviso quando ficam abaixo do mínimo; escolha\n * uma cor de texto que atinja a proporção adequada (`--color-brand-primary-foreground`). A tabela também mostra se\n * os pares controlados pela biblioteca atingem o mínimo. Bordas, anéis de foco e ícones não entram na medição.\n */\nconst meta = {\n  title: 'Theming/Contraste',\n  parameters: {\n    layout: 'padded',\n    // A tabela exibe as amostras abaixo do mínimo para facilitar a comparação.\n    a11y: { config: { rules: [{ id: 'color-contrast', enabled: false }] } },\n  },\n  render: () => (\n    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, max-content)', gap: 16 }}>\n      {BRANDS.flatMap((brand) => THEMES.map((theme) => <ContrastTable key={`${brand}-${theme}`} brand={brand} theme={theme} />))}\n    </div>\n  ),\n} satisfies Meta\n\nexport default meta\ntype Story = StoryObj<typeof meta>\n\nexport const PorMarcaEModo: Story = {\n  play: async ({ canvasElement }) => {\n    const sections = () => Array.from(canvasElement.querySelectorAll<HTMLElement>('section[data-brand][data-theme]'))\n    const rows = () => sections().flatMap((s) => Array.from(s.querySelectorAll<HTMLElement>('tr[data-pair]')))\n\n    await waitFor(() => {\n      expect(rows().length).toBeGreaterThan(0)\n      expect(rows().filter((row) => !row.dataset.status)).toHaveLength(0)\n    })\n\n    const brands = new Set(sections().map((s) => s.dataset.brand))\n    const themes = new Set(sections().map((s) => s.dataset.theme))\n    expect(brands.size).toBeGreaterThanOrEqual(2)\n    expect(themes.size).toBeGreaterThanOrEqual(2)\n\n    const falhas = sections().flatMap((s) =>\n      Array.from(s.querySelectorAll<HTMLElement>('tr[data-status=\"falha\"]')).map(\n        (row) => `${s.dataset.brand}/${s.dataset.theme} ${row.dataset.pair}=${row.dataset.ratio}`,\n      ),\n    )\n    expect(falhas, `Pares da lib abaixo do mínimo: ${falhas.join('; ')}`).toEqual([])\n  },\n}\n"},"stories":[{"id":"theming-contraste--por-marca-e-modo","name":"Por Marca E Modo","snippet":"const PorMarcaEModo = () => (\n  <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, max-content)', gap: 16 }}>\n    {BRANDS.flatMap((brand) => THEMES.map((theme) => <ContrastTable key={`${brand}-${theme}`} brand={brand} theme={theme} />))}\n  </div>\n);","exportName":"PorMarcaEModo","tags":["dev","test","manifest","play-fn"]}],"title":"Theming/Contraste"},"theming-densidade":{"id":"theming-densidade","name":"Densidade","path":"./src/docs/Densidade.stories.tsx","jsDocTags":{},"error":{"name":"No component found","message":"We could not detect the component from your story file. Specify meta.component.\n   9 |  * `data-density` ajusta o espaço e o ícone do botão. O tamanho `sm`–`2xl` define os valores mínimos.\n  10 |  */\n> 11 | const meta = {\n     | ^\n  12 |   title: 'Theming/Densidade',\n  13 |   parameters: { layout: 'padded' },\n  14 |   render: () => (\n\n./src/docs/Densidade.stories.tsx:\nimport type { Meta, StoryObj } from '@storybook/react-vite'\nimport { IconArrowForward } from '@handsondigital/idplugger-ui/icons'\nimport { expect, within } from 'storybook/test'\nimport { AppButton } from '../components/AppButton/AppButton'\n\nconst DENSITIES = ['regular', 'medium', 'large', 'extra-large'] as const\n\n/**\n * `data-density` ajusta o espaço e o ícone do botão. O tamanho `sm`–`2xl` define os valores mínimos.\n */\nconst meta = {\n  title: 'Theming/Densidade',\n  parameters: { layout: 'padded' },\n  render: () => (\n    <div style={{ display: 'grid', gap: 16 }}>\n      {DENSITIES.map((density) => (\n        <section key={density} aria-label={density} data-density={density} style={{ display: 'flex', alignItems: 'center', gap: 16 }}>\n          <strong style={{ width: 96 }}>{density}</strong>\n          <AppButton trailingIcon={<IconArrowForward />}>Participar</AppButton>\n          <AppButton size=\"2xl\" trailingIcon={<IconArrowForward />}>\n            Participar\n          </AppButton>\n        </section>\n      ))}\n    </div>\n  ),\n} satisfies Meta\n\nexport default meta\ntype Story = StoryObj<typeof meta>\n\nexport const PorDensidade: Story = {\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const expected = {\n      regular: [['8px', '20px'], ['12px', '24px']],\n      medium: [['8px', '20px'], ['12px', '24px']],\n      large: [['12px', '20px'], ['12px', '24px']],\n      'extra-large': [['12px', '24px'], ['12px', '24px']],\n    }\n    for (const density of DENSITIES) {\n      const section = canvas.getByRole('region', { name: density })\n      const buttons = section.querySelectorAll<HTMLElement>('.app-button')\n      await expect(buttons).toHaveLength(2)\n      buttons.forEach((button, i) => {\n        const icon = button.querySelector<HTMLElement>('.app-button__icon')!\n        const [gap, size] = expected[density][i]\n        expect(getComputedStyle(button).columnGap, `${density} #${i} gap`).toBe(gap)\n        expect(getComputedStyle(icon).width, `${density} #${i} icone`).toBe(size)\n        expect(getComputedStyle(icon).height, `${density} #${i} icone`).toBe(size)\n      })\n    }\n  },\n}\n"},"stories":[{"id":"theming-densidade--por-densidade","name":"Por Densidade","snippet":"const PorDensidade = () => (\n  <div style={{ display: 'grid', gap: 16 }}>\n    {DENSITIES.map((density) => (\n      <section key={density} aria-label={density} data-density={density} style={{ display: 'flex', alignItems: 'center', gap: 16 }}>\n        <strong style={{ width: 96 }}>{density}</strong>\n        <AppButton trailingIcon={<IconArrowForward />}>Participar</AppButton>\n        <AppButton size=\"2xl\" trailingIcon={<IconArrowForward />}>\n          Participar\n        </AppButton>\n      </section>\n    ))}\n  </div>\n);","exportName":"PorDensidade","tags":["dev","test","manifest","play-fn"]}],"import":"import { AppButton } from '@handsondigital/idplugger-ui';\nimport { IconArrowForward } from '@handsondigital/idplugger-ui/icons';","title":"Theming/Densidade"},"theming-duas-marcas":{"id":"theming-duas-marcas","name":"Duasmarcas","path":"./src/docs/DuasMarcas.stories.tsx","jsDocTags":{},"error":{"name":"No component found","message":"We could not detect the component from your story file. Specify meta.component.\n  36 |  * `data-theme=\"dark\"` à marca laranja. Componentes em portal (AppModal) copiam a marca e o modo do escopo de quem os abriu; sem gatilho, seguem o `<html>`.\n  37 |  */\n> 38 | const meta = {\n     | ^\n  39 |   title: 'Theming/Duas marcas',\n  40 |   parameters: { layout: 'padded' },\n  41 |   render: () => (\n\n./src/docs/DuasMarcas.stories.tsx:\nimport type { Meta, StoryObj } from '@storybook/react-vite'\nimport type { ReactNode } from 'react'\nimport { AppButton } from '../components/AppButton/AppButton'\nimport { AppInput } from '../components/AppInput/AppInput'\nimport { AppTag } from '../components/AppTag/AppTag'\nimport { expect, userEvent, waitFor, within } from 'storybook/test'\nimport { parseCssColor } from './contrast'\n\nfunction Panel({ label, brand, theme, children }: { label: string; brand?: string; theme?: string; children?: ReactNode }) {\n  return (\n    <section\n      aria-label={label}\n      data-brand={brand}\n      data-theme={theme}\n      style={{ display: 'grid', gap: 12, padding: 16, borderRadius: 8, background: 'var(--color-surface)', color: 'var(--color-foreground)' }}\n    >\n      <strong>{label}</strong>\n      <div style={{ display: 'flex', gap: 8 }}>\n        <AppButton>Participar</AppButton>\n        <AppButton tone=\"secondary\">Regulamento</AppButton>\n      </div>\n      <AppInput label={`CPF (${label})`} placeholder=\"000.000.000-00\" />\n      <div>\n        <AppTag onRemove={() => {}} removeLabel={`Remover tag (${label})`}>\n          Campanha\n        </AppTag>\n      </div>\n      {children}\n    </section>\n  )\n}\n\n/**\n * Prova de isolamento: a primeira seção fica sempre no modo claro (`data-theme=\"light\"`, não segue o modo da página), na marca escolhida na barra de ferramentas (idPlugger por padrão), e a seção do\n * meio tem `data-brand=\"campaign-orange\"`; botões, foco do campo e raio mudam só dentro dela. A terceira seção soma\n * `data-theme=\"dark\"` à marca laranja. Componentes em portal (AppModal) copiam a marca e o modo do escopo de quem os abriu; sem gatilho, seguem o `<html>`.\n */\nconst meta = {\n  title: 'Theming/Duas marcas',\n  parameters: { layout: 'padded' },\n  render: () => (\n    <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr)', gap: 16 }}>\n      <Panel label=\"Página\" theme=\"light\" />\n      <Panel label=\"Seção laranja\" brand=\"campaign-orange\" />\n      <Panel label=\"Seção laranja escura\" brand=\"campaign-orange\" theme=\"dark\" />\n    </div>\n  ),\n} satisfies Meta\n\nexport default meta\ntype Story = StoryObj<typeof meta>\n\nexport const LadoALado: Story = {\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    const channels = (value: string) => parseCssColor(value).slice(0, 3).map(Math.round).join(',')\n    const ORANGE = '194,65,12'\n    const PINK = '236,36,116'\n    const GRAY_900 = '16,24,40'\n    const WHITE = '255,255,255'\n\n    const read = async (label: string) => {\n      const section = canvas.getByRole('region', { name: label })\n      const s = within(section)\n      const input = s.getByLabelText(`CPF (${label})`)\n      const group = input.closest('.app-input-group') as HTMLElement\n      const button = s.getByRole('button', { name: 'Participar' })\n      await userEvent.click(input)\n      await waitFor(() => expect(input).toHaveFocus())\n      // a transição de borda precisa terminar antes da leitura\n      await waitFor(() => expect(channels(getComputedStyle(group).borderTopColor)).toBe(\n        label === 'Página' ? PINK : ORANGE,\n      ))\n      return {\n        buttonBg: channels(getComputedStyle(button).backgroundColor),\n        radius: getComputedStyle(button).borderTopLeftRadius,\n        focusBorder: channels(getComputedStyle(group).borderTopColor),\n        surface: channels(getComputedStyle(section).backgroundColor),\n        groupBg: channels(getComputedStyle(group).backgroundColor),\n      }\n    }\n\n    const page = await read('Página')\n    expect(page.buttonBg).toBe(PINK)\n    expect(page.radius).toBe('8px')\n    expect(page.focusBorder).toBe(PINK)\n\n    const orange = await read('Seção laranja')\n    expect(orange.buttonBg).toBe(ORANGE)\n    expect(orange.radius).toBe('4px')\n    expect(orange.focusBorder).toBe(ORANGE)\n    expect(orange.surface).toBe(WHITE)\n\n    const dark = await read('Seção laranja escura')\n    expect(dark.buttonBg).toBe(ORANGE)\n    expect(dark.radius).toBe('4px')\n    expect(dark.surface).toBe(GRAY_900)\n  },\n}\n"},"stories":[{"id":"theming-duas-marcas--lado-a-lado","name":"Lado A Lado","snippet":"const LadoALado = () => (\n  <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1fr)', gap: 16 }}>\n    <Panel label=\"Página\" theme=\"light\" />\n    <Panel label=\"Seção laranja\" brand=\"campaign-orange\" />\n    <Panel label=\"Seção laranja escura\" brand=\"campaign-orange\" theme=\"dark\" />\n  </div>\n);","exportName":"LadoALado","tags":["dev","test","manifest","play-fn"]}],"import":"import { AppButton, AppInput, AppTag } from '@handsondigital/idplugger-ui';","title":"Theming/Duas marcas"},"foundations-espaçamento":{"id":"foundations-espaçamento","name":"Espaçamento","path":"./src/docs/Espacamento.stories.tsx","jsDocTags":{},"error":{"name":"No component found","message":"We could not detect the component from your story file. Specify meta.component.\n  20 |  * Escala `--size-*` (base de 4px) e raio da marca `--radius-brand`, que acompanha a marca ativa.\n  21 |  */\n> 22 | const meta = {\n     | ^\n  23 |   title: 'Foundations/Espaçamento',\n  24 |   parameters: { layout: 'padded' },\n  25 | } satisfies Meta\n\n./src/docs/Espacamento.stories.tsx:\nimport type { Meta, StoryObj } from '@storybook/react-vite'\nimport { expect, within } from 'storybook/test'\n\nconst SIZES: [name: string, px: number][] = [\n  ['1', 4],\n  ['1half', 6],\n  ['2', 8],\n  ['2half', 10],\n  ['3', 12],\n  ['4', 16],\n  ['5', 20],\n  ['6', 24],\n  ['7', 28],\n  ['8', 32],\n]\n\nconst frame = { display: 'grid', gap: 8, padding: 16, background: 'var(--color-surface)', color: 'var(--color-foreground)' } as const\n\n/**\n * Escala `--size-*` (base de 4px) e raio da marca `--radius-brand`, que acompanha a marca ativa.\n */\nconst meta = {\n  title: 'Foundations/Espaçamento',\n  parameters: { layout: 'padded' },\n} satisfies Meta\n\nexport default meta\ntype Story = StoryObj<typeof meta>\n\nexport const Escala: Story = {\n  render: () => (\n    <ul aria-label=\"Escala de espaçamento\" style={{ ...frame, margin: 0, listStyle: 'none' }}>\n      {SIZES.map(([name, px]) => (\n        <li key={name} style={{ display: 'grid', gridTemplateColumns: '120px 56px 1fr', alignItems: 'center', gap: 12 }}>\n          <code>--size-{name}</code>\n          <span>{px}px</span>\n          <span\n            aria-hidden=\"true\"\n            data-size={name}\n            style={{ display: 'block', width: `var(--size-${name})`, height: 12, borderRadius: 2, background: 'var(--color-action-primary)' }}\n          />\n        </li>\n      ))}\n    </ul>\n  ),\n  play: async ({ canvasElement }) => {\n    for (const [name, px] of SIZES) {\n      const bar = canvasElement.querySelector<HTMLElement>(`[data-size=\"${name}\"]`)!\n      await expect(bar.getBoundingClientRect().width, `--size-${name}`).toBe(px)\n    }\n  },\n}\n\nexport const Raio: Story = {\n  render: () => (\n    <div style={frame}>\n      <div\n        data-radius\n        style={{ width: 160, height: 80, border: '2px solid var(--color-action-primary)', borderRadius: 'var(--radius-brand)' }}\n      />\n      <code>--radius-brand</code>\n    </div>\n  ),\n  play: async ({ canvasElement }) => {\n    await expect(within(canvasElement).getByText('--radius-brand')).toBeInTheDocument()\n    const box = canvasElement.querySelector<HTMLElement>('[data-radius]')!\n    await expect(parseFloat(getComputedStyle(box).borderTopLeftRadius)).toBeGreaterThan(0)\n  },\n}\n"},"stories":[{"id":"foundations-espaçamento--escala","name":"Escala","snippet":"const Escala = () => (\n  <ul aria-label=\"Escala de espaçamento\" style={{ ...frame, margin: 0, listStyle: 'none' }}>\n    {SIZES.map(([name, px]) => (\n      <li key={name} style={{ display: 'grid', gridTemplateColumns: '120px 56px 1fr', alignItems: 'center', gap: 12 }}>\n        <code>--size-{name}</code>\n        <span>{px}px</span>\n        <span\n          aria-hidden=\"true\"\n          data-size={name}\n          style={{ display: 'block', width: `var(--size-${name})`, height: 12, borderRadius: 2, background: 'var(--color-action-primary)' }}\n        />\n      </li>\n    ))}\n  </ul>\n);","exportName":"Escala","tags":["dev","test","manifest","play-fn"]},{"id":"foundations-espaçamento--raio","name":"Raio","snippet":"const Raio = () => (\n  <div style={frame}>\n    <div\n      data-radius\n      style={{ width: 160, height: 80, border: '2px solid var(--color-action-primary)', borderRadius: 'var(--radius-brand)' }}\n    />\n    <code>--radius-brand</code>\n  </div>\n);","exportName":"Raio","tags":["dev","test","manifest","play-fn"]}],"title":"Foundations/Espaçamento"},"foundations-paleta":{"id":"foundations-paleta","name":"Paleta","path":"./src/docs/Paleta.stories.tsx","jsDocTags":{},"error":{"name":"No component found","message":"We could not detect the component from your story file. Specify meta.component.\n  48 |  * (`data-brand`) e o modo (`data-theme`) ativos na barra de ferramentas. O nome do token aparece em texto abaixo.\n  49 |  */\n> 50 | const meta = {\n     | ^\n  51 |   title: 'Foundations/Paleta',\n  52 |   parameters: { layout: 'padded' },\n  53 | } satisfies Meta\n\n./src/docs/Paleta.stories.tsx:\nimport type { Meta, StoryObj } from '@storybook/react-vite'\nimport { expect, within } from 'storybook/test'\n\n/** Amostra de cor: o quadrado lê a variável; o nome fica abaixo, em texto do tema (contraste garantido pela superfície). */\nfunction Swatch({ token }: { token: string }) {\n  return (\n    <li style={{ display: 'grid', gap: 4, width: 168, listStyle: 'none' }}>\n      <span\n        aria-hidden=\"true\"\n        data-swatch={token}\n        style={{ display: 'block', height: 40, borderRadius: 6, border: '1px solid var(--color-border)', background: `var(${token})` }}\n      />\n      <code style={{ fontSize: 12, overflowWrap: 'anywhere' }}>{token}</code>\n    </li>\n  )\n}\n\nfunction Group({ title, tokens }: { title: string; tokens: string[] }) {\n  return (\n    <section aria-label={title} style={{ display: 'grid', gap: 8 }}>\n      <h3 style={{ margin: 0, fontSize: 16 }}>{title}</h3>\n      <ul style={{ display: 'flex', flexWrap: 'wrap', gap: 12, margin: 0, padding: 0 }}>\n        {tokens.map((token) => (\n          <Swatch key={token} token={token} />\n        ))}\n      </ul>\n    </section>\n  )\n}\n\nfunction Page({ groups }: { groups: [string, string[]][] }) {\n  return (\n    <div style={{ display: 'grid', gap: 24, padding: 16, background: 'var(--color-surface)', color: 'var(--color-foreground)' }}>\n      {groups.map(([title, tokens]) => (\n        <Group key={title} title={title} tokens={tokens} />\n      ))}\n    </div>\n  )\n}\n\nconst SCALES = ['red', 'orange', 'yellow', 'green', 'mint', 'teal', 'cyan', 'blue', 'indigo', 'purple', 'gray']\nconst STEPS = ['50', '100', '200', '300', '400', '500', '600', '700', '800', '900']\nconst NEUTRAL_STEPS = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', '100', '200', '300', '400', '500', '600', '700', '800', '900']\nconst status = ['success', 'info', 'warning', 'danger']\n\n/**\n * Amostras das cores como CSS custom properties de `tokens.css`. Cada quadrado lê `var(--…)`, então acompanha a marca\n * (`data-brand`) e o modo (`data-theme`) ativos na barra de ferramentas. O nome do token aparece em texto abaixo.\n */\nconst meta = {\n  title: 'Foundations/Paleta',\n  parameters: { layout: 'padded' },\n} satisfies Meta\n\nexport default meta\ntype Story = StoryObj<typeof meta>\n\n/** Contrato da marca: o que uma marca sobrescreve. */\nexport const Marca: Story = {\n  render: () => (\n    <Page\n      groups={[\n        ['Primária', ['--color-brand-primary', '--color-brand-primary-foreground', '--color-brand-primary-disabled']],\n        ['Secundária', ['--color-brand-secondary', '--color-brand-secondary-fg', '--color-brand-secondary-hover']],\n        ['Apoio', ['--color-brand-accent', '--color-brand-navy']],\n        ['Texto, fundo e bordas', ['--color-brand-text', '--color-brand-bg', '--color-brand-surface-muted', '--color-brand-border', '--color-brand-border-hover']],\n        ['Status', status.map((s) => `--color-brand-${s}`)],\n      ]}\n    />\n  ),\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await expect(canvas.getByText('--color-brand-primary')).toBeInTheDocument()\n    const swatch = canvasElement.querySelector<HTMLElement>('[data-swatch=\"--color-brand-primary\"]')!\n    await expect(getComputedStyle(swatch).backgroundColor).not.toBe('rgba(0, 0, 0, 0)')\n  },\n}\n\n/** Semânticos: derivam da marca e mudam com o modo de cor. */\nexport const Semanticas: Story = {\n  render: () => (\n    <Page\n      groups={[\n        ['Superfície', ['--color-surface', '--color-surface-muted', '--color-surface-strong']],\n        [\n          'Texto',\n          ['--color-foreground', '--color-foreground-strong', '--color-foreground-soft', '--color-foreground-muted', '--color-foreground-subtle', '--color-foreground-faint', '--color-foreground-disabled'],\n        ],\n        ['Borda', ['--color-border', '--color-border-strong', '--color-border-subtle', '--color-border-faint']],\n        [\n          'Ação primária',\n          ['--color-action-primary', '--color-action-primary-hover', '--color-action-primary-active', '--color-action-primary-disabled', '--color-action-primary-foreground'],\n        ],\n        ['Feedback (texto)', status.map((s) => `--color-feedback-${s}-fg`)],\n      ]}\n    />\n  ),\n  play: async ({ canvasElement }) => {\n    await expect(within(canvasElement).getByText('--color-surface-strong')).toBeInTheDocument()\n  },\n}\n\n/** Escalas primitivas: não mudam com marca nem modo. */\nexport const Escalas: Story = {\n  render: () => (\n    <Page\n      groups={[\n        ...SCALES.map((name): [string, string[]] => [name, STEPS.map((step) => `--color-${name}-${step}`)]),\n        ['neutral', NEUTRAL_STEPS.map((step) => `--color-neutral-${step}`)],\n      ]}\n    />\n  ),\n  play: async ({ canvasElement }) => {\n    await expect(within(canvasElement).getByText('--color-neutral-900')).toBeInTheDocument()\n  },\n}\n"},"stories":[{"id":"foundations-paleta--marca","name":"Marca","snippet":"const Marca = () => (\n  <Page\n    groups={[\n      ['Primária', ['--color-brand-primary', '--color-brand-primary-foreground', '--color-brand-primary-disabled']],\n      ['Secundária', ['--color-brand-secondary', '--color-brand-secondary-fg', '--color-brand-secondary-hover']],\n      ['Apoio', ['--color-brand-accent', '--color-brand-navy']],\n      ['Texto, fundo e bordas', ['--color-brand-text', '--color-brand-bg', '--color-brand-surface-muted', '--color-brand-border', '--color-brand-border-hover']],\n      ['Status', status.map((s) => `--color-brand-${s}`)],\n    ]}\n  />\n);","description":"Contrato da marca: o que uma marca sobrescreve.","exportName":"Marca","tags":["dev","test","manifest","play-fn"]},{"id":"foundations-paleta--semanticas","name":"Semanticas","snippet":"const Semanticas = () => (\n  <Page\n    groups={[\n      ['Superfície', ['--color-surface', '--color-surface-muted', '--color-surface-strong']],\n      [\n        'Texto',\n        ['--color-foreground', '--color-foreground-strong', '--color-foreground-soft', '--color-foreground-muted', '--color-foreground-subtle', '--color-foreground-faint', '--color-foreground-disabled'],\n      ],\n      ['Borda', ['--color-border', '--color-border-strong', '--color-border-subtle', '--color-border-faint']],\n      [\n        'Ação primária',\n        ['--color-action-primary', '--color-action-primary-hover', '--color-action-primary-active', '--color-action-primary-disabled', '--color-action-primary-foreground'],\n      ],\n      ['Feedback (texto)', status.map((s) => `--color-feedback-${s}-fg`)],\n    ]}\n  />\n);","description":"Semânticos: derivam da marca e mudam com o modo de cor.","exportName":"Semanticas","tags":["dev","test","manifest","play-fn"]},{"id":"foundations-paleta--escalas","name":"Escalas","snippet":"const Escalas = () => (\n  <Page\n    groups={[\n      ...SCALES.map((name): [string, string[]] => [name, STEPS.map((step) => `--color-${name}-${step}`)]),\n      ['neutral', NEUTRAL_STEPS.map((step) => `--color-neutral-${step}`)],\n    ]}\n  />\n);","description":"Escalas primitivas: não mudam com marca nem modo.","exportName":"Escalas","tags":["dev","test","manifest","play-fn"]}],"title":"Foundations/Paleta"},"vitrine":{"id":"vitrine","name":"Vitrine","path":"./src/docs/Vitrine.stories.tsx","jsDocTags":{},"error":{"name":"No component found","message":"We could not detect the component from your story file. Specify meta.component.\n  16 |  * contexto de uma campanha (sorteio, cupons, regulamento). Servem de exemplo rápido do que cada componente faz.\n  17 |  */\n> 18 | const meta = {\n     | ^\n  19 |   title: 'Vitrine',\n  20 |   parameters: { layout: 'centered' },\n  21 | } satisfies Meta\n\n./src/docs/Vitrine.stories.tsx:\nimport type { Meta, StoryObj } from '@storybook/react-vite'\nimport { useState } from 'react'\nimport { expect, userEvent, waitFor, within } from 'storybook/test'\nimport { IconConfirmationNumber, IconLocalOffer } from '@handsondigital/idplugger-ui/icons'\nimport { AppButton } from '../components/AppButton/AppButton'\nimport { AppModal } from '../components/AppModal/AppModal'\nimport { AppPagination } from '../components/AppPagination/AppPagination'\nimport { AppPaymentIcon } from '../components/AppPaymentIcon/AppPaymentIcon'\nimport { AppSpinner } from '../components/AppSpinner/AppSpinner'\nimport { AppTag } from '../components/AppTag/AppTag'\nimport { AppToast } from '../components/AppToast/AppToast'\nimport type { PaymentMethod } from '../components/AppPaymentIcon/paymentMethods'\n\n/**\n * Vitrine da home do portal: composições pequenas e interativas, cada uma só com componentes da biblioteca, no\n * contexto de uma campanha (sorteio, cupons, regulamento). Servem de exemplo rápido do que cada componente faz.\n */\nconst meta = {\n  title: 'Vitrine',\n  parameters: { layout: 'centered' },\n} satisfies Meta\n\nexport default meta\ntype Story = StoryObj<typeof meta>\n\n/** Paginação da lista de ganhadores. */\nexport const Paginacao: Story = {\n  render: function Render() {\n    const [page, setPage] = useState(3)\n    return <AppPagination page={page} pageCount={12} onPageChange={setPage} nav=\"button\" />\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await userEvent.click(canvas.getByRole('button', { name: 'Próxima' }))\n    // no viewport estreito alguns números ficam só no desktop (escondidos por CSS)\n    await expect(canvas.getByRole('button', { name: 'Página 4', hidden: true })).toHaveAttribute('aria-current', 'page')\n  },\n}\n\nconst CATEGORIAS = ['Eletrônicos', 'Viagens', 'Vale-compras', 'Experiências']\n\n/** Filtros removíveis de prêmios. */\nexport const Tags: Story = {\n  render: function Render() {\n    const [tags, setTags] = useState(CATEGORIAS)\n    return (\n      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', maxWidth: 360 }}>\n        {tags.map((tag) => (\n          <AppTag\n            key={tag}\n            icon={<IconLocalOffer size={14} />}\n            onRemove={() => setTags((current) => current.filter((item) => item !== tag))}\n            removeLabel={`Remover filtro ${tag}`}\n          >\n            {tag}\n          </AppTag>\n        ))}\n        {tags.length === 0 && (\n          <AppButton size=\"sm\" appearance=\"soft\" onClick={() => setTags(CATEGORIAS)}>\n            Restaurar filtros\n          </AppButton>\n        )}\n      </div>\n    )\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await userEvent.click(canvas.getByRole('button', { name: 'Remover filtro Viagens' }))\n    await expect(canvas.queryByText('Viagens')).not.toBeInTheDocument()\n  },\n}\n\n/** Regulamento em modal e aviso em toast. */\nexport const Feedback: Story = {\n  render: function Render() {\n    const [modalOpen, setModalOpen] = useState(false)\n    const [toast, setToast] = useState(false)\n    return (\n      <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center' }}>\n        <AppButton appearance=\"outline\" onClick={() => setModalOpen(true)}>\n          Ver regulamento\n        </AppButton>\n        <AppButton leadingIcon={<IconConfirmationNumber size={20} />} onClick={() => setToast(true)}>\n          Gerar número da sorte\n        </AppButton>\n        <AppModal\n          isOpen={modalOpen}\n          onClose={() => setModalOpen(false)}\n          title=\"Regulamento da promoção\"\n          footer={<AppButton onClick={() => setModalOpen(false)}>Li e aceito</AppButton>}\n        >\n          <p style={{ margin: 0 }}>\n            Participam pessoas físicas maiores de 18 anos, residentes no Brasil, que cadastrarem cupons fiscais de\n            compras dos produtos participantes durante o período da campanha.\n          </p>\n        </AppModal>\n        {toast && (\n          <AppToast type=\"success\" message=\"Seu número da sorte é 04.512.887\" onDismiss={() => setToast(false)} />\n        )}\n      </div>\n    )\n  },\n  play: async ({ canvasElement }) => {\n    const canvas = within(canvasElement)\n    await userEvent.click(canvas.getByRole('button', { name: 'Gerar número da sorte' }))\n    await expect(canvas.getByText('Seu número da sorte é 04.512.887')).toBeInTheDocument()\n    await userEvent.click(canvas.getByRole('button', { name: 'Ver regulamento' }))\n    const dialog = await within(document.body).findByRole('dialog', { name: 'Regulamento da promoção' })\n    await userEvent.click(within(dialog).getByRole('button', { name: 'Li e aceito' }))\n    await waitFor(() => expect(within(document.body).queryByRole('dialog')).not.toBeInTheDocument())\n  },\n}\n\nconst METODOS: PaymentMethod[] = ['visa', 'mastercard', 'amex', 'diners', 'discover']\n\n/** Bandeiras aceitas no checkout da campanha. */\nexport const Pagamento: Story = {\n  render: () => (\n    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, justifyContent: 'center' }}>\n      {METODOS.map((method) => (\n        <AppPaymentIcon key={method} method={method} size=\"lg\" />\n      ))}\n    </div>\n  ),\n}\n\n/** Estados de carregamento: spinner e botão enviando. */\nexport const Carregando: Story = {\n  render: () => (\n    <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 16, justifyContent: 'center' }}>\n      <AppSpinner size=\"lg\" label=\"Sorteando\" />\n      <AppButton isLoading>Enviando cupom</AppButton>\n    </div>\n  ),\n}\n\n/** Tons e aparências do botão mais usados numa campanha. */\nexport const Botoes: Story = {\n  render: () => (\n    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', maxWidth: 420 }}>\n      <AppButton>Quero participar</AppButton>\n      <AppButton tone=\"secondary\">Regulamento</AppButton>\n      <AppButton appearance=\"outline\">Ganhadores</AppButton>\n      <AppButton appearance=\"soft\">Meus cupons</AppButton>\n      <AppButton tone=\"success\" appearance=\"soft\">Cupom válido</AppButton>\n      <AppButton appearance=\"link\">Dúvidas frequentes</AppButton>\n    </div>\n  ),\n}\n"},"stories":[{"id":"vitrine--paginacao","name":"Paginacao","snippet":"const Paginacao = function Render() {\n  const [page, setPage] = useState(3)\n  return <AppPagination page={page} pageCount={12} onPageChange={setPage} nav=\"button\" />\n};","description":"Paginação da lista de ganhadores.","exportName":"Paginacao","tags":["dev","test","manifest","play-fn"]},{"id":"vitrine--tags","name":"Tags","snippet":"const Tags = function Render() {\n  const [tags, setTags] = useState(CATEGORIAS)\n  return (\n    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', maxWidth: 360 }}>\n      {tags.map((tag) => (\n        <AppTag\n          key={tag}\n          icon={<IconLocalOffer size={14} />}\n          onRemove={() => setTags((current) => current.filter((item) => item !== tag))}\n          removeLabel={`Remover filtro ${tag}`}\n        >\n          {tag}\n        </AppTag>\n      ))}\n      {tags.length === 0 && (\n        <AppButton size=\"sm\" appearance=\"soft\" onClick={() => setTags(CATEGORIAS)}>\n          Restaurar filtros\n        </AppButton>\n      )}\n    </div>\n  )\n};","description":"Filtros removíveis de prêmios.","exportName":"Tags","tags":["dev","test","manifest","play-fn"]},{"id":"vitrine--feedback","name":"Feedback","snippet":"const Feedback = function Render() {\n  const [modalOpen, setModalOpen] = useState(false)\n  const [toast, setToast] = useState(false)\n  return (\n    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center' }}>\n      <AppButton appearance=\"outline\" onClick={() => setModalOpen(true)}>\n        Ver regulamento\n      </AppButton>\n      <AppButton leadingIcon={<IconConfirmationNumber size={20} />} onClick={() => setToast(true)}>\n        Gerar número da sorte\n      </AppButton>\n      <AppModal\n        isOpen={modalOpen}\n        onClose={() => setModalOpen(false)}\n        title=\"Regulamento da promoção\"\n        footer={<AppButton onClick={() => setModalOpen(false)}>Li e aceito</AppButton>}\n      >\n        <p style={{ margin: 0 }}>\n          Participam pessoas físicas maiores de 18 anos, residentes no Brasil, que cadastrarem cupons fiscais de\n          compras dos produtos participantes durante o período da campanha.\n        </p>\n      </AppModal>\n      {toast && (\n        <AppToast type=\"success\" message=\"Seu número da sorte é 04.512.887\" onDismiss={() => setToast(false)} />\n      )}\n    </div>\n  )\n};","description":"Regulamento em modal e aviso em toast.","exportName":"Feedback","tags":["dev","test","manifest","play-fn"]},{"id":"vitrine--pagamento","name":"Pagamento","snippet":"const Pagamento = () => (\n  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, justifyContent: 'center' }}>\n    {METODOS.map((method) => (\n      <AppPaymentIcon key={method} method={method} size=\"lg\" />\n    ))}\n  </div>\n);","description":"Bandeiras aceitas no checkout da campanha.","exportName":"Pagamento","tags":["dev","test","manifest"]},{"id":"vitrine--carregando","name":"Carregando","snippet":"const Carregando = () => (\n  <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', gap: 16, justifyContent: 'center' }}>\n    <AppSpinner size=\"lg\" label=\"Sorteando\" />\n    <AppButton isLoading>Enviando cupom</AppButton>\n  </div>\n);","description":"Estados de carregamento: spinner e botão enviando.","exportName":"Carregando","tags":["dev","test","manifest"]},{"id":"vitrine--botoes","name":"Botoes","snippet":"const Botoes = () => (\n  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, justifyContent: 'center', maxWidth: 420 }}>\n    <AppButton>Quero participar</AppButton>\n    <AppButton tone=\"secondary\">Regulamento</AppButton>\n    <AppButton appearance=\"outline\">Ganhadores</AppButton>\n    <AppButton appearance=\"soft\">Meus cupons</AppButton>\n    <AppButton tone=\"success\" appearance=\"soft\">Cupom válido</AppButton>\n    <AppButton appearance=\"link\">Dúvidas frequentes</AppButton>\n  </div>\n);","description":"Tons e aparências do botão mais usados numa campanha.","exportName":"Botoes","tags":["dev","test","manifest"]}],"import":"import { AppButton, AppModal, AppPagination, AppPaymentIcon, AppSpinner, AppTag, AppToast } from '@handsondigital/idplugger-ui';\nimport { IconConfirmationNumber, IconLocalOffer } from '@handsondigital/idplugger-ui/icons';","title":"Vitrine"},"foundations-ícones":{"id":"foundations-ícones","name":"IconCheck","path":"./src/icons/Icons.stories.tsx","jsDocTags":{},"error":{"name":"react-docgen-typescript found no component docs","message":"File: dist/icons/es/index.mjs\nreact-docgen-typescript did not return any component docs for this file."},"stories":[{"id":"foundations-ícones--default","name":"Default","snippet":"const Default = () => <IconCheck size={24} />;","exportName":"Default","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-ícones--sizes","name":"Sizes","snippet":"const Sizes = () => (\n  <div style={{ display: 'flex', alignItems: 'center', gap: 16 }}>\n    <IconCheck size={16} />\n    <IconCheck size={20} />\n    <IconCheck size={24} />\n    <IconCheck size=\"2rem\" />\n  </div>\n);","exportName":"Sizes","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-ícones--common-icons","name":"Common Icons","snippet":"const CommonIcons = () => (\n  <div style={{ display: 'flex', alignItems: 'center', gap: 16, color: 'var(--color-brand-text)' }}>\n    <IconCheck />\n    <IconClose />\n    <IconMail />\n    <IconSearch />\n    <IconHelpOutline />\n    <IconErrorOutline />\n    <IconArrowDropDown />\n    <IconStar />\n  </div>\n);","exportName":"CommonIcons","tags":["dev","test","manifest","autodocs"]},{"id":"foundations-ícones--accessible-vs-decorative","name":"Accessible Vs Decorative","snippet":"const AccessibleVsDecorative = () => (\n  <p style={{ display: 'flex', alignItems: 'center', gap: 8, margin: 0 }}>\n    <IconStar title=\"Favorito\" />\n    <IconCheck />\n    <span>Participação confirmada</span>\n  </p>\n);","exportName":"AccessibleVsDecorative","tags":["dev","test","manifest","autodocs","play-fn"]},{"id":"foundations-ícones--galeria","name":"Galeria","snippet":"const Galeria = () => <IconGallery />;","exportName":"Galeria","tags":["dev","test","manifest","autodocs","play-fn"]}],"import":"import { AppButton, AppInput } from '@handsondigital/idplugger-ui';\nimport {\n  IconArrowDropDown,\n  IconCheck,\n  IconClose,\n  IconErrorOutline,\n  IconHelpOutline,\n  IconMail,\n  IconSearch,\n  IconStar,\n} from '@handsondigital/idplugger-ui/icons';","title":"Foundations/Ícones"}},"meta":{"docgen":"react-docgen-typescript","durationMs":3290}}