@aurea-uds/native 0.19.1 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { Pressable, View } from "react-native";
3
3
  import { useSafeAreaInsets } from "react-native-safe-area-context";
4
4
  import { useAnotarBottomNav } from "./barranav.js";
5
5
  import { Avatar, Badge } from "./display.js";
6
- import { comOpacidade, criarFolha, estadoAcessivel, fioDoEscolhido } from "./estilos.js";
6
+ import { canto, comOpacidade, criarFolha, estadoAcessivel, fioDoEscolhido } from "./estilos.js";
7
7
  import { Icon } from "./icon.js";
8
8
  import { Card } from "./layout.js";
9
9
  import { FilaRolante } from "./rolagem.js";
@@ -22,7 +22,7 @@ const folha = criarFolha((t) => ({
22
22
  marginHorizontal: t.size.space4, marginTop: t.size.space4,
23
23
  paddingVertical: t.size.space2, paddingHorizontal: t.size.space4,
24
24
  borderWidth: t.size.borderWidth, borderColor: t.color.border,
25
- borderRadius: t.size.radiusCard, backgroundColor: t.color.card,
25
+ ...canto(t.size.radiusCard), backgroundColor: t.color.card,
26
26
  },
27
27
  topo_flush: { paddingVertical: t.size.space2, paddingHorizontal: t.size.space5,
28
28
  backgroundColor: t.color.background },
@@ -35,7 +35,7 @@ const folha = criarFolha((t) => ({
35
35
  alignSelf: "center", marginTop: t.size.space4, justifyContent: "flex-start",
36
36
  gap: t.size.space2, padding: t.size.space2,
37
37
  borderWidth: t.size.borderWidth, borderColor: t.color.border,
38
- borderRadius: t.size.radiusControl, backgroundColor: t.color.card,
38
+ ...canto(t.size.radiusControl), backgroundColor: t.color.card,
39
39
  },
40
40
  // ── BottomNav ──────────────────────────────────────────────────────────────────────────────
41
41
  // 🔴 `floating` FLUTUA POR CIMA DA TELA, e isto é conserto de 19/09/2026 — a variante prometia
@@ -53,14 +53,14 @@ const folha = criarFolha((t) => ({
53
53
  position: "absolute", bottom: 0, zIndex: t.size.zSticky,
54
54
  flexDirection: "row", gap: t.size.space1, margin: t.size.space4, padding: t.size.space1,
55
55
  borderWidth: t.size.borderWidth, borderColor: t.color.border,
56
- borderRadius: t.size.radiusControl, backgroundColor: t.color.card,
56
+ ...canto(t.size.radiusControl), backgroundColor: t.color.card,
57
57
  boxShadow: [t.shadow.shadowMd],
58
58
  },
59
59
  // `edge` encosta na borda: sem margem, sem raio, só a linha de cima — e continua NO FLUXO,
60
60
  // porque uma barra encostada que flutuasse esconderia o fim da tela sem nada reservar.
61
61
  barra_edge: {
62
62
  position: "relative", left: undefined, right: undefined, bottom: undefined, zIndex: undefined,
63
- margin: 0, paddingHorizontal: 0, borderRadius: 0, backgroundColor: t.color.background,
63
+ margin: 0, paddingHorizontal: 0, ...canto(0), backgroundColor: t.color.background,
64
64
  borderWidth: 0, borderTopWidth: t.size.borderWidth, boxShadow: undefined,
65
65
  },
66
66
  // A pílula CHEIA, de uma borda à outra menos a margem — o de sempre. Mora fora da `barra` para
@@ -81,18 +81,18 @@ const folha = criarFolha((t) => ({
81
81
  // `space05` e não `space1` — a barra mais baixa (30/09/2026, pedido do Victor, aprovado pela
82
82
  // imagem). Com a moldura de 32 e o vão de 4 eram 9 entre o ícone e o rótulo; ver `marca`.
83
83
  // O NOME COLADO NO ÍCONE — 03/10/2026, pedido do Victor (*"o texto pode ficar mais próximo do
84
- // ícone"*): vão ZERO, como no Telegram, em que o nome começa onde a caixa do ícone acaba. O
84
+ // ícone"*): vão ZERO, como no app de referência, em que o nome começa onde a caixa do ícone acaba. O
85
85
  // `space05` daqui (30/09/2026) somava 2 aos 2 de folga da própria linha do nome; medido na
86
86
  // bancada, eram 9 de tinta a tinta no `pill` e 13 no `circle-bold`.
87
87
  gap: 0, minHeight: t.size.controlHLg,
88
- // 🔴 A ALTURA DO TELEGRAM — 03/10/2026, pedido do Victor: *"ainda acho ele muito largo
89
- // comparado a bottomnav como do telegram"*, e "largo" é a grossura. Medido no fonte do
90
- // Telegram para Android 12.10.6 (`DialogsActivity.MAIN_TABS_HEIGHT = 56`, `GlassTabView`): a
88
+ // 🔴 A ALTURA DE REFERÊNCIA — 03/10/2026, pedido do Victor: *"ainda acho ele muito largo
89
+ // comparado a bottomnav como [a do app de referência]"*, e "largo" é a grossura. Medido no
90
+ // fonte do app de referência para Android: a
91
91
  // pílula tem 56; o botão, 48; o ícone, 24; o nome, 12. A nossa media 73 no `circle-bold`. O
92
92
  // recheio de cima e de baixo cai de `space1` para `space05`, e o nome sai em 12 com a
93
93
  // entrelinha justa (ver o `Text` do rótulo). Igual na web (`aurea.css`).
94
94
  paddingHorizontal: t.size.space1, paddingVertical: t.size.space05,
95
- borderRadius: t.size.radiusControl,
95
+ ...canto(t.size.radiusControl),
96
96
  },
97
97
  // Com a pílula do tamanho do conteúdo, `flex: 1` MATA as abas: no RN ele é base ZERO, e a soma
98
98
  // de zeros é uma pílula de largura zero. Aqui cada aba mede o próprio conteúdo (base `auto`) e
@@ -105,11 +105,11 @@ const folha = criarFolha((t) => ({
105
105
  },
106
106
  // A CAIXA QUE ANCORA O CONTADOR, e ela existe por um defeito visto em tela: pendurado no ITEM,
107
107
  // o número cai no meio do RÓTULO. O `navigation-client.tsx:336` conta a história inteira — o
108
- // Victor viu o contador cobrir o nome em 17/08/2026, e a pesquisa (Material 3 e os guias de
109
- // barra de abas do iOS) diz o mesmo: canto superior do ÍCONE, nunca sobre o texto.
108
+ // Victor viu o contador cobrir o nome em 17/08/2026, e a pesquisa (uma referência de mercado e os
109
+ // guias de barra de abas do iOS) diz o mesmo: canto superior do ÍCONE, nunca sobre o texto.
110
110
  marca: { position: "relative", alignItems: "center", justifyContent: "center",
111
- width: 32, height: 32, borderRadius: t.size.radiusControl },
112
- marcaRedonda: { borderRadius: t.size.radiusFull },
111
+ width: 32, height: 32, ...canto(t.size.radiusControl) },
112
+ marcaRedonda: { ...canto(t.size.radiusFull) },
113
113
  contador: { position: "absolute", top: -t.size.space05, right: -t.size.space05 },
114
114
  // ── A BARRA FICA PARADA QUANDO SE TROCA DE ABA — pedido do Victor, 03/10/2026 ──────────────
115
115
  // *"me incomoda o bottom nav todo se mexer [...] quero ele estático, apenas os botões
@@ -128,13 +128,13 @@ const folha = criarFolha((t) => ({
128
128
  // (56 × 48).
129
129
  disco: {
130
130
  alignItems: "center", justifyContent: "center", gap: 0,
131
- width: 56, minHeight: t.size.controlHLg, borderRadius: t.size.radiusFull,
131
+ width: 56, minHeight: t.size.controlHLg, ...canto(t.size.radiusFull),
132
132
  paddingHorizontal: t.size.space1, paddingVertical: t.size.space1,
133
133
  },
134
- // `capsule` (a "A" da bancada, o Material 3 Expressive): a moldura do ícone vira a cápsula de
135
- // 56 × 32 do indicador ativo dele — os mesmos `--bottomnav-bold` e `--bottomnav-ring` do
134
+ // `capsule` (a "A" da bancada, de uma referência de mercado): a moldura do ícone vira a cápsula
135
+ // de 56 × 32 do indicador ativo dela — os mesmos `--bottomnav-bold` e `--bottomnav-ring` do
136
136
  // `aurea.css`, em todos os itens. O rótulo fica embaixo, fora dela.
137
- marcaCapsula: { width: 56, height: 32, borderRadius: t.size.radiusFull },
137
+ marcaCapsula: { width: 56, height: 32, ...canto(t.size.radiusFull) },
138
138
  // O contador fica no canto do ÍCONE, e não da cápsula: sem a cápsula pintada (item não
139
139
  // escolhido) ele ficaria solto, longe do sino. São os (56 − 32) / 2 a mais para dentro.
140
140
  contadorCapsula: { right: (56 - 32) / 2 - t.size.space05 },
@@ -168,7 +168,7 @@ const folha = criarFolha((t) => ({
168
168
  flexDirection: "row", alignItems: "center", gap: t.size.space3, width: "100%",
169
169
  minHeight: t.size.controlHLg,
170
170
  paddingVertical: t.size.space2, paddingHorizontal: t.size.space3,
171
- borderRadius: t.size.radiusCard - t.size.space1,
171
+ ...canto(t.size.radiusCard - t.size.space1),
172
172
  },
173
173
  // O MIOLO da linha: ícone + texto (+ valor em texto) + seta. Ele é quem toca; o que vem
174
174
  // depois dele, na moldura, é IRMÃO — ver o comentário no componente.
@@ -183,7 +183,7 @@ const folha = criarFolha((t) => ({
183
183
  // lá — `gap:3px; padding:3px` — e não de mim.
184
184
  abas: {
185
185
  flexDirection: "row", gap: 3, padding: 3,
186
- minHeight: t.size.controlHMd, borderRadius: t.size.radiusControl,
186
+ minHeight: t.size.controlHMd, ...canto(t.size.radiusControl),
187
187
  backgroundColor: t.color.muted,
188
188
  },
189
189
  // `padding:0 14px` é literal no `.tab` (`aurea.css:1127`). A aba NÃO estica (nada de `flex`):
@@ -194,18 +194,18 @@ const folha = criarFolha((t) => ({
194
194
  // silêncio, e o `tsc` só pegou porque são chaves do mesmo objeto.
195
195
  abaDeTab: {
196
196
  alignItems: "center", justifyContent: "center",
197
- paddingHorizontal: 14, borderRadius: t.size.radiusControl,
197
+ paddingHorizontal: 14, ...canto(t.size.radiusControl),
198
198
  },
199
199
  abaDeTabAtiva: { backgroundColor: t.color.secondary },
200
- // `variant="secondary"` (R-12, 01/10/2026): o `secondary` do HeroUI Native 1.0.10
201
- // (`styles/components/tabs.css`), com o fio da casa no lugar do indicador azul deles.
202
- // .tabs__list--variant-secondary padding 0 · border-bottom 1px, cor da borda
203
- // .tabs__list gap `* 1` → space1
204
- // .tabs__trigger padding-inline `* 3` → space3 · padding-block `* 1.5`
200
+ // `variant="secondary"` (R-12, 01/10/2026): a variante secundária da referência,
201
+ // com o fio da casa no lugar do indicador azul dela.
202
+ // fila (secundária) padding 0 · border-bottom 1px, cor da borda
203
+ // fila gap de 1 unidade → space1
204
+ // aba padding-inline de 3 unidades → space3 · padding-block de 1,5
205
205
  // → space1 + space05. Rótulo `text-base` + entrelinha 1.5 dá
206
206
  // 36, que é o `controlHMd`: a altura da fila da cápsula, então
207
207
  // trocar de variante não muda a altura da fila.
208
- // .tabs__indicator--variant-secondary border-bottom 2px na cor de destaque → `fioDoEscolhido`
208
+ // indicador (secundária) border-bottom 2px na cor de destaque → `fioDoEscolhido`
209
209
  abasSecundarias: {
210
210
  flexDirection: "row", gap: t.size.space1,
211
211
  borderBottomWidth: t.size.borderWidth, borderColor: t.color.border,
@@ -221,7 +221,7 @@ const folha = criarFolha((t) => ({
221
221
  passo: { flex: 1, alignItems: "center" },
222
222
  bolinha: {
223
223
  width: 32, height: 32, marginBottom: t.size.space2,
224
- alignItems: "center", justifyContent: "center", borderRadius: t.size.radiusFull,
224
+ alignItems: "center", justifyContent: "center", ...canto(t.size.radiusFull),
225
225
  borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
226
226
  backgroundColor: t.color.surface1,
227
227
  },
@@ -383,13 +383,14 @@ export function BottomNav({ items, current, variant = "floating", indicator = "n
383
383
  : _jsx(Badge, { tone: "danger", emphasis: "solid", size: "xs", dot: true }) }))] }));
384
384
  // 🔴 O PESO DO RÓTULO NÃO MUDA COM A ESCOLHA (03/10/2026). Era 500 no escolhido e 400 nos
385
385
  // outros, e texto mais grosso é texto mais LARGO: no `content` a barra mudava de largura a
386
- // cada toque, em todos os indicadores. Agora é 500 em todos — o "Label medium" do Material
387
- // 3, que também deixou de engrossar o escolhido no Expressive pela mesma razão. O que marca
386
+ // cada toque, em todos os indicadores. Agora é 500 em todos — o rótulo médio de uma
387
+ // referência de mercado, que também deixou de engrossar o escolhido numa revisão posterior
388
+ // pela mesma razão. O que marca
388
389
  // a escolha é a cor, o ícone cheio e a forma. No `expand` o nome é `sm`: ao lado do ícone,
389
390
  // e não embaixo dele.
390
391
  const rotulo = typeof it.label === "string"
391
392
  ? (nomeVisivel
392
- // 12 numa linha de 16, o do Telegram — e o `text-xs` da web. Antes era o `xs` do `Text`
393
+ // 12 numa linha de 16, o do app de referência — e o `text-xs` da web. Antes era o `xs` do `Text`
393
394
  // nativo, que sobe para 14 (ADR-0050) com linha de 21: era o que mais engrossava a
394
395
  // barra. A linha é o tamanho mais `space1`, como na web: com a entrelinha justa (14,4)
395
396
  // a perna do "j" passava da caixa. No `expand` o nome vai ao lado do ícone, em 14.
@@ -401,7 +402,7 @@ export function BottomNav({ items, current, variant = "floating", indicator = "n
401
402
  // `link` e não `tab`: uma aba troca um painel DESTA tela; isto troca de tela.
402
403
  accessibilityRole: "link", accessibilityLabel: !nomeVisivel && typeof it.label === "string" ? it.label : undefined, ...estadoAcessivel({ selected: ativo, disabled: !!it.disabled }), style: [
403
404
  s.aba, justa && s.aba_content,
404
- indicator === "subtle" && { borderRadius: t.size.radiusCard - t.size.space1 },
405
+ indicator === "subtle" && { ...canto(t.size.radiusCard - t.size.space1) },
405
406
  ativo && (indicator === "subtle" || indicator === "pill")
406
407
  && { backgroundColor: comOpacidade(t.color.primary, 0.12) },
407
408
  disco && s.aba_disco,
@@ -534,7 +535,7 @@ export function Stepper({ items, label, doneIcon = "check", errorIcon = "x-circl
534
535
  *
535
536
  * ⚠ **A fila ROLA na horizontal, e a web não rola — divergência deliberada, com fonte.** A
536
537
  * referência máxima de desenho deste projeto tem estados de rolagem na lista de abas
537
- * (`left-scroll`, `right-scroll`, `left-right-scroll` no inventário), e num telefone de 360dp
538
+ * (rolagem à esquerda, à direita e dos dois lados, no inventário), e num telefone de 360dp
538
539
  * quatro rótulos já não cabem. Espremer todas seria a outra saída, e ela apaga o rótulo — que é
539
540
  * o defeito que o app mediu no `SegmentedControl`. **A cápsula, o respiro e o raio continuam
540
541
  * sendo os do CSS**; o que muda é o transbordo.
@@ -555,7 +556,7 @@ export function Stepper({ items, label, doneIcon = "check", errorIcon = "x-circl
555
556
  * largura de tela grande. Não há tablet medido neste projeto, e no nativo vale demanda antes de
556
557
  * cobertura — a mesma decisão da `Table` do Lote 6.
557
558
  */
558
- export function Tabs({ tabs, value, onChange, label, justify, variant = "primary", style, ...rest }) {
559
+ export function Tabs({ tabs, value, onChange, label, justify, variant = "primary", panel = "card", style, ...rest }) {
559
560
  const t = useAureaTokens();
560
561
  const s = folha(t);
561
562
  const strings = useAureaStrings();
@@ -570,7 +571,5 @@ export function Tabs({ tabs, value, onChange, label, justify, variant = "primary
570
571
  ], children: [typeof it.label === "string"
571
572
  ? _jsx(Text, { size: "sm", weight: ativa ? 600 : 400, style: { color: ativa ? t.color.foreground : t.color.mutedForeground }, children: it.label })
572
573
  : it.label, ativa && secundaria && _jsx(View, { style: s.fioDaAba })] }, it.id));
573
- }) }) }), aberta
574
- ? (_jsx(Card, { variant: "inset", accessibilityLabel: typeof aberta.label === "string" ? aberta.label : undefined, style: s.painel, children: aberta.content }))
575
- : null] }));
574
+ }) }) }), aberta && panel === "plain" ? (_jsx(View, { accessibilityLabel: typeof aberta.label === "string" ? aberta.label : undefined, style: s.painel, children: aberta.content })) : aberta ? (_jsx(Card, { variant: "inset", accessibilityLabel: typeof aberta.label === "string" ? aberta.label : undefined, style: s.painel, children: aberta.content })) : null] }));
576
575
  }
package/dist/numero.d.ts CHANGED
@@ -4,8 +4,9 @@ import type { AureaIcon } from "./icon.js";
4
4
  import { type AureaFieldSize } from "./inputs.js";
5
5
  /**
6
6
  * Os tamanhos do `NumberField`: os três do campo e mais o `display` (R-16, 01/10/2026), o número
7
- * grande de destaque. Nenhuma referência da fila tem esse tamanho (o `NumberField` do HeroUI web
8
- * só tem `variant`; o telefone dele nem tem a peça; o ReUI também não), então ele é peça nossa —
7
+ * grande de destaque. Nenhuma referência da fila tem esse tamanho (o `NumberField` da principal,
8
+ * na web, só tem `variant`; no telefone ela nem tem a peça; a segunda também não), então ele é
9
+ * peça nossa —
9
10
  * e as medidas saem de escalas que JÁ existem, nenhuma nova:
10
11
  * letra `text3xl` (30) em seminegrito — o título 2 (`h2` do B-02). Escolha do Victor.
11
12
  * altura `controlHXl` — o degrau seguinte da escala de altura dos controles, que muda com a
@@ -73,7 +74,7 @@ export interface NumberFieldProps {
73
74
  * Ocupa a largura disponível em vez de abraçar o conteúdo. Padrão **false**.
74
75
  *
75
76
  * O padrão segue o `.number-field` da web, que é `inline-flex` (`aurea.css:704`) — e o mesmo
76
- * eixo existe na HeroUI (`fullWidth`, medido no inventário). **Ligue para moeda:** o campo em
77
+ * eixo existe na referência (medido no inventário). **Ligue para moeda:** o campo em
77
78
  * repouso tem `--space-16` (64dp), que cabe um contador e não cabe `R$ 1.234,50`.
78
79
  */
79
80
  fullWidth?: boolean;
package/dist/numero.js CHANGED
@@ -8,8 +8,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  //
9
9
  // ── A ADR-0024 ATRAVESSA, E FOI CONFERIDA ANTES DE SE AFIRMAR ISSO ───────────────────────────
10
10
  // A decisão da web é *"a Aurea entrega o MOMENTO, não o formato"*: formatar no **blur**, nunca
11
- // enquanto se digita. As três medições que a sustentam (o `Input mask` do USWDS publicado com
12
- // reprovação WCAG registrada, o abandono da máscara pelo MUI na v6, a prática de acessibilidade)
11
+ // enquanto se digita. As três medições que a sustentam (a máscara de entrada de um design system público, publicada com
12
+ // reprovação WCAG registrada, o abandono da máscara por uma das bibliotecas de referência, a
13
+ // prática de acessibilidade)
13
14
  // são sobre COMPORTAMENTO HUMANO, não sobre plataforma — então elas valem igual aqui, e não há
14
15
  // evidência nova que reabra a decisão (`decisions/README.md`).
15
16
  //
@@ -47,7 +48,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
47
48
  import * as React from "react";
48
49
  import { Platform, TextInput, View } from "react-native";
49
50
  import { IconButton } from "./actions.js";
50
- import { criarFolha, estadoAcessivel } from "./estilos.js";
51
+ import { canto, criarFolha, estadoAcessivel } from "./estilos.js";
51
52
  import { useCampo } from "./inputs.js";
52
53
  import { useAureaStrings, useAureaTokens, usePeleSobreAMarca } from "./theme.js";
53
54
  const alturaDoTamanho = (t, s) => s === "sm" ? t.size.controlHSm : s === "lg" ? t.size.controlHLg
@@ -63,8 +64,8 @@ const folha = criarFolha((t) => ({
63
64
  // divergência do nosso próprio CSS, entregue sem declarar, e ela só apareceu quando houve
64
65
  // imagem para olhar.
65
66
  //
66
- // ⚠ **A saída é o eixo da HeroUI, e não uma invenção minha:** o `number-field` deles publica
67
- // `fullWidth: [base, false, group, true]` (`INVENTORY-HEROUI.json`, medido em 22/08/2026).
67
+ // ⚠ **A saída é o eixo da referência, e não uma invenção minha:** o campo numérico dela publica
68
+ // um eixo de largura cheia, ligado e desligado (no inventário da referência, medido em 22/08/2026).
68
69
  // Esticar ou abraçar é DECISÃO DE USO, então vira prop — com o padrão em abraçar, que é o que
69
70
  // o nosso CSS já dizia.
70
71
  grupo: { flexDirection: "row", alignItems: "center", gap: t.size.space1,
@@ -76,7 +77,7 @@ const folha = criarFolha((t) => ({
76
77
  campo: {
77
78
  width: t.size.space16, textAlign: "center",
78
79
  borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
79
- borderRadius: t.size.radiusControl, backgroundColor: t.color.fieldBg,
80
+ ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
80
81
  // A mesma correção de Android do `Input` do Lote 4 — ver `inputs.tsx:280-296`.
81
82
  paddingVertical: 0, textAlignVertical: "center",
82
83
  },
@@ -202,7 +203,7 @@ const prender = (n, min, max) => {
202
203
  };
203
204
  // O texto que o campo mostra ENQUANTO SE EDITA: o número sem grupo e sem símbolo, com o separador
204
205
  // decimal do locale. É o oposto do que se mostra em repouso, e é a decisão da ADR-0024 — editar
205
- // "R$ 1.234,50" com o cursor no meio é o defeito que o MUI filmou.
206
+ // "R$ 1.234,50" com o cursor no meio é o defeito que uma das bibliotecas de referência filmou.
206
207
  const paraEdicao = (n, locale) => {
207
208
  if (n == null)
208
209
  return "";
@@ -342,9 +343,9 @@ export function NumberField({ value, defaultValue, onValueChange, min, max, step
342
343
  return direcao === 1 ? (max != null && base >= max) : (min != null && base <= min);
343
344
  };
344
345
  const mostrarBotoes = icons !== false && !readOnly;
345
- // 🔴 ACHADO PELA REFERÊNCIA, e não por mim — 12/09/2026. O inventário da HeroUI que já morava
346
- // no repositório (`audit/activity-2/INVENTORY-HEROUI.json`, medido em 22/08 sobre
347
- // `@heroui/react@3.2.4`) lista os estados do `number-field` deles:
346
+ // 🔴 ACHADO PELA REFERÊNCIA, e não por mim — 12/09/2026. O inventário da referência que já
347
+ // morava no repositório (medido em 22/08 sobre o pacote dela) lista os estados
348
+ // do campo numérico dela:
348
349
  //
349
350
  // disabled · focus-visible · FOCUS-WITHIN · hovered · invalid · pressed
350
351
  //
@@ -353,10 +354,10 @@ export function NumberField({ value, defaultValue, onValueChange, min, max, step
353
354
  // marca (`busca.tsx:520`). Inconsistência dentro da própria biblioteca, e invisível em teste
354
355
  // até alguém comparar com uma referência.
355
356
  //
356
- // ⚠ **A BORDA vai no CAMPO, e não no grupo — e aqui a Aurea diverge da HeroUI de propósito.**
357
- // Lá o `Group` carrega a caixa e o `Input` fica nu dentro dela. Aqui não: o `.number-field-group`
357
+ // ⚠ **A BORDA vai no CAMPO, e não no grupo — e aqui a Aurea diverge da referência de propósito.**
358
+ // Lá o grupo carrega a caixa e o campo fica nu dentro dela. Aqui não: o `.number-field-group`
358
359
  // do nosso CSS (`aurea.css:705`) é só `inline-flex` + `gap`, e quem tem borda é o `.input`
359
- // (`aurea.css:685`), com os dois botões FORA dela. O estado que faltava é o deles; a geometria
360
+ // (`aurea.css:685`), com os dois botões FORA dela. O estado que faltava é o dela; a geometria
360
361
  // continua sendo a nossa.
361
362
  const [focado, setFocado] = React.useState(false);
362
363
  return (_jsxs(View, { testID: testID, style: [s.grupo, fullWidth && s.grupoLargo, inativo && s.desabilitado, style], children: [mostrarBotoes && (_jsx(IconButton, { name: icons.decrement, label: strings.decrement, appearance: "ghost", size: tamDoBotao, disabled: inativo || noLimite(-1), onPress: () => empurrar(-1), testID: testID ? `${testID}-menos` : undefined })), _jsx(TextInput, { testID: testID ? `${testID}-campo` : undefined, value: mostrar, onChangeText: digitar, onFocus: () => { setFocado(true); setEmEdicao(paraEdicao(numero, locale)); }, onBlur: () => { setFocado(false); confirmar(); }, editable: !inativo && !readOnly, placeholder: placeholder, placeholderTextColor: peleDaMarca?.color ?? t.color.subtleForeground, keyboardType: keyboardType ?? tecladoPadrao,
package/dist/overlays.js CHANGED
@@ -58,7 +58,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
58
58
  import * as React from "react";
59
59
  import { Animated, Easing, Modal, PanResponder, Pressable, ScrollView, View, } from "react-native";
60
60
  import { Button } from "./actions.js";
61
- import { criarFolha } from "./estilos.js";
61
+ import { canto, cantosDeCima, criarFolha } from "./estilos.js";
62
62
  import { IconButton } from "./actions.js";
63
63
  import { RecuoDaFolha } from "./screen.js";
64
64
  import { Text } from "./text.js";
@@ -74,7 +74,7 @@ const folha = criarFolha((t) => ({
74
74
  superficie: {
75
75
  width: "100%", maxWidth: 560, padding: 24,
76
76
  borderWidth: t.size.borderWidth, borderColor: t.color.border,
77
- borderRadius: t.size.radiusCard,
77
+ ...canto(t.size.radiusCard),
78
78
  backgroundColor: t.color.popover,
79
79
  ...(t.shadow.shadowLg ? { boxShadow: [t.shadow.shadowLg] } : null),
80
80
  },
@@ -101,12 +101,15 @@ const folha = criarFolha((t) => ({
101
101
  maxHeight: "90%",
102
102
  paddingHorizontal: 24, paddingTop: t.size.space2, paddingBottom: 24,
103
103
  backgroundColor: t.color.popover,
104
- borderTopLeftRadius: t.size.radiusCard, borderTopRightRadius: t.size.radiusCard,
104
+ // HER-03 (06/10/2026, ADR-0058): 32 e não o 22 de painel — a folha acompanha o canto da tela
105
+ // do telefone. Decisão do Victor, olhando as duas na bancada. A lista do `Select` e a folha do
106
+ // `Combobox` sobem do mesmo jeito e levam o mesmo token.
107
+ ...cantosDeCima(t.size.radiusSheet),
105
108
  borderTopWidth: t.size.borderWidth, borderTopColor: t.color.border,
106
109
  ...(t.shadow.shadowLg ? { boxShadow: [t.shadow.shadowLg] } : null),
107
110
  },
108
111
  puxadorArea: { alignItems: "center", paddingVertical: t.size.space2 },
109
- puxador: { width: 40, height: 4, borderRadius: 999, backgroundColor: t.color.borderStrong },
112
+ puxador: { width: 40, height: 4, ...canto(999), backgroundColor: t.color.borderStrong },
110
113
  }));
111
114
  /** Duração da entrada de painel, em ms. A mesma `.28s` do `.toast` do CSS (aurea.css:1586). */
112
115
  const DURACAO = 280;
package/dist/rolagem.d.ts CHANGED
@@ -11,6 +11,13 @@ export interface FilaRolanteProps {
11
11
  * `end`. Quando não cabe, ela rola, e o alinhamento deixa de existir: começa no início.
12
12
  */
13
13
  justify?: AureaFilaJustify;
14
+ /**
15
+ * A fila OCUPA a linha quando cabe (A5, 06/10/2026 — o `fullWidth` do `SegmentedControl`). O
16
+ * recipiente do conteúdo cresce até a largura do rolador; quem cresce dentro dele é o filho, que
17
+ * também precisa de `flexGrow`. Quando não cabe, rola, como sempre. Vence o `justify`: cheia,
18
+ * ela não tem onde ficar.
19
+ */
20
+ fill?: boolean;
14
21
  }
15
22
  /** Onde a fila fica, na linha, quando cabe. O nome é o do `Cluster` (R-09): o eixo da fileira. */
16
23
  export type AureaFilaJustify = "start" | "center" | "end";
@@ -20,4 +27,4 @@ export type AureaFilaJustify = "start" | "center" | "end";
20
27
  * O componente fica com a informação em vez de adivinhar: `onLayout` dá a largura visível e
21
28
  * `onContentSizeChange` dá a do conteúdo. Com as duas, `transbordou` é uma conta, não um palpite.
22
29
  */
23
- export declare function FilaRolante({ children, style, testID, justify }: FilaRolanteProps): React.JSX.Element;
30
+ export declare function FilaRolante({ children, style, testID, justify, fill }: FilaRolanteProps): React.JSX.Element;
package/dist/rolagem.js CHANGED
@@ -32,7 +32,7 @@ const JUSTIFICAR = { center: "center", end: "flex-end" };
32
32
  * O componente fica com a informação em vez de adivinhar: `onLayout` dá a largura visível e
33
33
  * `onContentSizeChange` dá a do conteúdo. Com as duas, `transbordou` é uma conta, não um palpite.
34
34
  */
35
- export function FilaRolante({ children, style, testID, justify = "start" }) {
35
+ export function FilaRolante({ children, style, testID, justify = "start", fill }) {
36
36
  const [visivel, setVisivel] = React.useState(0);
37
37
  const [conteudo, setConteudo] = React.useState(0);
38
38
  const transbordou = conteudo > visivel && visivel > 0;
@@ -46,5 +46,6 @@ export function FilaRolante({ children, style, testID, justify = "start" }) {
46
46
  // largura do rolador (`flexGrow: 1`) e POSICIONA a cápsula lá dentro. Ela não estica: na
47
47
  // fileira, o filho tem a largura dele. Medido pelo app: rolador 335 de largura, fileira 281,
48
48
  // encostada à esquerda, e um `Cluster justify="center"` em volta não mudava nada.
49
- contentContainerStyle: justify === "start" ? { flexGrow: 0 } : { flexGrow: 1, justifyContent: JUSTIFICAR[justify] }, style: style, children: children }));
49
+ contentContainerStyle: fill ? { flexGrow: 1 }
50
+ : justify === "start" ? { flexGrow: 0 } : { flexGrow: 1, justifyContent: JUSTIFICAR[justify] }, style: style, children: children }));
50
51
  }
package/dist/screen.js CHANGED
@@ -146,7 +146,7 @@ function Rodape({ dentroDoRespiro, pegaABorda, respiroDaBarra, children }) {
146
146
  // ganhar altura. Nunca ganhava: o recuo ficava em zero e o último item, atrás dos botões do
147
147
  // sistema (achado E10 do app).
148
148
  //
149
- // A saída é a do HeroUI Native (`select.tsx`, `useSafeAreaInsets`): o número vem do CONTEXTO
149
+ // A saída é a da referência (`select.tsx`, `useSafeAreaInsets`): o número vem do CONTEXTO
150
150
  // do React, que atravessa o `Modal`, e vira um espaço de altura conhecida no fim da folha. Sem
151
151
  // `SafeAreaProvider` no app, vale a medida da abertura (`initialWindowMetrics`), que a
152
152
  // biblioteca calcula sem provider — e o componente não quebra quem não tem provider.
package/dist/sistema.d.ts CHANGED
@@ -40,6 +40,11 @@ export type AureaPhoto = {
40
40
  uri: string;
41
41
  width?: number;
42
42
  height?: number;
43
+ /**
44
+ * Quando a foto foi TIRADA, lida do EXIF (R-23). Só vem com a prop `exif`, e fica vazia quando
45
+ * a foto não traz a data — a que passou por um aplicativo de mensagens, por exemplo, perde o EXIF no caminho.
46
+ */
47
+ takenAt?: Date;
43
48
  };
44
49
  export interface PhotoInputProps {
45
50
  value?: AureaPhoto[];
@@ -56,6 +61,12 @@ export interface PhotoInputProps {
56
61
  offerSettings?: boolean;
57
62
  /** Avisado quando a permissão foi negada — o app pode querer contar uma história própria. */
58
63
  onPermissionDenied?: () => void;
64
+ /**
65
+ * Lê do EXIF a data em que a foto foi tirada e a entrega em `takenAt` (R-23). Desligado por
66
+ * padrão: ler o EXIF custa (no iPhone, a foto que está no iCloud desce inteira) e o app só
67
+ * paga quando precisa. Da galeria, é o que põe na ordem certa a foto que sobe dias depois.
68
+ */
69
+ exif?: boolean;
59
70
  addIcon?: AureaIcon | false;
60
71
  removeIcon?: AureaIcon;
61
72
  style?: StyleProp<ViewStyle>;
@@ -76,6 +87,8 @@ export interface PhotoInputProps {
76
87
  * | **câmera ou galeria?** | câmera, que é o que o plano pede | `source="library"` |
77
88
  * | como **remover**? | um `IconButton` no canto de cada miniatura | `removeIcon` |
78
89
  * | **quantas** cabem? | uma | `max` |
90
+ * | **várias de uma vez?** | da galeria, sim, quando cabe mais de uma (R-23) | `max` |
91
+ * | **a data** em que foi tirada? | não lê: ler o EXIF custa | `exif` → `takenAt` (R-23) |
79
92
  *
80
93
  * ⚠ **O gatilho some quando o limite é atingido**, em vez de ficar aceso e não fazer nada.
81
94
  *
@@ -85,10 +98,10 @@ export interface PhotoInputProps {
85
98
  *
86
99
  * | | |
87
100
  * |---|---|
88
- * | miniatura | quadrada de 64, a `Image` da `Gallery` (o `Avatar` `lg` do HeroUI) |
101
+ * | miniatura | quadrada de 64, a `Image` da `Gallery` (o `Avatar` `lg` da referência) |
89
102
  * | tocar nela | abre a foto grande, no MESMO zoom da `Gallery` (`FotoAmpliada`) |
90
103
  * | o X | com fundo, TODO fora da foto, no canto de cima à direita |
91
104
  * | leitor de tela | *"Foto 2 de 3"* (com uma só, *"Foto"*) e *"Abre a foto"*; o X, *"Remover foto 2"* |
92
105
  * | inativo | a foto ainda abre (olhar não muda nada); o X não remove |
93
106
  */
94
- export declare function PhotoInput({ value, onChange, max, source, disabled, offerSettings, onPermissionDenied, addIcon, removeIcon, style, testID, }: PhotoInputProps): React.JSX.Element;
107
+ export declare function PhotoInput({ value, onChange, max, source, disabled, offerSettings, onPermissionDenied, exif, addIcon, removeIcon, style, testID, }: PhotoInputProps): React.JSX.Element;
package/dist/sistema.js CHANGED
@@ -35,7 +35,7 @@ import { Linking, Platform, Pressable, View } from "react-native";
35
35
  import RNDateTimePicker, { DateTimePickerAndroid } from "@react-native-community/datetimepicker";
36
36
  import * as ImagePicker from "expo-image-picker";
37
37
  import { IconButton } from "./actions.js";
38
- import { criarFolha, estadoAcessivel } from "./estilos.js";
38
+ import { canto, criarFolha, estadoAcessivel } from "./estilos.js";
39
39
  import { Alert } from "./feedback.js";
40
40
  import { Icon } from "./icon.js";
41
41
  import { useCampo } from "./inputs.js";
@@ -46,12 +46,12 @@ const folha = criarFolha((t) => ({
46
46
  gatilho: {
47
47
  flexDirection: "row", alignItems: "center", justifyContent: "space-between",
48
48
  width: "100%", borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
49
- borderRadius: t.size.radiusControl, backgroundColor: t.color.fieldBg,
49
+ ...canto(t.size.radiusControl), backgroundColor: t.color.fieldBg,
50
50
  },
51
51
  invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
52
52
  desabilitado: { opacity: t.size.opacityDisabled },
53
- // R-22 (02/10/2026), a "B" da prancha: miniatura QUADRADA de 64 — o `Avatar` `lg` do HeroUI
54
- // Native, e a medida que o botão de pôr foto passou a ter também (era 72, número à mão) — e o X
53
+ // R-22 (02/10/2026), a "B" da prancha: miniatura QUADRADA de 64 — o `Avatar` `lg` da
54
+ // referência, e a medida que o botão de pôr foto passou a ter também (era 72, número à mão) — e o X
55
55
  // TODO FORA da foto. O X é o `IconButton` `sm` (30) com fundo; a área de toque dele é de 44
56
56
  // (`targetMin`), com o desenho no centro, então o deslocamento que põe o canto do DESENHO no
57
57
  // canto da foto é (30 + 44) / 2. A grade deixa esse espaço em cima, à direita e entre as linhas,
@@ -65,7 +65,7 @@ const folha = criarFolha((t) => ({
65
65
  remover: { position: "absolute", top: -foraDoX(t), right: -foraDoX(t) },
66
66
  adicionar: {
67
67
  alignItems: "center", justifyContent: "center", gap: t.size.space1,
68
- width: t.size.space16, height: t.size.space16, borderRadius: t.size.radiusLg,
68
+ width: t.size.space16, height: t.size.space16, ...canto(t.size.radiusLg),
69
69
  borderWidth: t.size.borderWidth, borderColor: t.color.borderStrong,
70
70
  borderStyle: "dashed", backgroundColor: t.color.fieldBg,
71
71
  },
@@ -128,6 +128,36 @@ export function DatePicker({ value, onChange, mode = "date", minimumDate, maximu
128
128
  style,
129
129
  ], children: [_jsx(Text, { size: tam === "sm" ? "xs" : tam === "lg" ? "base" : "md", tone: value ? "default" : "subtle", numberOfLines: 1, children: texto }), icon && _jsx(Icon, { name: icon, size: "sm", color: t.color.subtleForeground })] }), mostrarSeletorIOS && (_jsx(RNDateTimePicker, { value: value ?? new Date(), mode: mode, minimumDate: minimumDate, maximumDate: maximumDate, onChange: receber }))] }));
130
130
  }
131
+ // R-23 (06/10/2026) · a data em que a foto foi tirada, e NADA MAIS do EXIF.
132
+ //
133
+ // Lido no fonte do `expo-image-picker` 57.0.15: no iPhone o código junta o dicionário `{Exif}` no
134
+ // topo, então `DateTimeOriginal` chega com esse nome nos dois sistemas. O formato do EXIF é
135
+ // "AAAA:MM:DD HH:MM:SS", sem fuso. O iPhone pode mandar `OffsetTimeOriginal` ("-03:00"); a lista
136
+ // de etiquetas do Android não tem fuso, e aí vale a hora local do aparelho — que é a hora em que
137
+ // a pessoa estava, no caso comum de fotografar e lançar no mesmo lugar.
138
+ //
139
+ // ⚠ O EXIF de uma foto da galeria traz também a LOCALIZAÇÃO. Por isso esta função devolve uma
140
+ // data e o EXIF não sai daqui: o app não recebe o que não pediu.
141
+ function dataDaFoto(exif) {
142
+ const bruto = exif?.DateTimeOriginal ?? exif?.DateTimeDigitized;
143
+ if (typeof bruto !== "string")
144
+ return undefined;
145
+ const m = /^(\d{4}):(\d{2}):(\d{2})[ T](\d{2}):(\d{2}):(\d{2})/.exec(bruto.trim());
146
+ if (!m)
147
+ return undefined;
148
+ const [ano, mes, dia, hora, minuto, segundo] = m.slice(1).map(Number);
149
+ // "0000:00:00 00:00:00" é como câmera sem relógio escreve "sem data".
150
+ if (ano === 0 || mes < 1 || mes > 12 || dia < 1 || dia > 31 || hora > 23 || minuto > 59 || segundo > 59) {
151
+ return undefined;
152
+ }
153
+ const fuso = exif?.OffsetTimeOriginal ?? exif?.OffsetTimeDigitized;
154
+ const f = typeof fuso === "string" ? /^([+-])(\d{2}):(\d{2})$/.exec(fuso.trim()) : null;
155
+ if (f) {
156
+ const minutos = (f[1] === "-" ? -1 : 1) * (Number(f[2]) * 60 + Number(f[3]));
157
+ return new Date(Date.UTC(ano, mes - 1, dia, hora, minuto, segundo) - minutos * 60000);
158
+ }
159
+ return new Date(ano, mes - 1, dia, hora, minuto, segundo);
160
+ }
131
161
  /**
132
162
  * O anexo por foto.
133
163
  *
@@ -143,6 +173,8 @@ export function DatePicker({ value, onChange, mode = "date", minimumDate, maximu
143
173
  * | **câmera ou galeria?** | câmera, que é o que o plano pede | `source="library"` |
144
174
  * | como **remover**? | um `IconButton` no canto de cada miniatura | `removeIcon` |
145
175
  * | **quantas** cabem? | uma | `max` |
176
+ * | **várias de uma vez?** | da galeria, sim, quando cabe mais de uma (R-23) | `max` |
177
+ * | **a data** em que foi tirada? | não lê: ler o EXIF custa | `exif` → `takenAt` (R-23) |
146
178
  *
147
179
  * ⚠ **O gatilho some quando o limite é atingido**, em vez de ficar aceso e não fazer nada.
148
180
  *
@@ -152,13 +184,13 @@ export function DatePicker({ value, onChange, mode = "date", minimumDate, maximu
152
184
  *
153
185
  * | | |
154
186
  * |---|---|
155
- * | miniatura | quadrada de 64, a `Image` da `Gallery` (o `Avatar` `lg` do HeroUI) |
187
+ * | miniatura | quadrada de 64, a `Image` da `Gallery` (o `Avatar` `lg` da referência) |
156
188
  * | tocar nela | abre a foto grande, no MESMO zoom da `Gallery` (`FotoAmpliada`) |
157
189
  * | o X | com fundo, TODO fora da foto, no canto de cima à direita |
158
190
  * | leitor de tela | *"Foto 2 de 3"* (com uma só, *"Foto"*) e *"Abre a foto"*; o X, *"Remover foto 2"* |
159
191
  * | inativo | a foto ainda abre (olhar não muda nada); o X não remove |
160
192
  */
161
- export function PhotoInput({ value = [], onChange, max = 1, source = "camera", disabled, offerSettings = true, onPermissionDenied, addIcon = "camera", removeIcon = "x", style, testID, }) {
193
+ export function PhotoInput({ value = [], onChange, max = 1, source = "camera", disabled, offerSettings = true, onPermissionDenied, exif = false, addIcon = "camera", removeIcon = "x", style, testID, }) {
162
194
  const t = useAureaTokens();
163
195
  const s = folha(t);
164
196
  const strings = useAureaStrings();
@@ -185,16 +217,27 @@ export function PhotoInput({ value = [], onChange, max = 1, source = "camera", d
185
217
  return;
186
218
  }
187
219
  }
220
+ // R-23: da GALERIA, escolhe várias de uma vez quando cabe mais de uma, até o que falta para o
221
+ // `max`. A câmera tira uma por vez — no sistema, não há outro jeito.
222
+ const cabem = max - value.length;
188
223
  const r = source === "camera"
189
- ? await ImagePicker.launchCameraAsync({ quality: 0.7 })
190
- : await ImagePicker.launchImageLibraryAsync({ quality: 0.7 });
224
+ ? await ImagePicker.launchCameraAsync({ quality: 0.7, exif })
225
+ : await ImagePicker.launchImageLibraryAsync(cabem > 1
226
+ ? { quality: 0.7, exif, allowsMultipleSelection: true, selectionLimit: cabem }
227
+ : { quality: 0.7, exif });
191
228
  if (r.canceled || !r.assets?.length)
192
229
  return;
193
230
  const novas = r.assets
194
- .slice(0, max - value.length)
195
- .map((a) => ({ uri: a.uri, width: a.width, height: a.height }));
231
+ .slice(0, cabem)
232
+ .map((a) => {
233
+ const foto = { uri: a.uri, width: a.width, height: a.height };
234
+ const quando = exif ? dataDaFoto(a.exif) : undefined;
235
+ if (quando)
236
+ foto.takenAt = quando;
237
+ return foto;
238
+ });
196
239
  onChange?.([...value, ...novas]);
197
- }, [source, max, value, onChange, onPermissionDenied]);
240
+ }, [source, max, value, onChange, onPermissionDenied, exif]);
198
241
  return (_jsxs(View, { testID: testID, style: style, children: [negadoDeVez && (_jsx(Alert, { variant: "warning", children: _jsxs(View, { style: { gap: t.size.space2 }, children: [_jsx(Text, { size: "sm", tone: "muted", children: strings.cameraDenied }), offerSettings && (_jsx(Pressable, { onPress: () => Linking.openSettings(), accessibilityRole: "button", accessibilityLabel: strings.openSettings, children: _jsx(Text, { size: "sm", weight: 600, tone: "primary", children: strings.openSettings }) }))] }) })), _jsxs(View, { style: [s.galeria, value.length > 0 && s.comX], children: [value.map((foto, n) => (_jsxs(View, { style: s.miniatura, children: [_jsx(Pressable, { onPress: () => setAberta(n), accessibilityRole: "imagebutton", accessibilityLabel: nomeDa(n), accessibilityHint: strings.photoOpen, children: _jsx(Image, { source: foto.uri, alt: "", ratio: 1 }) }), _jsx(View, { style: s.remover, children: _jsx(IconButton, { appearance: "solid", size: "sm", name: removeIcon, label: `${strings.photoRemove} ${n + 1}`, disabled: inativo, onPress: () => onChange?.(value.filter((_, i) => i !== n)) }) })] }, `${foto.uri}-${n}`))), !cheio && (_jsx(Pressable, { onPress: inativo ? undefined : escolher, disabled: inativo, accessibilityRole: "button", accessibilityLabel: campo?.label ?? strings.photoAdd, ...estadoAcessivel({ disabled: !!inativo }), style: [s.adicionar, inativo && s.desabilitado], children: addIcon && _jsx(Icon, { name: addIcon, size: "lg", color: t.color.subtleForeground }) }))] }), _jsx(FotoAmpliada, { source: fotoAberta?.uri, title: aberta != null ? nomeDa(aberta) : "", alt: aberta != null ? nomeDa(aberta) : "",
199
242
  // A proporção da foto, quando a câmera a deu: a grande aparece inteira, sem tarja à toa.
200
243
  ratio: fotoAberta?.width && fotoAberta.height ? fotoAberta.width / fotoAberta.height : 1, onClose: () => setAberta(null) })] }));
package/dist/text.d.ts CHANGED
@@ -10,14 +10,14 @@ export type AureaTextFont = "ui" | "editorial" | "code";
10
10
  export type AureaTextTone = "default" | "muted" | "subtle" | "primary" | "link" | "danger" | "success" | "warning" | "info";
11
11
  export type AureaTextLeading = "none" | "tight" | "normal" | "relaxed";
12
12
  /**
13
- * O PAPEL do texto — B-02, 25/09/2026, no molde do `Typography` do HeroUI Native 1.0.10. Uma lista
13
+ * O PAPEL do texto — B-02, 25/09/2026, no molde do componente de tipografia da referência. Uma lista
14
14
  * fechada: título 1–6, texto, texto pequeno, texto mínimo e código.
15
15
  */
16
16
  export type AureaTextType = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "body" | "body-sm" | "body-xs" | "code";
17
17
  export interface TextProps extends TextPropsRN {
18
18
  /**
19
- * O papel (B-02). Dá tamanho, peso, entrelinha e fonte de uma vez, com os números do HeroUI
20
- * Native — os MESMOS da web, sem o degrau a mais do `size`. Uma opção solta passada junto
19
+ * O papel (B-02). Dá tamanho, peso, entrelinha e fonte de uma vez, com os números da
20
+ * referência — os MESMOS da web, sem o degrau a mais do `size`. Uma opção solta passada junto
21
21
  * (`size`, `weight`…) continua valendo por cima dele.
22
22
  */
23
23
  type?: AureaTextType;
@@ -49,7 +49,7 @@ export type AureaTypographyAlign = "start" | "center" | "end" | "justify";
49
49
  interface AureaTypographyBase extends Omit<TextPropsRN, "children"> {
50
50
  color?: AureaTypographyColor;
51
51
  weight?: AureaTypographyWeight;
52
- /** `start`/`end` viram `left`/`right`, que o React Native já espelha em RTL (nota do HeroUI Native). */
52
+ /** `start`/`end` viram `left`/`right`, que o React Native já espelha em RTL (nota da referência). */
53
53
  align?: AureaTypographyAlign;
54
54
  /** Uma linha só, cortada com reticências (`numberOfLines={1}`). */
55
55
  truncate?: boolean;
@@ -58,7 +58,7 @@ interface AureaTypographyBase extends Omit<TextPropsRN, "children"> {
58
58
  export interface HeadingProps extends AureaTypographyBase {
59
59
  type?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
60
60
  }
61
- /** Título. Marca `accessibilityRole="header"` sozinho, como o HeroUI Native. */
61
+ /** Título. Marca `accessibilityRole="header"` sozinho, como a referência. */
62
62
  export declare function Heading({ type, accessibilityRole, ...rest }: HeadingProps): React.JSX.Element;
63
63
  export interface ParagraphProps extends AureaTypographyBase {
64
64
  type?: "body" | "body-sm" | "body-xs";