@aurea-uds/native 0.13.0 → 0.14.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/dist/busca.d.ts +6 -0
- package/dist/busca.js +3 -3
- package/dist/estilos.d.ts +17 -0
- package/dist/estilos.js +20 -0
- package/dist/index.d.ts +2 -2
- package/dist/inputs.d.ts +9 -1
- package/dist/inputs.js +10 -18
- package/dist/navigation.d.ts +10 -1
- package/dist/navigation.js +29 -6
- package/dist/numero.d.ts +17 -1
- package/dist/numero.js +10 -5
- package/dist/text.js +1 -1
- package/package.json +2 -2
package/dist/busca.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ import { type AureaFieldSize } from "./inputs.js";
|
|
|
6
6
|
export interface AureaComboboxItem {
|
|
7
7
|
value: string;
|
|
8
8
|
label: string;
|
|
9
|
+
/**
|
|
10
|
+
* Uma segunda linha embaixo do rótulo, apagada ("Pacote de 1 kg") — R-14, 01/10/2026. É o
|
|
11
|
+
* `Select.ItemDescription` do HeroUI Native 1.0.10 (`styles/components/select.css:117`): letra
|
|
12
|
+
* `text-sm` (14), cor apagada. A busca continua olhando só o `label`.
|
|
13
|
+
*/
|
|
14
|
+
description?: string;
|
|
9
15
|
disabled?: boolean;
|
|
10
16
|
}
|
|
11
17
|
export interface ComboboxProps {
|
package/dist/busca.js
CHANGED
|
@@ -322,13 +322,13 @@ export function Combobox({ items, value, onValueChange, onSearchChange, searchDe
|
|
|
322
322
|
color: t.color.foreground },
|
|
323
323
|
] }), texto.length > 0 && (_jsx(IconButton, { name: "x", label: strings.searchClear, appearance: "ghost", size: "sm", onPress: () => digitar(""), testID: testID ? `${testID}-busca-limpar` : undefined }))] }), loading && (_jsx(View, { style: s.carregando, children: _jsx(Spinner, { label: strings.comboboxLoading }) })), nada && (_jsx(View, { style: s.vazio, children: typeof empty === "string" || empty == null
|
|
324
324
|
? _jsx(Text, { size: "sm", tone: "muted", children: empty ?? strings.comboboxEmpty })
|
|
325
|
-
: empty })), _jsx(FlatList, { data: filtrados, keyExtractor: (i) => i.value, keyboardShouldPersistTaps: "handled", onEndReached: onEndReached, onEndReachedThreshold: ANTECEDENCIA_DE_PAGINA, renderItem: ({ item }) => (
|
|
325
|
+
: empty })), _jsx(FlatList, { data: filtrados, keyExtractor: (i) => i.value, keyboardShouldPersistTaps: "handled", onEndReached: onEndReached, onEndReachedThreshold: ANTECEDENCIA_DE_PAGINA, renderItem: ({ item }) => (_jsxs(Pressable, { disabled: item.disabled, onPress: () => { onValueChange?.(item); fechar(); }, accessibilityRole: "menuitem", ...estadoAcessivel({
|
|
326
326
|
selected: item.value === value?.value, disabled: !!item.disabled,
|
|
327
|
-
}), style: [
|
|
327
|
+
}), accessibilityHint: item.description, style: [
|
|
328
328
|
s.opcao,
|
|
329
329
|
item.value === value?.value && s.opcaoEscolhida,
|
|
330
330
|
item.disabled && s.desabilitado,
|
|
331
|
-
], children: _jsx(Text, { size: "md", weight: item.value === value?.value ? 600 : 400, children: item.label }) })) }), _jsx(RecuoDaFolha, { comTeclado: true })] })] }) }) })] }));
|
|
331
|
+
], children: [_jsx(Text, { size: "md", weight: item.value === value?.value ? 600 : 400, children: item.label }), item.description != null && (_jsx(Text, { size: "xs", tone: "muted", children: item.description }))] })) }), _jsx(RecuoDaFolha, { comTeclado: true })] })] }) }) })] }));
|
|
332
332
|
}
|
|
333
333
|
// ── A DOBRA DE ACENTO, e por que ela é sondada em vez de presumida ───────────────────────────
|
|
334
334
|
// Buscar "acucar" tem de achar "açúcar" — num catálogo em português, exigir o acento certo é
|
package/dist/estilos.d.ts
CHANGED
|
@@ -33,6 +33,23 @@ export declare function criarFolha<T extends NamedStyles<T> | NamedStyles<Record
|
|
|
33
33
|
* um ícone) não tinha como escrevê-lo sem número à mão. O `check 39` cobra o teste dele.
|
|
34
34
|
*/
|
|
35
35
|
export declare const comOpacidade: (cor: string, pct: number) => string;
|
|
36
|
+
/**
|
|
37
|
+
* 🔴 O FIO AMARELO DO ESCOLHIDO — o sinal único da casa para "este é o escolhido".
|
|
38
|
+
*
|
|
39
|
+
* O `aurea.css:1037-1039` põe este fio em TODOS os selecionados (`.is-selected`, botão alternado,
|
|
40
|
+
* `.segmented button.active`, item ativo da lateral), e o comentário de lá diz por quê: *"Um
|
|
41
|
+
* usuário aprende uma vez e reconhece em todo lugar (pedido do Victor, 24/07)."* Os três números
|
|
42
|
+
* saem daquela linha, não daqui: altura 2 (fração de pixel borra), recuo 15 de cada lado
|
|
43
|
+
* (`inset-inline:15px`), e o amarelo a 75% (cheio ele grita mais que o próprio rótulo).
|
|
44
|
+
*
|
|
45
|
+
* ⚠ **Morava dentro do `SegmentedControl` e mudou de casa em 01/10/2026**, quando a aba de
|
|
46
|
+
* `<Tabs variant="secondary">` (R-12) passou a precisar do mesmo fio. Copiar os números para o
|
|
47
|
+
* segundo arquivo é o defeito que o `CLAUDE.md` nomeia. Quem desenha o fio, desenha este.
|
|
48
|
+
*
|
|
49
|
+
* ⚠ Em peça estreita o recuo de 15 de cada lado zera a largura e o fio some — **e é o mesmo
|
|
50
|
+
* comportamento da web**, onde `inset-inline:15px` numa caixa estreita não desenha nada.
|
|
51
|
+
*/
|
|
52
|
+
export declare const fioDoEscolhido: (t: AureaTokens) => ViewStyle;
|
|
36
53
|
/**
|
|
37
54
|
* A reação ao TOQUE de tudo que é alvo inteiro — hoje o `Button`, o `IconButton` e o `Card` com
|
|
38
55
|
* `onPress`. Os números são os do core: `.btn:active { transform:scale(.97); opacity:.9 }` e
|
package/dist/estilos.js
CHANGED
|
@@ -49,6 +49,26 @@ export function criarFolha(descrever) {
|
|
|
49
49
|
export const comOpacidade = (cor, pct) => /^#[0-9a-fA-F]{6}$/.test(cor)
|
|
50
50
|
? cor + Math.round(Math.max(0, Math.min(1, pct)) * 255).toString(16).padStart(2, "0")
|
|
51
51
|
: cor;
|
|
52
|
+
/**
|
|
53
|
+
* 🔴 O FIO AMARELO DO ESCOLHIDO — o sinal único da casa para "este é o escolhido".
|
|
54
|
+
*
|
|
55
|
+
* O `aurea.css:1037-1039` põe este fio em TODOS os selecionados (`.is-selected`, botão alternado,
|
|
56
|
+
* `.segmented button.active`, item ativo da lateral), e o comentário de lá diz por quê: *"Um
|
|
57
|
+
* usuário aprende uma vez e reconhece em todo lugar (pedido do Victor, 24/07)."* Os três números
|
|
58
|
+
* saem daquela linha, não daqui: altura 2 (fração de pixel borra), recuo 15 de cada lado
|
|
59
|
+
* (`inset-inline:15px`), e o amarelo a 75% (cheio ele grita mais que o próprio rótulo).
|
|
60
|
+
*
|
|
61
|
+
* ⚠ **Morava dentro do `SegmentedControl` e mudou de casa em 01/10/2026**, quando a aba de
|
|
62
|
+
* `<Tabs variant="secondary">` (R-12) passou a precisar do mesmo fio. Copiar os números para o
|
|
63
|
+
* segundo arquivo é o defeito que o `CLAUDE.md` nomeia. Quem desenha o fio, desenha este.
|
|
64
|
+
*
|
|
65
|
+
* ⚠ Em peça estreita o recuo de 15 de cada lado zera a largura e o fio some — **e é o mesmo
|
|
66
|
+
* comportamento da web**, onde `inset-inline:15px` numa caixa estreita não desenha nada.
|
|
67
|
+
*/
|
|
68
|
+
export const fioDoEscolhido = (t) => ({
|
|
69
|
+
position: "absolute", left: 15, right: 15, bottom: 0, height: 2,
|
|
70
|
+
borderRadius: t.size.radiusFull, backgroundColor: comOpacidade(t.color.primary, 0.75),
|
|
71
|
+
});
|
|
52
72
|
/**
|
|
53
73
|
* A reação ao TOQUE de tudo que é alvo inteiro — hoje o `Button`, o `IconButton` e o `Card` com
|
|
54
74
|
* `onPress`. Os números são os do core: `.btn:active { transform:scale(.97); opacity:.9 }` e
|
package/dist/index.d.ts
CHANGED
|
@@ -23,7 +23,7 @@ export { defaultStrings, ptBR, gravidadeDoEstado, AUREA_UNIVERSAL_STATES } from
|
|
|
23
23
|
export type { AureaStrings, AureaUniversalState } from "./strings.js";
|
|
24
24
|
export { useReduceMotion } from "./movimento.js";
|
|
25
25
|
export { BottomNav, Topbar, NavList, Stepper, Tabs } from "./navigation.js";
|
|
26
|
-
export type { BottomNavProps, TopbarProps, NavListProps, StepperProps, AureaNavItem, AureaNavListItem, AureaStepItem, AureaStepState, AureaBottomNavVariant, AureaBottomNavIndicator, AureaBottomNavWidth, AureaTopbarVariant, AureaTopbarInset, TabsProps, AureaTabItem, } from "./navigation.js";
|
|
26
|
+
export type { BottomNavProps, TopbarProps, NavListProps, StepperProps, AureaNavItem, AureaNavListItem, AureaStepItem, AureaStepState, AureaBottomNavVariant, AureaBottomNavIndicator, AureaBottomNavWidth, AureaTopbarVariant, AureaTopbarInset, TabsProps, AureaTabItem, AureaTabsVariant, } from "./navigation.js";
|
|
27
27
|
export { Field, Label, Input, Textarea, Select, Switch, Checkbox, Radio, RadioGroup, SegmentedControl, Form, KeyboardAvoiding, useCampo, } from "./inputs.js";
|
|
28
28
|
export type { FieldProps, LabelProps, InputProps, TextareaProps, SelectProps, SwitchProps, CheckboxProps, RadioProps, RadioGroupProps, RadioGroupItemProps, AureaRadioIndicatorPlacement, SegmentedControlProps, FormProps, KeyboardAvoidingProps, AureaFieldSize, } from "./inputs.js";
|
|
29
29
|
export { InputGroup, InputGroupAddon, PasswordField, useGrupoDeCampo } from "./inputs.js";
|
|
@@ -39,7 +39,7 @@ export type { ChartProps, ChartLegendProps, AureaSeries, AureaChartMark } from "
|
|
|
39
39
|
export { Combobox, SearchField } from "./busca.js";
|
|
40
40
|
export type { ComboboxProps, SearchFieldProps, AureaComboboxItem } from "./busca.js";
|
|
41
41
|
export { NumberField, formatarNumero, lerNumero, separadoresDoLocale } from "./numero.js";
|
|
42
|
-
export type { NumberFieldProps, AureaSeparadores } from "./numero.js";
|
|
42
|
+
export type { NumberFieldProps, AureaSeparadores, AureaNumberFieldSize } from "./numero.js";
|
|
43
43
|
export { Image, Gallery } from "./midia.js";
|
|
44
44
|
export type { ImageProps, GalleryProps, AureaGalleryItem, AureaImageSource, } from "./midia.js";
|
|
45
45
|
export type { AureaFilaJustify } from "./rolagem.js";
|
package/dist/inputs.d.ts
CHANGED
|
@@ -282,10 +282,18 @@ export interface RadioGroupItemProps extends Omit<PressableProps, "children" | "
|
|
|
282
282
|
invalid?: boolean;
|
|
283
283
|
/** O lado da marca só neste item; sem ele, vale o do grupo. */
|
|
284
284
|
indicatorPlacement?: AureaRadioIndicatorPlacement;
|
|
285
|
+
/**
|
|
286
|
+
* Um ícone antes do texto (R-19, 01/10/2026). O HeroUI não tem esta prop: no `RadioGroup.Item`
|
|
287
|
+
* dele o ícone entra como mais um filho, e a Aurea traduz filho livre em nome de ícone, como em
|
|
288
|
+
* todo o resto. Tamanho `iconLg` (24, o mesmo da marca; o HeroUI usa 22 nos ícones de lista, que
|
|
289
|
+
* não existe aqui — escolha do Victor), vão de 12 até o texto. Na opção escolhida sai a forma
|
|
290
|
+
* cheia (ADR-0053), se o registro a tiver.
|
|
291
|
+
*/
|
|
292
|
+
icon?: IconName;
|
|
285
293
|
style?: StyleProp<ViewStyle>;
|
|
286
294
|
}
|
|
287
295
|
declare function RaizDoGrupoDeRadio({ value, onValueChange, disabled, invalid, label, orientation, indicatorPlacement, style, children, ...rest }: RadioGroupProps): React.JSX.Element;
|
|
288
|
-
declare function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indicatorPlacement, style, accessibilityLabel, ...rest }: RadioGroupItemProps): React.JSX.Element;
|
|
296
|
+
declare function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indicatorPlacement, icon, style, accessibilityLabel, ...rest }: RadioGroupItemProps): React.JSX.Element;
|
|
289
297
|
/**
|
|
290
298
|
* Um conjunto de opções em que só uma fica escolhida — o `RadioGroup` do HeroUI Native.
|
|
291
299
|
*
|
package/dist/inputs.js
CHANGED
|
@@ -39,7 +39,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
39
39
|
// .segmented :922 linha, gap 3, padding 3, minH controlHMd, fundo muted
|
|
40
40
|
import * as React from "react";
|
|
41
41
|
import { Animated, KeyboardAvoidingView as KeyboardAvoidingViewRN, Modal, Platform, Pressable, ScrollView, TextInput, View, } from "react-native";
|
|
42
|
-
import {
|
|
42
|
+
import { criarFolha, estadoAcessivel, fioDoEscolhido } from "./estilos.js";
|
|
43
43
|
import { FilaRolante } from "./rolagem.js";
|
|
44
44
|
import { IconButton } from "./actions.js";
|
|
45
45
|
import { Icon } from "./icon.js";
|
|
@@ -99,20 +99,9 @@ const folha = criarFolha((t) => ({
|
|
|
99
99
|
segmento: { flex: 1, alignItems: "center", justifyContent: "center",
|
|
100
100
|
paddingHorizontal: 14, borderRadius: t.size.radiusControl },
|
|
101
101
|
segmentoAtivo: { backgroundColor: t.color.secondary },
|
|
102
|
-
// 🔴 O FIO AMARELO DO ESCOLHIDO — ele faltava, e a falta era metade do defeito C4.
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
// diz por quê, com data: *"Item de nav ativo, aba ativa, item de lista lateral e botão
|
|
106
|
-
// alternado ligado mostram o MESMO sinal (…) Um usuário aprende uma vez e reconhece em todo
|
|
107
|
-
// lugar (pedido do Victor, 24/07)."*
|
|
108
|
-
// Os três números saem daquela linha, não de mim: altura 2 (fração de pixel borra), recuo 15,
|
|
109
|
-
// e o amarelo a 75% (cheio ele grita mais que o próprio rótulo).
|
|
110
|
-
// ⚠ Em segmento estreito o recuo de 15 de cada lado zera a largura e o fio some — **e é o
|
|
111
|
-
// mesmo comportamento da web**, onde `inset-inline:15px` num box estreito não desenha nada.
|
|
112
|
-
fioDoSegmento: {
|
|
113
|
-
position: "absolute", left: 15, right: 15, bottom: 0, height: 2,
|
|
114
|
-
borderRadius: t.size.radiusFull, backgroundColor: comOpacidade(t.color.primary, 0.75),
|
|
115
|
-
},
|
|
102
|
+
// 🔴 O FIO AMARELO DO ESCOLHIDO — ele faltava, e a falta era metade do defeito C4. Os números
|
|
103
|
+
// e a razão moram no `fioDoEscolhido` (`estilos.ts`), que a aba do `Tabs` secundário também usa.
|
|
104
|
+
fioDoSegmento: fioDoEscolhido(t),
|
|
116
105
|
formulario: { gap: t.size.space5 },
|
|
117
106
|
// A folha do `Select`: no RN não existe `<select>`, então a lista é um `Modal` — que é
|
|
118
107
|
// exatamente o "motor novo sobre `Modal`" que a §5.2.4 previu.
|
|
@@ -388,7 +377,7 @@ function RaizDoGrupoDeRadio({ value, onValueChange, disabled, invalid, label, or
|
|
|
388
377
|
const contexto = React.useMemo(() => ({ value, onValueChange, disabled, invalid, indicatorPlacement }), [value, onValueChange, disabled, invalid, indicatorPlacement]);
|
|
389
378
|
return (_jsx(GrupoDeRadio.Provider, { value: contexto, children: _jsx(View, { accessibilityRole: "radiogroup", accessibilityLabel: label, ...estadoAcessivel({ disabled: !!disabled }), style: [{ gap: t.size.space3, flexDirection: orientation === "horizontal" ? "row" : "column" }, style], ...rest, children: children }) }));
|
|
390
379
|
}
|
|
391
|
-
function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indicatorPlacement, style, accessibilityLabel, ...rest }) {
|
|
380
|
+
function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indicatorPlacement, icon, style, accessibilityLabel, ...rest }) {
|
|
392
381
|
const t = useAureaTokens();
|
|
393
382
|
const s = folha(t);
|
|
394
383
|
const grupo = React.useContext(GrupoDeRadio);
|
|
@@ -403,7 +392,7 @@ function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indi
|
|
|
403
392
|
const noInicio = (indicatorPlacement ?? grupo?.indicatorPlacement ?? "end") === "start";
|
|
404
393
|
const texto = (label != null || description != null) && (_jsxs(View, { style: { flex: 1, minWidth: 0 }, children: [typeof label === "string"
|
|
405
394
|
? _jsx(Text, { size: "base", weight: 500, tone: erro ? "danger" : "default", children: label }) : label, description != null && (typeof description === "string"
|
|
406
|
-
? _jsx(Text, { size: "
|
|
395
|
+
? _jsx(Text, { size: "xs", tone: "muted", children: description }) : description)] }, "texto"));
|
|
407
396
|
const marcaDesenhada = (_jsx(View, { style: [
|
|
408
397
|
s.marcaBase,
|
|
409
398
|
{ width: marca, height: marca, borderRadius: t.size.radiusFull },
|
|
@@ -412,11 +401,14 @@ function ItemDoGrupoDeRadio({ value, label, description, disabled, invalid, indi
|
|
|
412
401
|
borderColor: erro ? perigo : t.color.controlSelected },
|
|
413
402
|
], children: escolhido && _jsx(View, { style: { width: ponto, height: ponto, borderRadius: t.size.radiusFull,
|
|
414
403
|
backgroundColor: t.color.controlSelectedForeground } }) }, "marca"));
|
|
404
|
+
// O ícone é decorativo: o rótulo já diz o que a opção é, e o `Icon` sem `label` sai da árvore
|
|
405
|
+
// de acessibilidade. A cor acompanha a do rótulo, inclusive no erro.
|
|
406
|
+
const glifo = icon != null && (_jsx(Icon, { name: icon, size: "lg", weight: escolhido ? "fill" : "regular", color: erro ? perigo : t.color.foreground }, "icone"));
|
|
415
407
|
return (_jsx(Pressable, { onPress: inativo || escolhido ? undefined : () => grupo?.onValueChange?.(value), disabled: inativo, accessibilityRole: "radio", ...estadoAcessivel({ checked: escolhido, disabled: !!inativo }), accessibilityLabel: accessibilityLabel ?? (typeof label === "string" ? label : undefined), accessibilityHint: typeof description === "string" ? description : undefined, style: [
|
|
416
408
|
{ flexDirection: "row", alignItems: "center", justifyContent: "space-between",
|
|
417
409
|
gap: t.size.space3, minHeight: t.size.targetMin },
|
|
418
410
|
inativo && s.desabilitado, style,
|
|
419
|
-
], ...rest, children: noInicio ? [marcaDesenhada, texto] : [texto, marcaDesenhada] }));
|
|
411
|
+
], ...rest, children: noInicio ? [marcaDesenhada, glifo, texto] : [glifo, texto, marcaDesenhada] }));
|
|
420
412
|
}
|
|
421
413
|
/**
|
|
422
414
|
* Um conjunto de opções em que só uma fica escolhida — o `RadioGroup` do HeroUI Native.
|
package/dist/navigation.d.ts
CHANGED
|
@@ -200,7 +200,16 @@ export interface TabsProps extends ViewProps {
|
|
|
200
200
|
label?: string;
|
|
201
201
|
/** Onde a fila de abas fica quando cabe: `start` (padrão), `center` ou `end` (E3). */
|
|
202
202
|
justify?: AureaFilaJustify;
|
|
203
|
+
/**
|
|
204
|
+
* O jeito da fila, com os nomes do HeroUI (R-12, 01/10/2026):
|
|
205
|
+
* - `primary` (padrão): a cápsula, com a aba aberta num fundo `secondary`.
|
|
206
|
+
* - `secondary`: sem cápsula — um fio fino embaixo da fila inteira e o **fio amarelo** da casa
|
|
207
|
+
* embaixo da aba aberta, o mesmo do `SegmentedControl`.
|
|
208
|
+
*/
|
|
209
|
+
variant?: AureaTabsVariant;
|
|
203
210
|
}
|
|
211
|
+
/** Os dois jeitos da fila de abas, com os nomes do `Tabs` do HeroUI Native. */
|
|
212
|
+
export type AureaTabsVariant = "primary" | "secondary";
|
|
204
213
|
/**
|
|
205
214
|
* As abas DENTRO da tela — trocar o painel, não trocar de página.
|
|
206
215
|
*
|
|
@@ -234,4 +243,4 @@ export interface TabsProps extends ViewProps {
|
|
|
234
243
|
* largura de tela grande. Não há tablet medido neste projeto, e no nativo vale demanda antes de
|
|
235
244
|
* cobertura — a mesma decisão da `Table` do Lote 6.
|
|
236
245
|
*/
|
|
237
|
-
export declare function Tabs({ tabs, value, onChange, label, justify, style, ...rest }: TabsProps): React.JSX.Element;
|
|
246
|
+
export declare function Tabs({ tabs, value, onChange, label, justify, variant, style, ...rest }: TabsProps): React.JSX.Element;
|
package/dist/navigation.js
CHANGED
|
@@ -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 { Badge } from "./display.js";
|
|
6
|
-
import { comOpacidade, criarFolha, estadoAcessivel } from "./estilos.js";
|
|
6
|
+
import { 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";
|
|
@@ -133,6 +133,24 @@ const folha = criarFolha((t) => ({
|
|
|
133
133
|
paddingHorizontal: 14, borderRadius: t.size.radiusControl,
|
|
134
134
|
},
|
|
135
135
|
abaDeTabAtiva: { backgroundColor: t.color.secondary },
|
|
136
|
+
// `variant="secondary"` (R-12, 01/10/2026): o `secondary` do HeroUI Native 1.0.10
|
|
137
|
+
// (`styles/components/tabs.css`), com o fio da casa no lugar do indicador azul deles.
|
|
138
|
+
// .tabs__list--variant-secondary padding 0 · border-bottom 1px, cor da borda
|
|
139
|
+
// .tabs__list gap `* 1` → space1
|
|
140
|
+
// .tabs__trigger padding-inline `* 3` → space3 · padding-block `* 1.5`
|
|
141
|
+
// → space1 + space05. Rótulo `text-base` + entrelinha 1.5 dá
|
|
142
|
+
// 36, que é o `controlHMd`: a altura da fila da cápsula, então
|
|
143
|
+
// trocar de variante não muda a altura da fila.
|
|
144
|
+
// .tabs__indicator--variant-secondary border-bottom 2px na cor de destaque → `fioDoEscolhido`
|
|
145
|
+
abasSecundarias: {
|
|
146
|
+
flexDirection: "row", gap: t.size.space1,
|
|
147
|
+
borderBottomWidth: t.size.borderWidth, borderColor: t.color.border,
|
|
148
|
+
},
|
|
149
|
+
abaSecundaria: {
|
|
150
|
+
alignItems: "center", justifyContent: "center", minHeight: t.size.controlHMd,
|
|
151
|
+
paddingHorizontal: t.size.space3, paddingVertical: t.size.space1 + t.size.space05,
|
|
152
|
+
},
|
|
153
|
+
fioDaAba: fioDoEscolhido(t),
|
|
136
154
|
painel: { marginTop: t.size.space3 },
|
|
137
155
|
// ── Stepper ────────────────────────────────────────────────────────────────────────────────
|
|
138
156
|
trilha: { flexDirection: "row" },
|
|
@@ -418,16 +436,21 @@ export function Stepper({ items, label, doneIcon = "check", errorIcon = "x-circl
|
|
|
418
436
|
* largura de tela grande. Não há tablet medido neste projeto, e no nativo vale demanda antes de
|
|
419
437
|
* cobertura — a mesma decisão da `Table` do Lote 6.
|
|
420
438
|
*/
|
|
421
|
-
export function Tabs({ tabs, value, onChange, label, justify, style, ...rest }) {
|
|
439
|
+
export function Tabs({ tabs, value, onChange, label, justify, variant = "primary", style, ...rest }) {
|
|
422
440
|
const t = useAureaTokens();
|
|
423
441
|
const s = folha(t);
|
|
424
442
|
const strings = useAureaStrings();
|
|
425
443
|
const aberta = tabs.find((it) => it.id === value);
|
|
426
|
-
|
|
444
|
+
const secundaria = variant === "secondary";
|
|
445
|
+
return (_jsxs(View, { style: style, ...rest, children: [_jsx(FilaRolante, { justify: justify, children: _jsx(View, { accessibilityRole: "tablist", accessibilityLabel: label ?? strings.tabsLabel, style: secundaria ? s.abasSecundarias : s.abas, children: tabs.map((it) => {
|
|
427
446
|
const ativa = it.id === value;
|
|
428
|
-
return (
|
|
429
|
-
|
|
430
|
-
|
|
447
|
+
return (_jsxs(Pressable, { onPress: it.disabled ? undefined : () => onChange?.(it.id), disabled: it.disabled, accessibilityRole: "tab", ...estadoAcessivel({ selected: ativa, disabled: !!it.disabled }), accessibilityLabel: typeof it.label === "string" ? it.label : undefined, style: [
|
|
448
|
+
secundaria ? s.abaSecundaria : s.abaDeTab,
|
|
449
|
+
ativa && !secundaria && s.abaDeTabAtiva,
|
|
450
|
+
it.disabled && { opacity: t.size.opacityDisabled },
|
|
451
|
+
], children: [typeof it.label === "string"
|
|
452
|
+
? _jsx(Text, { size: "sm", weight: ativa ? 600 : 400, style: { color: ativa ? t.color.foreground : t.color.mutedForeground }, children: it.label })
|
|
453
|
+
: it.label, ativa && secundaria && _jsx(View, { style: s.fioDaAba })] }, it.id));
|
|
431
454
|
}) }) }), aberta
|
|
432
455
|
? (_jsx(Card, { variant: "inset", accessibilityLabel: typeof aberta.label === "string" ? aberta.label : undefined, style: s.painel, children: aberta.content }))
|
|
433
456
|
: null] }));
|
package/dist/numero.d.ts
CHANGED
|
@@ -2,6 +2,18 @@ import * as React from "react";
|
|
|
2
2
|
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
3
|
import type { IconName } from "./icon-names.js";
|
|
4
4
|
import { type AureaFieldSize } from "./inputs.js";
|
|
5
|
+
/**
|
|
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 —
|
|
9
|
+
* e as medidas saem de escalas que JÁ existem, nenhuma nova:
|
|
10
|
+
* letra `text3xl` (30) em seminegrito — o título 2 (`h2` do B-02). Escolha do Victor.
|
|
11
|
+
* altura `controlHXl` — o degrau seguinte da escala de altura dos controles, que muda com a
|
|
12
|
+
* densidade como as outras três.
|
|
13
|
+
* largura `space24` (96): o `space16` (64) do campo comum não cabe "1.234" em 30.
|
|
14
|
+
* botões os do `lg`, o maior do `IconButton`.
|
|
15
|
+
*/
|
|
16
|
+
export type AureaNumberFieldSize = AureaFieldSize | "display";
|
|
5
17
|
/** Os separadores de um locale, derivados de um número-sonda. */
|
|
6
18
|
export type AureaSeparadores = {
|
|
7
19
|
decimal: string;
|
|
@@ -52,7 +64,11 @@ export interface NumberFieldProps {
|
|
|
52
64
|
disabled?: boolean;
|
|
53
65
|
/** Mostra o valor e não deixa editar — os botões também somem. */
|
|
54
66
|
readOnly?: boolean;
|
|
55
|
-
|
|
67
|
+
/**
|
|
68
|
+
* `sm` · `md` · `lg`, como os outros campos, e `display`: o número grande de destaque, com a
|
|
69
|
+
* letra do título 2 (30). Ver `AureaNumberFieldSize`. Moeda em `display` pede `fullWidth`.
|
|
70
|
+
*/
|
|
71
|
+
size?: AureaNumberFieldSize;
|
|
56
72
|
/**
|
|
57
73
|
* Ocupa a largura disponível em vez de abraçar o conteúdo. Padrão **false**.
|
|
58
74
|
*
|
package/dist/numero.js
CHANGED
|
@@ -50,8 +50,10 @@ import { IconButton } from "./actions.js";
|
|
|
50
50
|
import { criarFolha, estadoAcessivel } from "./estilos.js";
|
|
51
51
|
import { useCampo } from "./inputs.js";
|
|
52
52
|
import { useAureaStrings, useAureaTokens, usePeleSobreAMarca } from "./theme.js";
|
|
53
|
-
const alturaDoTamanho = (t, s) => s === "sm" ? t.size.controlHSm : s === "lg" ? t.size.controlHLg
|
|
54
|
-
|
|
53
|
+
const alturaDoTamanho = (t, s) => s === "sm" ? t.size.controlHSm : s === "lg" ? t.size.controlHLg
|
|
54
|
+
: s === "display" ? t.size.controlHXl : t.size.controlHMd;
|
|
55
|
+
const fonteDoTamanho = (t, s) => s === "sm" ? t.size.textSm : s === "lg" ? t.size.textLg
|
|
56
|
+
: s === "display" ? t.size.text3xl : t.size.textBase; // ADR-0050: um degrau acima da web
|
|
55
57
|
const folha = criarFolha((t) => ({
|
|
56
58
|
// 🔴 ELE ESTICAVA, E NÃO DEVIA — achado em 12/09/2026, olhando a primeira imagem da vitrine.
|
|
57
59
|
//
|
|
@@ -79,6 +81,7 @@ const folha = criarFolha((t) => ({
|
|
|
79
81
|
paddingVertical: 0, textAlignVertical: "center",
|
|
80
82
|
},
|
|
81
83
|
campoLargo: { width: undefined, flex: 1, minWidth: t.size.space16 },
|
|
84
|
+
campoDisplay: { width: t.size.space24 },
|
|
82
85
|
invalido: { borderColor: t.color.danger400 ?? t.color.destructive },
|
|
83
86
|
desabilitado: { opacity: t.size.opacityDisabled },
|
|
84
87
|
}));
|
|
@@ -250,6 +253,7 @@ export function NumberField({ value, defaultValue, onValueChange, min, max, step
|
|
|
250
253
|
const strings = useAureaStrings();
|
|
251
254
|
const campo = useCampo();
|
|
252
255
|
const tam = size ?? campo?.size ?? "md";
|
|
256
|
+
const tamDoBotao = tam === "display" ? "lg" : tam;
|
|
253
257
|
const inativo = disabled ?? campo?.disabled;
|
|
254
258
|
const [interno, setInterno] = React.useState(defaultValue ?? null);
|
|
255
259
|
const numero = value !== undefined ? value : interno;
|
|
@@ -355,14 +359,15 @@ export function NumberField({ value, defaultValue, onValueChange, min, max, step
|
|
|
355
359
|
// (`aurea.css:685`), com os dois botões FORA dela. O estado que faltava é o deles; a geometria
|
|
356
360
|
// continua sendo a nossa.
|
|
357
361
|
const [focado, setFocado] = React.useState(false);
|
|
358
|
-
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:
|
|
362
|
+
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,
|
|
359
363
|
// O nome vem do `Field`, como em todo controle deste pacote — e `label` cobre quem usa o
|
|
360
364
|
// campo solto. Sem um dos dois, é um nó anônimo para o leitor de tela.
|
|
361
365
|
accessibilityLabel: label ?? campo?.label, accessibilityHint: campo?.hint, ...estadoAcessivel({ disabled: !!inativo }), "aria-invalid": campo?.invalido, style: [
|
|
362
366
|
s.campo,
|
|
367
|
+
tam === "display" && s.campoDisplay,
|
|
363
368
|
fullWidth && s.campoLargo,
|
|
364
369
|
{ height: alturaDoTamanho(t, tam), fontSize: fonteDoTamanho(t, tam),
|
|
365
|
-
fontFamily: t.font.ui[400], color: t.color.foreground },
|
|
370
|
+
fontFamily: t.font.ui[tam === "display" ? 600 : 400], color: t.color.foreground },
|
|
366
371
|
campo?.invalido && s.invalido,
|
|
367
372
|
// A ORDEM IMPORTA e é a mesma do `Input` do Lote 4: o inválido vem antes, o foco
|
|
368
373
|
// depois. Um campo inválido que está sendo corrigido tem de mostrar que está ativo —
|
|
@@ -373,5 +378,5 @@ export function NumberField({ value, defaultValue, onValueChange, min, max, step
|
|
|
373
378
|
// O foco continua existindo, por espessura.
|
|
374
379
|
peleDaMarca,
|
|
375
380
|
peleDaMarca && focado && { borderWidth: t.size.borderWidth * 2 },
|
|
376
|
-
] }), mostrarBotoes && (_jsx(IconButton, { name: icons.increment, label: strings.increment, appearance: "ghost", size:
|
|
381
|
+
] }), mostrarBotoes && (_jsx(IconButton, { name: icons.increment, label: strings.increment, appearance: "ghost", size: tamDoBotao, disabled: inativo || noLimite(1), onPress: () => empurrar(1), testID: testID ? `${testID}-mais` : undefined }))] }));
|
|
377
382
|
}
|
package/dist/text.js
CHANGED
|
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
3
3
|
//
|
|
4
4
|
// É o **bloqueio 3** da §5.2 do NATIVE.md, e a razão dele é estrutural, não de escopo:
|
|
5
5
|
//
|
|
6
|
-
// web: body { font-family:var(--font-ui); font-size:var(--text-
|
|
6
|
+
// web: body { font-family:var(--font-ui); font-size:var(--text-sm);
|
|
7
7
|
// line-height:var(--leading-normal) } ← e TODO <p>/<span>/<h1> herda
|
|
8
8
|
// nativo: não há cascata de estilo de texto através de `View`, e não há `<p>`.
|
|
9
9
|
//
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurea-uds/native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "A Aurea UDS para React Native: o provider de tema e densidade, os componentes e os ícones do Phosphor sobre react-native-svg.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aurea",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"NOTICE"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@aurea-uds/tokens": "^0.
|
|
54
|
+
"@aurea-uds/tokens": "^0.14.1"
|
|
55
55
|
},
|
|
56
56
|
"peerDependencies": {
|
|
57
57
|
"@react-native-community/datetimepicker": ">=8",
|