diff --git a/docs/accessibility.md b/docs/accessibility.md index 33c8943..e5cee4c 100644 --- a/docs/accessibility.md +++ b/docs/accessibility.md @@ -11,7 +11,7 @@ hSQLite Editor targets WCAG 2.2 Level AA for the latest release. Accessibility i - Controls require programmatic names; placeholders are not labels. - Dialogs require an accessible name, appropriate description, focus containment, and focus restoration. - Status and error feedback must be exposed without moving focus unnecessarily. -- SQL tabs keep form controls outside `role="tab"`. F2 starts an inline rename, Enter commits, Escape cancels, and both paths restore focus to the same tab. Rename and close commands for the active tab live outside the tablist and remain keyboard reachable. +- SQL tabs keep form controls outside `role="tab"`. F2 starts an inline rename, Enter commits, Escape cancels, and both paths restore focus to the same tab. Rename and close commands are siblings of their tab, appear on hover or focus, and remain keyboard reachable in that order. The New tab command follows the tablist in the same horizontal scroll sequence. Closing a tab restores focus to the resulting active tab. Closing all tabs requires a count-specific destructive confirmation whose initial focus is Cancel. - Error toasts use atomic assertive announcements; informational toasts use atomic polite announcements. Toasts never take focus, and their close buttons have localized accessible names. - Results-grid sorting, row selection, current-row movement, and column operations require keyboard equivalents or an accessible command surface. - SQL Map table and field selectors expose names derived from the visible database identifiers. Relationship controls support Enter and Space, preserve pressed state while a source is selected, and announce source, cancellation, blocked validation, and completion within the open dialog. diff --git a/index.html b/index.html index 0b632cd..ee3c9cd 100644 --- a/index.html +++ b/index.html @@ -1983,9 +1983,10 @@ align-items: center; gap: 9px; min-width: 0; - width: 100%; + width: auto; + flex: 1 1 auto; min-height: 32px; - padding: 0 10px 0 12px; + padding: 0 64px 0 12px; border: 0; border-radius: 999px; background: transparent; @@ -2072,6 +2073,67 @@ display: none; } +.sql-tab-actions-portal { +position: absolute; +display: inline-flex; + align-items: center; + justify-content: flex-end; + gap: 0; + padding-right: 3px; + opacity: 0; + visibility: hidden; + pointer-events: none; + transition: opacity 0.15s ease, visibility 0.15s ease; + z-index: 2; +} + +.sql-tab-actions-portal.is-revealed, + .sql-tab-actions-portal:focus-within { +opacity: 1; + visibility: visible; +} + +.sql-tab-actions-portal.is-revealed .sql-tab-inline-action, + .sql-tab-actions-portal:focus-within .sql-tab-inline-action { +pointer-events: auto; +} + +.sql-tab-actions-portal:has([data-tab-rename-id]:disabled) { +display: none; +} + +.sql-tab-actions-portal .ui-button.sql-tab-inline-action { +width: 26px; + height: 26px; + min-width: 26px; + min-height: 26px; + padding: 0; + border: 0; + border-radius: 6px; + background: transparent; + color: var(--mutedText); + box-shadow: none; +} + +.sql-tab-actions-portal .ui-button.sql-tab-inline-action:hover { +border: 0; + background: color-mix(in srgb, var(--danger) 12%, var(--input-bg)); + color: var(--danger); + box-shadow: none; +} + +.sql-tab-actions-portal .ui-button.sql-tab-inline-rename:hover { +background: color-mix(in srgb, var(--info) 10%, var(--input-bg)); + color: var(--foreground); +} + +.sql-tab-actions-portal .ui-button.sql-tab-inline-action:focus-visible { +border: 0; + outline: none; + background: color-mix(in srgb, var(--ring) 10%, var(--input-bg)); + box-shadow: inset 0 0 0 2px var(--ring); +} + .sql-tab-header-action { width: 30px; height: 30px; @@ -2079,6 +2141,29 @@ flex: 0 0 auto; } +.sql-tabs-close-all { +border-color: transparent; + background: color-mix(in srgb, var(--border) 35%, transparent); + color: var(--mutedText); +} + +.sql-tabs-close-all:not(:disabled):hover { +border-color: color-mix(in srgb, var(--border) 70%, transparent); + background: color-mix(in srgb, var(--border) 55%, transparent); + color: var(--foreground); +} + +@media (hover: none), (pointer: coarse) { +.sql-tab-actions-portal.active { +opacity: 1; + visibility: visible; +} + +.sql-tab-actions-portal.active .sql-tab-inline-action { +pointer-events: auto; +} +} + .new-sql-tab-btn { width: 34px; height: 30px; @@ -2957,7 +3042,7 @@ overflow: visible; } -.sql-tabs { +.sql-tabs-strip { display: flex; align-items: center; gap: 6px; @@ -2969,6 +3054,27 @@ padding-bottom: 2px; } +.sql-tabs { +display: flex; + align-items: center; + gap: 6px; + flex: 0 0 auto; + min-width: 0; +} + +.sql-tabs-stack { +position: relative; + display: flex; + flex: 0 0 auto; + min-width: 0; +} + +.sql-tab-actions-layer { +position: absolute; + inset: 0; + pointer-events: none; +} + .sql-tabs-overflow { position: relative; flex: 0 0 auto; @@ -3030,17 +3136,17 @@ white-space: nowrap; } -.sql-tabs.is-overflowing { +.sql-tabs-strip.is-overflowing { overflow-x: auto; scrollbar-width: thin; scrollbar-gutter: stable; } -.sql-tabs::-webkit-scrollbar { +.sql-tabs-strip::-webkit-scrollbar { height: 0; } -.sql-tabs.is-overflowing::-webkit-scrollbar { +.sql-tabs-strip.is-overflowing::-webkit-scrollbar { height: 8px; } @@ -3067,7 +3173,7 @@ } .sql-tabs-header::after { -right: 38px; +right: 76px; background: linear-gradient(to left, var(--panel), transparent); } @@ -5357,16 +5463,14 @@

Schema

-
- - +
+
@@ -5422,9 +5525,6 @@

Instruções SQL

- @@ -5624,6 +5724,17 @@

Fechar aba?

+ +
@@ -205,9 +202,6 @@

Instruções SQL

- @@ -407,6 +401,17 @@

Fechar aba?

+ +