@aurea-uds/native 0.28.0 → 0.29.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.
- package/dist/busca.js +12 -9
- package/dist/index.d.ts +1 -1
- package/dist/inputs.js +5 -2
- package/dist/layout.d.ts +11 -2
- package/dist/layout.js +43 -8
- package/dist/overlays.js +5 -5
- package/dist/theme.d.ts +23 -0
- package/dist/theme.js +43 -2
- package/package.json +2 -2
package/dist/busca.js
CHANGED
|
@@ -76,7 +76,7 @@ import { KeyboardAvoiding, useCampo } from "./inputs.js";
|
|
|
76
76
|
import { useReduceMotion, driverNativo } from "./movimento.js";
|
|
77
77
|
import { RecuoDaFolha } from "./screen.js";
|
|
78
78
|
import { Text } from "./text.js";
|
|
79
|
-
import { useAureaStrings, useAureaTokens, ForaDaMarca, usePeleSobreAMarca } from "./theme.js";
|
|
79
|
+
import { useAureaStrings, useAureaTokens, useTokensDoApp, ForaDaMarca, usePeleSobreAMarca } from "./theme.js";
|
|
80
80
|
// As mesmas contas do `inputs.tsx`, e elas são repetidas AQUI de propósito: exportá-las de lá
|
|
81
81
|
// tornaria pública uma conta interna do outro módulo, e um `import` de função privada entre
|
|
82
82
|
// módulos irmãos é o começo de um acoplamento que ninguém declara. São três linhas.
|
|
@@ -215,6 +215,9 @@ const folha = criarFolha((t) => ({
|
|
|
215
215
|
export function Combobox({ items, value, onValueChange, onSearchChange, searchDelay = ESPERA_PADRAO, loading, onEndReached, placeholder, searchPlaceholder, empty, clearable = true, draggable = true, disabled, size, chevron = "caret-down", searchIcon = "magnifying-glass", searchKeyboardType, style, testID, }) {
|
|
216
216
|
const t = useAureaTokens();
|
|
217
217
|
const s = folha(t);
|
|
218
|
+
// A folha sai do fluxo: pinta com os tokens do APP (ADR-0063 — ver `useTokensDoApp`).
|
|
219
|
+
const tf = useTokensDoApp();
|
|
220
|
+
const sf = folha(tf);
|
|
218
221
|
const peleDaMarca = usePeleSobreAMarca();
|
|
219
222
|
const strings = useAureaStrings();
|
|
220
223
|
const campo = useCampo();
|
|
@@ -307,7 +310,7 @@ export function Combobox({ items, value, onValueChange, onSearchChange, searchDe
|
|
|
307
310
|
peleDaMarca,
|
|
308
311
|
inativo && s.desabilitado,
|
|
309
312
|
style,
|
|
310
|
-
], children: [_jsx(Pressable, { testID: testID, onPress: inativo ? undefined : () => setAberto(true), disabled: inativo, accessibilityRole: "button", accessibilityLabel: campo?.label, accessibilityHint: campo?.hint, accessibilityValue: { text: value?.label }, ...estadoAcessivel({ disabled: !!inativo, expanded: aberto }), style: s.gatilho, children: _jsx(Text, { size: tam === "sm" ? "xs" : tam === "lg" ? "base" : "md", tone: value ? "default" : "subtle", numberOfLines: 1, style: { flex: 1, minWidth: 0 }, children: value?.label ?? placeholder ?? "" }) }), _jsxs(View, { style: s.acoes, children: [clearable && value != null && !inativo && (_jsx(IconButton, { name: "x", label: strings.comboboxClear, appearance: "ghost", size: "sm", onPress: () => onValueChange?.(null), testID: testID ? `${testID}-limpar` : undefined })), chevron && (_jsx(Pressable, { accessible: false, disabled: inativo, style: s.setaToque, onPress: inativo ? undefined : () => setAberto(true), testID: testID ? `${testID}-seta` : undefined, children: _jsx(Icon, { name: chevron, size: "sm", color: t.color.subtleForeground }) }))] })] }), _jsx(ForaDaMarca, { children: _jsx(Modal, { visible: aberto, transparent: true, animationType: reduzir !== false ? "none" : "slide", statusBarTranslucent: true, navigationBarTranslucent: true, onRequestClose: fechar, children: _jsxs(KeyboardAvoiding, { style:
|
|
313
|
+
], children: [_jsx(Pressable, { testID: testID, onPress: inativo ? undefined : () => setAberto(true), disabled: inativo, accessibilityRole: "button", accessibilityLabel: campo?.label, accessibilityHint: campo?.hint, accessibilityValue: { text: value?.label }, ...estadoAcessivel({ disabled: !!inativo, expanded: aberto }), style: s.gatilho, children: _jsx(Text, { size: tam === "sm" ? "xs" : tam === "lg" ? "base" : "md", tone: value ? "default" : "subtle", numberOfLines: 1, style: { flex: 1, minWidth: 0 }, children: value?.label ?? placeholder ?? "" }) }), _jsxs(View, { style: s.acoes, children: [clearable && value != null && !inativo && (_jsx(IconButton, { name: "x", label: strings.comboboxClear, appearance: "ghost", size: "sm", onPress: () => onValueChange?.(null), testID: testID ? `${testID}-limpar` : undefined })), chevron && (_jsx(Pressable, { accessible: false, disabled: inativo, style: s.setaToque, onPress: inativo ? undefined : () => setAberto(true), testID: testID ? `${testID}-seta` : undefined, children: _jsx(Icon, { name: chevron, size: "sm", color: t.color.subtleForeground }) }))] })] }), _jsx(ForaDaMarca, { children: _jsx(Modal, { visible: aberto, transparent: true, animationType: reduzir !== false ? "none" : "slide", statusBarTranslucent: true, navigationBarTranslucent: true, onRequestClose: fechar, children: _jsxs(KeyboardAvoiding, { style: sf.fundoDaLista, children: [_jsx(Pressable, { style: sf.fundoDeToque, onPress: fechar, accessible: false, testID: testID ? `${testID}-fundo` : undefined }), _jsxs(Animated.View, { style: [sf.lista, { transform: [{ translateY: arrasto }] }], onLayout: (e) => { altura.current = e.nativeEvent.layout.height; }, children: [_jsx(View, { style: sf.puxadorArea, ...(draggable ? gestos.panHandlers : null), accessibilityElementsHidden: true, importantForAccessibility: "no-hide-descendants", children: _jsx(View, { style: sf.puxador }) }), _jsxs(View, { style: [sf.grupo, { height: alturaDoTamanho(t, tam) }], ...(draggable ? gestos.panHandlers : null), children: [searchIcon && _jsx(Icon, { name: searchIcon, size: "sm", color: tf.color.subtleForeground }), _jsx(TextInput, { testID: testID ? `${testID}-busca` : undefined, value: texto, onChangeText: digitar, placeholder: searchPlaceholder ?? strings.comboboxSearch, placeholderTextColor: tf.color.subtleForeground,
|
|
311
314
|
// ⚠ `autoFocus` é o que faz a folha valer a pena: abrir um campo de busca e
|
|
312
315
|
// exigir um segundo toque para o teclado subir é um toque a mais em cada
|
|
313
316
|
// cadastro. O foco entra com a folha; o teclado vem junto.
|
|
@@ -318,17 +321,17 @@ export function Combobox({ items, value, onValueChange, onSearchChange, searchDe
|
|
|
318
321
|
// plataforma, não decoração: diz à pessoa que aquele campo é de busca antes de
|
|
319
322
|
// ela digitar a primeira letra.
|
|
320
323
|
returnKeyType: "search", keyboardType: searchKeyboardType, style: [
|
|
321
|
-
|
|
322
|
-
{ fontSize: fonteDoTamanho(t, tam), fontFamily:
|
|
323
|
-
color:
|
|
324
|
-
] }), 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:
|
|
324
|
+
sf.campoDeTexto,
|
|
325
|
+
{ fontSize: fonteDoTamanho(t, tam), fontFamily: tf.font.ui[400],
|
|
326
|
+
color: tf.color.foreground },
|
|
327
|
+
] }), 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: sf.carregando, children: _jsx(Spinner, { label: strings.comboboxLoading }) })), nada && (_jsx(View, { style: sf.vazio, children: typeof empty === "string" || empty == null
|
|
325
328
|
? _jsx(Text, { size: "sm", tone: "muted", children: empty ?? strings.comboboxEmpty })
|
|
326
329
|
: 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({
|
|
327
330
|
selected: item.value === value?.value, disabled: !!item.disabled,
|
|
328
331
|
}), accessibilityHint: item.description, style: [
|
|
329
|
-
|
|
330
|
-
item.value === value?.value &&
|
|
331
|
-
item.disabled &&
|
|
332
|
+
sf.opcao,
|
|
333
|
+
item.value === value?.value && sf.opcaoEscolhida,
|
|
334
|
+
item.disabled && sf.desabilitado,
|
|
332
335
|
], 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 })] })] }) }) })] }));
|
|
333
336
|
}
|
|
334
337
|
// ── A DOBRA DE ACENTO, e por que ela é sondada em vez de presumida ───────────────────────────
|
package/dist/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export type { IconProps, IconName, PhosphorIconName, AureaIconNames, IconWeight,
|
|
|
11
11
|
export { Screen } from "./screen.js";
|
|
12
12
|
export type { ScreenProps, AureaScreenBackground, AureaScreenEdge } from "./screen.js";
|
|
13
13
|
export { Stack, Cluster, Grid, Card, Separator } from "./layout.js";
|
|
14
|
-
export type { StackProps, ClusterProps, AureaStackAlign, AureaClusterAlign, AureaClusterJustify, GridProps, CardProps, SeparatorProps, AureaCardVariant, AureaGridMin, } from "./layout.js";
|
|
14
|
+
export type { StackProps, ClusterProps, AureaStackAlign, AureaClusterAlign, AureaClusterJustify, GridProps, CardProps, SeparatorProps, AureaCardVariant, AureaCardAccent, AureaGridMin, } from "./layout.js";
|
|
15
15
|
export { Button, IconButton, LinkButton, ThemeToggle } from "./actions.js";
|
|
16
16
|
export type { ButtonProps, IconButtonProps, LinkButtonProps, ThemeToggleProps, AureaButtonAppearance, AureaButtonSize, AureaButtonTone, AureaShareData, } from "./actions.js";
|
|
17
17
|
export { Spinner, Skeleton, Progress, Alert, EmptyState, DataState, ICONE_DA_VARIANTE } from "./feedback.js";
|
package/dist/inputs.js
CHANGED
|
@@ -46,7 +46,7 @@ import { Icon } from "./icon.js";
|
|
|
46
46
|
import { useReduceMotion, driverNativo } from "./movimento.js";
|
|
47
47
|
import { RecuoDaFolha } from "./screen.js";
|
|
48
48
|
import { Text } from "./text.js";
|
|
49
|
-
import { useAureaStrings, useAureaTokens, usePeleSobreAMarca, ForaDaMarca } from "./theme.js";
|
|
49
|
+
import { useAureaStrings, useAureaTokens, useTokensDoApp, usePeleSobreAMarca, ForaDaMarca } from "./theme.js";
|
|
50
50
|
// `alturaDoTamanho` e `respiroDoTamanho` saem do arquivo (não do pacote) desde 02/10/2026: o
|
|
51
51
|
// `FileInput` (R-21) desenha um gatilho com a medida do campo, e copiar os números para lá é o
|
|
52
52
|
// defeito que o `CLAUDE.md` nomeia.
|
|
@@ -588,6 +588,9 @@ export function SegmentedControl({ items, value, onChange, label, disabled, just
|
|
|
588
588
|
export function Select({ items, value, onChange, placeholder, disabled, size, chevron = "caret-down", style, testID, }) {
|
|
589
589
|
const t = useAureaTokens();
|
|
590
590
|
const s = folha(t);
|
|
591
|
+
// A folha sai do fluxo: pinta com os tokens do APP (ADR-0063 — ver `useTokensDoApp`).
|
|
592
|
+
const tf = useTokensDoApp();
|
|
593
|
+
const sf = folha(tf);
|
|
591
594
|
const peleDaMarca = usePeleSobreAMarca();
|
|
592
595
|
const campo = useCampo();
|
|
593
596
|
const tam = size ?? campo?.size ?? "md";
|
|
@@ -603,7 +606,7 @@ export function Select({ items, value, onChange, placeholder, disabled, size, ch
|
|
|
603
606
|
peleDaMarca,
|
|
604
607
|
inativo && s.desabilitado,
|
|
605
608
|
style,
|
|
606
|
-
], children: [_jsx(Text, { size: tam === "sm" ? "xs" : tam === "lg" ? "base" : "md", tone: escolhido ? "default" : "subtle", numberOfLines: 1, children: escolhido?.label ?? placeholder ?? "" }), chevron && _jsx(Icon, { name: chevron, size: "sm", color: peleDaMarca?.color ?? t.color.subtleForeground })] }), _jsx(ForaDaMarca, { children: _jsx(Modal, { visible: aberto, transparent: true, animationType: "slide", statusBarTranslucent: true, navigationBarTranslucent: true, onRequestClose: () => setAberto(false), children: _jsxs(View, { style:
|
|
609
|
+
], children: [_jsx(Text, { size: tam === "sm" ? "xs" : tam === "lg" ? "base" : "md", tone: escolhido ? "default" : "subtle", numberOfLines: 1, children: escolhido?.label ?? placeholder ?? "" }), chevron && _jsx(Icon, { name: chevron, size: "sm", color: peleDaMarca?.color ?? t.color.subtleForeground })] }), _jsx(ForaDaMarca, { children: _jsx(Modal, { visible: aberto, transparent: true, animationType: "slide", statusBarTranslucent: true, navigationBarTranslucent: true, onRequestClose: () => setAberto(false), children: _jsxs(View, { style: sf.fundoDaLista, children: [_jsx(Pressable, { style: sf.fundoDeToque, onPress: () => setAberto(false), accessible: false }), _jsxs(View, { style: sf.lista, children: [_jsx(ScrollView, { children: items.map((it) => (_jsx(Pressable, { disabled: it.disabled, onPress: () => { onChange?.(it.value); setAberto(false); }, accessibilityRole: "menuitem", ...estadoAcessivel({ selected: it.value === value, disabled: !!it.disabled }), style: [sf.opcao, it.disabled && sf.desabilitado], children: _jsx(Text, { size: "md", weight: it.value === value ? 600 : 400, children: it.label }) }, it.value))) }), _jsx(RecuoDaFolha, {})] })] }) }) })] }));
|
|
607
610
|
}
|
|
608
611
|
/**
|
|
609
612
|
* A pilha de campos, com o respiro do `--space-5`.
|
package/dist/layout.d.ts
CHANGED
|
@@ -92,9 +92,18 @@ export interface SeparatorProps extends ViewProps {
|
|
|
92
92
|
* comportamento certo.
|
|
93
93
|
*/
|
|
94
94
|
export declare function Separator({ orientation, label, style, ...rest }: SeparatorProps): React.JSX.Element;
|
|
95
|
-
export type AureaCardVariant = "base" | "raised" | "interactive" | "inset" | "selected" | "danger" | "brand";
|
|
95
|
+
export type AureaCardVariant = "base" | "raised" | "interactive" | "inset" | "selected" | "danger" | "brand" | "contrast";
|
|
96
|
+
/** O tom do traço no topo (`accent`, MT-02, ADR-0063) — os MESMOS cinco da web. */
|
|
97
|
+
export type AureaCardAccent = "brand" | "success" | "info" | "warning" | "danger";
|
|
96
98
|
interface CardBase extends ViewProps {
|
|
97
99
|
children?: React.ReactNode;
|
|
100
|
+
/**
|
|
101
|
+
* O traço de cor no topo (MT-02, ADR-0063, 10/10/2026): `--accent-width` (4), na cor CHEIA do
|
|
102
|
+
* tom, igual nos dois temas. É enfeite — o nome da caixa diz o assunto —, e por isso a ADR-0063
|
|
103
|
+
* abriu a exceção na ADR-0061 (borda com a cor de fundo). Funciona com `onPress`, com
|
|
104
|
+
* `accessible` e dentro da `Grid`.
|
|
105
|
+
*/
|
|
106
|
+
accent?: AureaCardAccent;
|
|
98
107
|
}
|
|
99
108
|
/**
|
|
100
109
|
* 🔴 **O `brand` EXIGE `action`, e isso é de propósito — a regra é do TIPO, não de documento.**
|
|
@@ -162,5 +171,5 @@ export type CardProps = CardDaMarca | CardComum | CardTocavel;
|
|
|
162
171
|
* volta de um `Card` com `Button` dentro) — é o ponto em que a referência não serve.
|
|
163
172
|
* Cartão com duas ações não tem `onPress`: cada ação é um botão dentro de um cartão comum.
|
|
164
173
|
*/
|
|
165
|
-
export declare function Card(
|
|
174
|
+
export declare function Card(props: CardProps): React.JSX.Element;
|
|
166
175
|
export {};
|
package/dist/layout.js
CHANGED
|
@@ -17,9 +17,9 @@ import { Pressable, StyleSheet, View } from "react-native";
|
|
|
17
17
|
// `@aurea-uds/react` ja' faz (o `Stack` da web e' `HTMLAttributes & RefAttributes`, sem
|
|
18
18
|
// envelope). O `ViewProps`/`TextProps` do RN 0.87 ja' declaram `ref`, entao ele viaja no
|
|
19
19
|
// `...rest` sem nada a mais.
|
|
20
|
-
import { criarFolha, peleDoCartao, peleDoCartaoEscolhido, REACAO_AO_TOQUE, estadoAcessivel } from "./estilos.js";
|
|
20
|
+
import { canto, criarFolha, peleDoCartao, peleDoCartaoEscolhido, REACAO_AO_TOQUE, estadoAcessivel } from "./estilos.js";
|
|
21
21
|
import { Text } from "./text.js";
|
|
22
|
-
import { useAureaTokens, SobreAMarca } from "./theme.js";
|
|
22
|
+
import { useAureaTheme, useAureaTokens, SobreAMarca, TemaDentro } from "./theme.js";
|
|
23
23
|
const folha = criarFolha((t) => ({
|
|
24
24
|
// A LINHA DO SISTEMA, e os números são os mesmos do `.separator` da web (`aurea.css`): cor de
|
|
25
25
|
// `border` e espessura de UM pixel. ⚠ Um pixel não sai de `--space-*` de propósito — a linha
|
|
@@ -51,6 +51,24 @@ const folha = criarFolha((t) => ({
|
|
|
51
51
|
// O amarelo é o DE PREENCHER — `primary`, o mesmo do botão sólido. A borda some: uma superfície
|
|
52
52
|
// cheia não precisa de contorno, e um contorno sobre o amarelo mede 2,43 no claro (invisível).
|
|
53
53
|
card_brand: { backgroundColor: t.color.primary, borderColor: "transparent" },
|
|
54
|
+
// MT-01 (ADR-0063): o `contrast` é pintado DENTRO do tema escuro (`TemaDentro`), então o fundo do
|
|
55
|
+
// `cardBase` já é o cartão do escuro. No claro, sem linha em volta (13,3:1 contra a tela); no
|
|
56
|
+
// escuro, o amarelo, com a borda de sempre.
|
|
57
|
+
card_contrast: { borderColor: "transparent" },
|
|
58
|
+
contrasteNoEscuro: { borderColor: t.color.primary },
|
|
59
|
+
// MT-02 (ADR-0063): o traço no topo. Uma borda mais grossa só em cima, com o canto 22, desenha
|
|
60
|
+
// errado no Android (react-native#51926, fechada sem conserto em 24/03/2026: a borda sai do
|
|
61
|
+
// contorno e deixa vão). Então o traço é uma faixa de `accentWidth` numa camada que se recorta no
|
|
62
|
+
// canto do cartão, por cima da borda de 1 — o mesmo desenho do `border-top` da web, que afina na
|
|
63
|
+
// curva. A camada cobre a CAIXA DA BORDA (deslocada de `borderWidth` para fora), e o recheio de
|
|
64
|
+
// cima cresce o que o traço come, para o conteúdo ficar onde fica na web.
|
|
65
|
+
comTraco: { paddingTop: t.size.cardPad + t.size.accentWidth - t.size.borderWidth },
|
|
66
|
+
tracoCamada: {
|
|
67
|
+
position: "absolute", top: -t.size.borderWidth, left: -t.size.borderWidth,
|
|
68
|
+
right: -t.size.borderWidth, bottom: -t.size.borderWidth,
|
|
69
|
+
...canto(t.size.radiusCard), overflow: "hidden",
|
|
70
|
+
},
|
|
71
|
+
traco: { height: t.size.accentWidth },
|
|
54
72
|
// A ação fica embaixo, separada pelo mesmo respiro que o resto da casa usa entre blocos.
|
|
55
73
|
acaoDaMarca: { marginTop: t.size.space3 },
|
|
56
74
|
}));
|
|
@@ -194,20 +212,37 @@ export function Separator({ orientation = "horizontal", label, style, ...rest })
|
|
|
194
212
|
* volta de um `Card` com `Button` dentro) — é o ponto em que a referência não serve.
|
|
195
213
|
* Cartão com duas ações não tem `onPress`: cada ação é um botão dentro de um cartão comum.
|
|
196
214
|
*/
|
|
197
|
-
export function Card(
|
|
215
|
+
export function Card(props) {
|
|
216
|
+
// MT-01 (ADR-0063, 10/10/2026): o `contrast` é o tema escuro DENTRO do cartão, então TODO filho
|
|
217
|
+
// se ajusta — texto, selo, botão, campo —, e não só a lista declarada do `brand`. A marca não
|
|
218
|
+
// atravessa: dentro de um cartão amarelo, o `contrast` não é amarelo, e a tinta dele não vale.
|
|
219
|
+
if (props.variant === "contrast") {
|
|
220
|
+
return (_jsx(TemaDentro, { tema: "dark", children: _jsx(SobreAMarca.Provider, { value: null, children: _jsx(CorpoDoCartao, { ...props }) }) }));
|
|
221
|
+
}
|
|
222
|
+
return _jsx(CorpoDoCartao, { ...props });
|
|
223
|
+
}
|
|
224
|
+
/** A cor CHEIA de cada tom do traço — a mesma nos dois temas (ADR-0063, exceção à ADR-0061). */
|
|
225
|
+
const COR_DO_TRACO = {
|
|
226
|
+
brand: "primary", success: "success", info: "info", warning: "warning", danger: "destructive",
|
|
227
|
+
};
|
|
228
|
+
function CorpoDoCartao({ variant, accent, style, ...rest }) {
|
|
198
229
|
const t = useAureaTokens();
|
|
230
|
+
const { theme: temaDoApp } = useAureaTheme();
|
|
199
231
|
const s = folha(t);
|
|
200
232
|
const { action, children, onPress, disabled, ...resto } = rest;
|
|
233
|
+
// O contorno do `contrast` olha o tema do APP: dentro do cartão os tokens já são os do escuro.
|
|
234
|
+
const contorno = variant === "contrast" && temaDoApp === "dark" ? s.contrasteNoEscuro : null;
|
|
235
|
+
const traco = accent == null ? null : (_jsx(View, { pointerEvents: "none", collapsable: false, style: s.tracoCamada, children: _jsx(View, { style: [s.traco, { backgroundColor: t.color[COR_DO_TRACO[accent]] }] }) }));
|
|
201
236
|
if (onPress != null) {
|
|
202
237
|
const pele = variant ?? "interactive";
|
|
203
|
-
return (
|
|
204
|
-
s.cardBase, s[`card_${pele}`],
|
|
238
|
+
return (_jsxs(Pressable, { onPress: onPress, disabled: disabled, accessibilityRole: "button", ...estadoAcessivel({ disabled: !!disabled }), style: ({ pressed: tocando }) => [
|
|
239
|
+
s.cardBase, s[`card_${pele}`], contorno, traco != null && s.comTraco,
|
|
205
240
|
tocando && REACAO_AO_TOQUE.pressionado, disabled && REACAO_AO_TOQUE.inerte,
|
|
206
241
|
style,
|
|
207
|
-
], ...resto, children: children }));
|
|
242
|
+
], ...resto, children: [traco, children] }));
|
|
208
243
|
}
|
|
209
|
-
const corpo = (_jsxs(_Fragment, { children: [children, action != null && _jsx(View, { style: s.acaoDaMarca, children: action })] }));
|
|
210
|
-
const pele = _jsx(View, { style: [s.cardBase, s[`card_${variant ?? "base"}`], style], ...resto, children: corpo });
|
|
244
|
+
const corpo = (_jsxs(_Fragment, { children: [traco, children, action != null && _jsx(View, { style: s.acaoDaMarca, children: action })] }));
|
|
245
|
+
const pele = (_jsx(View, { style: [s.cardBase, s[`card_${variant ?? "base"}`], contorno, traco != null && s.comTraco, style], ...resto, children: corpo }));
|
|
211
246
|
// 🔴 SOBRE O AMARELO A COR DO TEXTO NÃO É ESCOLHA, É OBRIGAÇÃO — e os números decidiram isto.
|
|
212
247
|
// Medido nos dois temas, texto contra o `primary`:
|
|
213
248
|
// texto comum ........ 10,34 no claro · **1,83 no escuro** 🔴 ilegível
|
package/dist/overlays.js
CHANGED
|
@@ -62,7 +62,7 @@ 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";
|
|
65
|
-
import { useAureaStrings,
|
|
65
|
+
import { useAureaStrings, useTokensDoApp, ForaDaMarca } from "./theme.js";
|
|
66
66
|
import { useReduceMotion, driverNativo } from "./movimento.js";
|
|
67
67
|
const folha = criarFolha((t) => ({
|
|
68
68
|
fundo: { flex: 1, backgroundColor: t.color.overlay },
|
|
@@ -163,7 +163,7 @@ const naoAtravessa = { onStartShouldSetResponder: () => true };
|
|
|
163
163
|
* fica presa — o equivalente exato de um diálogo web que ignora `Escape`.
|
|
164
164
|
*/
|
|
165
165
|
export function Dialog({ open, title, children, footer, onClose, scroll = true, style, testID, }) {
|
|
166
|
-
const t =
|
|
166
|
+
const t = useTokensDoApp();
|
|
167
167
|
const s = folha(t);
|
|
168
168
|
const strings = useAureaStrings();
|
|
169
169
|
const Corpo = scroll ? ScrollView : View;
|
|
@@ -192,7 +192,7 @@ export function Dialog({ open, title, children, footer, onClose, scroll = true,
|
|
|
192
192
|
* separa esta caixa de um `Dialog` para quem não vê é o texto, não um atributo.
|
|
193
193
|
*/
|
|
194
194
|
export function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, destructive, onConfirm, onCancel, testID, }) {
|
|
195
|
-
const t =
|
|
195
|
+
const t = useTokensDoApp();
|
|
196
196
|
const s = folha(t);
|
|
197
197
|
const strings = useAureaStrings();
|
|
198
198
|
return (_jsx(ForaDaMarca, { children: _jsx(Modal, { visible: open, transparent: true, animationType: "fade", statusBarTranslucent: true, navigationBarTranslucent: true, onRequestClose: onCancel, testID: testID, children: _jsx(View, { style: [s.fundo, s.centro], children: _jsxs(View, { ...naoAtravessa, style: [s.superficie, s.confirmar], children: [_jsx(View, { style: s.cabecalho, children: _jsx(Text, { size: "lg", weight: 600, accessibilityRole: "header", style: s.titulo, children: title }) }), _jsx(View, { style: s.corpo, children: typeof description === "string"
|
|
@@ -211,7 +211,7 @@ export function ConfirmDialog({ open, title, description, confirmLabel, cancelLa
|
|
|
211
211
|
* cascata de `prefers-reduced-motion` que a web ganha de graça.
|
|
212
212
|
*/
|
|
213
213
|
export function Drawer({ open, title, children, onClose, side = "right", scroll = true, style, testID, }) {
|
|
214
|
-
const t =
|
|
214
|
+
const t = useTokensDoApp();
|
|
215
215
|
const s = folha(t);
|
|
216
216
|
const strings = useAureaStrings();
|
|
217
217
|
const reduzir = useReduceMotion();
|
|
@@ -267,7 +267,7 @@ export function Drawer({ open, title, children, onClose, side = "right", scroll
|
|
|
267
267
|
* terço da altura da folha. Fechar cedo demais é como um gesto de fechar vira perda de dado.
|
|
268
268
|
*/
|
|
269
269
|
export function BottomSheet({ open, title, children, onClose, grabber = true, draggable = true, scroll = true, style, testID, }) {
|
|
270
|
-
const t =
|
|
270
|
+
const t = useTokensDoApp();
|
|
271
271
|
const s = folha(t);
|
|
272
272
|
const reduzir = useReduceMotion();
|
|
273
273
|
const arrasto = React.useRef(new Animated.Value(0)).current;
|
package/dist/theme.d.ts
CHANGED
|
@@ -118,6 +118,29 @@ export declare function useSobreAMarca(): SobreAMarcaValor | null;
|
|
|
118
118
|
export declare function ForaDaMarca({ children }: {
|
|
119
119
|
children?: React.ReactNode;
|
|
120
120
|
}): React.JSX.Element;
|
|
121
|
+
/**
|
|
122
|
+
* O tema num pedaço da tela — o `Card variant="contrast"` (MT-01, ADR-0063, 10/10/2026). Os filhos
|
|
123
|
+
* leem os tokens do `tema` pedido; o resto do app não muda. É o jeito da referência principal de
|
|
124
|
+
* fazer um pedaço escuro (o tema aplicado num elemento), e o da web (`data-theme` no cartão).
|
|
125
|
+
*
|
|
126
|
+
* ⚠ **O `useAureaTheme()` continua o do app**: dentro do pedaço, `theme` diz o tema do APP, e o
|
|
127
|
+
* `setTheme` troca o do app. Só os tokens mudam — é o que pinta.
|
|
128
|
+
*
|
|
129
|
+
* Interno: o público é o `Card variant="contrast"`. O que sai do fluxo (folha, sobreposto) passa
|
|
130
|
+
* pelo `ForaDaMarca` e volta ao app.
|
|
131
|
+
*/
|
|
132
|
+
/**
|
|
133
|
+
* Os tokens do APP, mesmo dentro de um pedaço com tema próprio. Quem desenha uma janela que sai do
|
|
134
|
+
* fluxo (a folha, o diálogo) pinta o FUNDO dela com isto: o `ForaDaMarca` devolve o contexto do app
|
|
135
|
+
* só para quem lê o contexto DENTRO da janela (o texto, o botão), e o fundo é calculado antes, por
|
|
136
|
+
* quem abre. Medido na bancada do Lote N (10/10/2026): sem isto, a lista do `Select` aberta de
|
|
137
|
+
* dentro do `contrast` saía com o fundo do escuro e a letra do claro. Interno.
|
|
138
|
+
*/
|
|
139
|
+
export declare function useTokensDoApp(): AureaTokens;
|
|
140
|
+
export declare function TemaDentro({ tema, children }: {
|
|
141
|
+
tema: AureaThemeName;
|
|
142
|
+
children?: React.ReactNode;
|
|
143
|
+
}): React.JSX.Element;
|
|
121
144
|
/**
|
|
122
145
|
* A pele que um CAMPO tem de vestir quando está dentro de um `Card variant="brand"`, ou `null`
|
|
123
146
|
* quando não está.
|
package/dist/theme.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { useColorScheme } from "react-native";
|
|
4
4
|
import { IconRegistryProvider } from "./icon.js";
|
|
@@ -45,6 +45,8 @@ export function AureaProvider({ children, theme, density, defaultTheme, defaultD
|
|
|
45
45
|
// um contexto a mais só se paga quando ele muda em outra hora, e este muda junto — é a mesma
|
|
46
46
|
// conta que o cabeçalho deste arquivo já fez para os dois contextos que viraram um.
|
|
47
47
|
strings: strings ?? defaultStrings,
|
|
48
|
+
fontes: fontFamilies,
|
|
49
|
+
raiz: null,
|
|
48
50
|
}), [temaEfetivo, densidadeEfetiva, setTheme, setDensity, fontFamilies, strings]);
|
|
49
51
|
// O registro de ícones fica num contexto PRÓPRIO: ele não muda quando o tema muda, e juntá-lo
|
|
50
52
|
// ao valor do tema faria toda árvore que só desenha ícone re-renderizar na troca de tema.
|
|
@@ -119,7 +121,46 @@ export function useSobreAMarca() {
|
|
|
119
121
|
* passa por aqui.
|
|
120
122
|
*/
|
|
121
123
|
export function ForaDaMarca({ children }) {
|
|
122
|
-
|
|
124
|
+
// ✅ **E corta o tema do pedaço também (ADR-0063, 10/10/2026).** A mesma armadilha vale para o
|
|
125
|
+
// `Card variant="contrast"`: ele entrega os tokens do ESCURO aos filhos, e a folha de um `Select`
|
|
126
|
+
// aberto dali sairia escura sobre um app claro. Na web isso não acontece porque a folha vai para
|
|
127
|
+
// o fim da página (portal), fora do pedaço; aqui, quem sai do fluxo volta ao valor do app.
|
|
128
|
+
const v = React.useContext(Contexto);
|
|
129
|
+
const corpo = _jsx(SobreAMarcaCtx.Provider, { value: null, children: children });
|
|
130
|
+
return v?.raiz ? _jsx(Contexto.Provider, { value: v.raiz, children: corpo }) : corpo;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* O tema num pedaço da tela — o `Card variant="contrast"` (MT-01, ADR-0063, 10/10/2026). Os filhos
|
|
134
|
+
* leem os tokens do `tema` pedido; o resto do app não muda. É o jeito da referência principal de
|
|
135
|
+
* fazer um pedaço escuro (o tema aplicado num elemento), e o da web (`data-theme` no cartão).
|
|
136
|
+
*
|
|
137
|
+
* ⚠ **O `useAureaTheme()` continua o do app**: dentro do pedaço, `theme` diz o tema do APP, e o
|
|
138
|
+
* `setTheme` troca o do app. Só os tokens mudam — é o que pinta.
|
|
139
|
+
*
|
|
140
|
+
* Interno: o público é o `Card variant="contrast"`. O que sai do fluxo (folha, sobreposto) passa
|
|
141
|
+
* pelo `ForaDaMarca` e volta ao app.
|
|
142
|
+
*/
|
|
143
|
+
/**
|
|
144
|
+
* Os tokens do APP, mesmo dentro de um pedaço com tema próprio. Quem desenha uma janela que sai do
|
|
145
|
+
* fluxo (a folha, o diálogo) pinta o FUNDO dela com isto: o `ForaDaMarca` devolve o contexto do app
|
|
146
|
+
* só para quem lê o contexto DENTRO da janela (o texto, o botão), e o fundo é calculado antes, por
|
|
147
|
+
* quem abre. Medido na bancada do Lote N (10/10/2026): sem isto, a lista do `Select` aberta de
|
|
148
|
+
* dentro do `contrast` saía com o fundo do escuro e a letra do claro. Interno.
|
|
149
|
+
*/
|
|
150
|
+
export function useTokensDoApp() {
|
|
151
|
+
const v = usar("useTokensDoApp");
|
|
152
|
+
return (v.raiz ?? v).tokens;
|
|
153
|
+
}
|
|
154
|
+
export function TemaDentro({ tema, children }) {
|
|
155
|
+
const v = usar("TemaDentro");
|
|
156
|
+
const valor = React.useMemo(() => ({
|
|
157
|
+
...v,
|
|
158
|
+
tokens: resolverTokens(tema, v.controle.density, v.fontes),
|
|
159
|
+
raiz: v.raiz ?? v,
|
|
160
|
+
}), [v, tema]);
|
|
161
|
+
if (v.tokens.theme === tema)
|
|
162
|
+
return _jsx(_Fragment, { children: children });
|
|
163
|
+
return _jsx(Contexto.Provider, { value: valor, children: children });
|
|
123
164
|
}
|
|
124
165
|
/**
|
|
125
166
|
* A pele que um CAMPO tem de vestir quando está dentro de um `Card variant="brand"`, ou `null`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurea-uds/native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
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",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"NOTICE"
|
|
56
56
|
],
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@aurea-uds/tokens": "^0.
|
|
58
|
+
"@aurea-uds/tokens": "^0.29.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@react-native-community/datetimepicker": ">=8",
|