@softize/opus 12.5.2 → 12.5.4
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/CHANGELOG.md +17 -0
- package/package.json +1 -1
- package/src/ui/components/patterns/dock.tsx +16 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ Depois de qualquer bump, rode os gates (`typecheck` · `test` · `opus check` ·
|
|
|
7
7
|
`opus copy --check` · `base copy check` · `manifest:check`) — eles apontam o que a
|
|
8
8
|
mudança cobra do seu código.
|
|
9
9
|
|
|
10
|
+
## 12.5.4 — 2026-08-25
|
|
11
|
+
|
|
12
|
+
A `Dock` lembra por onde o Tab entra depois que o foco sai dela: quem andou até a quinta ação e
|
|
13
|
+
voltou para a tela reentra na quinta, não no começo da barra. E o recálculo por render passa a ter
|
|
14
|
+
o teste que faltava — o da 12.5.3 remontava a barra em vez de re-renderizá-la, então passava igual
|
|
15
|
+
contra o código bugado. Os casos cobertos agora são os reais: ação recém-montada não vira um
|
|
16
|
+
segundo ponto de entrada, e sumir com a ação que era a entrada não deixa a barra fora do Tab.
|
|
17
|
+
|
|
18
|
+
A nota da 12.5.3 dizia que todo re-render devolvia a entrada ao primeiro ícone; o que de fato
|
|
19
|
+
acontece é isso aqui — a entrada se perde quando as ações da barra mudam ou quando o foco sai.
|
|
20
|
+
|
|
21
|
+
## 12.5.3 — 2026-08-24
|
|
22
|
+
|
|
23
|
+
O roving tabindex da `Dock` sobrevive ao re-render do consumidor. Antes o efeito devolvia o ponto
|
|
24
|
+
de entrada ao primeiro ícone a cada render da tela em volta, tirando do Tab justamente o botão em
|
|
25
|
+
foco — a barra prometia um ponto de entrada e entregava outro assim que qualquer estado mudava.
|
|
26
|
+
|
|
10
27
|
## 12.5.2 — 2026-08-24
|
|
11
28
|
|
|
12
29
|
`SidebarItem` aplica `className` sempre na linha, recolhida ou aberta. Antes a prop mudava de alvo
|
package/package.json
CHANGED
|
@@ -35,17 +35,29 @@ export interface DockProps {
|
|
|
35
35
|
/** Barra flutuante ancorada à superfície. O contêiner precisa ser `relative`. */
|
|
36
36
|
export function Dock({ position = 'bottom', label, className, children }: DockProps): React.ReactElement {
|
|
37
37
|
const ref = React.useRef<HTMLDivElement>(null)
|
|
38
|
+
// Onde o Tab entra na barra. Fica num ref porque precisa sobreviver ao foco SAIR dela: quem
|
|
39
|
+
// andou até o quinto ícone e voltou pra tela espera reentrar no quinto, não no primeiro.
|
|
40
|
+
const entrada = React.useRef<HTMLButtonElement | null>(null)
|
|
38
41
|
|
|
39
42
|
// Roving tabindex: uma toolbar tem UM ponto de entrada no Tab; dentro dela, as setas andam.
|
|
40
43
|
// Sem isto as setas seriam um caminho a mais, e a barra continuaria cobrando um Tab por ícone.
|
|
41
|
-
const roving = React.useCallback((focado?: HTMLElement) => {
|
|
44
|
+
const roving = React.useCallback((focado?: HTMLElement | null) => {
|
|
42
45
|
const items = Array.from(ref.current?.querySelectorAll<HTMLButtonElement>('button') ?? [])
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
// Foco fora da barra não move a entrada — só confirma a que já estava valendo.
|
|
47
|
+
if (focado instanceof HTMLButtonElement && items.includes(focado)) entrada.current = focado
|
|
48
|
+
const lembrada = entrada.current
|
|
49
|
+
const alvo =
|
|
50
|
+
(lembrada !== null && items.includes(lembrada) && !lembrada.disabled ? lembrada : undefined) ??
|
|
51
|
+
items.find((item) => !item.disabled)
|
|
52
|
+
entrada.current = alvo ?? null
|
|
53
|
+
for (const item of items) item.tabIndex = item === alvo ? 0 : -1
|
|
45
54
|
}, [])
|
|
46
55
|
|
|
47
56
|
React.useEffect(() => {
|
|
48
|
-
|
|
57
|
+
// Roda a cada render porque as ações da barra mudam com o estado da tela: sem recalcular, um
|
|
58
|
+
// ícone recém-montado entraria no Tab por conta própria, e sumir com o ícone que era a
|
|
59
|
+
// entrada deixaria a barra inteira fora do Tab.
|
|
60
|
+
roving(document.activeElement as HTMLElement | null)
|
|
49
61
|
})
|
|
50
62
|
|
|
51
63
|
// Navegação de toolbar: as setas andam entre as ações, e Home/End vão às pontas. Sem isso
|