Explore as categorias reais de tokens da v5 e os temas azuis claro e escuro do Tamagui em um painel completo de hábitos com componentes nativos, validação, progresso e recuperação para estados vazios.
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
size.$2
28
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
size.$3
36
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
size.$4
44
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
size.$5
52
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
size.$6
64
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$1.5
4
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$2
7
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$2.5
10
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$3
13
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$3.5
16
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$4
18
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$5
24
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
space.$6
32
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
radius.1
3
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
radius.2
5
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
radius.3
7
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
radius.4
9
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
radius.5
10
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
radius.6
16
Valor real da configuração v5. O mesmo rótulo numérico de token tem significados diferentes para tamanho, espaço e raio; não trate $4 como um valor universal em pixels.
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
light_blue.backgroundHover
hsla(210, 100%, 99%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
light_blue.backgroundPress
hsla(205, 92%, 95%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
light_blue.color
hsla(216, 71%, 23%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
light_blue.borderColor
hsla(203, 100%, 92%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
light_blue.borderColorFocus
hsla(203, 100%, 92%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
light_blue.placeholderColor
hsla(206, 100%, 50%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
dark_blue.backgroundHover
hsla(212, 69%, 16%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
dark_blue.backgroundPress
hsla(215, 42%, 9%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
dark_blue.color
hsla(205, 100%, 88%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
dark_blue.borderColor
hsla(209, 100%, 19%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
dark_blue.borderColorFocus
hsla(209, 100%, 19%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
dark_blue.placeholderColor
hsla(206, 100%, 50%, 1)
Função semântica resolvida do tema azul v5. O componente pode selecionar um tema filho mais específico para os estados de passar o cursor, pressionar ou ativo.
Configuração versionada e CSS do sistema de design Tamagui
Use a predefinição v5 identificada
Este exemplo fixa tamagui e @tamagui/config na versão 2.7.7 e importa defaultConfig de @tamagui/config/v5. O nome da configuração é v5; ele não corresponde à versão principal do pacote npm. Confundir esses dois números levaria o leitor a usar o comando de instalação errado. createTamagui é executado uma vez, fora do componente, e o CSS gerado é inserido antes de o painel ser renderizado, para que as variáveis do tema e os estilos nativos tenham uma definição real na web.
Deixe explícita a pequena substituição de configuração
O código-fonte fornecido define onlyAllowShorthands como false porque este exemplo didático usa propriedades por extenso e mais legíveis, como padding e backgroundColor. Essa é uma escolha da aplicação, além do preset. A base v5 não inclui um mecanismo de animação, e este exemplo não inventa um nem afirma oferecer transições animadas. O comportamento simples da barra de progresso e da caixa de seleção funciona sem adicionar uma dependência de animação separada.
Sistema de design Tamagui: tokens de tamanho, espaçamento e raio
Não confunda rótulos de tokens com o mesmo nome
Na configuração v5 fixada, size $4 é 44, space $4 é 18 e radius 4 é 9. Portanto, não é possível converter o tamanho de um componente, o espaço entre elementos e o raio dos cantos usando uma única regra de multiplicação. A referência lista cada categoria separadamente, e o exemplo usa esses valores específicos de cada categoria em props Tamagui reais. Isso é mais útil do que uma lista de incrementos genéricos de 4 px, que a configuração não utiliza.
size.$4 = 44
space.$4 = 18
radius.4 = 9
fonte do corpo $4 = 15px, com altura da linha de 23px
Mantenha a escala tipográfica separada também
A fonte do corpo $4 tem 15px, com altura da linha de 23px, enquanto o tamanho do componente $4 continua sendo 44. A pilha de fontes do sistema é fornecida pela v5 e não exige o download de nenhuma fonte. H1, H2 e Text recebem seus contextos tipográficos nativos; os valores explícitos de fontSize e lineHeight no código-fonte definem a hierarquia do painel original. A largura externa de 880px é uma escolha de layout local, não um token Tamagui global.
Sistema de design Tamagui: temas semânticos e aparência
Combine um tema claro ou escuro com um tema filho azul
TamaguiProvider recebe o defaultTheme escolhido, e Theme name="blue" resolve o tema filho correspondente. O código-fonte usa os papéis background, backgroundHover, color e borderColor, em vez de repetir valores hexadecimais literais por toda a árvore de componentes. A tabela registra os valores reais de light_blue e dark_blue para que o leitor possa comparar a configuração resolvida, em vez de presumir uma única paleta fixa da marca.
Preserve o estado do painel ao mudar a aparência
A variável dark é independente das linhas, do rascunho do campo de entrada e do filtro. Mudar a aparência atualiza os componentes nativos sem alterar o painel. Botões e caixas de seleção podem escolher os próprios valores de tema filho do componente, então a cor computada deles pode ser diferente do token de fundo do elemento pai. Inspecione o estado renderizado antes de simplificar a hierarquia em CSS personalizados.
Sistema de design Tamagui: caixas de seleção e progresso derivado
Mantenha o estado de conclusão em uma única coleção de linhas
Cada linha tem um ID estável, um texto legível e um booleano done. Checkbox recebe checked e onCheckedChange; somente o valor literal true marca a tarefa como concluída. Checkbox.Indicator exibe a marca de seleção. O texto ao lado e o nome acessível identificam o mesmo hábito, enquanto o tachado reforça visualmente o estado de conclusão. O código-fonte não cria uma contagem separada que possa ficar desatualizada em relação às linhas.
Calcule o progresso com base no painel inteiro
Sistema de design Tamagui: validação de rascunho e recuperação de duplicatas
Adicione um campo de entrada realmente controlado
Input mantém o rascunho atual por meio de value e onChangeText. A ação Add habit remove os espaços em branco no início e no fim e rejeita valores vazios com uma mensagem visível, aria-invalid e uma descrição do erro. Após o envio de um valor vazio, o foco volta para o campo de entrada. Uma verificação de duplicatas que não diferencia maiúsculas de minúsculas impede a criação de outra linha com o mesmo texto e mantém o rascunho disponível para correção. Essas regras pertencem ao painel original, não à biblioteca.
Atualize o painel somente após uma adição válida
Um rascunho válido adiciona uma nova linha incompleta, limpa o campo de entrada e remove o erro. O denominador do progresso muda imediatamente, pois é derivado da nova coleção. Adicionar um hábito não cria um lembrete nem registra uma conta. O painel é mantido deliberadamente no estado local React, e recarregar o documento restaura os dados de exemplo.
Sistema de design Tamagui: visualizações filtradas e recuperação de estados vazios
Deixe claro o escopo do filtro
A opção Show unfinished only oculta as linhas concluídas, mas as mantém na coleção. Quando não há mais nada nessa visualização, um estado vazio com texto explica que a lista completa continua existindo e oferece uma ação direta para voltar a ela. É um estado vazio significativo, causado pelas escolhas do usuário, não um alternador decorativo que troca cartões de exemplo arbitrários.
Mantenha a redefinição separada da aparência
Reset sample board restaura as três linhas iniciais, limpa o rascunho e o erro e volta à lista completa. A aparência atual não muda. Como cada alteração é um estado explícito, redefinir o painel não exige recarregar o documento nem descartar o provider configurado. É possível testar a recuperação do tema e do conteúdo de forma independente.
Sistema de design Tamagui: stacks responsivos e leitura acessível
Deixe o conteúdo das stacks determinar a altura
YStack organiza o fluxo principal de leitura, e XStack alinha os controles do cabeçalho, as linhas com caixas de seleção e as ações. Os grupos de controles se reorganizam em várias linhas em vez de exigir uma largura fixa de desktop. O contêiner externo tem no máximo 880px e usa o token real space $4 para o preenchimento. O texto de cada linha pode encolher e quebrar em várias linhas, enquanto os controles continuam disponíveis em larguras de 280px e maiores.
Teste as interações após a reorganização do layout
O teste no navegador adiciona um hábito, marca-o como concluído, filtra a lista e muda a aparência antes de verificar se há conteúdo excedente. Uma captura de tela apenas do layout inicial não revelaria se um erro, um rótulo longo ou um estado filtrado prejudica a composição estreita. As semânticas nativas da caixa de seleção e o texto visível foram testados junto com o progresso derivado, em vez de se presumir que funcionariam só por estarem presentes.
Sistema de design Tamagui: build completa para o navegador
Forneça o provider, o CSS e as definições de build
Os três arquivos fornecidos bastam para este estudo local na web. O JSX inclui o provider, uma configuração, o tema CSS gerado e o painel completo. build.mjs fixa o destino web e o ambiente de produção, além de fornecer um fallback vazio para process.env, usado por outras leituras de ambiente exclusivas do navegador. Sem essa última definição, este bundle simples pode falhar com process is not defined, mesmo que seja compilado.
Salve tamagui.jsx, build.mjs e index.html juntos.
Instale os pacotes React e Tamagui fixados.
Compile e sirva o diretório local.
Teste adições vazias e duplicadas, conclusão, filtros, tema e redefinição.
Mantenha separadas a adoção nativa e a web
Exemplos de componentes do sistema de design Tamagui
tamagui.jsx
Configuração, CSS gerado, componentes nativos e estado completo do painel.
jsx
import React,{useState} from 'react';import{createRoot}from'react-dom/client';
import{createTamagui,TamaguiProvider,Theme,YStack,XStack,Text,H1,H2,Button,Input,Checkbox,Progress,Separator}from'tamagui';import{defaultConfig}from'@tamagui/config/v5';
const config=createTamagui({...defaultConfig,settings:{...defaultConfig.settings,onlyAllowShorthands:false}});const sheet=document.createElement('style');sheet.textContent=config.getCSS();document.head.append(sheet);
const initial=[{id:1,text:'Read ten pages',done:false},{id:2,text:'Step outside for a break',done:true},{id:3,text:'Write one useful note',done:false}];
function App(){const[dark,setDark]=useState(false),[rows,setRows]=useState(initial),[draft,setDraft]=useState(''),[error,setError]=useState(''),[filter,setFilter]=useState(false);const done=rows.filter(x=>x.done).length;let shown=rows.filter(x=>!filter||!x.done);function add(){let text=draft.trim();if(!text){setError('Write a small habit before adding it.');document.querySelector('#habit-input')?.focus();return}if(rows.some(x=>x.text.toLowerCase()===text.toLowerCase())){setError('That habit is already in this list.');return}setRows([...rows,{id:Date.now(),text,done:false}]);setDraft('');setError('')}return <TamaguiProvider config={config} defaultTheme={dark?'dark':'light'}><Theme name="blue"><YStack backgroundColor="$background" color="$color" padding="$4" gap="$4" maxWidth={880} margin="auto" width="100%" minHeight={0}><XStack justifyContent="space-between" alignItems="center" flexWrap="wrap" gap="$3"><Text fontSize="$2" fontWeight="700">TAMAGUI / ORIGINAL HABIT BOARD</Text><Button size="$3" onPress={()=>setDark(!dark)}>{dark?'Light appearance':'Dark appearance'}</Button></XStack><H1 fontSize="$8" lineHeight="$8">A little progress, every day.</H1><Text fontSize="$4" lineHeight="$5">A local board built with Tamagui 2.7.7 and its v5 blue theme. Your changes stay in this page; no account or daily reminder is connected.</Text><YStack backgroundColor="$backgroundHover" borderWidth={1} borderColor="$borderColor" borderRadius="$4" padding="$4" gap="$3"><XStack justifyContent="space-between" gap="$3" flexWrap="wrap"><H2 fontSize="$5">Today’s small steps</H2><Text id="progress-count" aria-live="polite">{done} of {rows.length} complete</Text></XStack><Progress value={rows.length?done/rows.length*100:0} size="$2" aria-label="Completed habits"><Progress.Indicator animation={undefined}/></Progress><Button size="$3" alignSelf="flex-start" onPress={()=>setFilter(!filter)}>{filter?'Show all habits':'Show unfinished only'}</Button><Separator/>{shown.length?shown.map(row=><XStack key={row.id} gap="$3" alignItems="center" paddingVertical="$2"><Checkbox id={'habit-'+row.id} checked={row.done} onCheckedChange={value=>setRows(rows.map(x=>x.id===row.id?{...x,done:value===true}:x))} aria-label={row.text} size="$4"><Checkbox.Indicator><Text fontWeight="700">✓</Text></Checkbox.Indicator></Checkbox><Text flex={1} fontSize="$4" lineHeight="$5" textDecorationLine={row.done?'line-through':'none'} opacity={row.done?.65:1}>{row.text}</Text></XStack>):<YStack gap="$3"><Text fontWeight="700">Nothing unfinished in this view</Text><Text>All your habits remain in the full list. You can revisit any completed item.</Text><Button onPress={()=>setFilter(false)}>Return to all habits</Button></YStack>}</YStack><YStack gap="$3"><Text htmlFor="habit-input" tag="label" fontWeight="700">Add one small habit</Text><Input id="habit-input" value={draft} onChangeText={v=>{setDraft(v);setError('')}} placeholder="For example, stretch for five minutes" aria-describedby={error?'habit-error':undefined} aria-invalid={!!error} onKeyPress={e=>{if(e.nativeEvent.key==='Enter')add()}}/><Text id="habit-error" color="$color" aria-live="polite">{error}</Text><XStack gap="$3" flexWrap="wrap"><Button theme="active" onPress={add}>Add habit</Button><Button onPress={()=>{setRows(initial);setDraft('');setError('');setFilter(false)}}>Reset sample board</Button></XStack></YStack><Text fontSize="$2" lineHeight="$3">Native Checkbox, Input, Button and Progress components; original board content and state. Theme changes preserve the current board.</Text></YStack></Theme></TamaguiProvider>}
createRoot(document.getElementById('root')).render(<App/>);
Implemente o painel de hábitos completo para web em Tamagui 2.7.7, usando o preset v5. Mantenha distintas as categorias de tokens de tamanho, espaçamento, raio e fonte; preserve o tema CSS gerado, os temas filhos azuis claro/escuro, as caixas de seleção controladas, a validação de espaços em branco e duplicatas, o denominador do progresso baseado em todas as linhas, a recuperação da visualização de itens inacabados e a redefinição sem alterar a aparência.
05
Fontes e escopo do sistema de design Tamagui
Componentes web Tamagui 2.7.7 reais que usam o preset v5. O painel de hábitos e as regras de estado são código OpenDesign original; não há integração com contas, lembretes ou comportamento de dispositivos nativos.