@aurea-uds/native 0.8.5 → 0.8.6
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/inputs.js +25 -24
- package/dist/layout.d.ts +27 -3
- package/dist/layout.js +27 -4
- package/dist/navigation.js +3 -5
- package/dist/rolagem.d.ts +16 -0
- package/dist/rolagem.js +45 -0
- package/dist/text.js +11 -2
- package/dist/theme.d.ts +10 -0
- package/dist/theme.js +30 -0
- package/package.json +2 -2
package/dist/inputs.js
CHANGED
|
@@ -40,6 +40,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
|
|
|
40
40
|
import * as React from "react";
|
|
41
41
|
import { Animated, KeyboardAvoidingView as KeyboardAvoidingViewRN, Modal, Platform, Pressable, ScrollView, TextInput, View, } from "react-native";
|
|
42
42
|
import { comOpacidade, criarFolha } from "./estilos.js";
|
|
43
|
+
import { FilaRolante } from "./rolagem.js";
|
|
43
44
|
import { IconButton } from "./actions.js";
|
|
44
45
|
import { Icon } from "./icon.js";
|
|
45
46
|
import { useReduceMotion } from "./movimento.js";
|
|
@@ -415,30 +416,30 @@ export function SegmentedControl({ items, value, onChange, label, disabled, styl
|
|
|
415
416
|
const s = folha(t);
|
|
416
417
|
const campo = useCampo();
|
|
417
418
|
const inativo = disabled ?? campo?.disabled;
|
|
418
|
-
return (_jsx(View, { accessibilityRole: "radiogroup", accessibilityLabel: label ?? campo?.label, style: [s.segmentada, inativo && s.desabilitado, style], ...rest, children: items.map((it) => {
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
419
|
+
return (_jsx(FilaRolante, { children: _jsx(View, { accessibilityRole: "radiogroup", accessibilityLabel: label ?? campo?.label, style: [s.segmentada, inativo && s.desabilitado, style], ...rest, children: items.map((it) => {
|
|
420
|
+
const ativo = it.value === value;
|
|
421
|
+
return (_jsxs(Pressable, { onPress: inativo ? undefined : () => onChange?.(it.value), disabled: inativo, accessibilityRole: "radio", accessibilityState: { checked: ativo, disabled: !!inativo }, accessibilityLabel: typeof it.label === "string" ? it.label : undefined, style: [s.segmento, ativo && s.segmentoAtivo], children: [typeof it.label === "string"
|
|
422
|
+
? _jsx(Text, { size: "sm", weight: ativo ? 600 : 400,
|
|
423
|
+
// 🔴 ERA `foreground`, E ISSO QUEBRAVA A LINGUAGEM DE SELECIONADO.
|
|
424
|
+
// Achado pelo consumidor em 17/09/2026. A web pinta o escolhido com a
|
|
425
|
+
// MARCA (`aurea.css:937-938`), e o comentário de cima daquela regra diz
|
|
426
|
+
// que nav ativo, aba ativa, item de lista e botão ligado mostram o mesmo
|
|
427
|
+
// sinal — ordem do Victor, 24/07. O `SegmentedControl` daqui discordava
|
|
428
|
+
// da web **e do `BottomNav` deste mesmo pacote**, que já usa este token.
|
|
429
|
+
//
|
|
430
|
+
// ⚠ **`primaryEmphasis` e NÃO `primary`, e a razão está no CSS:** *"sem
|
|
431
|
+
// fundo, a marca vira TEXTO, e o amarelo puro"* não se lê no claro
|
|
432
|
+
// (`aurea.css:358`). É a mesma lição que a `0.8.3` pagou no `Button`.
|
|
433
|
+
// No escuro os dois valem o mesmo amarelo; no claro este aprofunda.
|
|
434
|
+
//
|
|
435
|
+
// ⚠ **Uma divergência declarada, não escondida:** para o `.segmented` a
|
|
436
|
+
// web usa uma mistura própria (`primary 45% + foreground`) em vez do
|
|
437
|
+
// token, enquanto para o `.bottom-nav` usa o token. São dois âmbares
|
|
438
|
+
// parecidos para a MESMA linguagem, e isso é incoerência DA WEB. Escolhi
|
|
439
|
+
// o token, que deixa os dois componentes daqui iguais entre si.
|
|
440
|
+
style: { color: ativo ? t.color.primaryEmphasis : t.color.mutedForeground }, children: it.label })
|
|
441
|
+
: it.label, ativo && _jsx(View, { style: s.fioDoSegmento })] }, it.value));
|
|
442
|
+
}) }) }));
|
|
442
443
|
}
|
|
443
444
|
/**
|
|
444
445
|
* A escolha de um de muitos.
|
package/dist/layout.d.ts
CHANGED
|
@@ -55,11 +55,34 @@ export interface SeparatorProps extends ViewProps {
|
|
|
55
55
|
* comportamento certo.
|
|
56
56
|
*/
|
|
57
57
|
export declare function Separator({ orientation, label, style, ...rest }: SeparatorProps): React.JSX.Element;
|
|
58
|
-
export type AureaCardVariant = "base" | "raised" | "interactive" | "inset" | "selected" | "danger";
|
|
59
|
-
|
|
60
|
-
variant?: AureaCardVariant;
|
|
58
|
+
export type AureaCardVariant = "base" | "raised" | "interactive" | "inset" | "selected" | "danger" | "brand";
|
|
59
|
+
interface CardBase extends ViewProps {
|
|
61
60
|
children?: React.ReactNode;
|
|
62
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* 🔴 **O `brand` EXIGE `action`, e isso é de propósito — a regra é do TIPO, não de documento.**
|
|
64
|
+
*
|
|
65
|
+
* O cartão na cor da marca entrou em 17/09/2026 e é a **primeira superfície grande preenchida
|
|
66
|
+
* com o amarelo** neste sistema. Até aqui ele só pintava coisa pequena: o ponto do contador, a
|
|
67
|
+
* pílula do passo atual, o link de pular para o conteúdo. Um cartão amarelo é precedente, e
|
|
68
|
+
* precedente sem trava vira decoração — outras telas pedem o mesmo e o amarelo deixa de
|
|
69
|
+
* significar "aja aqui".
|
|
70
|
+
*
|
|
71
|
+
* A regra combinada foi *"o cartão amarelo é só para pedir uma ação da pessoa"*. **Escrita num
|
|
72
|
+
* documento, ela apagaria** — este repositório tem registro disso em cada arquivo, e a §"Afirmação
|
|
73
|
+
* velha" do `CLAUDE.md` existe por causa desse desgaste. Então ela mora no tipo: sem `action`, o
|
|
74
|
+
* `brand` não compila. É a mesma escolha que faz o `label` do `IconButton` ser obrigatório.
|
|
75
|
+
*/
|
|
76
|
+
interface CardDaMarca extends CardBase {
|
|
77
|
+
variant: "brand";
|
|
78
|
+
/** O que a pessoa faz aqui — um `Button`, um `IconButton`, um campo. Sem isto não compila. */
|
|
79
|
+
action: React.ReactNode;
|
|
80
|
+
}
|
|
81
|
+
interface CardComum extends CardBase {
|
|
82
|
+
variant?: Exclude<AureaCardVariant, "brand">;
|
|
83
|
+
action?: never;
|
|
84
|
+
}
|
|
85
|
+
export type CardProps = CardDaMarca | CardComum;
|
|
63
86
|
/**
|
|
64
87
|
* Superfície flutuante, raio 22 (`--radius-card`) — identidade declarada INTOCÁVEL.
|
|
65
88
|
*
|
|
@@ -69,3 +92,4 @@ export interface CardProps extends ViewProps {
|
|
|
69
92
|
* que É um alvo — quem o torna tocável é a tela.
|
|
70
93
|
*/
|
|
71
94
|
export declare function Card({ variant, style, ...rest }: CardProps): React.JSX.Element;
|
|
95
|
+
export {};
|
package/dist/layout.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// Aurea nativo — os primitivos de layout: `Stack`, `Cluster`, `Grid`, `Card`.
|
|
3
3
|
//
|
|
4
4
|
// Medidos no core da web antes de escrever (passo 1 do BUILDING.md), e o que eles são lá:
|
|
@@ -19,7 +19,7 @@ import { View } from "react-native";
|
|
|
19
19
|
// `...rest` sem nada a mais.
|
|
20
20
|
import { criarFolha } from "./estilos.js";
|
|
21
21
|
import { Text } from "./text.js";
|
|
22
|
-
import { useAureaTokens } from "./theme.js";
|
|
22
|
+
import { useAureaTokens, SobreAMarca } 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
|
|
@@ -52,6 +52,11 @@ const folha = criarFolha((t) => ({
|
|
|
52
52
|
card_inset: { backgroundColor: t.color.surfaceInset, borderColor: "transparent" },
|
|
53
53
|
card_selected: { borderColor: t.color.primaryOutline, backgroundColor: t.color.surface2 },
|
|
54
54
|
card_danger: { borderColor: t.color.danger400 ?? t.color.destructive, backgroundColor: t.color.dangerBg },
|
|
55
|
+
// O amarelo é o DE PREENCHER — `primary`, o mesmo do botão sólido. A borda some: uma superfície
|
|
56
|
+
// cheia não precisa de contorno, e um contorno sobre o amarelo mede 2,43 no claro (invisível).
|
|
57
|
+
card_brand: { backgroundColor: t.color.primary, borderColor: "transparent" },
|
|
58
|
+
// A ação fica embaixo, separada pelo mesmo respiro que o resto da casa usa entre blocos.
|
|
59
|
+
acaoDaMarca: { marginTop: t.size.space3 },
|
|
55
60
|
}));
|
|
56
61
|
/** Coluna com `--space-4` entre os filhos. **Sem prop de espaçamento, de propósito.** */
|
|
57
62
|
export function Stack({ style, ...rest }) {
|
|
@@ -112,6 +117,24 @@ export function Separator({ orientation = "horizontal", label, style, ...rest })
|
|
|
112
117
|
* que É um alvo — quem o torna tocável é a tela.
|
|
113
118
|
*/
|
|
114
119
|
export function Card({ variant = "base", style, ...rest }) {
|
|
115
|
-
const
|
|
116
|
-
|
|
120
|
+
const t = useAureaTokens();
|
|
121
|
+
const s = folha(t);
|
|
122
|
+
const { action, children, ...resto } = rest;
|
|
123
|
+
const corpo = (_jsxs(_Fragment, { children: [children, action != null && _jsx(View, { style: s.acaoDaMarca, children: action })] }));
|
|
124
|
+
const pele = _jsx(View, { style: [s.cardBase, s[`card_${variant}`], style], ...resto, children: corpo });
|
|
125
|
+
// 🔴 SOBRE O AMARELO A COR DO TEXTO NÃO É ESCOLHA, É OBRIGAÇÃO — e os números decidiram isto.
|
|
126
|
+
// Medido nos dois temas, texto contra o `primary`:
|
|
127
|
+
// texto comum ........ 10,34 no claro · **1,83 no escuro** 🔴 ilegível
|
|
128
|
+
// texto esmaecido ..... 4,24 no claro · **1,35 no escuro** 🔴 ilegível
|
|
129
|
+
// primary-foreground .. 4,54 nos DOIS ✅ único que serve
|
|
130
|
+
// Sem forçar, o cartão da marca sairia quebrado no tema escuro **sem ninguém ver no claro**.
|
|
131
|
+
// ⚠ **E no RN não há cascata de cor**: `color` num `View` não desce para o `Text` de dentro.
|
|
132
|
+
// A saída é CONTEXTO — a mesma decisão que o `Field` do Lote 4 tomou para empurrar nome e dica.
|
|
133
|
+
//
|
|
134
|
+
// ⚠ **Consequência declarada: sobre o amarelo existe UMA cor de texto, não duas.** O tom
|
|
135
|
+
// `muted` mede 1,35 no escuro, então ele não pode sobreviver aqui. A hierarquia dentro deste
|
|
136
|
+
// cartão sai de PESO e TAMANHO, não de cor — e isso é restrição do contraste, não gosto.
|
|
137
|
+
return variant === "brand"
|
|
138
|
+
? _jsx(SobreAMarca.Provider, { value: t.color.primaryForeground, children: pele })
|
|
139
|
+
: pele;
|
|
117
140
|
}
|
package/dist/navigation.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Pressable, View
|
|
2
|
+
import { Pressable, View } from "react-native";
|
|
3
3
|
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
4
4
|
import { Badge } from "./display.js";
|
|
5
5
|
import { comOpacidade, criarFolha } from "./estilos.js";
|
|
6
6
|
import { Icon } from "./icon.js";
|
|
7
7
|
import { Card } from "./layout.js";
|
|
8
|
+
import { FilaRolante } from "./rolagem.js";
|
|
8
9
|
import { Text } from "./text.js";
|
|
9
10
|
import { useAureaStrings, useAureaTokens } from "./theme.js";
|
|
10
11
|
const folha = criarFolha((t) => ({
|
|
@@ -317,10 +318,7 @@ export function Tabs({ tabs, value, onChange, label, style, ...rest }) {
|
|
|
317
318
|
const s = folha(t);
|
|
318
319
|
const strings = useAureaStrings();
|
|
319
320
|
const aberta = tabs.find((it) => it.id === value);
|
|
320
|
-
return (_jsxs(View, { style: style, ...rest, children: [_jsx(
|
|
321
|
-
// Sem isto o conteúdo estica até a largura do rolador e o `padding` de 3 da cápsula
|
|
322
|
-
// aparece como faixa vazia à direita quando as abas cabem.
|
|
323
|
-
contentContainerStyle: { flexGrow: 0 }, children: _jsx(View, { accessibilityRole: "tablist", accessibilityLabel: label ?? strings.tabsLabel, style: s.abas, children: tabs.map((it) => {
|
|
321
|
+
return (_jsxs(View, { style: style, ...rest, children: [_jsx(FilaRolante, { children: _jsx(View, { accessibilityRole: "tablist", accessibilityLabel: label ?? strings.tabsLabel, style: s.abas, children: tabs.map((it) => {
|
|
324
322
|
const ativa = it.id === value;
|
|
325
323
|
return (_jsx(Pressable, { onPress: it.disabled ? undefined : () => onChange?.(it.id), disabled: it.disabled, accessibilityRole: "tab", accessibilityState: { selected: ativa, disabled: !!it.disabled }, accessibilityLabel: typeof it.label === "string" ? it.label : undefined, style: [s.abaDeTab, ativa && s.abaDeTabAtiva, it.disabled && { opacity: 0.5 }], children: typeof it.label === "string"
|
|
326
324
|
? _jsx(Text, { size: "sm", weight: ativa ? 600 : 400, style: { color: ativa ? t.color.foreground : t.color.mutedForeground }, children: it.label })
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { type StyleProp, type ViewStyle } from "react-native";
|
|
3
|
+
export interface FilaRolanteProps {
|
|
4
|
+
/** O conteúdo da fila — normalmente a cápsula com os itens dentro. */
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
/** Estilo do invólucro externo, não do conteúdo. */
|
|
7
|
+
style?: StyleProp<ViewStyle>;
|
|
8
|
+
testID?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Uma linha que rola para o lado quando não cabe, e que sabe QUANDO não cabe.
|
|
12
|
+
*
|
|
13
|
+
* O componente fica com a informação em vez de adivinhar: `onLayout` dá a largura visível e
|
|
14
|
+
* `onContentSizeChange` dá a do conteúdo. Com as duas, `transbordou` é uma conta, não um palpite.
|
|
15
|
+
*/
|
|
16
|
+
export declare function FilaRolante({ children, style, testID }: FilaRolanteProps): React.JSX.Element;
|
package/dist/rolagem.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// A FILA QUE ROLA — e por que ela existe em vez de cada componente resolver o seu.
|
|
3
|
+
//
|
|
4
|
+
// 🔴 **ISTO NÃO É DESENHO NOVO: É TRADUÇÃO QUE FALTOU.** O consumidor pediu em 17/09/2026 um
|
|
5
|
+
// grupo de opções que coubesse com seis itens, e a primeira resposta que eu ia dar era criar um
|
|
6
|
+
// componente de "chips". **Medindo a web antes, o pedido já estava resolvido lá:**
|
|
7
|
+
//
|
|
8
|
+
// aurea.css:2127, em tela de até 640px:
|
|
9
|
+
// .tabs,.pagination,.segmented { max-width:100%; overflow-x:auto; }
|
|
10
|
+
//
|
|
11
|
+
// Ou seja: **na web o segmentado e as abas JÁ rolam no telefone.** O nativo é que não traduziu.
|
|
12
|
+
// Criar um terceiro jeito de escolher teria sido inventar o que já existia — e essa briga tem
|
|
13
|
+
// nome neste repositório: o `Sidebar`.
|
|
14
|
+
//
|
|
15
|
+
// ⚠ **E o sinal de "tem mais" foi pedido junto, com razão:** quem não sabe que dá para arrastar
|
|
16
|
+
// não acha a sexta opção. A saída óbvia do React Native **não serve** — `fadingEdgeLength` é
|
|
17
|
+
// `@platform android` (medido no tipo do RN), e usá-la daria o aviso no Android e **nada no
|
|
18
|
+
// iPhone**. É a armadilha de um alvo só que este projeto já pagou várias vezes.
|
|
19
|
+
// Gradiente também não: proibido desde a Fase 0.
|
|
20
|
+
//
|
|
21
|
+
// **O que fica, e é o mesmo da web:** a opção cortada pela borda é o sinal, e ele vem do recorte.
|
|
22
|
+
// O que este módulo acrescenta é MEDIR se há transbordo, para (1) mostrar a barra de rolagem só
|
|
23
|
+
// quando ela significa alguma coisa e (2) dar ao teste um número para conferir.
|
|
24
|
+
// ⚠ **Declarado: se o corte LÊ bem é pergunta de vidro, e nenhum aparelho deste projeto rodou
|
|
25
|
+
// iOS.** O que está provado aqui é a medição, não a leitura.
|
|
26
|
+
import * as React from "react";
|
|
27
|
+
import { ScrollView } from "react-native";
|
|
28
|
+
/**
|
|
29
|
+
* Uma linha que rola para o lado quando não cabe, e que sabe QUANDO não cabe.
|
|
30
|
+
*
|
|
31
|
+
* O componente fica com a informação em vez de adivinhar: `onLayout` dá a largura visível e
|
|
32
|
+
* `onContentSizeChange` dá a do conteúdo. Com as duas, `transbordou` é uma conta, não um palpite.
|
|
33
|
+
*/
|
|
34
|
+
export function FilaRolante({ children, style, testID }) {
|
|
35
|
+
const [visivel, setVisivel] = React.useState(0);
|
|
36
|
+
const [conteudo, setConteudo] = React.useState(0);
|
|
37
|
+
const transbordou = conteudo > visivel && visivel > 0;
|
|
38
|
+
return (_jsx(ScrollView, { horizontal: true, testID: testID, onLayout: (e) => setVisivel(e.nativeEvent.layout.width), onContentSizeChange: (w) => setConteudo(w),
|
|
39
|
+
// A barra só aparece quando ela quer dizer alguma coisa. Com tudo cabendo ela seria ruído,
|
|
40
|
+
// e é assim que o `overflow-x:auto` da web se comporta: sem transbordo, sem barra.
|
|
41
|
+
showsHorizontalScrollIndicator: transbordou,
|
|
42
|
+
// Sem isto o conteúdo estica até a largura do rolador, e o respiro da cápsula aparece como
|
|
43
|
+
// faixa vazia à direita quando os itens cabem.
|
|
44
|
+
contentContainerStyle: { flexGrow: 0 }, style: style, children: children }));
|
|
45
|
+
}
|
package/dist/text.js
CHANGED
|
@@ -22,7 +22,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
22
22
|
import * as React from "react";
|
|
23
23
|
import { Text as TextRN } from "react-native";
|
|
24
24
|
import { criarFolha } from "./estilos.js";
|
|
25
|
-
import { useAureaTokens } from "./theme.js";
|
|
25
|
+
import { useAureaTokens, useSobreAMarca } from "./theme.js";
|
|
26
26
|
const TAMANHO = {
|
|
27
27
|
xs: "textXs", sm: "textSm", md: "textMd", base: "textBase", lg: "textLg",
|
|
28
28
|
xl: "textXl", "2xl": "text2xl", "3xl": "text3xl", "4xl": "text4xl", "5xl": "text5xl",
|
|
@@ -61,6 +61,7 @@ const folha = criarFolha((t) => {
|
|
|
61
61
|
export function Text({ size = "md", weight = 400, font = "ui", tone = "default", leading = "normal", italic = false, align, tracking, style, ...rest }) {
|
|
62
62
|
const t = useAureaTokens();
|
|
63
63
|
const s = folha(t);
|
|
64
|
+
const sobreAMarca = useSobreAMarca();
|
|
64
65
|
const proprio = React.useMemo(() => {
|
|
65
66
|
const fontSize = t.size[TAMANHO[size]] ?? t.size.textMd;
|
|
66
67
|
const escala = t.font[font];
|
|
@@ -79,5 +80,13 @@ export function Text({ size = "md", weight = 400, font = "ui", tone = "default",
|
|
|
79
80
|
...(align ? { textAlign: align } : null),
|
|
80
81
|
};
|
|
81
82
|
}, [t, size, weight, font, leading, italic, align, tracking]);
|
|
82
|
-
|
|
83
|
+
// 🔴 SOBRE UMA SUPERFÍCIE DA MARCA A COR É FORÇADA, e ela vence até o tom explícito.
|
|
84
|
+
// Medido contra o `primary` nos dois temas: texto comum dá **1,83 no escuro**, esmaecido
|
|
85
|
+
// **1,35**, e `danger` menos ainda. **Nenhum tom alcança os 4,5 da norma sobre o amarelo** —
|
|
86
|
+
// só o `primary-foreground`, com 4,54. Respeitar um `tone` ali dentro seria obedecer a prop e
|
|
87
|
+
// entregar texto que não se lê.
|
|
88
|
+
// ⚠ **A consequência está declarada e não é neutra:** dentro de um cartão da marca não existe
|
|
89
|
+
// texto esmaecido. A hierarquia sai de PESO e TAMANHO.
|
|
90
|
+
// ⚠ E `style` continua por último de propósito: quem passa cor à mão assume a conta.
|
|
91
|
+
return _jsx(TextRN, { style: [s[tone], sobreAMarca && { color: sobreAMarca }, proprio, style], ...rest });
|
|
83
92
|
}
|
package/dist/theme.d.ts
CHANGED
|
@@ -73,3 +73,13 @@ export declare function useAureaTokens(): AureaTokens;
|
|
|
73
73
|
* `strings.ts`.
|
|
74
74
|
*/
|
|
75
75
|
export declare function useAureaStrings(): AureaStrings;
|
|
76
|
+
/** O provedor. Quem usa é o `Card variant="brand"`. */
|
|
77
|
+
export declare const SobreAMarca: React.Context<string | null>;
|
|
78
|
+
/**
|
|
79
|
+
* A cor que o texto tem de usar quando está sobre a marca, ou `null` quando não está.
|
|
80
|
+
*
|
|
81
|
+
* ⚠ **Ela vence TODOS os tons, inclusive os explícitos.** Um `tone="danger"` sobre o amarelo
|
|
82
|
+
* mediria menos que os 4,5 da norma, então respeitá-lo entregaria texto ilegível em nome da
|
|
83
|
+
* obediência. **Sobre o amarelo existe UMA cor de texto** — a hierarquia sai de peso e tamanho.
|
|
84
|
+
*/
|
|
85
|
+
export declare function useSobreAMarca(): string | null;
|
package/dist/theme.js
CHANGED
|
@@ -109,3 +109,33 @@ export function useAureaTokens() {
|
|
|
109
109
|
export function useAureaStrings() {
|
|
110
110
|
return usar("useAureaStrings").strings;
|
|
111
111
|
}
|
|
112
|
+
// ─────────────────────────────────────────────────────────────────────────────────────────────
|
|
113
|
+
// Sobre a marca — a cor de texto FORÇADA dentro de uma superfície amarela
|
|
114
|
+
// ─────────────────────────────────────────────────────────────────────────────────────────────
|
|
115
|
+
//
|
|
116
|
+
// 🔴 **Isto existe porque o contraste não deixou escolha**, e os números estão no `layout.tsx`:
|
|
117
|
+
// sobre o `primary`, o texto comum mede **1,83 no tema escuro** e o esmaecido **1,35**. Os dois
|
|
118
|
+
// são ilegíveis. O único par que serve nos DOIS temas é `primary-foreground`, com 4,54.
|
|
119
|
+
//
|
|
120
|
+
// ⚠ **E no React Native não há cascata de cor** — `color` num `View` não desce para o `Text` de
|
|
121
|
+
// dentro, como desceria no CSS. Então a cor tem de viajar por CONTEXTO, que é exatamente a
|
|
122
|
+
// decisão que o `Field` do Lote 4 tomou para empurrar nome, dica e estado de inválido.
|
|
123
|
+
//
|
|
124
|
+
// ⚠ **Ele mora AQUI e não no `layout.tsx` por uma razão de estrutura:** o `layout.tsx` importa o
|
|
125
|
+
// `Text`, então se ele também exportasse o contexto o `text.tsx` teria de importar de volta — um
|
|
126
|
+
// ciclo. Este módulo é o que os dois já importam.
|
|
127
|
+
//
|
|
128
|
+
// ⚠ **Não sai pela porta da frente do pacote.** É acordo interno entre o `Card` e o `Text`.
|
|
129
|
+
const SobreAMarcaCtx = React.createContext(null);
|
|
130
|
+
/** O provedor. Quem usa é o `Card variant="brand"`. */
|
|
131
|
+
export const SobreAMarca = SobreAMarcaCtx;
|
|
132
|
+
/**
|
|
133
|
+
* A cor que o texto tem de usar quando está sobre a marca, ou `null` quando não está.
|
|
134
|
+
*
|
|
135
|
+
* ⚠ **Ela vence TODOS os tons, inclusive os explícitos.** Um `tone="danger"` sobre o amarelo
|
|
136
|
+
* mediria menos que os 4,5 da norma, então respeitá-lo entregaria texto ilegível em nome da
|
|
137
|
+
* obediência. **Sobre o amarelo existe UMA cor de texto** — a hierarquia sai de peso e tamanho.
|
|
138
|
+
*/
|
|
139
|
+
export function useSobreAMarca() {
|
|
140
|
+
return React.useContext(SobreAMarcaCtx);
|
|
141
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aurea-uds/native",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.6",
|
|
4
4
|
"description": "React Native target for Aurea UDS: the theme x density provider, the first components and the Carbon icons, drawn on react-native-svg.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aurea",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"NOTICE"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@aurea-uds/tokens": "^0.8.
|
|
50
|
+
"@aurea-uds/tokens": "^0.8.6"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@react-native-community/datetimepicker": ">=8",
|