RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Configs/Cursor rules/Shopify/horizon

Cursor rule

.cursor/rules/modal-accessibility.mdc

Modal window accessibility compliance and ARIA Dialog Pattern

Cursor rules

Quality

40/100

Scores the file, not the repository.

Length

500 words

1 headings · 1 code blocks

Repository

428

— · pushed 17 days ago

Last changed

3 days ago

First indexed 3 days ago.
Shopify/horizon/.cursor/rules/modal-accessibility.mdcRawGitHub
1---
2description: Modal window accessibility compliance and ARIA Dialog Pattern
3globs: *.vue, *.jsx, *.tsx, *.html, *.php, *.js, *.ts, *.liquid
4alwaysApply: false
5---
6# Modal Window Accessibility Standards
7 
8Ensures modal windows follow WCAG compliance and ARIA Dialog Pattern specifications.
9 
10<rule>
11name: modal_accessibility_standards
12description: Enforce modal window accessibility standards and ARIA Dialog Pattern compliance
13filters:
14 - type: file_extension
15 pattern: "\\.(vue|jsx|tsx|html|liquid|php|js|ts)$"
16 
17actions:
18 - type: enforce
19 conditions:
20 # Dialog role requirement
21 - pattern: "(?i)<(div|section|article)[^>]*(?:modal|dialog)[^>]*>"
22 pattern_negate: "role=\"dialog\""
23 message: "Modal containers must have role='dialog' attribute."
24 
25 # aria-modal requirement
26 - pattern: "(?i)<[^>]*role=\"dialog\"[^>]*>"
27 pattern_negate: "aria-modal=\"true\""
28 message: "Dialog elements must have aria-modal='true' attribute."
29 
30 # aria-labelledby or aria-label requirement
31 - pattern: "(?i)<[^>]*role=\"dialog\"[^>]*>"
32 pattern_negate: "(aria-labelledby|aria-label)"
33 message: "Dialog elements must have either aria-labelledby or aria-label for accessibility."
34 
35 # Empty aria-label check
36 - pattern: "(?i)<[^>]*role=\"dialog\"[^>]*aria-label=\"\"[^>]*>"
37 message: "Dialog aria-label should not be empty; provide a meaningful description."
38 
39 # Button without proper close functionality
40 - pattern: "(?i)<button[^>]*(?:close|dismiss|cancel)[^>]*>"
41 pattern_negate: "(onClick|onclick|@click|v-on:click)"
42 message: "Modal close buttons should have proper click handlers to close the dialog."
43 
44 # Close button should have aria-label
45 - pattern: "(?i)<button[^>]*(?:close|dismiss|×|&times;)[^>]*>"
46 pattern_negate: "aria-label=\"[^\"]*[Cc]lose[^\"]*\""
47 message: "Modal close buttons should have aria-label='Close' or similar descriptive text for screen readers."
48 
49 # Missing focus trap indicators
50 - pattern: "(?i)(?:showModal|openModal|displayModal)\\s*\\("
51 message: "When opening modals, ensure focus management is implemented (focus should move to an element inside the dialog)."
52 
53 # Modal launcher should have aria-haspopup
54 - pattern: "(?i)<button[^>]*(?:open|show|launch)[^>]*(?:modal|dialog)[^>]*>"
55 pattern_negate: "aria-haspopup=\"dialog\""
56 message: "Buttons that open modals should include aria-haspopup='dialog' to inform users a dialog will open."
57 
58 - type: suggest
59 message: |
60 **Modal Window Accessibility Best Practices:**
61 
62 **Required ARIA Attributes:**
63 - **role='dialog':** Set on the modal container element
64 - **aria-modal='true':** Indicates the dialog is modal
65 - **aria-labelledby:** Reference to visible dialog title, OR
66 - **aria-label:** Descriptive label if no visible title exists
67 - **aria-haspopup='dialog':** Set on buttons/elements that trigger the modal to inform users a dialog will open
68 
69 **Keyboard Interaction Requirements:**
70 - **Initial Focus:** When dialog opens, focus must move to an element inside the dialog
71 - **Tab Cycling:** Tab key should cycle through tabbable elements within the dialog only
72 - **Shift+Tab:** Should cycle backwards through tabbable elements within the dialog
73 - **Escape Key:** Must close the dialog
74 - **Focus Trap:** Focus should be contained within the modal while open
75 
76 **Focus Management:**
77 - Implement focus trapping to prevent tab navigation outside the modal
78 - Return focus to the triggering element when modal closes
79 - Move focus to the close button (first focusable element) when modal opens
80 - Ensure close button is positioned first in DOM order within the dialog
81 
82 **Structure Requirements:**
83 - All interactive elements must be descendants of the dialog container
84 - Position close button first in DOM order within the dialog container
85 - Use semantic HTML within the modal (headings, buttons, form labels)
86 - Provide clear visual focus indicators
87 - Close buttons should use aria-label="Close" with &times; entity for visual 'x' icon
88 
89 **Example Implementation:**
90```html
91 <!-- Modal launcher -->
92 <button aria-haspopup="dialog" onclick="openModal()">Open Settings</button>
93 
94 <!-- Modal dialog -->
95 <div role="dialog" aria-modal="true" aria-labelledby="modal-title">
96 <button type="button" aria-label="Close" onclick="closeModal()">&times;</button>
97 <h2 id="modal-title">Modal Title</h2>
98 <p>Modal content...</p>
99 </div>
100```
101 
102 **JavaScript Considerations:**
103 - Implement proper event listeners for Escape key
104 - Manage body scroll when modal is open
105 - Handle focus restoration on modal close
106 
107metadata:
108 priority: high
109 version: 1.0
110</rule>
111 

Sections

  • Modal Window Accessibility Standards

What it covers

ui

Glob targeting

  • *.vue
  • *.jsx
  • *.tsx
  • *.html
  • *.php
  • *.js
  • *.ts
  • *.liquid

Format

Cursor rules

The most expressive format here. Many small .mdc files, each with frontmatter declaring when it should load, so a rule about migrations only enters context when a migration is open. Costs the most to maintain and only one editor reads it.

What the corpus says about it

Repository

Owner
Shopify
Language
—
License
—
Archived
no

All configs in this repo

Also in Shopify/horizon

Diff this repo’s formats

One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?

The other instruction files in this repository
RepositoryFormatStackCoversScoreChanged
Shopify/horizon.cursor/rules/accordion-accessibility.mdc · 428Cursor rulesunclassifiedui40/1003 days ago
Shopify/horizon.cursor/rules/animation-accessibility.mdc · 428Cursor rulesunclassifiedui40/1003 days ago
Shopify/horizon.cursor/rules/blocks.mdc · 428Cursor rulesunclassifiedstylearchtypesdatabase+262/1003 days ago
Shopify/horizon.cursor/rules/breadcrumb-accessibility.mdc · 428Cursor rulesunclassifiedui36/1003 days ago
Shopify/horizon.cursor/rules/carousel-accessibility.mdc · 428Cursor rulesunclassifiedui32/1003 days ago
Shopify/horizon.cursor/rules/cart-drawer-accessibility.mdc · 428Cursor rulesunclassifiedui40/1003 days ago
Shopify/horizon.cursor/rules/chat-window-accessibility.mdc · 428Cursor rulesunclassifiedstyleui24/1003 days ago
Shopify/horizon.cursor/rules/color-contrast-accessibility.mdc · 428Cursor rulesunclassifiedlint-formatui44/1003 days ago
Shopify/horizon.cursor/rules/color-swatch-accessibility.mdc · 428Cursor rulesunclassifiedui40/1003 days ago
Shopify/horizon.cursor/rules/commit-messages.mdc · 428Cursor rulesunclassifiedsetuplint-formattypesgit62/1003 days ago
Shopify/horizon.cursor/rules/css-standards.mdc · 428Cursor rulesunclassifiedstylearchuiperformance+349/1003 days ago
Shopify/horizon.cursor/rules/disclosure-accessibility.mdc · 428Cursor rulesunclassifiedui40/1003 days ago
Shopify/horizon.cursor/rules/dropdown-navigation-accessibility.mdc · 428Cursor rulesunclassifiedstyleui36/1003 days ago
Shopify/horizon.cursor/rules/flip-card-accessibility.mdc · 428Cursor rulesunclassifiedstyleui36/1003 days ago
Shopify/horizon.cursor/rules/form-accessibility.mdc · 428Cursor rulesunclassifiedui32/1003 days ago
Shopify/horizon.cursor/rules/javascript-standards.mdc · 428Cursor rulesunclassifiedstylearchtypesui+254/1003 days ago
Shopify/horizon.cursor/rules/landmark-accessibility.mdc · 428Cursor rulesunclassifiedui40/1003 days ago
Shopify/horizon.cursor/rules/liquid.mdc · 428Cursor rulesunclassifiedbuildstyletypesdatabase+277/1003 days ago
Shopify/horizon.cursor/rules/locales.mdc · 428Cursor rulesunclassifiedarch49/1003 days ago
Shopify/horizon.cursor/rules/localization.mdc · 428Cursor rulesunclassifiedstyle54/1003 days ago
Diff against .cursor/rules/accordion-accessibility.mdc Diff against .cursor/rules/animation-accessibility.mdc Diff against .cursor/rules/blocks.mdc Diff against .cursor/rules/breadcrumb-accessibility.mdc Diff against .cursor/rules/carousel-accessibility.mdc Diff against .cursor/rules/cart-drawer-accessibility.mdc Diff against .cursor/rules/chat-window-accessibility.mdc Diff against .cursor/rules/color-contrast-accessibility.mdc Diff against .cursor/rules/color-swatch-accessibility.mdc Diff against .cursor/rules/commit-messages.mdc Diff against .cursor/rules/css-standards.mdc Diff against .cursor/rules/disclosure-accessibility.mdc Diff against .cursor/rules/dropdown-navigation-accessibility.mdc Diff against .cursor/rules/flip-card-accessibility.mdc Diff against .cursor/rules/form-accessibility.mdc Diff against .cursor/rules/javascript-standards.mdc Diff against .cursor/rules/landmark-accessibility.mdc Diff against .cursor/rules/liquid.mdc Diff against .cursor/rules/locales.mdc Diff against .cursor/rules/localization.mdc
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack