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/color-swatch-accessibility.mdc

Color swatch component accessibility compliance pattern

Cursor rules

Quality

40/100

Scores the file, not the repository.

Length

647 words

1 headings · 2 code blocks

Repository

428

— · pushed 17 days ago

Last changed

3 days ago

First indexed 3 days ago.
Shopify/horizon/.cursor/rules/color-swatch-accessibility.mdcRawGitHub
1---
2description: Color swatch component accessibility compliance pattern
3globs: *.vue, *.jsx, *.tsx, *.html, *.php, *.js, *.ts, *.liquid
4alwaysApply: false
5---
6# Color Swatch Variant Selector Component Accessibility Standards
7 
8Ensures color swatch variant selectors follow WCAG compliance and provide proper accessibility for all users.
9 
10<rule>
11name: color_swatch_accessibility_standards
12description: Enforce color swatch variant selector accessibility standards and WCAG compliance
13filters:
14 - type: file_extension
15 pattern: "\\.(vue|jsx|tsx|html|liquid|php|js|ts|css|scss|sass|less)$"
16 
17actions:
18 - type: enforce
19 conditions:
20 # Radio buttons hidden with display: none (accessibility blocker)
21 - pattern: "(?i)input\\[type=\"radio\"\\].*\\{[^}]*display:\\s*none"
22 message: "Radio buttons must not use display: none as it removes keyboard and screen reader access. Use appearance: none or visually-hidden class instead."
23 
24 # Color swatches missing accessible labels
25 - pattern: "(?i)<input[^>]*type=\"radio\"[^>]*>"
26 pattern_negate: "(id.*for|label.*for)"
27 message: "Color swatch radio buttons must have associated label elements via id/for attributes."
28 
29 # Color-only information without text alternatives
30 - pattern: "(?i)<[^>]*(?:color|swatch|variant)[^>]*>"
31 pattern_negate: "(data-label|aria-label|title|data-tooltip|class.*tooltip)"
32 message: "Color swatches must include text alternatives (data-label, tooltips, labels) as color alone cannot convey information to all users."
33 
34 # Missing fieldset and legend for variant groups
35 - pattern: "(?i)<input[^>]*type=\"radio\"[^>]*name=\"[^\"]*\"[^>]*>"
36 pattern_negate: "(fieldset|role=\"group\"|aria-labelledby)"
37 message: "Radio button groups should be wrapped in fieldset with legend or have role='group' with aria-labelledby."
38 
39 # Missing keyboard navigation support
40 - pattern: "(?i)<[^>]*(?:color|swatch|variant)[^>]*>"
41 pattern_negate: "(onKeyDown|onkeydown|@keydown|v-on:keydown|tabindex)"
42 message: "Color swatch components should handle keyboard navigation (arrow keys) for variant selection."
43 
44 # Missing focus indicators
45 - pattern: "(?i)<[^>]*(?:color|swatch|variant)[^>]*>"
46 pattern_negate: "(focus|:focus|outline|box-shadow)"
47 message: "Color swatch components must have visible focus indicators for keyboard navigation."
48 
49 # Tooltip missing proper accessibility
50 - pattern: "(?i)<[^>]*(?:tooltip|title)[^>]*>"
51 pattern_negate: "(role=\"tooltip\"|aria-describedby|aria-label)"
52 message: "Color swatch tooltips must have proper ARIA attributes for screen reader accessibility."
53 
54 - type: suggest
55 message: |
56 **Color Swatch Variant Selector Accessibility Best Practices:**
57 
58 **Required Accessibility Features:**
59 - **Keyboard Navigation:** Arrow keys (←/→) to navigate between variants
60 - **Screen Reader Support:** Proper labeling and announcements
61 - **Focus Indicators:** Highly visible focus states
62 - **Text Alternatives:** Tooltips or labels for color information
63 - **Proper Styling:** Use appearance: none instead of display: none
64 - **Label Focus:** Labels automatically receive focus when their associated input is focused (no tabindex needed)
65 - **Input Focus:** Radio inputs are naturally focusable and part of tab order (no tabindex needed)
66 
67 **Implementation Patterns:**
68 
69 **Basic Color Swatch Structure:**
70```html
71 <fieldset class="color-swatches">
72 <legend>Color</legend>
73 <div class="swatch-group" role="radiogroup" aria-labelledby="color-legend">
74 <input type="radio"
75 id="color-red"
76 name="color"
77 value="red"
78 class="visually-hidden">
79 <label for="color-red"
80 class="color-swatch"
81 data-label="Red - Classic crimson shade">
82 <span class="swatch-color" style="background-color: red;"></span>
83 </label>
84 
85 <input type="radio"
86 id="color-blue"
87 name="color"
88 value="blue"
89 class="visually-hidden">
90 <label for="color-blue"
91 class="color-swatch"
92 data-label="Blue - Navy blue shade">
93 <span class="swatch-color" style="background-color: blue;"></span>
94 </label>
95 </div>
96 </fieldset>
97```
98 
99 **CSS for Accessible Styling:**
100```css
101 /* Visually hide radio buttons while keeping them accessible */
102 .visually-hidden {
103 position: absolute;
104 width: 1px;
105 height: 1px;
106 padding: 0;
107 margin: -1px;
108 overflow: hidden;
109 clip: rect(0, 0, 0, 0);
110 white-space: nowrap;
111 border: 0;
112 }
113 
114 /* Focus Management: Labels automatically receive focus when their input is focused */
115 /* No tabindex needed on labels - they are naturally focusable through their input association */
116 /* No tabindex needed on inputs - radio inputs are naturally focusable and part of tab order */
117 
118 /* Alternative: Use appearance: none for custom styling */
119 input[type="radio"] {
120 appearance: none;
121 -webkit-appearance: none;
122 -moz-appearance: none;
123 /* Custom styling here */
124 }
125 
126 /* Color swatch styling */
127 .color-swatch {
128 display: inline-block;
129 width: 40px;
130 height: 40px;
131 border: 2px solid transparent;
132 border-radius: 50%;
133 cursor: pointer;
134 position: relative;
135 transition: border-color 0.2s ease;
136 }
137 
138 .color-swatch:focus {
139 outline: 3px solid #0056b3;
140 outline-offset: 2px;
141 border-color: #0056b3;
142 }
143 
144 /* Show focus styles on label when input is focused */
145 .color-swatch:has(+ input:focus) {
146 outline: 3px solid #0056b3;
147 outline-offset: 2px;
148 border-color: #0056b3;
149 }
150 
151 /* Alternative: Use :focus-within for broader browser support */
152 .color-swatch:focus-within {
153 outline: 3px solid #0056b3;
154 outline-offset: 2px;
155 border-color: #0056b3;
156 }
157 
158 .color-swatch:has(+ input:checked) {
159 border-color: #212529;
160 box-shadow: 0 0 0 2px #fff, 0 0 0 4px #212529;
161 }
162 
163 .swatch-color {
164 width: 100%;
165 height: 100%;
166 border-radius: 50%;
167 display: block;
168 }
169 
170 /* Tooltip styling */
171 .color-swatch::after {
172 content: attr(data-label);
173 position: absolute;
174 bottom: 100%;
175 left: 50%;
176 transform: translateX(-50%);
177 background: #212529;
178 color: white;
179 padding: 4px 8px;
180 border-radius: 4px;
181 font-size: 0.75rem;
182 white-space: nowrap;
183 opacity: 0;
184 pointer-events: none;
185 transition: opacity 0.2s ease;
186 z-index: 1000;
187 }
188 
189 .color-swatch:hover::after,
190 .color-swatch:focus::after,
191 .color-swatch:has(+ input:focus)::after {
192 opacity: 1;
193 }
194```
195 

Sections

  • Color Swatch Variant Selector Component 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/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
Shopify/horizon.cursor/rules/mobile-accessibility-standards.mdc · 428Cursor rulesunclassifiedstyleui36/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/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 Diff against .cursor/rules/mobile-accessibility-standards.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