@aurea-uds/react 0.4.0 → 0.6.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/system.js CHANGED
@@ -7,7 +7,14 @@ import React from "react";
7
7
  import { Toast as BaseToast } from "@base-ui/react/toast";
8
8
  import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
9
9
  import { DirectionProvider } from "@base-ui/react/direction-provider";
10
- import { cx, StringsContext, SpriteContext, PortalContext, defaultStrings, defaultSpriteUrl, useSpriteUrl, useAureaStrings, usePortalContainer } from "./internal.js";
10
+ import { peleDoEixo } from "./pure.js";
11
+ import { cx, StringsContext, SpriteContext, PortalContext, ThemeContext, DensityContext, usePortalContainer, defaultStrings, defaultSpriteUrl, useSpriteUrl, useAureaStrings } from "./internal.js";
12
+ // `theme` e `density` seguem a convenção controlado/não-controlado do resto da biblioteca
13
+ // (`Toggle`, `ToggleGroup`): passe `theme` para mandar, `defaultTheme` para semear, e ouça por
14
+ // `onThemeChange`. Sem nenhum dos dois, o provider ADOTA o que o documento já trouxer no
15
+ // `<html>` — e essa é a parte que importa: o `data-theme` do markup existe para não haver
16
+ // piscada de tema no carregamento, e um provider que o sobrescrevesse na primeira pintura
17
+ // reintroduziria exatamente a piscada que ele evita.
11
18
  // `portalContainer` (achado B7, Parte C do PLANO-1.0): onde TODO popup da biblioteca é montado.
12
19
  // Configuração de aplicação, então entra aqui uma vez — o mesmo raciocínio do `spriteUrl`, e
13
20
  // pela mesma razão medida: com prop por componente seriam nove sítios repassando a mesma coisa
@@ -15,9 +22,44 @@ import { cx, StringsContext, SpriteContext, PortalContext, defaultStrings, defau
15
22
  // Sem ela nada muda: o Base UI monta no `document.body`, que é o que permite empilhar e
16
23
  // posicionar sem herdar `overflow` nem `transform`. Com ela, o consumidor aponta para um nó
17
24
  // dentro do landmark dele e o conteúdo do popup deixa de ficar fora de qualquer marco.
18
- export function AureaProvider({ children, strings, direction = "ltr", spriteUrl = defaultSpriteUrl, portalContainer }) {
25
+ export function AureaProvider({ children, strings, direction = "ltr", spriteUrl = defaultSpriteUrl, portalContainer, theme, defaultTheme, onThemeChange, density, defaultDensity, onDensityChange }) {
19
26
  const value = React.useMemo(() => strings ? { ...defaultStrings, ...strings } : defaultStrings, [strings]);
20
- return _jsx(StringsContext.Provider, { value: value, children: _jsx(SpriteContext.Provider, { value: spriteUrl, children: _jsx(PortalContext.Provider, { value: portalContainer, children: _jsx(DirectionProvider, { direction: direction, children: _jsx(BaseToast.Provider, { children: _jsxs(BaseTooltip.Provider, { children: [children, _jsx(AureaToastViewport, {})] }) }) }) }) }) });
27
+ const temaCtx = useEixoDoDocumento("theme", theme, defaultTheme, onThemeChange);
28
+ const densCtx = useEixoDoDocumento("density", density, defaultDensity, onDensityChange);
29
+ const tema = React.useMemo(() => ({ theme: temaCtx.valor, setTheme: temaCtx.set,
30
+ // `toggleTheme` existe porque é o gesto real: um botão de tema não escolhe entre dois
31
+ // valores, ele inverte o atual. Deixar isso para o consumidor é como o catálogo e os docs
32
+ // acabaram com duas implementações divergentes da mesma coisa.
33
+ toggleTheme: () => temaCtx.set(temaCtx.valor === "light" ? "dark" : "light") }), [temaCtx]);
34
+ const dens = React.useMemo(() => ({ density: densCtx.valor, setDensity: densCtx.set }), [densCtx]);
35
+ return _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, { children: _jsxs(BaseTooltip.Provider, { children: [children, _jsx(AureaToastViewport, {})] }) }) }) }) }) }) }) });
36
+ }
37
+ /** Um eixo de apresentação que vive no `<html>`: tema ou densidade. A conta é a mesma para os
38
+ * dois, e escrevê-la duas vezes seria o defeito do §21 cometido dentro do próprio conserto
39
+ * dele. */
40
+ function useEixoDoDocumento(attr, controlado, semente, aviso) {
41
+ // Nada de ler `document` durante o render: em SSR ele não existe, e o valor lido no cliente
42
+ // divergiria do renderizado no servidor (erro de hidratação). O estado nasce da semente, e o
43
+ // efeito abaixo adota o que o documento já traz.
44
+ const [interno, setInterno] = React.useState(semente);
45
+ const valor = controlado ?? interno;
46
+ React.useEffect(() => {
47
+ const raiz = document.documentElement;
48
+ if (valor === undefined) {
49
+ const doDoc = raiz.dataset[attr];
50
+ if (doDoc)
51
+ setInterno(doDoc); // adota o markup em vez de sobrescrevê-lo
52
+ return;
53
+ }
54
+ if (raiz.dataset[attr] !== valor)
55
+ raiz.dataset[attr] = valor;
56
+ }, [attr, valor]);
57
+ const set = React.useCallback((v) => {
58
+ if (controlado === undefined)
59
+ setInterno(v);
60
+ aviso?.(v);
61
+ }, [controlado, aviso]);
62
+ return React.useMemo(() => ({ valor, set }), [valor, set]);
21
63
  }
22
64
  export const useToast = () => BaseToast.useToastManager();
23
65
  // useAureaTheme (M7): ler e trocar os DOIS eixos que a Aurea põe no <html> — `data-theme` e
@@ -77,4 +119,4 @@ function AureaToastViewport() {
77
119
  }
78
120
  // spriteUrl aqui é OVERRIDE local (dois sprites na mesma página, por exemplo). O normal é
79
121
  // não passar nada e deixar o AureaProvider dizer de onde vêm os glifos.
80
- export function Icon({ name, spriteUrl, size = "md", className, ...props }) { const base = useSpriteUrl(); return _jsx("svg", { "aria-hidden": "true", className: cx("icon", size !== "md" && `icon-${size}`, className), ...props, children: _jsx("use", { href: `${spriteUrl ?? base}#i-${name}` }) }); }
122
+ export function Icon({ name, spriteUrl, size, className, ...props }) { const base = useSpriteUrl(); return _jsx("svg", { "aria-hidden": "true", className: cx("icon", peleDoEixo("icon", size), className), ...props, children: _jsx("use", { href: `${spriteUrl ?? base}#i-${name}` }) }); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/react",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "React components for Aurea UDS. Import @aurea-uds/fonts/css and @aurea-uds/core/css alongside.",
5
5
  "keywords": [
6
6
  "aurea",