npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

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

About

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

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

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

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

Open Software & Tools

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

© 2025 – Pkg Stats / Ryan Hefner

@cursosactive/p360-new-ui

v1.0.63

Published

<div align="center">

Readme

P360 New UI

Uma biblioteca de componentes React moderna e acessível, construída com TypeScript, Vite e Chakra UI.

React TypeScript Chakra UI

✨ Introdução

A P360 New UI é uma biblioteca de componentes React que implementa o sistema de design da plataforma P360. Desenvolvida com TypeScript, Vite e Chakra UI, oferece componentes consistentes, acessíveis e altamente personalizáveis para acelerar o desenvolvimento de interfaces.

Principais características:

  • ✅ Totalmente tipada com TypeScript
  • ✅ Construída sobre o Chakra UI (já incluído)
  • ✅ Sistema de temas customizável
  • ✅ Documentação com Storybook
  • ✅ Componentes acessíveis por padrão
  • ✅ Fácil customização e extensão

🚀 Como executar o Storybook

O Storybook permite visualizar e testar todos os componentes disponíveis:

# Clone o repositório
git clone [email protected]:paciente360/p360-new-ui.git

# Acesse a pasta do projeto
cd p360-new-ui

# Instale as dependências
npm install

# Execute o Storybook
npm run storybook

O Storybook estará disponível em http://localhost:6006.

📦 Instalação via NPM

Para instalar a biblioteca em seu projeto:

npm install @cursosactive/p360-new-ui

Configuração necessária

Como a biblioteca utiliza o Chakra UI, você precisa envolver sua aplicação com o ChakraProvider. Além disso, para que o useToast funcione corretamente, você também precisa colocá-lo em sua aplicação.

// main.tsx ou App.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import { ChakraProvider } from '@cursosactive/p360-new-ui'
import { theme } from "@cursosactive/p360-new-ui";
import { customToaster as Toaster } from "@cursosactive/p360-new-ui";
import App from './App'

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <React.StrictMode>
    <ChakraProvider value={theme}>
      <App />
      <Toaster />
    </ChakraProvider>
  </React.StrictMode>
)

🎨 Sobre o Chakra UI

Esta biblioteca já inclui o Chakra UI e estende seus componentes com a identidade visual do produto P360. Todos os componentes são construídos sobre a base sólida do Chakra, o que significa que você pode usar todas as propriedades de estilização e temas do Chakra UI.

📚 Consulte a documentação oficial do Chakra UI para conhecer todos os componentes base e suas propriedades.


📚 Documentação dos Componentes

🏷️ Badge

O componente Badge é utilizado para exibir informações em formato de etiqueta, podendo conter texto e ícone opcional.

Importação

import { CustomBadge as Badge } from '@cursosactive/p360-new-ui';
import { SomeIcon } from 'lucide-react'; // Exemplo de ícone

Uso Básico

// Badge simples
<Badge text="Novo" />

// Badge com ícone
<Badge text="Completo" icon={<CheckIcon />} />

// Badge com clique no ícone
<Badge 
  text="Remover" 
  icon={<XIcon />} 
  onIconClick={() => console.log('Ícone clicado')} 
/>

// Badge com variantes
<Badge text="Outline" variant="outline" />
<Badge text="Subtle" variant="subtle" />

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | text | string | - | Obrigatório. Texto exibido no badge | | icon | React.ReactNode | undefined | Ícone opcional à esquerda do texto | | variant | "solid" \| "outline" \| "subtle" | "solid" | Variante visual do badge | | onIconClick | () => void | undefined | Callback executado ao clicar no ícone | | ...FlexProps | FlexProps | - | Todas as props do Chakra UI Flex |

Variantes Visuais

  • solid: Fundo laranja com texto preto (padrão)
  • outline: Borda vermelha com texto vermelho, fundo transparente
  • subtle: Fundo verde claro com texto verde escuro

Estilização Adicional

O componente aceita todas as props de estilização do Chakra UI Flex, permitindo customização completa:

<Badge 
  text="Customizado" 
  bg="purple.500" 
  color="white"
  borderRadius="full"
  px={4}
  py={2}
/>

🎯 Button

O componente Button é um botão personalizável com suporte a múltiplas variantes, tamanhos e ícones.

Importação

import { CustomButton as Button } from '@cursosactive/p360-new-ui';
import { PlusIcon } from 'lucide-react';

Uso Básico

// Botão sólido (padrão)
<Button>Clique aqui</Button>

// Botão com ícone
<Button icon={PlusIcon}>Adicionar</Button>

// Botão apenas com ícone
<Button icon={PlusIcon} aria-label="Adicionar" />

// Variantes
<Button variant="outline">Outline</Button>
<Button variant="subtle">Subtle</Button>
<Button variant="ghost">Ghost</Button>

// Tamanhos
<Button size="sm">Pequeno</Button>
<Button size="md">Médio (padrão)</Button>
<Button size="lg">Grande</Button>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | variant | "solid" \| "outline" \| "subtle" \| "ghost" | "solid" | Variante visual do botão | | size | "sm" \| "md" \| "lg" | "md" | Tamanho do botão | | icon | ComponentType<LucideProps> | undefined | Componente de ícone do Lucide | | ...ChakraButtonProps | ButtonProps | - | Todas as props do Chakra Button |

Variantes Visuais

  • solid: Fundo azul com texto branco (primário)
  • outline: Borda azul com texto azul, fundo transparente
  • subtle: Fundo azul claro com texto azul escuro
  • ghost: Apenas texto azul, underline no hover

Tamanhos

| Tamanho | Padding Horizontal | Padding Vertical | Tamanho da Fonte | Tamanho do Ícone | |---------|-------------------|------------------|------------------|------------------| | sm | 16px (4) | 8px (2) | sm (14px) | 16px | | md | 24px (6) | 12px (3) | md (16px) | 18px | | lg | 32px (8) | 16px (4) | lg (18px) | 20px |

Estados

O botão inclui estilos automáticos para estados de hover, focus e disabled:

<Button isDisabled>Desabilitado</Button>
<Button isLoading>Carregando...</Button>

🃏 Card

O componente Card é um container versátil para agrupar conteúdo relacionado.

Importação

import { CustomCard as Card } from '@cursosactive/p360-new-ui';

Uso Básico

// Card básico
<Card>
  <Heading size="md">Título do Card</Heading>
  <Text>Conteúdo do card aqui</Text>
</Card>

// Card elevado
<Card variant="elevated">
  Conteúdo com sombra
</Card>

// Card com hover personalizado
<Card 
  hover 
  hoverStyles={{ bg: 'gray.50', transform: 'translateY(-2px)' }}
>
  Card com efeito hover
</Card>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | variant | "elevated" \| "flat" | "flat" | Variante visual do card | | hover | boolean | true | Habilita efeitos hover | | hoverStyles | BoxProps | undefined | Estilos customizados para hover | | ...BoxProps | BoxProps | - | Todas as props do Chakra Box |

Variantes Visuais

  • elevated: Fundo branco com sombra suave (box-shadow)
  • flat: Fundo branco com borda cinza (padrão)

Efeitos Hover

Por padrão, o card não aplica estilos especiais no hover, mas você pode habilitar e customizar:

// Hover padrão (sem estilos específicos)
<Card hover>Card com hover</Card>

// Hover customizado
<Card 
  hover 
  hoverStyles={{ 
    bg: 'blue.50', 
    borderColor: 'blue.200',
    transform: 'scale(1.02)',
    transition: 'all 0.2s'
  }}
>
  Card com hover personalizado
</Card>

Customização

O card aceita todas as props de estilização do Chakra UI Box:

<Card
  p={6}
  bg="gray.50"
  borderWidth="2px"
  borderColor="blue.300"
  borderRadius="xl"
>
  Card completamente customizado
</Card>

🏠 Header

O componente Header é um cabeçalho fixo para aplicações, com sombra e estilo consistente.

Importação

import { CustomHeader as Header } from '@cursosactive/p360-new-ui';

Uso Básico

// Header básico
<Header>
  <Text>Logo</Text>
  <Button>Menu</Button>
</Header>

// Header com padding customizado
<Header padding="24px">
  Conteúdo do header
</Header>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | padding | string | "16px" | Espaçamento interno do header | | ...BoxProps | BoxProps | - | Todas as props do Chakra Box |

Características

  • Posição fixa no topo
  • Fundo branco com sombra suave
  • Display flex com espaço entre os elementos
  • Border bottom sutil para separação visual

Customização

<Header
  padding="20px"
  bg="blue.600"
  color="white"
  boxShadow="md"
>
  Header customizado
</Header>

⌨️ Input

O componente Input é um campo de entrada de texto com validação integrada e máscaras para diversos formatos.

Importação

import { CustomInput as Input } from '@cursosactive/p360-new-ui';
import type { InputRef } from '@cursosactive/p360-new-ui';

Uso Básico

// Input básico
<Input
  label="Nome"
  value={name}
  onChange={setName}
/>

// Input com validação
<Input
  label="Email"
  variant="email"
  value={email}
  onChange={setEmail}
  required
/>

// Input com máscara
<Input
  label="CPF"
  variant="cpf"
  value={cpf}
  onChange={setCpf}
  placeholder="000.000.000-00"
/>

// Input de busca
<Input
  variant="search"
  placeholder="Buscar..."
  value={search}
  onChange={setSearch}
/>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | label | string | undefined | Rótulo do campo | | variant | "text" \| "email" \| "cpf" \| "date" \| "search" \| "password" \| "number" \| "phone" | "text" | Tipo de entrada com validação específica | | value | string | - | Obrigatório. Valor do campo | | onChange | (value: string) => void | - | Obrigatório. Callback de mudança | | required | boolean | false | Se o campo é obrigatório | | showAsterisk | boolean | true | Mostrar asterisco em campos obrigatórios | | errorMessage | string \| null | undefined | Mensagem de erro customizada | | containerProps | BoxProps | undefined | Props do container | | placeholder | string | undefined | Texto placeholder |

Variantes com Máscaras

  • cpf: 000.000.000-00
  • date: 00/00/0000
  • phone: (00) 00000-0000
  • number: Apenas números

Validação Automática

O input inclui validação automática baseada no variant:

// Validação de email
<Input variant="email" value={email} onChange={setEmail} />

// Validação de CPF
<Input variant="cpf" value={cpf} onChange={setCpf} />

// Validação de data
<Input variant="date" value={date} onChange={setDate} />

Ref e Validação Programática

const inputRef = useRef<InputRef>(null);

// Validar campo
const isValid = inputRef.current?.validate();

// Verificar se está vazio
const isEmpty = inputRef.current?.isEmpty();

<Input ref={inputRef} label="Email" variant="email" value={email} onChange={setEmail} />

📋 Datalist

O componente Datalist é um campo de entrada com sugestões em tempo real, no qual você pode filtrar as opções e exibir conforme o usuário digita.

Importação

import { CustomDatalist as Datalist } from '@cursosactive/p360-new-ui';

Uso Básico

// Datalist básico
<Datalist
  value={value}
  onChange={setValue}
  options={options}
/>

// Com label e placeholder
<Datalist
  label="Frutas"
  placeholder="Digite para buscar..."
  value={value}
  onChange={setValue}
  options={fruitsOptions}
/>

// Com validação obrigatória
<Datalist
  label="Seleção Obrigatória"
  placeholder="Escolha uma opção"
  value={value}
  onChange={setValue}
  options={options}
  required
  errorMessage={error}
/>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | value | string | - | Obrigatório. Valor atual do campo | | onChange | (value: string) => void | - | Obrigatório. Callback quando o valor muda | | options | Option[] | - | Obrigatório. Array de opções para sugestões | | label | string | undefined | Label do campo | | placeholder | string | undefined | Placeholder do input | | errorMessage | string \| null | undefined | Mensagem de erro abaixo do campo | | required | boolean | false | Indica se o campo é obrigatório | | showAsterisk | boolean | true | Mostra asterisco vermelho quando required é true | | w | BoxProps["w"] | "100%" | Largura do componente | | containerProps | BoxProps | undefined | Props adicionais para o container | | ...Field.Root props | FieldProps | - | Todas as props do Chakra UI Field |

Tipo Option

interface Option {
  value: string;    // Valor único da opção
  label: string;    // Texto exibido para o usuário
}

Comportamento

  • Sugestões em tempo real: Mostra até 5 opções filtradas conforme digitação
  • Fechamento automático: A lista de sugestões fecha ao clicar fora ou selecionar uma opção
  • Validação integrada: Exibe mensagem de erro quando fornecido
  • Focus/Blur: Gerencia automaticamente a visibilidade das sugestões

Estilização

O componente herda todos os estilos do Chakra UI Field e Input, permitindo customização:

<Datalist
  label="Customizado"
  value={value}
  onChange={setValue}
  options={options}
  // Estilos do container
  containerProps={{
    bg: "gray.50",
    p: 4,
    borderRadius: "lg"
  }}
/>

Exemplo Completo

const [selectedFruit, setSelectedFruit] = useState("");
const fruits = [
  { value: "apple", label: "Maçã" },
  { value: "banana", label: "Banana" },
  { value: "orange", label: "Laranja" }
];

<Datalist
  label="Fruta Favorita"
  placeholder="Digite o nome da fruta..."
  value={selectedFruit}
  onChange={setSelectedFruit}
  options={fruits}
  required
  errorMessage={!selectedFruit ? "Selecione uma fruta" : null}
/>

Observações

  • As sugestões são case-insensitive (não diferenciam maiúsculas/minúsculas)
  • Máximo de 5 sugestões exibidas simultaneamente
  • Compatível com acessibilidade (ARIA)
  • Integrado com o sistema de temas do Chakra UI

🪟 Modal

O componente Modal é uma janela modal overlay com controles de ação e fechamento.

Importação

import { CustomModal as Modal } from '@cursosactive/p360-new-ui';

Uso Básico

// Modal básico
<Modal isOpen={isOpen} onClose={onClose}>
  <Text>Conteúdo do modal</Text>
</Modal>

// Modal com título e ações
<Modal
  isOpen={isOpen}
  onClose={onClose}
  title="Confirmação"
  successButtonText="Confirmar"
  cancelButtonText="Cancelar"
  onButtonClick={(type) => console.log(type)}
>
  <Text>Tem certeza que deseja excluir?</Text>
</Modal>

// Modal simples sem footer
<Modal
  isOpen={isOpen}
  onClose={onClose}
  variant="simple"
>
  <Text>Modal sem botões de ação</Text>
</Modal>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | isOpen | boolean | - | Obrigatório. Controla a visibilidade do modal | | onClose | () => void | - | Obrigatório. Callback de fechamento | | title | string | undefined | Título do modal | | maxW | string | "xl" | Largura máxima do modal | | successButtonText | string | "Confirm" | Texto do botão de sucesso | | cancelButtonText | string | "Cancel" | Texto do botão de cancelamento | | onButtonClick | (type: "success" \| "cancel") => void | undefined | Callback de clique nos botões | | variant | "action" \| "simple" | "action" | Variante com ou sem botões de ação |

Comportamento

  • Overlay escuro semi-transparente
  • Fechamento ao clicar fora do modal ou no botão ×
  • Scroll automático para conteúdo longo
  • Portal para evitar problemas de z-index

Customização de Tamanho

<Modal isOpen={isOpen} onClose={onClose} maxW="4xl">
  Conteúdo largo
</Modal>

<Modal isOpen={isOpen} onClose={onClose} maxW="md">
  Conteúdo estreito
</Modal>

🧭 Navbar

O componente Navbar é uma barra de navegação horizontal com items selecionáveis.

Importação

import { CustomNavbar as Navbar } from '@cursosactive/p360-new-ui';
import type { NavbarOption } from '@cursosactive/p360-new-ui';

Uso Básico

const options: NavbarOption[] = [
  { id: 'home', label: 'Início' },
  { id: 'about', label: 'Sobre' },
  { id: 'contact', label: 'Contato' },
];

<Navbar options={options} onItemSelect={(id) => console.log(id)} />

// Navbar com ícones
const optionsWithIcons: NavbarOption[] = [
  { id: 'home', label: 'Início', iconStart: <HomeIcon /> },
  { id: 'settings', label: 'Configurações', iconEnd: <SettingsIcon /> },
];

<Navbar options={optionsWithIcons} />

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | options | NavbarOption[] | - | Obrigatório. Array de opções de navegação | | defaultSelectedId | string | undefined | ID da opção selecionada por padrão | | onItemSelect | (id: string) => void | undefined | Callback de seleção de item | | gap | number \| string | 4 | Espaçamento entre os items | | ...StackProps | StackProps | - | Todas as props do Chakra Stack |

Tipo NavbarOption

interface NavbarOption {
  id: string;
  label: string;
  disabled?: boolean;
  iconStart?: React.ReactNode;
  iconEnd?: React.ReactNode;
}

Estados Visuais

  • Selecionado: Cor azul com borda inferior
  • Hover: Efeito de hover suave
  • Disabled: Opacidade reduzida e cursor não permitido

Customização

<Navbar
  options={options}
  gap={6}
  padding={4}
  bg="gray.50"
  borderRadius="md"
/>

❓ NotFound

O componente NotFound é uma página de erro 404 padrão com opção de retorno.

Importação

import { CustomNotFound as NotFound } from '@cursosactive/p360-new-ui';

Uso Básico

// NotFound básico
<NotFound />

// NotFound customizado
<NotFound
  title="Página não encontrada"
  description="Não foi possível encontrar o que você procura."
  buttonText="Voltar para o início"
  onButtonClick={() => navigate('/')}
/>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | title | string | "404" | Título da página | | description | string | "This page was not found!" | Descrição do erro | | buttonText | string | "Back to Home" | Texto do botão | | onButtonClick | () => void | undefined | Callback do botão |

Layout

  • Centralizado vertical e horizontalmente
  • Fundo cinza claro
  • Tipografia em tons de cinza
  • Botão de ação centralizado

Customização

O componente é geralmente usado como página completa, mas pode ser customizado via props:

<NotFound
  title="Conteúdo indisponível"
  description="Este conteúdo não está mais disponível ou não existe."
  buttonText="Voltar"
  onButtonClick={handleBack}
/>

📋 Select

O componente Select é um dropdown de seleção com acessibilidade e validação.

Importação

import { CustomSelect as Select } from '@cursosactive/p360-new-ui';

Uso Básico

const options = [
  { value: 'option1', label: 'Opção 1' },
  { value: 'option2', label: 'Opção 2' },
  { value: 'option3', label: 'Opção 3' },
];

// Select básico
<Select
  label="Selecione uma opção"
  options={options}
  value={selected}
  onChange={setSelected}
/>

// Select com validação
<Select
  label="Categoria"
  options={options}
  value={category}
  onChange={setCategory}
  required
  errorMessage={error}
/>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | label | string | undefined | Rótulo do select | | placeholder | string | undefined | Texto placeholder | | value | string | - | Obrigatório. Valor selecionado | | onChange | (value: string) => void | - | Obrigatório. Callback de mudança | | options | Option[] | - | Obrigatório. Array de opções | | errorMessage | string \| null | undefined | Mensagem de erro | | required | boolean | false | Se o campo é obrigatório | | showAsterisk | boolean | true | Mostrar asterisco em campos obrigatórios | | w | BoxProps["w"] | "100%" | Largura do componente | | containerProps | BoxProps | undefined | Props do container |

Tipo Option

interface Option {
  value: string;
  label: string;
}

Características

  • Acessível com teclado
  • Scroll automático para muitas opções
  • Validação integrada
  • Estilo consistente com a identidade visual

Customização

<Select
  label="País"
  options={countries}
  value={country}
  onChange={setCountry}
  w="300px"
  containerProps={{ mt: 8 }}
  placeholder="Selecione um país"
/>

📚 Sidebar

O componente Sidebar é uma barra lateral colapsável para navegação.

Importação

import { CustomSidebar as Sidebar } from '@cursosactive/p360-new-ui';

Uso Básico

// Sidebar básico
<Sidebar>
  <Text>Conteúdo da sidebar</Text>
</Sidebar>

// Sidebar controlada
<Sidebar
  collapsed={isCollapsed}
  onCollapseChange={setIsCollapsed}
>
  <NavigationMenu />
</Sidebar>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | initialCollapsed | boolean | false | Estado inicial colapsado | | width | string | "220px" | Largura expandida | | collapsedWidth | string | "60px" | Largura colapsada | | padding | string | "20px 16px" | Espaçamento interno | | collapsed | boolean | undefined | Estado controlado colapsado | | onCollapseChange | (collapsed: boolean) => void | undefined | Callback de mudança de estado | | collapseButtonText | string | "Collapse" | Texto do botão de colapso | | ...HTMLAttributes | HTMLAttributes | - | Props HTML padrão |

Comportamento

  • Transição suave de 300ms
  • Botão de colapso/expandir no rodapé
  • Scroll vertical para conteúdo longo
  • Posição fixa à esquerda

Modo Controlado vs Não Controlado

// Modo não controlado (gerencia estado interno)
<Sidebar initialCollapsed={false}>
  Conteúdo
</Sidebar>

// Modo controlado (estado gerenciado externamente)
<Sidebar
  collapsed={isCollapsed}
  onCollapseChange={setIsCollapsed}
>
  Conteúdo
</Sidebar>

Customização de Dimensões

<Sidebar
  width="280px"
  collapsedWidth="80px"
  padding="24px 20px"
>
  Conteúdo com sidebar larga
</Sidebar>

📝 Textarea

O componente Textarea é um campo de texto multilinha com validação.

Importação

import { CustomTextarea as Textarea } from '@cursosactive/p360-new-ui';
import type { TextareaRef } from '@cursosactive/p360-new-ui';

Uso Básico

// Textarea básico
<Textarea
  label="Descrição"
  value={description}
  onChange={setDescription}
/>

// Textarea com validação
<Textarea
  label="Comentário"
  value={comment}
  onChange={setComment}
  required
  errorMessage={error}
/>

Props

| Prop | Tipo | Padrão | Descrição | |------|------|--------|-----------| | label | string | undefined | Rótulo do textarea | | value | string | - | Obrigatório. Valor do campo | | onChange | (value: string) => void | - | Obrigatório. Callback de mudança | | required | boolean | false | Se o campo é obrigatório | | showAsterisk | boolean | true | Mostrar asterisco em campos obrigatórios | | errorMessage | string \| null | undefined | Mensagem de erro | | containerProps | BoxProps | undefined | Props do container |

Ref e Validação Programática

const textareaRef = useRef<TextareaRef>(null);

// Validar campo
const isValid = textareaRef.current?.validate();

// Verificar se está vazio
const isEmpty = textareaRef.current?.isEmpty();

<Textarea
  ref={textareaRef}
  label="Mensagem"
  value={message}
  onChange={setMessage}
  required
/>

Características

  • Altura mínima de 100px
  • Redimensionamento vertical
  • Validação de campo obrigatório
  • Estilo consistente com Input

Customização

<Textarea
  label="Observações"
  value={notes}
  onChange={setNotes}
  containerProps={{ mt: 6, mb: 6 }}
  minH="150px"
/>

🪝 Hooks Utilitários

useIsMobile

Hook para detectar responsivamente se a tela está em modo mobile com base no breakpoint.

Importação

import { customUseIsMobile as useIsMobile } from '@cursosactive/p360-new-ui';

Uso Básico

const isMobile = useIsMobile();

return (
  <div>
    {isMobile ? (
      <Text>Modo Mobile</Text>
    ) : (
      <Text>Modo Desktop</Text>
    )}
  </div>
);

Comportamento

  • Breakpoint: 768px (define mobile como width < 768px)
  • Estado inicial: undefined até a primeira medição ser concluída
  • Atualização automática: Atualiza quando a janela é redimensionada
  • Valor retornado: boolean (true para mobile, false para desktop)

Exemplo de Uso Condicional

const isMobile = useIsMobile();

return (
  <Box>
    {isMobile === undefined ? (
      <Spinner size="sm" />
    ) : isMobile ? (
      <MobileNavigation />
    ) : (
      <DesktopNavigation />
    )}
  </Box>
);

Características

  • SSR Compatible: Retorna undefined durante a renderização inicial no servidor
  • Performance: Usa Media Query Listeners nativos
  • Cleanup: Remove event listeners automaticamente

useToast

Hook para exibir notificações toast com diferentes tipos e estilos.

Importação

import { customUseToast as useToast } from '@cursosactive/p360-new-ui';
import type { ToastOptions } from '@cursosactive/p360-new-ui';

Uso Básico

const toast = useToast();

// Toast de sucesso
toast.success({
  title: 'Sucesso!',
  description: 'Operação concluída com sucesso.',
});

// Toast de erro
toast.error({
  title: 'Erro',
  description: 'Algo deu errado.',
});

// Toast de carregamento
toast.loading({
  title: 'Processando...',
  description: 'Aguarde um momento.',
});

Métodos Disponíveis

| Método | Descrição | Tipo | |--------|-----------|------| | success | Toast de sucesso (verde) | (options: ToastOptions) => void | | error | Toast de erro (vermelho) | (options: ToastOptions) => void | | info | Toast informativo (azul) | (options: ToastOptions) => void | | loading | Toast de carregamento (cinza) | (options: ToastOptions) => void | | create | Toast customizado com tipo específico | (options: ToastCreateOptions) => void | | dismiss | Fechar toast específico ou todos | (id?: string) => void |

Tipo ToastOptions

interface ToastOptions {
  title?: string;
  description?: string;
  duration?: number;
  placement?: 'top-start' | 'top' | 'top-end' | 'bottom-start' | 'bottom' | 'bottom-end';
  // ... outras props do Chakra UI Toast
}

Exemplos Avançados

const toast = useToast();

// Toast com duração customizada
toast.success({
  title: 'Customizado',
  description: 'Este toast ficará visível por 10 segundos',
  duration: 10000, // 10 segundos
});

// Toast com posicionamento específico
toast.info({
  title: 'Informação',
  description: 'Toast no canto superior direito',
  placement: 'top-end',
});

// Fechar toasts programaticamente
const handleClose = () => {
  toast.dismiss(); // Fecha todos
  toast.dismiss('specific-toast-id'); // Fecha específico
};

Opções Comuns

  • duration: Tempo em milissegundos que o toast ficará visível (padrão: 5000ms)
  • placement: Posição na tela (padrão: 'bottom')
  • isClosable: Se mostra botão de fechar (padrão: true)

Integração com Operações Assíncronas

const toast = useToast();

const handleSubmit = async () => {
  const loadingToast = toast.loading({
    title: 'Enviando dados...',
    description: 'Por favor, aguarde.',
  });

  try {
    await api.submitData(data);
    toast.success({
      title: 'Sucesso!',
      description: 'Dados enviados com sucesso.',
    });
  } catch (error) {
    toast.error({
      title: 'Erro',
      description: 'Falha ao enviar dados.',
    });
  } finally {
    toast.dismiss(loadingToast);
  }
};

🎨 Personalização e Temas

Todos os componentes herdam o tema do Chakra UI e podem ser customizados através do tema da aplicação:

// Exemplo de customização do tema
const theme = extendTheme({
  components: {
    Button: {
      baseStyle: {
        borderRadius: 'lg',
      },
    },
    Card: {
      baseStyle: {
        container: {
          boxShadow: 'md',
        },
      },
    },
  },
});

<ChakraProvider theme={theme}>
  <App />
</ChakraProvider>

🤝 Contribuição

Para contribuir com a biblioteca:

  1. Faça fork do repositório
  2. Crie uma branch para sua feature (git checkout -b new-feature)
  3. Commit suas mudanças (git commit -m 'Add some Feature')
  4. Push para a branch (git push origin new-feature)
  5. Abra um Pull Request