@aurea-uds/native 0.7.0 → 0.8.1
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.
- package/README.md +135 -3
- package/dist/busca.d.ts +126 -0
- package/dist/busca.js +393 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +21 -0
- package/dist/inputs.d.ts +31 -1
- package/dist/inputs.js +19 -2
- package/dist/midia.d.ts +98 -0
- package/dist/midia.js +181 -0
- package/dist/numero.d.ts +108 -0
- package/dist/numero.js +327 -0
- package/dist/strings.d.ts +26 -0
- package/dist/strings.js +16 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -6,9 +6,18 @@ Pacote **irmão** do `@aurea-uds/react`, não um wrapper dele: componentes próp
|
|
|
6
6
|
`View`/`Text`/`Pressable`, consumindo `@aurea-uds/tokens`. Só os tokens atravessam — decisão de
|
|
7
7
|
18/07/2026, registrada no `ROADMAP.md` Fase 7.
|
|
8
8
|
|
|
9
|
-
> **Estado:
|
|
10
|
-
>
|
|
11
|
-
>
|
|
9
|
+
> **Estado: 51 componentes.** O **Lote 7** entrou em 11/09/2026 e é o primeiro que **não sai do
|
|
10
|
+
> plano** — ele saiu do APP. O consumidor mediu três lacunas na primeira tela que a pessoa toca, e
|
|
11
|
+
> elas viraram cinco componentes: **`Combobox`, `SearchField`, `NumberField`, `Image` e
|
|
12
|
+
> `Gallery`**, mais a prop `formatOnBlur` no `Input`. **Zero dependência nova.**
|
|
13
|
+
> Ver a seção **Buscar, número e mídia** abaixo, e o `NATIVE.md` §8.
|
|
14
|
+
>
|
|
15
|
+
> ⚠ **O `Combobox` DIVERGE da web de propósito** — ele aceita busca REMOTA em seleção única, que
|
|
16
|
+
> lá não existe ([ADR-0043](../../decisions/0043-o-combobox-nativo-diverge-da-web-e-a-presenca-da-prop-e-a-chave.md)).
|
|
17
|
+
> ⚠ **Os cinco do Lote 7 ainda não rodaram em aparelho** — só em teste.
|
|
18
|
+
>
|
|
19
|
+
> **O PLANO fechou no Lote 6**, em 09/09/2026 (`Timeline`, `DataList`, `Table`), e o **`Chart`** —
|
|
20
|
+
> a única peça que tinha ficado de fora — entrou no mesmo dia pela
|
|
12
21
|
> [ADR-0041](../../decisions/0041-o-motor-de-grafico-do-nativo-e-nosso-sobre-react-native-svg.md).
|
|
13
22
|
>
|
|
14
23
|
> ⚠ **O `Chart` é o único componente deste pacote cuja GEOMETRIA é nossa.** Na web ele é 79 linhas
|
|
@@ -219,6 +228,129 @@ leitor anuncia.
|
|
|
219
228
|
O `behavior` muda com a plataforma — `padding` no iOS, `height` no Android — e a Aurea escolhe
|
|
220
229
|
por você. Um só nos dois lados deixa metade dos aparelhos com o botão de salvar sob o teclado.
|
|
221
230
|
|
|
231
|
+
## Buscar, número e mídia
|
|
232
|
+
|
|
233
|
+
O **Lote 7** (11/09/2026). Três lacunas que o app mediu, e não o plano — `NATIVE.md` §8.
|
|
234
|
+
|
|
235
|
+
### `Combobox` — digitar para achar um item
|
|
236
|
+
|
|
237
|
+
⚠ **Não confunda com o `Select`.** A escolha entre os dois é de TAMANHO DE LISTA, e a linha é
|
|
238
|
+
dura: o `Select` monta todos os itens num `ScrollView` — serve para unidades, estados e tipos.
|
|
239
|
+
**Um catálogo de milhares de linhas ali trava.** O `Combobox` usa `FlatList` e aceita busca remota.
|
|
240
|
+
|
|
241
|
+
```tsx
|
|
242
|
+
import {Combobox, Field} from "@aurea-uds/native";
|
|
243
|
+
|
|
244
|
+
// ① catálogo REMOTO — a Aurea não filtra, o app busca
|
|
245
|
+
<Field label="Item">
|
|
246
|
+
<Combobox
|
|
247
|
+
items={resultados} // a lista JÁ BUSCADA
|
|
248
|
+
value={escolhido} // o ITEM inteiro, não o id
|
|
249
|
+
onValueChange={setEscolhido}
|
|
250
|
+
onSearchChange={buscar} // ← a presença desta prop DESLIGA o filtro da Aurea
|
|
251
|
+
loading={buscando}
|
|
252
|
+
onEndReached={proximaPagina}
|
|
253
|
+
/>
|
|
254
|
+
</Field>
|
|
255
|
+
|
|
256
|
+
// ② lista NA MÃO — a Aurea filtra, ignorando acento e caixa
|
|
257
|
+
<Combobox items={unidades} value={unidade} onValueChange={setUnidade} />
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**A regra em uma linha: `onSearchChange` presente = a Aurea não filtra.** É presença de prop, não
|
|
261
|
+
configuração — e ela existe porque filtrar de novo o que o servidor devolveu esconde resultado.
|
|
262
|
+
|
|
263
|
+
| | |
|
|
264
|
+
|---|---|
|
|
265
|
+
| espera antes de chamar `onSearchChange` | **250 ms**. `searchDelay={0}` desliga |
|
|
266
|
+
| onde se digita | **dentro da folha**, não no gatilho — o teclado ocupa metade da tela |
|
|
267
|
+
| `value` | o **item inteiro**: numa busca remota a lista some debaixo da escolha |
|
|
268
|
+
| ícones a registrar | `chevron--down`, `search`, `close` |
|
|
269
|
+
|
|
270
|
+
### `SearchField` — filtrar o que já está na tela
|
|
271
|
+
|
|
272
|
+
Outro papel: o `Combobox` **escolhe** de um catálogo e devolve a escolha; este **filtra** e
|
|
273
|
+
devolve texto.
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
<SearchField placeholder="Filtrar" onSearchChange={setFiltro} />
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### `NumberField` — moeda, medida e contador
|
|
280
|
+
|
|
281
|
+
```tsx
|
|
282
|
+
<Field label="Valor">
|
|
283
|
+
<NumberField value={valor} onValueChange={setValor}
|
|
284
|
+
format={{style: "currency", currency: "BRL"}} locale="pt-BR" />
|
|
285
|
+
</Field>
|
|
286
|
+
|
|
287
|
+
<Field label="Litros">
|
|
288
|
+
<NumberField value={litros} onValueChange={setLitros}
|
|
289
|
+
format={{maximumFractionDigits: 1}} locale="pt-BR" min={0} />
|
|
290
|
+
</Field>
|
|
291
|
+
|
|
292
|
+
<Field label="Quantidade">
|
|
293
|
+
<NumberField value={qtd} onValueChange={setQtd} min={0} step={1} />
|
|
294
|
+
</Field>
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
⚠ **O que sai por `onValueChange` é `number`, sempre** — `1234.5`, nunca `"R$ 1.234,50"`.
|
|
298
|
+
|
|
299
|
+
⚠ **Formata no BLUR, e só no blur** ([ADR-0024](../../decisions/0024-mascara-de-campo-e-o-momento-nao-o-formato.md)
|
|
300
|
+
e [ADR-0042](../../decisions/0042-o-intl-e-o-formatador-do-nativo-e-a-volta-e-nossa.md)). Enquanto
|
|
301
|
+
o campo tem foco, ele mostra exatamente o que foi digitado. Máscara ao vivo é o defeito que o
|
|
302
|
+
USWDS publicou com reprovação WCAG registrada e que o MUI abandonou na v6.
|
|
303
|
+
|
|
304
|
+
⚠ **`notation: "compact"` é recusado** — quebrado no motor JS do RN nos dois sistemas. Sai aviso em
|
|
305
|
+
`__DEV__` e a opção é ignorada; o resto do formato sobrevive.
|
|
306
|
+
|
|
307
|
+
Os três auxiliares são públicos, porque o app tem o mesmo problema fora do campo:
|
|
308
|
+
|
|
309
|
+
```tsx
|
|
310
|
+
import {formatarNumero, lerNumero, separadoresDoLocale} from "@aurea-uds/native";
|
|
311
|
+
|
|
312
|
+
formatarNumero(1234.5, "pt-BR", {style: "currency", currency: "BRL"}); // "R$ 1.234,50"
|
|
313
|
+
lerNumero("R$ 1.234,50", "pt-BR"); // 1234.5
|
|
314
|
+
lerNumero("", "pt-BR"); // null ← não é 0
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Para **texto** (placa, documento, telefone) o momento é o mesmo e o formato é seu:
|
|
318
|
+
|
|
319
|
+
```tsx
|
|
320
|
+
<Input value={placa} onChangeText={setPlaca} formatOnBlur={(v) => v.toUpperCase()} />
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
⚠ `formatOnBlur` exige o campo **controlado** — o valor formatado sai por `onChangeText`.
|
|
324
|
+
|
|
325
|
+
### `Image` e `Gallery` — mostrar foto
|
|
326
|
+
|
|
327
|
+
⚠ **`Image` NÃO é o `Image` do React Native com outra pele.** Ele faz as duas coisas que o
|
|
328
|
+
primitivo cru não faz: **reserva a caixa** antes dos bytes (sem isso o layout salta) e **cai para
|
|
329
|
+
um substituto** quando eles não vêm (sem isso uma URL quebrada deixa buraco).
|
|
330
|
+
|
|
331
|
+
```tsx
|
|
332
|
+
<Image source={foto.uri} alt="Frente do item" ratio="4/3" />
|
|
333
|
+
|
|
334
|
+
<Gallery items={fotos} zoom selected={atual} onSelect={setAtual} />
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
| | |
|
|
338
|
+
|---|---|
|
|
339
|
+
| `ratio` | aceita `4/3`, `"4/3"`, `"16:9"` ou o número. A web usa string; o RN quer número |
|
|
340
|
+
| `alt` | **obrigatório**. Decorativa de verdade se escreve `alt=""`, explícito |
|
|
341
|
+
| ampliar | é o **`Dialog`** que já existe, não uma superfície nova |
|
|
342
|
+
| legenda | com legenda, o nome vai para o LADRILHO e a imagem sai da árvore de acessibilidade |
|
|
343
|
+
| ícone a registrar | `image` (o substituto) |
|
|
344
|
+
|
|
345
|
+
Quem já usa `expo-image` por cache de disco troca o elemento sem perder a pele:
|
|
346
|
+
|
|
347
|
+
```tsx
|
|
348
|
+
<Image render={<ExpoImage contentFit="cover" transition={150} />} source={u} alt="…" />
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
⚠ `fit` **não** é traduzido para o elemento passado — `resizeMode` é do `Image` do RN e o
|
|
352
|
+
`expo-image` chama a mesma coisa de `contentFit`. Quem passa o elemento escreve a prop dele.
|
|
353
|
+
|
|
222
354
|
## Data e câmera
|
|
223
355
|
|
|
224
356
|
Estes dois **não saem do barril** — são o único ponto do pacote com importação própria:
|
package/dist/busca.d.ts
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
import { type IconName } from "./icon.js";
|
|
4
|
+
import { type AureaFieldSize } from "./inputs.js";
|
|
5
|
+
/** Uma linha do catálogo. **Mesma forma da web** (`ComboboxOption`), mais o `disabled` que o `Select` daqui já tinha. */
|
|
6
|
+
export interface AureaComboboxItem {
|
|
7
|
+
value: string;
|
|
8
|
+
label: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export interface ComboboxProps {
|
|
12
|
+
/**
|
|
13
|
+
* O que a folha mostra. **Com `onSearchChange`, é a lista JÁ BUSCADA** — a Aurea não filtra e
|
|
14
|
+
* não guarda; ela desenha o que chegou.
|
|
15
|
+
*/
|
|
16
|
+
items: AureaComboboxItem[];
|
|
17
|
+
/**
|
|
18
|
+
* O escolhido, como ITEM inteiro e não como `value` — mesma escolha da web, e ela tem razão
|
|
19
|
+
* prática aqui: numa busca remota o item escolhido pode não estar mais em `items` (a pessoa
|
|
20
|
+
* digitou outra coisa depois de escolher), e o gatilho ainda precisa saber que rótulo mostrar.
|
|
21
|
+
* Guardar só o `value` deixaria o campo em branco no instante seguinte à escolha.
|
|
22
|
+
*/
|
|
23
|
+
value?: AureaComboboxItem | null;
|
|
24
|
+
onValueChange?: (v: AureaComboboxItem | null) => void;
|
|
25
|
+
/**
|
|
26
|
+
* O que foi digitado, já com espera. **A presença desta prop DESLIGA o filtro da Aurea** — é a
|
|
27
|
+
* chave entre catálogo remoto e lista na mão, e é presença, não configuração.
|
|
28
|
+
*/
|
|
29
|
+
onSearchChange?: (query: string) => void;
|
|
30
|
+
/**
|
|
31
|
+
* A espera antes de chamar `onSearchChange`, em ms. Padrão **250**.
|
|
32
|
+
*
|
|
33
|
+
* Não é enfeite de performance: sem ela, "cadeira" são sete chamadas ao servidor e seis
|
|
34
|
+
* respostas descartadas — e a última a chegar pode não ser a última pedida. `0` desliga.
|
|
35
|
+
*/
|
|
36
|
+
searchDelay?: number;
|
|
37
|
+
/** Mostra o anel no lugar da lista. Use enquanto a busca remota não voltou. */
|
|
38
|
+
loading?: boolean;
|
|
39
|
+
/** Fim da lista alcançado — é por aqui que o catálogo remoto pagina. */
|
|
40
|
+
onEndReached?: () => void;
|
|
41
|
+
/** O que o gatilho mostra sem escolha. */
|
|
42
|
+
placeholder?: string;
|
|
43
|
+
/** O que o campo da folha mostra vazio. Sem ele, a frase `comboboxSearch` do provider. */
|
|
44
|
+
searchPlaceholder?: string;
|
|
45
|
+
/** O que a folha mostra sem resultado. Sem ele, a frase `comboboxEmpty` do provider. */
|
|
46
|
+
empty?: React.ReactNode;
|
|
47
|
+
/** Mostra o botão de limpar no gatilho quando há escolha. Padrão **true**. */
|
|
48
|
+
clearable?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Arrastar o cabeçalho da folha para baixo fecha. Ligado.
|
|
51
|
+
*
|
|
52
|
+
* ⚠ **É a ÚNICA saída por gesto no iOS** — lá não há botão VOLTAR, então sem isto restaria só
|
|
53
|
+
* tocar no fundo. Mesmo gesto, mesmo limiar e mesma curva do `BottomSheet` do Lote 5.
|
|
54
|
+
*/
|
|
55
|
+
draggable?: boolean;
|
|
56
|
+
disabled?: boolean;
|
|
57
|
+
size?: AureaFieldSize;
|
|
58
|
+
/** O glifo da seta. Registre-o, ou passe `false`. */
|
|
59
|
+
chevron?: IconName | false;
|
|
60
|
+
/** O glifo da lupa no campo da folha. Registre-o, ou passe `false`. */
|
|
61
|
+
searchIcon?: IconName | false;
|
|
62
|
+
style?: StyleProp<ViewStyle>;
|
|
63
|
+
testID?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* O campo em que se DIGITA para achar um item.
|
|
67
|
+
*
|
|
68
|
+
* ```tsx
|
|
69
|
+
* // catálogo remoto — a Aurea não filtra, o app busca
|
|
70
|
+
* <Field label="Item">
|
|
71
|
+
* <Combobox
|
|
72
|
+
* items={resultados}
|
|
73
|
+
* value={escolhido}
|
|
74
|
+
* onValueChange={setEscolhido}
|
|
75
|
+
* onSearchChange={buscarNoServidor}
|
|
76
|
+
* loading={buscando}
|
|
77
|
+
* onEndReached={proximaPagina}
|
|
78
|
+
* />
|
|
79
|
+
* </Field>
|
|
80
|
+
*
|
|
81
|
+
* // lista na mão — a Aurea filtra
|
|
82
|
+
* <Combobox items={unidades} value={unidade} onValueChange={setUnidade} />
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* ⚠ **O gatilho é `button`, não `combobox`** — e desta vez a razão é medida, não herdada do
|
|
86
|
+
* `Select`: `role="combobox"` mapeia no Android (`roleDescription`) e **não mapeia no iOS**; e o
|
|
87
|
+
* gatilho, de qualquer forma, não aceita digitação. Quem digita é o campo da folha, que leva
|
|
88
|
+
* `role="search"` — esse mapeia nos dois. A tabela com arquivo e linha está no topo deste módulo.
|
|
89
|
+
*
|
|
90
|
+
* ⚠ **Ele não guarda a escolha nem o texto buscado.** `value` e o que se digita são do app, como
|
|
91
|
+
* na web e pela mesma razão do achado I1 da auditoria: um componente com a sua própria cópia do
|
|
92
|
+
* estado é a segunda fonte de verdade que ninguém sabe que existe.
|
|
93
|
+
*/
|
|
94
|
+
export declare function Combobox({ items, value, onValueChange, onSearchChange, searchDelay, loading, onEndReached, placeholder, searchPlaceholder, empty, clearable, draggable, disabled, size, chevron, searchIcon, style, testID, }: ComboboxProps): React.JSX.Element;
|
|
95
|
+
export interface SearchFieldProps {
|
|
96
|
+
value?: string;
|
|
97
|
+
onChangeText?: (v: string) => void;
|
|
98
|
+
/** Chamado com o texto já esperado. Mesma espera do `Combobox`, e mesmo padrão de 250 ms. */
|
|
99
|
+
onSearchChange?: (query: string) => void;
|
|
100
|
+
searchDelay?: number;
|
|
101
|
+
placeholder?: string;
|
|
102
|
+
disabled?: boolean;
|
|
103
|
+
size?: AureaFieldSize;
|
|
104
|
+
/** O glifo da lupa. Padrão `search`; `false` tira. */
|
|
105
|
+
icon?: IconName | false;
|
|
106
|
+
/** Mostra o botão de limpar quando há texto. Padrão **true**. */
|
|
107
|
+
clearable?: boolean;
|
|
108
|
+
onSubmit?: () => void;
|
|
109
|
+
style?: StyleProp<ViewStyle>;
|
|
110
|
+
testID?: string;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* A lupa + o campo, numa peça só.
|
|
114
|
+
*
|
|
115
|
+
* ⚠ **Não é o mesmo papel do `Combobox`, e confundir os dois é o erro comum:** o `Combobox`
|
|
116
|
+
* ESCOLHE um item de um catálogo e devolve a escolha; este FILTRA o que já está na tela e devolve
|
|
117
|
+
* texto. Um cadastro pede o primeiro; uma lista com muitas linhas pede o segundo.
|
|
118
|
+
*
|
|
119
|
+
* ⚠ **`role="search"`, e ele mapeia nos dois sistemas** — conferido no fonte do RN 0.87.1, com
|
|
120
|
+
* arquivo e linha no topo deste módulo. É a diferença entre este componente e o `Combobox`, cujo
|
|
121
|
+
* gatilho não pôde levar `combobox` porque o iOS não tem o trait.
|
|
122
|
+
*
|
|
123
|
+
* ⚠ **A borda mora no GRUPO, não no campo** — é o `.input-group` da web (`aurea.css:741`), e é o
|
|
124
|
+
* que deixa lupa, campo e botão de limpar dentro de uma caixa só em vez de três.
|
|
125
|
+
*/
|
|
126
|
+
export declare function SearchField({ value, onChangeText, onSearchChange, searchDelay, placeholder, disabled, size, icon, clearable, onSubmit, style, testID, }: SearchFieldProps): React.JSX.Element;
|