Skip to content

Commit 55c4d29

Browse files
committed
Add accessibility first testing page
1 parent 7893e8c commit 55c4d29

File tree

12 files changed

+388
-2
lines changed

12 files changed

+388
-2
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"workbench.colorCustomizations": {
33
"activityBar.background": "#ca82d2",
4+
"activityBar.activeBackground": "#ca82d2",
45
"activityBar.activeBorder": "#e6e1b9",
56
"activityBar.foreground": "#15202b",
67
"activityBar.inactiveForeground": "#15202b99",

apps/components_guide_web/lib/components_guide_web.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ defmodule ComponentsGuideWeb do
4343
import ComponentsGuideWeb.Gettext
4444
alias ComponentsGuideWeb.Router.Helpers, as: Routes
4545
import Phoenix.LiveView, only: [live_render: 2, live_render: 3]
46+
alias ComponentsGuideWeb.StylingHelpers, as: Styling
4647
end
4748
end
4849

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
defmodule ComponentsGuideWeb.AccessibilityFirstTestingController do
2+
use ComponentsGuideWeb, :controller
3+
4+
def index(conn, _params) do
5+
render(conn, "index.html")
6+
end
7+
end

apps/components_guide_web/lib/components_guide_web/router.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ defmodule ComponentsGuideWeb.Router do
2121

2222
get "/links", LinksController, :index
2323

24+
get "/accessibility-first-testing", AccessibilityFirstTestingController, :index
2425
get "/swiftui", SwiftUIController, :index
2526
get "/react+typescript", ReactTypescriptController, :index
2627

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<%
2+
topics = [
3+
"Landmarks",
4+
"Roles",
5+
"Widgets",
6+
"States",
7+
"Forms",
8+
"Tables",
9+
"ARIA",
10+
"Keyboard Navigation",
11+
"TDD",
12+
"BDD",
13+
"Integration Testing",
14+
"Jest",
15+
"Atomic Design",
16+
]
17+
%>
18+
19+
<header class="text-white" style="background: <%= header_background %>;">
20+
<section class="container px-6 pt-12 pb-12">
21+
<h1 class="mx-auto max-w-4xl text-5xl text-center font-bold leading-tight text-shadow">
22+
<%= "🥇 Accessibility-First Testing" %>
23+
</h1>
24+
<p class="my-8 mx-auto max-w-3xl text-4xl text-center leading-snug italic text-yellow-100 text-shadow">
25+
<%#= "Write simpler, more robust tests using accessibility affordances." %>
26+
<%= "Write simpler, more robust tests via user-friendly accessibility affordances." %>
27+
</p>
28+
<p class="py-2 text-xl text-center">
29+
Topics include:
30+
<%= for topic <- topics do %>
31+
<a href="#" class="inline-block mx-1 mb-3 px-4 py-2 font-bold bg-white text-blue-600 hover:bg-blue-500 hover:text-white rounded shadow-xl"><%= topic %></a>
32+
<% end %>
33+
</p>
34+
</section>
35+
</header>
36+
37+
<div class="bg-white">
38+
<%= section "Topics", class: "container pt-8 pb-16 text-2xl" do %>
39+
<%= topic_article(title: "Landmarks and roles") do %>
40+
<p>Define what your elements are using a clear standard. Let your users quickly jump around the key parts of your page (better UX), and leverage those in your tests (better DX).</p>
41+
<% end %>
42+
<%= topic_article(title: "Widgets, Attributes & States") do %>
43+
<p>Learn the standards for interactive widgets usable by touch, mouse, and keyboard. Let users know which page is current or which sub-control is selected.</p>
44+
<% end %>
45+
<%= topic_article(title: "BDD with Jest & React Testing Library") do %>
46+
<p>Learn a consistent pattern to write your component tests in Jest. Use @testing-library to find elements in a realistic way. Describe your contexts and scenarios with plain language.</p>
47+
<% end %>
48+
<%= topic_article(title: "Atomic Design") do %>
49+
<p>Organize your components into distict folders. Break them up at the right level, then compose them. Test them differently. Incorporate ARIA roles into the atomic design approach.</p>
50+
<% end %>
51+
<% end %>
52+
</div>

apps/components_guide_web/lib/components_guide_web/templates/layout/_header.html.eex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
</a>
66
<nav role="navigation" class="flex-grow sm:pl-8 lg:px-16 text-base md:text-base">
77
<ul class="flex flex-col md:flex-row justify-around pt-2 pb-2">
8+
<li><a href="/accessibility-first-testing" class="block px-4 py-2 md:py-3 font-bold border-b-4 border-transparent hover:bg-gray-800 hover:border-red-400"><%= "A11Y-First Testing" %></a></li>
89
<li><a href="/react+typescript" class="block px-4 py-2 md:py-3 font-bold border-b-4 border-transparent hover:bg-gray-800 hover:border-red-400"><%= "React + TypeScript" %></a></li>
910
<li><a href="/swiftui" class="block px-4 py-2 md:py-3 font-bold border-b-4 border-transparent hover:bg-gray-800 hover:border-red-400"><%= "SwiftUI + Combine" %></a></li>
10-
<li><a href="/links" class="block px-4 py-2 md:py-3 font-bold border-b-4 border-transparent hover:bg-gray-800 hover:border-red-400"><%= "Community Resources" %></a></li>
11+
<li><a href="/links" class="block px-4 py-2 md:py-3 font-bold border-b-4 border-transparent hover:bg-gray-800 hover:border-red-400"><%= "Other Resources" %></a></li>
1112
<% if false do %>
1213
<li class="py-1">
1314
<a href="/signin/github" class="inline-block md:block px-4 py-2 md:py-2 font-bold text-white bg-red-700 rounded" style="background: linear-gradient(0deg, #E0003C 0%, #FF493F 50%, #FF584A 100%);">
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
defmodule ComponentsGuideWeb.AccessibilityFirstTestingView do
2+
use ComponentsGuideWeb, :view
3+
require EEx
4+
use ComponentsGuideWeb.Snippets
5+
6+
def header_background do
7+
Styling.linear_gradient("150grad", [
8+
{:lab, 70, 40, -50},
9+
{:lab, 60, -30, -50},
10+
{:lab, 50, 0, -80}
11+
])
12+
end
13+
14+
# def_E :topic_article, quote(do: ~E"""
15+
# <article class="mb-8">
16+
# <h2 class="mb-2 text-4xl leading-normal text-teal-800"><%= @title %></h2>
17+
# <%= block[:do] %>
18+
# </article>
19+
# """)
20+
21+
# EEx.function_from_string(
22+
# :def,
23+
# :topic_article,
24+
# """
25+
# <article class="mb-8">
26+
# <h2 class="mb-2 text-4xl leading-normal text-teal-800"><%= @title %></h2>
27+
# <%= block[:do] %>
28+
# </article>
29+
# """,
30+
# [:assigns, :block],
31+
# engine: Phoenix.HTML.Engine
32+
# )
33+
34+
def topic_article(assigns, block) do
35+
~E"""
36+
<article class="mb-8">
37+
<h2 class="mb-2 text-4xl leading-normal text-teal-800"><%= @title %></h2>
38+
<%= block[:do] %>
39+
</article>
40+
"""
41+
end
42+
43+
# def topic_article(title, content_html) do
44+
# <article class="mb-8">
45+
# <h2 class="mb-2 text-4xl leading-normal text-teal-800">Atomic design</h2>
46+
# <p>
47+
# Learn how to name components. Apply the single responsibility principle. Find the indivisible component units, and compose them together into larger molecules.
48+
# </p>
49+
# </article>
50+
# end
51+
end
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
defmodule ComponentsGuideWeb.Snippets do
2+
require EEx
3+
use Phoenix.HTML
4+
5+
defmacro __using__(_opts) do
6+
quote do
7+
def section(label, attrs, block) do
8+
content_tag(:section, [aria_label: label] ++ attrs, block)
9+
end
10+
end
11+
end
12+
13+
defmacro defhello do
14+
quote do
15+
def yep, do: 5
16+
end
17+
end
18+
19+
defmacro def_E(call1, source) do
20+
# call2 = Macro.escape(call1, unquote: nil)
21+
# call2 = Macro.escape(call1, unquote: true)
22+
# call2 = Macro.escape(call1)
23+
# call2 = :topic_article
24+
# args = Macro.generate_arguments(2, nil)
25+
26+
# source2 = Macro.escape(source)
27+
28+
quote bind_quoted: binding() do
29+
info = Keyword.merge([file: __ENV__.file, line: __ENV__.line], engine: Phoenix.HTML.Engine)
30+
args = [{:assigns, [line: info[:line]], nil}, {:block, [line: info[:line]], nil}]
31+
# compiled = EEx.compile_string(source, info)
32+
compiled =
33+
quote do
34+
compiled = unquote(source)
35+
end
36+
37+
# def topic_article(assigns, block), do: 4
38+
# def topic_article(assigns, block), do: 4
39+
40+
# def unquote(call1)(assigns, block), do: unquote(compiled)
41+
42+
def unquote(call1)(unquote_splicing(args)), do: unquote(source)
43+
44+
# def unquote(call2)(assigns, block) do
45+
# unquote(compiled)
46+
# end
47+
48+
# def({
49+
# quote do
50+
# call
51+
# end,
52+
# Macro.generate_arguments(2, __MODULE__)
53+
# },
54+
# do: 4
55+
# )
56+
57+
# unquote(
58+
# quote do
59+
# def unquote(call)(assigns, block), do: quote(compiled)
60+
# end
61+
# )
62+
end
63+
end
64+
end
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
defmodule ComponentsGuideWeb.StylingHelpers do
2+
@moduledoc """
3+
Conveniences for creating gradient backgrounds
4+
"""
5+
6+
# Source: https://github.com/Evercoder/culori
7+
8+
defp convert_component({:linear_srgb, c}, :srgb) do
9+
if c > 0.0031308 do
10+
1.055 * :math.pow(c, 1.0 / 2.4) - 0.055
11+
else
12+
12.92 * c
13+
end
14+
end
15+
16+
def convert({:linear_srgb, r, g, b}, :srgb) do
17+
{
18+
:srgb,
19+
convert_component({:linear_srgb, r}, :srgb),
20+
convert_component({:linear_srgb, g}, :srgb),
21+
convert_component({:linear_srgb, b}, :srgb)
22+
}
23+
end
24+
25+
def convert({:xyz, x, y, z}, :srgb) do
26+
{
27+
:linear_srgb,
28+
x * 3.1338561 - y * 1.6168667 - 0.4906146 * z,
29+
x * -0.9787684 + y * 1.9161415 + 0.0334540 * z,
30+
x * 0.0719453 - y * 0.2289914 + 1.4052427 * z
31+
}
32+
|> convert(:srgb)
33+
end
34+
35+
@xn 0.96422
36+
@yn 1.00000
37+
@zn 0.82521
38+
39+
@k :math.pow(29, 3) / :math.pow(3, 3)
40+
@e :math.pow(6, 3) / :math.pow(29, 3)
41+
42+
def convert({:lab, l, a, b}, :xyz) do
43+
fy = (l + 16) / 116
44+
fx = a / 500 + fy
45+
fz = fy - b / 200
46+
47+
converter = fn v ->
48+
cubed = :math.pow(v, 3)
49+
50+
if cubed > @e do
51+
cubed
52+
else
53+
(116 * v - 16) / @k
54+
end
55+
end
56+
57+
{
58+
:xyz,
59+
converter.(fx) * @xn,
60+
converter.(fy) * @yn,
61+
converter.(fz) * @zn
62+
}
63+
end
64+
65+
def convert({:lab, _l, _a, _b} = input, :srgb) do
66+
convert(input, :xyz) |> convert(:srgb)
67+
end
68+
69+
def to_css({:srgb, r, g, b}) do
70+
"rgba(#{(r * 255) |> round},#{(g * 255) |> round},#{(b * 255) |> round},1)"
71+
end
72+
73+
def to_css(color_tuple) when is_tuple(color_tuple) and elem(color_tuple, 0) in [:lab] do
74+
color_tuple |> convert(:srgb) |> to_css()
75+
end
76+
77+
def linear_gradient(angle, colors) when is_list(colors) do
78+
linear_gradient(angle, :array.from_list(colors))
79+
end
80+
81+
def linear_gradient(angle, colors_array) do
82+
true = :array.is_array(colors_array)
83+
84+
max = :array.size(colors_array) - 1
85+
86+
colors_css =
87+
:array.foldr(
88+
fn index, color, list ->
89+
percentage = "#{index / max * 100}%"
90+
["#{color |> to_css} #{percentage}" | list]
91+
end,
92+
[],
93+
colors_array
94+
)
95+
|> Enum.join(",")
96+
97+
"linear-gradient(#{angle}, #{colors_css})"
98+
end
99+
end

apps/components_guide_web/mix.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ defmodule ComponentsGuideWeb.MixProject do
4646
{:gettext, "~> 0.11"},
4747
{:components_guide, in_umbrella: true},
4848
{:jason, "~> 1.0"},
49-
{:plug_cowboy, "~> 2.0"}
49+
{:plug_cowboy, "~> 2.0"},
50+
{:benchee, "~> 1.0", only: :dev}
5051
]
5152
end
5253

0 commit comments

Comments
 (0)