@aurea-uds/react 0.61.0 → 0.62.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.
@@ -17,7 +17,12 @@ import { Icon } from "./system.js";
17
17
  export function Accordion({ items, variant = "default", multiple = false, defaultValue, indicator = "chevron", size = "md", orientation = "vertical", className }) {
18
18
  const grupo = React.useId();
19
19
  const deLado = orientation === "horizontal";
20
- const lista = _jsx("div", { className: cx("accordion", variant === "surface" && "accordion-surface", indicator === "plus" && "accordion-plus", size === "lg" && "accordion-lg", deLado && "accordion-horizontal", !deLado && className), children: items.map(i => _jsxs("details", { className: "accordion-item", name: multiple && !deLado ? undefined : grupo, open: defaultValue?.includes(i.id) || undefined, children: [_jsxs("summary", { "aria-disabled": i.disabled || undefined, tabIndex: i.disabled ? -1 : undefined, onClick: i.disabled ? (e) => e.preventDefault()
20
+ // DE LADO, SEMPRE HÁ UM À VISTA também na abertura (06/11/2026, a D4 da auditoria externa — decisão do Victor, "Abrir o
21
+ // primeiro"): sem `defaultValue`, o horizontal nascia com tudo fechado, só as tiras em pé e nenhuma área de conteúdo. Agora
22
+ // nasce com o primeiro item que não está desligado. A referência não tem o horizontal; o de pé continua como o dela,
23
+ // fechado.
24
+ const abertos = defaultValue ?? (deLado ? [items.find(i => !i.disabled)?.id].filter(Boolean) : undefined);
25
+ const lista = _jsx("div", { className: cx("accordion", variant === "surface" && "accordion-surface", indicator === "plus" && "accordion-plus", size === "lg" && "accordion-lg", deLado && "accordion-horizontal", !deLado && className), children: items.map(i => _jsxs("details", { className: "accordion-item", name: multiple && !deLado ? undefined : grupo, open: abertos?.includes(i.id) || undefined, children: [_jsxs("summary", { "aria-disabled": i.disabled || undefined, tabIndex: i.disabled ? -1 : undefined, onClick: i.disabled ? (e) => e.preventDefault()
21
26
  : deLado ? (e) => { if (e.currentTarget.parentElement.open)
22
27
  e.preventDefault(); } : undefined, children: [_jsx("span", { className: "accordion-title", children: i.title }), _jsx("span", { className: "accordion-chevron", "aria-hidden": "true" })] }), _jsx("div", { className: "accordion-content", children: i.content })] }, i.id)) });
23
28
  return deLado ? _jsx("div", { className: cx("accordion-horizontal-frame", className), children: lista }) : lista;
@@ -103,6 +103,10 @@ export function MediaPlayer({ kind = "video", src, poster, title, subtitle, clas
103
103
  setCurrent(el.currentTime); onTimeUpdate?.(e); }, onLoadedMetadata: (e) => { onMeta(); onLoadedMetadata?.(e); }, onDurationChange: (e) => { const el = m(); if (el)
104
104
  setDuration(el.duration); onDurationChange?.(e); }, onProgress: (e) => { syncBuf(); onProgress?.(e); }, onVolumeChange: (e) => { syncVol(); onVolumeChange?.(e); }, children: children })] }), kind === "video" && title && _jsx("div", { className: "media-overlay-title", children: _jsxs("div", { children: [_jsx("strong", { children: title }), subtitle && _jsx("span", { children: subtitle })] }) }), _jsxs("div", { className: "media-controls", children: [_jsxs("div", { className: "media-seek", style: { "--media-played": `${playedPct}%` }, children: [_jsxs("div", { className: "media-seek-track", children: [_jsx("span", { className: "media-seek-buffered", style: { width: `${bufferedPct}%` } }), _jsx("span", { className: "media-seek-played" })] }), _jsx("input", { type: "range", min: 0, max: duration > 0 ? duration : 0, step: "any", value: Math.min(current, duration || 0), "aria-label": s.mediaSeek, "aria-valuetext": valueText, onChange: e => seek(Number(e.target.value)) })] }), _jsxs("div", { className: "media-control-row", children: [_jsxs("div", { className: "media-control-group", children: [_jsx("button", { className: "media-control", type: "button", "aria-label": playing ? s.mediaPause : s.mediaPlay, onClick: togglePlay, children: _jsx(Icon, { name: playing ? "pause" : "play" }) }), _jsx("button", { className: "media-control", type: "button", "aria-label": s.mediaSkipBack, onClick: () => skip(-10), children: _jsx(Icon, { name: "clock-counter-clockwise" }) }), _jsx("button", { className: "media-control", type: "button", "aria-label": s.mediaSkipForward, onClick: () => skip(10), children: _jsx(Icon, { name: "clock-clockwise" }) }), _jsxs("span", { className: "media-time", children: [clockTime(current), " / ", clockTime(duration)] })] }), _jsxs("div", { className: "media-control-group", children: [_jsx("button", { className: "media-control", type: "button", "aria-label": muted ? s.mediaUnmute : s.mediaMute, onClick: toggleMute, children: _jsx(Icon, { name: muted || volume === 0 ? "speaker-slash" : "speaker-high" }) }), _jsx("input", { className: "media-volume", type: "range", min: 0, max: 100, value: volPct, "aria-label": s.mediaVolume, "aria-valuetext": `${volPct}%`, onChange: e => setVol(Number(e.target.value) / 100) }), hasCaptions && _jsx("button", { className: cx("media-control", captionsOn && "active"), type: "button", "aria-label": captionsOn ? s.mediaCaptionsHide : s.mediaCaptionsShow, "aria-pressed": captionsOn, onClick: toggleCaptions, children: _jsx(Icon, { name: "closed-captioning" }) }), kind === "video" && _jsx("button", { className: "media-control", type: "button", "aria-label": fullscreen ? s.mediaFullscreenExit : s.mediaFullscreenEnter, onClick: toggleFullscreen, children: _jsx(Icon, { name: fullscreen ? "arrows-in" : "arrows-out" }) })] })] })] })] });
105
105
  }
106
+ // SÓ `https:` (06/11/2026, a D5 da auditoria externa — decisão do Victor): a moldura aceitava qualquer endereço, sem
107
+ // `sandbox` — não rouba nada da página (medido: o `data:` roda isolado), mas pode mostrar conteúdo falso. Sem `https:`, a
108
+ // moldura fica vazia e o link de origem não aparece.
109
+ const soHttps = (u) => !!u && /^https:\/\//i.test(u.trim());
106
110
  function comAutoplay(src) { try {
107
111
  const u = new URL(src);
108
112
  u.searchParams.set("autoplay", "1");
@@ -119,9 +123,9 @@ export function MediaEmbed({ src, title, poster, ratio = "16/9", href, autoplay
119
123
  React.useEffect(() => { if (clicou)
120
124
  frameRef.current?.focus(); }, [clicou]);
121
125
  const endereco = clicou && autoplay ? comAutoplay(src) : src;
122
- return _jsxs("div", { className: cx("media-embed", className), style: style, children: [_jsx("div", { className: "media-embed-frame", style: { aspectRatio: ratio }, children: ativo
126
+ return _jsxs("div", { className: cx("media-embed", className), style: style, children: [_jsx("div", { className: "media-embed-frame", style: { aspectRatio: ratio }, children: !soHttps(src) ? null : ativo
123
127
  ? _jsx("iframe", { ref: frameRef, src: endereco, title: title, loading: "lazy", referrerPolicy: "strict-origin-when-cross-origin", allow: "autoplay; encrypted-media; fullscreen; picture-in-picture", allowFullScreen: true, ...rest })
124
- : _jsxs("button", { type: "button", className: "media-embed-facade", "aria-label": `${s.mediaPlay}: ${title}`, onClick: () => { setAtivo(true); setClicou(true); }, children: [_jsx("img", { src: poster, alt: "", loading: "lazy", decoding: "async" }), _jsx("span", { className: "media-embed-play", "aria-hidden": "true", children: _jsx(Icon, { name: "play-circle", weight: "fill" }) })] }) }), href && _jsxs("a", { className: "media-embed-link", href: href, target: "_blank", rel: "noopener", children: [_jsx(Icon, { name: "arrow-square-out" }), s.mediaEmbedOpen] })] });
128
+ : _jsxs("button", { type: "button", className: "media-embed-facade", "aria-label": `${s.mediaPlay}: ${title}`, onClick: () => { setAtivo(true); setClicou(true); }, children: [_jsx("img", { src: poster, alt: "", loading: "lazy", decoding: "async" }), _jsx("span", { className: "media-embed-play", "aria-hidden": "true", children: _jsx(Icon, { name: "play-circle", weight: "fill" }) })] }) }), soHttps(href) && _jsxs("a", { className: "media-embed-link", href: href, target: "_blank", rel: "noopener", children: [_jsx(Icon, { name: "arrow-square-out" }), s.mediaEmbedOpen] })] });
125
129
  }
126
130
  export function Image({ ratio, fit, alt, className, style, render, onError, frame, srcDark, ...props }) {
127
131
  const [quebrou, setQuebrou] = React.useState(false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aurea-uds/react",
3
- "version": "0.61.0",
3
+ "version": "0.62.0",
4
4
  "description": "Os componentes React da Aurea UDS. Importe @aurea-uds/fonts/css e @aurea-uds/core/css junto.",
5
5
  "keywords": [
6
6
  "aurea",