RivoProvider
import { RivoProvider } from '@rivocode/ui'Quando usar
Raiz obrigatória. Sem ele nada tem estilo.
theme: rivocode-dark (padrão), rivocode-light ou system.
density: comfortable (padrão) ou compact, que encolhe todo controle.
scope: global veste a página inteira; local veste só esta árvore e pinta o
fundo, para quando o design system entra num projeto que já existe.
Carrega por dentro o provedor de dica, a fiação de aviso e o container de portal que leva o tema junto. Não monte nenhum deles à mão.
Os tipos do tema
RivoTheme são os dois temas de casa, rivocode-dark e rivocode-light.
RivoThemeSetting é o que a prop theme aceita: os dois de casa, system, ou
o nome do tema de um cliente. RivoResolvedTheme é o tema depois que system
já virou um dos dois.
A união aceita nome livre de propósito. Sem isso, vestir um cliente terminava
num erro de tipo, e o projeto começava escrevendo as no ponto de entrada do
sistema, que é o pior lugar possível para ensinar que casting é normal.
RivoDensity é comfortable ou compact. Os dois tipos aparecem quando a
escolha vem de fora, de uma preferência salva ou da configuração do cliente:
const [theme, setTheme] = useState<RivoThemeSetting>('system')
const density: RivoDensity = usuario.prefereCompacto ? 'compact' : 'comfortable'
<RivoProvider theme={theme} density={density}>
Sentido da escrita
dir="rtl" espelha o que depende de lado: qual seta abre o submenu, para onde o
Select alinha, de onde a folha lateral entra e para onde o gesto de fechar
vai. O provider escreve o dir no elemento raiz e no container de portal, então
o que renderiza em portal também vira.
O layout continua com você, e pelas classes lógicas do Tailwind: ps-* e pe-*
no lugar de pl-* e pr-*, text-start no lugar de text-left. Componente
espelhado dentro de página que ainda mede da esquerda fica pior do que página
inteira sem espelhar nenhum.
Ler o que o provider decidiu
useRivoContext() devolve o tema já resolvido, a densidade e o container de
portal. Serve para a tela que precisa concordar com a escolha (o logotipo que
troca entre claro e escuro, o mapa de terceiro que recebe a cor por prop, o
portal de uma peça de fora que precisa nascer vestida):
const { theme, density, portalContainer } = useRivoContext()
Fora do provider ele lança erro, com o nome do provider na mensagem. É de propósito: o silêncio aqui vira uma tela sem estilo que ninguém sabe explicar.
No React Native
Traduz, e ganha uma prop que no web não existe: fonts. No navegador as três famílias chegam pelo CSS de tokens; no celular não há CSS de fonte, e carregar arquivo de fonte é decisão do app, não da biblioteca. O app carrega com o expo-font e declara os nomes uma vez (<RivoProvider fonts={{ sans: 'Manrope', display: 'Poppins', mono: 'JetBrainsMono' }}>), e o catálogo inteiro passa a vesti-los. Sem a prop, tudo sai na fonte do sistema e nada quebra. Passe junto o isFontLoaded={isLoaded} do expo-font: nome de fonte ausente falha calado no React Native, e é esse retorno que faz o provider avisar em __DEV__.
density não existe aqui, e não é omissão de paridade. Alvo de toque não encolhe em tela de dedo: comfortable é a única altura, e a prop saiu da API.
E theme troca a tela inteira apenas entre os dois temas de casa. rivocode-dark, rivocode-light e system trocam no mesmo quadro, porque as cores foram compiladas como light-dark() e o provider só gira o esquema do Appearance. Tema de cliente não troca cor de classe nenhuma em runtime: o compilador do react-native-css crava o hex dentro da regra (.bg-accent vira {"backgroundColor":"#d4f34a"}, literal), e nos 56 KB de CSS compilado não sobra uma ocorrência de --. Não existe variável viva para redefinir depois do build.
O mapa de tema saiu do provider. Ele alcançava só quem lê cor por JS - ChartDonut, ChartRadial, o giro do Button, o trilho do Switch -, e saía donut de um tema e botão de outro, lado a lado. Uma metade que discorda da outra é pior do que nenhuma: o provider passou a resolver os 45 papéis lendo o CSS compilado, uma classe bg- por papel, então contexto e classe dizem sempre a mesma cor. A releitura acontece inclusive quando o app declara o esquema dentro de um efeito, depois da montagem - antes disso a paleta era lida uma vez e congelava, e saía meia tela num esquema e meia no outro. Com o mapa sem função, ele foi removido: theme aceita só rivocode-dark, rivocode-light e system, e a prop scheme saiu junto, porque era ela que escolhia o esquema do mapa.
O caminho que funciona é o CSS do app, antes de compilar - e agora ele veste a tela inteira, gráfico incluído: sobrescreva os papéis num @theme do seu global.css, depois do @rivocode/ui-native/theme.css, e rode npx rivocode-ui-native-css de novo. Ele tem um teto de arquitetura: light-dark() tem duas vagas, então são dois temas por build, um claro e um escuro. Um app de um cliente cabe folgado; uma vitrine de cinco temas, como a do web, pede cinco bundles. O guia de temas tem o passo a passo.
API
| Prop | Tipo |
|---|---|
density0.4.0 | RivoDensity |
dir0.4.0Sentido da escrita. | "ltr" | "rtl" |
scope0.4.0`global` veste a pagina inteira, para projeto novo. | "global" | "local" |
theme0.4.0`system` segue a preferencia do sistema operacional. | RivoThemeSetting |
toastPosition0.4.0Em que canto os avisos aparecem. | ToastPosition |
Além destas, a peça aceita className, style, id e children, repassados ao elemento de baixo.
Esta peça ainda não tem exemplo que roda: a prosa e a tabela de props abaixo são o que existe hoje. É uma lacuna nossa, e não uma característica dela.