@aurea-uds/react 0.32.0 → 0.33.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/actions.d.ts +17 -9
- package/dist/actions.js +30 -9
- package/dist/calendar.js +1 -1
- package/dist/feedback-client.d.ts +3 -1
- package/dist/feedback-client.js +4 -2
- package/dist/identity-client.d.ts +6 -1
- package/dist/identity-client.js +2 -5
- package/dist/index.d.ts +1 -1
- package/dist/inputs-client.d.ts +31 -2
- package/dist/inputs-client.js +40 -9
- package/dist/internal.d.ts +6 -4
- package/dist/internal.js +2 -1
- package/dist/markup.d.ts +46 -6
- package/dist/markup.js +42 -9
- package/dist/navigation-client.d.ts +7 -3
- package/dist/navigation-client.js +26 -14
- package/dist/overlays.js +7 -7
- package/dist/pure.d.ts +7 -0
- package/dist/pure.js +2 -2
- package/dist/system.d.ts +8 -5
- package/dist/system.js +36 -5
- package/package.json +1 -1
package/dist/system.js
CHANGED
|
@@ -22,11 +22,28 @@ import { cx, StringsContext, SpriteContext, PortalContext, ThemeContext, Density
|
|
|
22
22
|
// Sem ela nada muda: o Base UI monta no `document.body`, que é o que permite empilhar e
|
|
23
23
|
// posicionar sem herdar `overflow` nem `transform`. Com ela, o consumidor aponta para um nó
|
|
24
24
|
// dentro do landmark dele e o conteúdo do popup deixa de ficar fora de qualquer marco.
|
|
25
|
-
export function AureaProvider({ children, strings, direction = "ltr", spriteUrl = defaultSpriteUrl, portalContainer, theme, defaultTheme, onThemeChange, density, defaultDensity, onDensityChange, toastPlacement = "bottom" }) {
|
|
25
|
+
export function AureaProvider({ children, strings, direction = "ltr", spriteUrl = defaultSpriteUrl, portalContainer, theme, defaultTheme, onThemeChange, onThemePreferenceChange, density, defaultDensity, onDensityChange, toastPlacement = "bottom" }) {
|
|
26
26
|
const value = React.useMemo(() => strings ? { ...defaultStrings, ...strings } : defaultStrings, [strings]);
|
|
27
|
-
|
|
27
|
+
// "SYSTEM" (15/10/2026, a chave de três posições da referência): a PREFERÊNCIA pode ser `"system"`, e aí o tema na
|
|
28
|
+
// tela é o do sistema (`prefers-color-scheme`), e muda junto com ele. O documento recebe sempre o tema RESOLVIDO —
|
|
29
|
+
// o CSS só conhece `dark` e `light`. Sem preferência, o provider continua adotando o que o documento trouxer.
|
|
30
|
+
const [prefInterna, setPrefInterna] = React.useState(defaultTheme);
|
|
31
|
+
const preferencia = theme ?? prefInterna;
|
|
32
|
+
// Só quem SEGUE o sistema pergunta a ele: o provider sem `"system"` não abre `matchMedia` nenhum (o custo por
|
|
33
|
+
// aplicação é cobrado em `custo-responsivo` e `ssr-responsivo`, que pegaram a primeira versão, 15/10/2026).
|
|
34
|
+
const segue = preferencia === "system";
|
|
35
|
+
const assina = React.useCallback((cb) => segue ? assinaEsquema(cb) : () => { }, [segue]);
|
|
36
|
+
const sistemaEscuro = React.useSyncExternalStore(assina, segue ? leEsquemaEscuro : semEsquema, semEsquema);
|
|
37
|
+
const resolvido = preferencia === "system" ? (sistemaEscuro ? "dark" : "light") : preferencia;
|
|
38
|
+
const temaCtx = useEixoDoDocumento("theme", resolvido, undefined, undefined);
|
|
39
|
+
const escolher = React.useCallback((p) => {
|
|
40
|
+
if (theme === undefined)
|
|
41
|
+
setPrefInterna(p);
|
|
42
|
+
onThemePreferenceChange?.(p);
|
|
43
|
+
onThemeChange?.(p === "system" ? (leEsquemaEscuro() ? "dark" : "light") : p);
|
|
44
|
+
}, [theme, onThemeChange, onThemePreferenceChange]);
|
|
28
45
|
const densCtx = useEixoDoDocumento("density", density, defaultDensity, onDensityChange);
|
|
29
|
-
const tema = React.useMemo(() => ({ theme: temaCtx.valor,
|
|
46
|
+
const tema = React.useMemo(() => ({ theme: temaCtx.valor, preference: preferencia ?? temaCtx.valor, setTheme: escolher,
|
|
30
47
|
// `toggleTheme` existe porque é o gesto real: um botão de tema não escolhe entre dois
|
|
31
48
|
// valores, ele inverte o atual. Deixar isso para o consumidor é como o catálogo e os docs
|
|
32
49
|
// acabaram com duas implementações divergentes da mesma coisa.
|
|
@@ -38,13 +55,24 @@ export function AureaProvider({ children, strings, direction = "ltr", spriteUrl
|
|
|
38
55
|
// ⚠ Achado em 09/09/2026 SÓ porque o `useAureaTheme` passou a delegar para cá: a divergência
|
|
39
56
|
// existia desde sempre e nenhum teste a pegava, porque cada metade era testada sozinha.
|
|
40
57
|
// Agora a regra é uma: desconhecido resolve para claro e alterna para ESCURO.
|
|
41
|
-
toggleTheme: () =>
|
|
58
|
+
toggleTheme: () => escolher(temaCtx.valor === "dark" ? "light" : "dark") }), [temaCtx, preferencia, escolher]);
|
|
42
59
|
const dens = React.useMemo(() => ({ density: densCtx.valor, setDensity: densCtx.set }), [densCtx]);
|
|
43
60
|
// GAR-14: os avisos presos a um botão vivem num gerenciador do MÓDULO (ver `avisosAncorados`), então
|
|
44
61
|
// só o provedor de FORA monta o hospedeiro deles — com dois, cada aviso apareceria duas vezes.
|
|
45
62
|
const deFora = !React.useContext(DentroDoProviderContext);
|
|
46
63
|
return _jsx(DentroDoProviderContext.Provider, { value: true, children: _jsx(StringsContext.Provider, { value: value, children: _jsx(SpriteContext.Provider, { value: spriteUrl, children: _jsx(PortalContext.Provider, { value: portalContainer, children: _jsx(ThemeContext.Provider, { value: tema, children: _jsx(DensityContext.Provider, { value: dens, children: _jsx(DirectionProvider, { direction: direction, children: _jsx(BaseToast.Provider, { timeout: TEMPO_DO_AVISO, children: _jsxs(BaseTooltip.Provider, { children: [children, _jsx(AureaToastViewport, { placement: toastPlacement }), deFora && _jsx(BaseToast.Provider, { toastManager: avisosAncorados, children: _jsx(AvisosAncorados, {}) })] }) }) }) }) }) }) }) }) });
|
|
47
64
|
}
|
|
65
|
+
// O esquema do sistema, para a preferência `"system"`. Sem `matchMedia` (servidor, jsdom), claro.
|
|
66
|
+
const ESQUEMA_ESCURO = "(prefers-color-scheme: dark)";
|
|
67
|
+
const assinaEsquema = (cb) => {
|
|
68
|
+
if (typeof matchMedia !== "function")
|
|
69
|
+
return () => { };
|
|
70
|
+
const m = matchMedia(ESQUEMA_ESCURO);
|
|
71
|
+
m.addEventListener("change", cb);
|
|
72
|
+
return () => m.removeEventListener("change", cb);
|
|
73
|
+
};
|
|
74
|
+
const leEsquemaEscuro = () => typeof matchMedia === "function" && matchMedia(ESQUEMA_ESCURO).matches;
|
|
75
|
+
const semEsquema = () => false;
|
|
48
76
|
/** Um eixo de apresentação que vive no `<html>`: tema ou densidade. A conta é a mesma para os
|
|
49
77
|
* dois, e escrevê-la duas vezes seria o defeito do §21 cometido dentro do próprio conserto
|
|
50
78
|
* dele. */
|
|
@@ -121,12 +149,15 @@ export function useAureaTheme() {
|
|
|
121
149
|
const ctxDens = React.useContext(DensityContext);
|
|
122
150
|
return React.useMemo(() => ({
|
|
123
151
|
theme, density,
|
|
152
|
+
/** O que foi escolhido (15/10/2026): pode ser `"system"`. Fora de um provider, o tema na tela. */
|
|
153
|
+
preference: (dentroDeProvider ? ctxTema.preference : theme) ?? theme,
|
|
124
154
|
setTheme: (t) => {
|
|
125
155
|
if (dentroDeProvider) {
|
|
126
156
|
ctxTema.setTheme(t);
|
|
127
157
|
return;
|
|
128
158
|
}
|
|
129
|
-
|
|
159
|
+
// Fora de provider, `"system"` escreve o tema do sistema AGORA; seguir as mudanças dele é do provider.
|
|
160
|
+
document.documentElement.dataset.theme = t === "system" ? (leEsquemaEscuro() ? "dark" : "light") : t;
|
|
130
161
|
},
|
|
131
162
|
setDensity: (d) => {
|
|
132
163
|
if (dentroDeProvider) {
|