Skip to content

Commit

Permalink
wrap tabs in focusable div with tabindex - add Keyboard from dash ext…
Browse files Browse the repository at this point in the history
…ensions - add callback to handle keyboard navigation for Tabs
  • Loading branch information
tilen1976 committed Aug 19, 2024
1 parent 7e3d2af commit 9794572
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 43 deletions.
139 changes: 119 additions & 20 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ python-dotenv = ">=1.0.1"
ssb-dash-components = ">=0.8.1"
dapla-toolbelt-metadata = ">=0.2.0"
gunicorn = ">=23.0.0"
dash-extensions = "^1.0.18"

[tool.poetry.group.dev.dependencies]
mypy = ">=0.950"
Expand Down Expand Up @@ -108,6 +109,7 @@ module = [
"pyarrow.parquet",
"dash.development.base_component",
"pytest_mock",
"dash_extensions",
]
ignore_missing_imports = true

Expand Down
57 changes: 34 additions & 23 deletions src/datadoc/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from dash import Dash
from dash import dcc
from dash import html
from dash_extensions import Keyboard
from flask_healthz import healthz

from datadoc import config
Expand Down Expand Up @@ -52,34 +53,44 @@ def build_app(app: type[Dash]) -> Dash:
),
build_controls_bar(),
html.Div(id="alerts-section"),
dcc.Tabs(
id="tabs",
className="ssb-tabs",
value="dataset",
children=[
dcc.Tab(
label="Datasett",
children=ssb.Title(
"Rediger datasett",
size=2,
className="workspace-tab-title",
),
html.Div(
[
dcc.Tabs(
id="tabs",
className="ssb-tabs",
value="dataset",
className="workspace-tab",
children=[
dcc.Tab(
label="Datasett",
children=ssb.Title(
"Rediger datasett",
size=2,
className="workspace-tab-title",
),
value="dataset",
className="workspace-tab",
),
dcc.Tab(
label="Variabler",
children=ssb.Title(
"Rediger variabler",
size=2,
className="workspace-tab-title",
),
value="variables",
className="workspace-tab",
),
],
),
dcc.Tab(
label="Variabler",
children=ssb.Title(
"Rediger variabler",
size=2,
className="workspace-tab-title",
),
value="variables",
className="workspace-tab",
html.Div(id="display-tab"),
Keyboard(
id="keyboard",
captureKeys=["ArrowLeft", "ArrowRight"],
),
],
tabIndex="0",
className="focusable-tabs-section",
),
html.Div(id="display-tab"),
],
className="main-content-app",
),
Expand Down
20 changes: 20 additions & 0 deletions src/datadoc/frontend/callbacks/register_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,26 @@ def callback_render_tabs(tab: html.Article) -> html.Article | None:
"""Return correct tab content."""
return render_tabs(tab)

@app.callback(
Output("tabs", "value"),
Input("keyboard", "keydown"),
Input("tabs", "value"),
)
def switch_tabs(keydown: dict, current_tab: str) -> str:
"""Handle keyboard events and switch tabs.
This callback is designed to make Dash core component Tabs
with children Tab focusable and keyboard interactive,
enhancing accessibility by allowing users to navigate between tabs
using the arrow keys.
"""
if keydown:
if keydown["key"] == "ArrowRight":
return "variables" if current_tab == "dataset" else "dataset"
if keydown["key"] == "ArrowLeft":
return "dataset" if current_tab == "variables" else "variables"
return current_tab

@app.callback(
Output(VARIABLES_INFORMATION_ID, "children"),
Input("dataset-opened-counter", "data"),
Expand Down

0 comments on commit 9794572

Please sign in to comment.