|
17 | 17 |
|
18 | 18 | <div class="text-base lg:text-lg flex items-stretch bg-gray-900">
|
19 | 19 | <nav class="w-48 lg:w-64 bg-gray-100 border-r border-gray-200">
|
| 20 | + <div class="sticky top-0"> |
20 | 21 | <h2 class="pt-4 pl-4 italic">I want to make an element:</h2>
|
21 |
| - <ul class="sticky top-0 p-2 pl-8 list-none leading-loose"> |
22 |
| - <li><%= link "Hidden", to: "#hide" %> |
| 22 | + <ul class="p-2 pl-8 list-none leading-loose"> |
| 23 | + <li><%= link "Hidden", to: "#hidden" %> |
23 | 24 | <li><%= link "Current", to: "#current" %>
|
24 | 25 | <li><%= link "Selected", to: "#selected" %>
|
25 | 26 | <li><%= link "Invalid", to: "#invalid" %>
|
26 | 27 | <li><%= link "Required", to: "#required" %>
|
27 |
| - <li><%= link "Readonly", to: "#readonly" %> |
| 28 | + <li><%= link "Disabled", to: "#disabled" %> |
28 | 29 | <li><%= link("All Queries 🔗", to: "https://testing-library.com/docs/dom-testing-library/api-queries") %>
|
29 | 30 | <li><%= link("All Matchers 🔗", to: "https://github.com/testing-library/jest-dom") %>
|
30 | 31 | </ul>
|
| 32 | + </div> |
31 | 33 | </nav>
|
32 | 34 | <div class="mx-auto flex-shrink">
|
33 | 35 | <section aria-label="Roles Cheatsheet" class="max-w-xl lg:max-w-4xl px-6 pt-8 pb-16 text-white">
|
34 | 36 | <article aria-labelledby="hidden" class="space-y-4">
|
35 | 37 | <%= h2.(line("I want to **hide** an element"), id: "hidden") %>
|
36 | 38 |
|
37 |
| - <p>To hide something first ask, to whom do I want to show the content? |
| 39 | + <p><%= line("When hide content, first ask: whom do I want to **show** the content?") %> |
38 | 40 |
|
39 | 41 | <%= list [
|
40 | 42 | "Show to **everyone**. 👂✅ 👁✅",
|
41 | 43 | "Hide from **everyone**. 👂❌ 👁❌",
|
42 |
| - "**Screen reader affordance:** show to screen reader users, hide to sighted users. 👂✅ 👁❌", |
43 |
| - "**Visual affordance:** show to sighted users, hide to screen reader users. 👂❌ 👁✅" |
| 44 | + "*Screen reader affordance:* show to screen reader users, **hide to sighted users**. 👂✅ 👁❌", |
| 45 | + "*Visual affordance:* show to sighted users, **hide from screen reader users**. 👂❌ 👁✅" |
44 | 46 | ] %>
|
45 | 47 |
|
46 | 48 | <section aria-labelledby="hidden-all-heading">
|
47 | 49 | <%= h3.("Hidden to everyone", id: "hidden-all-heading") %>
|
48 |
| - <p>To hide to everyone, add the <code>hidden</code> attribute.</p> |
| 50 | + <p>To hide from everyone, add the <code>hidden</code> attribute.</p> |
49 | 51 | <%= h4.("Test") %>
|
50 | 52 | <%=
|
51 | 53 | """
|
|
73 | 75 | <section aria-labelledby="hidden-visually-heading">
|
74 | 76 | <%#= h3.("Visually hidden (assistive technology only)", id: "hidden-visually-heading") %>
|
75 | 77 | <%= h3.("Assistive technology affordance (visually hidden)", id: "hidden-visually-heading") %>
|
76 |
| - <p>To show to assistive technology but hide visually, add the <code>visually-hidden</code> class.</p> |
| 78 | + <p>To show to people using assistive technology such as screen readers, yet hide from visual users, define and use a <code>visually-hidden</code> class.</p> |
77 | 79 | <%= h4.("Test") %>
|
78 | 80 | <%=
|
79 | 81 | """
|
|
88 | 90 | <%=
|
89 | 91 | """
|
90 | 92 | <a href="/profile">
|
91 |
| - <span class="icon-user"></span> |
| 93 | + <span class="icon-user"></span> <!-- e.g. 👤 --> |
92 | 94 | <span class="visually-hidden">Profile</span>
|
93 | 95 | </a>
|
94 | 96 | """ |> code_block(:html)
|
|
146 | 148 | </article>
|
147 | 149 |
|
148 | 150 | <article aria-labelledby="current" class="space-y-4">
|
149 |
| - <%= h2.(line("I want to make an element **current**"), id: "current") %> |
| 151 | + <%= h2.(line("I want to say this element is **current**"), id: "current") %> |
| 152 | + |
| 153 | + <section aria-labelledby="current-page-heading"> |
| 154 | + <%= h3.("Current page", id: "current-page-heading") %> |
| 155 | + <p>Imagine a navigation bar full of links. If you visit one of these links, a popular pattern is to differentiate the current page’s link visually. For example, it might be underlined.</p> |
| 156 | + <p>To hide to everyone, add the <code>hidden</code> attribute.</p> |
| 157 | + <%= h4.("Test") %> |
| 158 | + <%= |
| 159 | + """ |
| 160 | + it("is current page", () => { |
| 161 | + expect(screen.getByRole('link', { name: 'Pricing' })) |
| 162 | + .toHaveAttribute('aria-current', 'page'); |
| 163 | + }) |
| 164 | + """ |> code_block(:js) |
| 165 | + %> |
| 166 | + <%= h4.("Markup") %> |
| 167 | + <%= |
| 168 | + """ |
| 169 | + <a href="/features">Features</a> |
| 170 | + <a href="/pricing" aria-current=page>Pricing</a> |
| 171 | + <a href="/terms">Terms</a> |
| 172 | + """ |> code_block(:html) |
| 173 | + %> |
| 174 | + <%= h4.("Styling") %> |
| 175 | + <%= |
| 176 | + """ |
| 177 | + a { |
| 178 | + border-bottom: 2px solid transparent; |
| 179 | + } |
| 180 | + a[aria-current=page] { |
| 181 | + border-bottom-color: pink; |
| 182 | + } |
| 183 | + """ |> code_block(:css) |
| 184 | + %> |
| 185 | + </section> |
| 186 | + |
| 187 | + <section aria-labelledby="current-notes-heading"> |
| 188 | + <%= h3.("Notes", id: "current-notes-heading") %> |
| 189 | + <ul> |
| 190 | + <li><%= link("Marking elements as the current one using aria-current", to: "https://www.accessibility-developer-guide.com/examples/sensible-aria-usage/current/") %> |
| 191 | + </ul> |
| 192 | + </section> |
| 193 | + </article> |
150 | 194 |
|
151 |
| - <p>You can hide using a large range of techniques. What you first want to ask is, from whom do I want to hide the content? |
| 195 | + <article aria-labelledby="selected" class="space-y-4"> |
| 196 | + <%= h2.(line("I want to say this element is **selected**"), id: "selected") %> |
| 197 | + |
| 198 | + <ul> |
| 199 | + <li>Selected tab in a list |
| 200 | + </ul> |
| 201 | + </article> |
| 202 | + |
| 203 | + <article aria-labelledby="invalid" class="space-y-4"> |
| 204 | + <%= h2.(line("I want to say this element is **invalid**"), id: "invalid") %> |
| 205 | + |
| 206 | + <section aria-labelledby="invalid-email-field-heading"> |
| 207 | + <%= h3.("Invalid email field", id: "invalid-email-field-heading") %> |
| 208 | + <%= h4.("Test") %> |
| 209 | + <%= |
| 210 | + """ |
| 211 | + it("is invalid", () => { |
| 212 | + expect(screen.getByRole('textbox', { name: 'Email' })) |
| 213 | + .toBeInvalid(); |
| 214 | + }) |
| 215 | +
|
| 216 | + it("shows error message", () => { |
| 217 | + expect(screen.getByRole('textbox', { name: 'Email' })) |
| 218 | + .toHaveDescription('Email must be a valid address'); |
| 219 | + }) |
| 220 | + """ |> code_block(:js) |
| 221 | + %> |
| 222 | + <%= h4.("Markup") %> |
| 223 | + <%= |
| 224 | + """ |
| 225 | + <label for=email-field>Email</label> |
| 226 | + <input |
| 227 | + id=email-field |
| 228 | + type=email |
| 229 | + name=email |
| 230 | + aria-invalid |
| 231 | + aria-describedby=email-error |
| 232 | + > |
| 233 | + <p id=email-error>Email must be a valid address</p> |
| 234 | + """ |> code_block(:html) |
| 235 | + %> |
| 236 | + </section> |
| 237 | + </article> |
| 238 | + |
| 239 | + <article aria-labelledby="required" class="space-y-4"> |
| 240 | + <%= h2.(line("I want to say this element is **required**"), id: "required") %> |
| 241 | + |
| 242 | + <section aria-labelledby="required-email-field-heading"> |
| 243 | + <%= h3.("Required form field", id: "required-email-field-heading") %> |
| 244 | + <%= h4.("Test") %> |
| 245 | + <%= |
| 246 | + """ |
| 247 | + it("is required", () => { |
| 248 | + expect(screen.getByRole('textbox', { name: 'Email' })) |
| 249 | + .toBeRequired(); |
| 250 | + }) |
| 251 | + """ |> code_block(:js) |
| 252 | + %> |
| 253 | + <%= h4.("Markup") %> |
| 254 | + <%= |
| 255 | + """ |
| 256 | + <label> |
| 257 | + Email |
| 258 | + <input type=email name=email required> |
| 259 | + </label> |
| 260 | + """ |> code_block(:html) |
| 261 | + %> |
| 262 | + </section> |
| 263 | + </article> |
| 264 | + |
| 265 | + <article aria-labelledby="disabled" class="space-y-4"> |
| 266 | + <%= h2.(line("I want to **disable** an element"), id: "disabled") %> |
| 267 | + |
| 268 | + <section aria-labelledby="readonly-email-field-heading"> |
| 269 | + <%= h3.("Read-only form field", id: "readonly-email-field-heading") %> |
| 270 | + <%= h4.("Test") %> |
| 271 | + <%= |
| 272 | + """ |
| 273 | + it("is disabled", () => { |
| 274 | + expect(screen.getByRole('textbox', { name: 'Email' })) |
| 275 | + .toBeDisabled(); |
| 276 | + }) |
| 277 | + """ |> code_block(:js) |
| 278 | + %> |
| 279 | + <%= h4.("Markup") %> |
| 280 | + <%= |
| 281 | + """ |
| 282 | + <label> |
| 283 | + Email |
| 284 | + <input type=email name=email disabled> |
| 285 | + </label> |
| 286 | + """ |> code_block(:html) |
| 287 | + %> |
| 288 | + </section> |
152 | 289 | </article>
|
153 | 290 |
|
154 | 291 | </section>
|
|
0 commit comments