Skip to content

Commit 51ee48e

Browse files
committed
Add accessibility role tables
1 parent a7be05f commit 51ee48e

File tree

13 files changed

+227
-25
lines changed

13 files changed

+227
-25
lines changed

apps/components_guide_web/assets/css/app.css

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ article a {
3535
article a:hover {
3636
text-decoration: underline;
3737
}
38+
article figcaption {
39+
font-style: italic;
40+
}
3841

3942
.a\{font-bold\} a {
4043
font-weight: bold;
@@ -49,22 +52,34 @@ a:hover {
4952
text-decoration: var(--hover\:links-decoration);
5053
}
5154

52-
h2, p, li {
55+
h2, h3, p, li, table {
5356
margin-left: var(--item-spacing-left);
5457
margin-right: var(--item-spacing-right);
5558
}
59+
table {
60+
width: calc(100% - var(--item-spacing-left) - var(--item-spacing-right));
61+
}
5662
h2 {
5763
font-size: var(--heading-2-size);
58-
padding: var(--heading-2-padding);
64+
padding: var(--heading-2-spacing);
65+
}
66+
h3 {
67+
font-size: var(--heading-3-size);
68+
padding: var(--heading-3-spacing);
5969
}
6070
p {
61-
padding: var(--paragraph-padding);
71+
padding: var(--paragraph-spacing);
6272
}
6373
li {
64-
padding: var(--listitem-padding);
74+
padding: var(--listitem-spacing);
75+
}
76+
table {
77+
margin: var(--table-spacing);
78+
margin-left: var(--item-spacing-left);
79+
margin-right: var(--item-spacing-right);
6580
}
6681
:not(pre) > code {
67-
padding: var(--code-padding);
82+
padding: var(--code-spacing);
6883
border-radius: var(--code-radius);
6984
}
7085

@@ -81,10 +96,13 @@ input {
8196
--item-spacing-left: 1rem;
8297
--item-spacing-right: 1rem;
8398
--heading-2-size: var(--size-3xl);
84-
--heading-2-padding: var(--size-base) 0;
85-
--paragraph-padding: 0.5rem 0;
86-
--listitem-padding: 0.5rem 0;
87-
--code-padding: 0 0.1875em;
99+
--heading-2-spacing: var(--size-base) 0;
100+
--heading-3-size: var(--size-2xl);
101+
--heading-3-spacing: var(--size-base) 0;
102+
--paragraph-spacing: 0.5rem 0;
103+
--listitem-spacing: 0.5rem 0;
104+
--table-spacing: var(--size-xl) 0;
105+
--code-spacing: 0 0.1875em;
88106
--code-radius: 0.125em;
89107
}
90108

apps/components_guide_web/lib/components_guide_web/endpoint.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ defmodule ComponentsGuideWeb.Endpoint do
2121
at: "/",
2222
from: :components_guide_web,
2323
gzip: false,
24-
only: ~w(css fonts images js favicon.ico robots.txt)
24+
only: ~w(css fonts images js favicon.ico robots.txt collected)
2525

2626
# Code reloading can be explicitly enabled under the
2727
# :code_reloader configuration of your endpoint.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
defmodule ComponentsGuideWeb.TemplateEngines.ImageEngine do
2+
@moduledoc false
3+
4+
@behaviour Phoenix.Template.Engine
5+
6+
require ExImageInfo
7+
8+
def compile(path, _name) do
9+
data = File.read!(path)
10+
11+
media_type = MIME.from_path(path)
12+
hash = :crypto.hash(:sha256, data)
13+
hash_base64 = hash |> Base.url_encode64()
14+
extension = MIME.extensions(media_type) |> List.first()
15+
static_path = Path.join(["collected", media_type, "#{hash_base64}.#{extension}"])
16+
17+
image_info_type = case media_type do
18+
"image/png" -> :png
19+
end
20+
21+
{_, width, height, _} = ExImageInfo.info(data, image_info_type)
22+
23+
result = %{
24+
source_path: path,
25+
static_path: static_path,
26+
width: width,
27+
height: height,
28+
}
29+
30+
Macro.escape(result)
31+
end
32+
end

apps/components_guide_web/lib/components_guide_web/markdown_engine.ex renamed to apps/components_guide_web/lib/components_guide_web/template_engines/markdown_engine.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
defmodule ComponentsGuideWeb.MarkdownEngine do
1+
defmodule ComponentsGuideWeb.TemplateEngines.MarkdownEngine do
22
@moduledoc false
33

44
@behaviour Phoenix.Template.Engine

apps/components_guide_web/lib/components_guide_web/templates/react_typescript/index.html.eex

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
</header>
1818
</div>
1919

20-
<div class="bg-white">
21-
<div class="content max-w-4xl mx-auto py-8 text-lg">
22-
<%= render(@view_module, @article <> ".html") %>
20+
<article>
21+
<div class="bg-white">
22+
<div class="content max-w-4xl mx-auto py-8 text-lg">
23+
<%= render(@view_module, @article <> ".html", conn: @conn) %>
24+
</div>
2325
</div>
24-
</div>
26+
</article>
2527

2628
<div class="bg-white" hidden>
2729
<section class="container pt-8 pb-16 text-2xl">
21.2 KB
Loading
78.2 KB
Loading

apps/components_guide_web/lib/components_guide_web/templates/react_typescript/testing.html.md

Lines changed: 143 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,153 @@
11
## Behavior and markup > implementation details
22

3+
## Accessibility-first testing: a standard-based approach
34

5+
- Build components
6+
- Test components work as expected
7+
- Test-drive components
8+
- Learnable & deterministic
49

5-
## Roles > Tag Names
10+
## Build components
611

7-
You can find a list of roles here [in the spec](https://www.w3.org/TR/wai-aria/#widget_roles).
12+
Most semantic HTML elements have a role.
813

9-
![list-of-roles.png](list-of-roles.png)
14+
<table class="text-left table-fixed">
15+
<thead>
16+
<tr>
17+
<th style="width: 12em">Role name</th>
18+
<th>HTML element</th>
19+
</tr>
20+
</thead>
21+
<tbody class="border text-white bg-teal-900">
22+
<%= table_rows([
23+
["**link**", "`<a href=…>`"],
24+
["_none_", "`<a>`"],
25+
["**button**", "`<button>`"],
26+
["**button**", "`<input type=button>`"],
27+
["**textbox**", "`<textarea>`"],
28+
["**textbox**", "`<input type=text>`"],
29+
["**radio**", "`<input type=radio>`"],
30+
["**heading**", "`<h1>`"],
31+
["**heading**", "`<h2>`"],
32+
["**heading**", "`<h3>`"],
33+
["**document**", "`<body>`"],
34+
]) %>
35+
</tbody>
36+
</table>
37+
38+
<table class="text-left table-fixed">
39+
<caption class="text-2xl">Landmarks</caption>
40+
<thead>
41+
<tr>
42+
<th style="width: 12em">Role name</th>
43+
<th>HTML element</th>
44+
</tr>
45+
</thead>
46+
<tbody class="border text-white bg-teal-900">
47+
<%= table_rows([
48+
["**main**", "`<main>`"],
49+
["**navigation**", "`<nav>`"],
50+
["**complementary**", "`<aside>`"],
51+
["**region**", "`<section>`"],
52+
]) %>
53+
</tbody>
54+
</table>
55+
56+
<table class="text-left table-fixed">
57+
<caption class="text-2xl">Content</caption>
58+
<thead>
59+
<tr>
60+
<th style="width: 12em">Role name</th>
61+
<th>HTML element</th>
62+
</tr>
63+
</thead>
64+
<tbody class="border text-white bg-teal-900">
65+
<%= table_rows([
66+
["**link**", "`<a href=…>`"],
67+
["_none_", "`<a>`"],
68+
["**heading**", "`<h1>`, `<h2>`, `<h3>`, etc"],
69+
["**list**", "`<ul>`, `<ol>`"],
70+
["**listitem**", "`<li>`"],
71+
["**term**", "`<dt>`"],
72+
["**definition**", "`<dd>`"],
73+
["**img**", "`<img alt=\"Some description\">`"],
74+
["_none_", "`<img alt=\"\">`"],
75+
["**separator**", "`<hr>`"],
76+
["**figure**", "`<figure>`"],
77+
["_none_", "`<p>`"],
78+
["_none_", "`<div>`"],
79+
["_none_", "`<span>`"],
80+
["**button**", "`<summary>`"],
81+
]) %>
82+
</tbody>
83+
</table>
84+
85+
<table class="text-left table-fixed">
86+
<caption class="text-2xl">Forms</caption>
87+
<thead>
88+
<tr>
89+
<th style="width: 12em">Role name</th>
90+
<th>HTML element</th>
91+
</tr>
92+
</thead>
93+
<tbody class="border text-white bg-teal-900">
94+
<%= table_rows([
95+
["**form**", "`<form>`"],
96+
["**button**", "`<button>`"],
97+
["**button**", "`<input type=button>`"],
98+
["**textbox**", "`<textarea>`"],
99+
["**textbox**", "`<input type=text>`"],
100+
["**textbox**", "`<input type=email>`"],
101+
["**textbox**", "`<input type=tel>`"],
102+
["**textbox**", "`<input type=url>`"],
103+
["**searchbox**", "`<input type=search>` with no `list` attribute"],
104+
["**radio**", "`<input type=radio>`"],
105+
["**checkbox**", "`<input type=checkbox>`"],
106+
["**combobox**", "`<select>`"],
107+
["**listbox**", "`<select>` with `multiple` attribute"],
108+
["**option**", "`<option>`"],
109+
["**slider**", "`<input type=range>`"],
110+
["_none_", "`<input type=password>`"],
111+
["progressbar", "`<progress>`"],
112+
["group", "`<fieldset>`"],
113+
["status", "`<output>`"],
114+
["_none_", "`<legend>`"],
115+
]) %>
116+
</tbody>
117+
</table>
118+
119+
<table class="text-left">
120+
<caption class="text-2xl">Tables</caption>
121+
<thead>
122+
<tr>
123+
<th>Role name</th>
124+
<th>HTML element</th>
125+
</tr>
126+
</thead>
127+
<tbody class="border text-white bg-teal-900">
128+
<%= table_rows([
129+
["**table**", "`<table>`"],
130+
["**rowgroup**", "`<tbody>`, `<thead>`, `<tfoot>`"],
131+
["**rowheader**", "`<th>`"],
132+
["**columnheader**", "`<th>`"],
133+
["**row**", "`<tr>`"],
134+
["**cell**", "`<td>`"],
135+
]) %>
136+
</tbody>
137+
</table>
138+
139+
## Test components work as expected
140+
141+
### Roles > Tag Names
142+
143+
<figure>
144+
<%= collected_image(@conn, "list-of-roles") %>
145+
<figcaption>
146+
<%= line("A list of roles [from the wai-aria spec](https://www.w3.org/TR/wai-aria/#widget_roles).") %>
147+
</figcaption>
148+
</figure>
10149

11-
## Roles > Test IDs
150+
### Roles > Test IDs
12151

13152
- Test IDs are fragile. They are not part of behaviour.
14153
- Easier to write tests first.

apps/components_guide_web/lib/components_guide_web/views/collected_view.ex

Whitespace-only changes.

apps/components_guide_web/lib/components_guide_web/views/react_typescript_view.ex

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,22 @@ defmodule ComponentsGuideWeb.ReactTypescriptView do
77
b = -90
88
color = {:lab, l, a, b}
99

10-
gradient = Styling.linear_gradient("150grad", [
11-
{:lab, l * 1.1, a * 1.1, b * 1.4},
12-
color,
13-
{:lab, l * 1.3, a * 0.5, b * 0.5},
14-
])
10+
gradient =
11+
Styling.linear_gradient("150grad", [
12+
{:lab, l * 1.1, a * 1.1, b * 1.4},
13+
color,
14+
{:lab, l * 1.3, a * 0.5, b * 0.5}
15+
])
1516

1617
"background-color: #{color |> Styling.to_css()}; background-image: #{gradient};"
1718
end
1819

20+
def collected_image(conn, name) do
21+
%{static_path: path_to_image, width: width, height: height} = render(name)
22+
url = Routes.static_path(conn, "/" <> path_to_image)
23+
tag(:img, src: url, width: width / 2, height: height / 2)
24+
end
25+
1926
def table_rows(rows_content) do
2027
Enum.map(rows_content, &table_row/1)
2128
end

0 commit comments

Comments
 (0)