Cursor rule
.cursor/rules/cart-drawer-accessibility.mdcCart drawer component accessibility compliance pattern
Cursor rules
Quality
40/100
Scores the file, not the repository.Length
1,144 words
1 headings · 4 code blocksRepository
428
— · pushed 17 days agoLast changed
3 days ago
First indexed 3 days ago.123456# Cart Drawer Component Accessibility Standards78Ensures cart drawer components follow WCAG compliance and ARIA Dialog Pattern specifications for ecommerce applications.910<rule>11name: cart_drawer_accessibility_standards12description: Enforce cart drawer component accessibility standards and ARIA Dialog Pattern compliance13filters:14 - type: file_extension15 pattern: "\\.(vue|jsx|tsx|html|liquid|php|js|ts)$"1617actions:18 - type: enforce19 conditions:20 # Cart activator missing aria-haspopup21 - pattern: "(?i)<button[^>]*(?:cart|basket|shopping)[^>]*>"22 pattern_negate: "aria-haspopup=\"dialog\""23 message: "Cart activator buttons must include aria-haspopup='dialog' to inform users a dialog will open."2425 # Cart container missing dialog role26 - pattern: "(?i)<(div|section|aside)[^>]*(?:cart|basket|drawer)[^>]*>"27 pattern_negate: "role=\"dialog\""28 message: "Cart drawer containers must have role='dialog' attribute."2930 # Cart container missing aria-modal31 - pattern: "(?i)<[^>]*role=\"dialog\"[^>]*(?:cart|basket|drawer)[^>]*>"32 pattern_negate: "aria-modal=\"true\""33 message: "Cart drawer dialog elements must have aria-modal='true' attribute."3435 # Cart container missing proper labeling36 - pattern: "(?i)<[^>]*role=\"dialog\"[^>]*(?:cart|basket|drawer)[^>]*>"37 pattern_negate: "(aria-labelledby|aria-label)"38 message: "Cart drawer dialog elements must have either aria-labelledby or aria-label for accessibility."3940 # Empty aria-label check41 - pattern: "(?i)<[^>]*role=\"dialog\"[^>]*(?:cart|basket|drawer)[^>]*aria-label=\"\"[^>]*>"42 message: "Cart drawer aria-label should not be empty; provide a meaningful description like 'Shopping Cart'."4344 # Close button missing proper functionality45 - pattern: "(?i)<button[^>]*(?:close|dismiss|cancel)[^>]*(?:cart|basket|drawer)[^>]*>"46 pattern_negate: "(onClick|onclick|@click|v-on:click)"47 message: "Cart drawer close buttons should have proper click handlers to close the dialog."4849 # Close button missing aria-label50 - pattern: "(?i)<button[^>]*(?:close|dismiss|×|×)[^>]*(?:cart|basket|drawer)[^>]*>"51 pattern_negate: "aria-label=\"[^\"]*[Cc]lose[^\"]*\""52 message: "Cart drawer close buttons should have aria-label='Close cart' or similar descriptive text."5354 # Missing focus management indicators55 - pattern: "(?i)(?:openCart|showCart|toggleCart|openDrawer)\\s*\\("56 message: "When opening cart drawers, ensure focus management is implemented (focus should move to first focusable element inside the dialog)."5758 # Missing checkout button accessibility59 - pattern: "(?i)<button[^>]*(?:checkout|proceed|purchase)[^>]*(?:cart|basket|drawer)[^>]*>"60 pattern_negate: "(aria-label|aria-describedby)"61 message: "Cart drawer checkout buttons should have proper labeling for screen readers."6263 # Quantity inputs missing aria-live for screen reader announcements64 - pattern: "(?i)<input[^>]*type=\"number\"[^>]*(?:quantity|qty)[^>]*>"65 pattern_negate: "aria-live=\"polite\""66 message: "Cart quantity inputs must have aria-live='polite' to announce value changes to screen readers."6768 # Missing focus management for item removal69 - pattern: "(?i)(?:removeItem|remove.*item|delete.*item)\\s*\\("70 pattern_negate: "focus\\(|focus\\(\\).*close|close.*focus\\(\\"71 message: "When removing cart items, implement focus management to shift focus to a logical location (e.g., close button) for better user experience."7273 - type: suggest74 message: |75 **Cart Drawer Component Accessibility Best Practices:**7677 **Required ARIA Attributes:**78 - **aria-haspopup='dialog':** Set on cart activator buttons to inform users a dialog will open79 - **role='dialog':** Set on the cart drawer container element80 - **aria-modal='true':** Indicates the cart drawer is modal and traps focus81 - **aria-labelledby:** Reference to visible cart title, OR82 - **aria-label:** Descriptive label like "Shopping Cart" if no visible title exists8384 **Keyboard Interaction Requirements:**85 - **Initial Focus:** When cart drawer opens, focus must move to the first focusable element (typically close button)86 - **Tab Cycling:** Tab key should cycle through focusable elements within the cart drawer only87 - **Shift+Tab:** Should cycle backwards through focusable elements within the cart drawer88 - **Escape Key:** Must close the cart drawer and return focus to the activator89 - **Focus Trap:** Focus should be contained within the cart drawer while open9091 **Focus Management:**92 - Implement focus trapping to prevent tab navigation outside the cart drawer93 - Return focus to the cart activator when drawer closes94 - Move focus to the close button (first focusable element) when drawer opens95 - Ensure close button is positioned first in DOM order within the dialog container96 - **Item Removal Focus:** When removing cart items, shift focus to the close button for logical positioning97 - **Quantity Changes:** Maintain focus on quantity controls during updates to prevent focus loss9899 **Screen Reader Interaction:**100 - Activator should announce "dialog popup" when focused101 - On activation, announce "{Cart label}, dialog" when focus moves to cart drawer102 - Provide clear navigation through cart content103 - Announce return to activator when drawer closes104 - **Quantity Updates:** Use aria-live="polite" on quantity inputs to announce value changes105 - **Item Removal:** Announce item removal with descriptive text (e.g., "Product Name removed from cart")106 - **Dynamic Content:** Ensure all cart state changes are announced to screen readers107108 **Structure Requirements:**109 - All interactive elements must be descendants of the cart drawer container110 - Position close button first in DOM order within the cart drawer container111 - Use semantic HTML within the cart drawer (headings, buttons, form labels)112 - Provide clear visual focus indicators113 - Close buttons should use aria-label="Close cart" with × entity for visual 'x' icon114115 **Implementation Patterns:**116117 **Cart Activator Button:**118```html119 <button class="cart-activator"120 aria-haspopup="dialog"121 aria-label="View shopping cart"122 onclick="openCartDrawer()">123 <svg aria-hidden="true" width="24" height="24">124 <!-- Cart icon -->125 </svg>126 <span class="cart-count">3</span>127 </button>128```129130 **Cart Drawer Container:**131```html132 <div role="dialog"133 aria-modal="true"134 aria-labelledby="cart-title"135 class="cart-drawer"136 id="cart-drawer">137 <button type="button"138 aria-label="Close cart"139 onclick="closeCartDrawer()"140 class="cart-close">×</button>141 <h2 id="cart-title">Shopping Cart</h2>142 <div class="cart-items">143 <!-- Cart items -->144 </div>145 <div class="cart-summary">146 <p>Total: $99.99</p>147 <button aria-label="Proceed to checkout"148 onclick="proceedToCheckout()">149 Checkout150 </button>151 </div>152 </div>153```154155 **Quantity Controls with aria-live:**156```html157 <div class="quantity-controls">158 <button class="quantity-btn decrease-btn"159 aria-label="Decrease quantity"160 onclick="updateQuantity(itemId, -1)">-</button>161 <input type="number"162 class="quantity-input"163 value="1"164 min="1"165 aria-label="Quantity for Product Name"166 aria-live="polite"167 onchange="setQuantity(itemId, this.value)">168 <button class="quantity-btn increase-btn"169 aria-label="Increase quantity"170 onclick="updateQuantity(itemId, 1)">+</button>171 </div>172```173174 **Item Removal with Focus Management:**175```javascript176 function removeItem(itemId) {177 const item = cartItems.find(item => item.id === itemId);178 if (item) {179 cartItems = cartItems.filter(item => item.id !== itemId);180181 // Remove only the specific cart item element182 const cartItem = document.querySelector(`[data-item-id="${itemId}"]`);183 if (cartItem) {184 cartItem.remove();185 }186187 // Update cart state188 updateCartCount();189 updateCartTotal();190191 // Announce removal to screen readers192 announceToScreenReader(`${item.name} removed from cart`);193194 // Shift focus to close button for logical focus management195 const closeButton = document.querySelector('.cart-close');196 if (closeButton) {197 closeButton.focus();198 }199 }200 }201```202203 **JavaScript Considerations:**204 - Implement proper event listeners for Escape key205 - Manage body scroll when cart drawer is open206 - Handle focus restoration on cart drawer close207 - Implement focus trapping within cart drawer208 - Store reference to activator for focus return209 - Handle dynamic cart content updates210 - Ensure proper announcement of cart state changes211 - **Quantity Management:** Update only specific DOM elements instead of re-rendering entire cart212 - **Focus Management:** Shift focus to close button when removing items213 - **Performance:** Avoid unnecessary DOM manipulation to maintain accessibility features214215 **Quantity Controls and Item Management:**216 - **aria-live="polite":** Add to all quantity input fields for screen reader announcements217 - **Focus Preservation:** Maintain focus on quantity controls during updates to prevent keyboard navigation issues218 - **Value Announcements:** Screen readers should announce new quantity values when inputs change219 - **Item Removal Focus:** Shift focus to close button after removing items for logical navigation flow220 - **Dynamic Updates:** Avoid full cart re-rendering to preserve focus and improve performance221222 **Ecommerce-Specific Considerations:**223 - Announce cart item count changes224 - Provide clear product information in cart items225 - Ensure checkout button is prominently accessible226 - Handle empty cart states appropriately227 - Provide clear pricing and total information228 - Support quantity adjustments with proper labeling229 - Handle cart item removal with confirmation230231 **Accessibility Notes:**232 - Cart drawers should not contain critical page navigation233 - Ensure cart content is fully accessible to screen readers234 - Test with screen readers to ensure proper announcement235 - Consider using aria-live regions for dynamic cart updates236 - Provide clear error messages for cart operations237 - Ensure cart drawer works with keyboard-only navigation238 - Test focus management with multiple cart activators239240metadata:241 priority: high242 version: 1.0243</rule>244
Also in Shopify/horizon
Diff this repo’s formatsOne 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?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| Shopify/horizon.cursor/rules/accordion-accessibility.mdc · 428 | Cursor rules | ui | 40/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/animation-accessibility.mdc · 428 | Cursor rules | ui | 40/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/blocks.mdc · 428 | Cursor rules | stylearchtypesdatabase+2 | 62/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/breadcrumb-accessibility.mdc · 428 | Cursor rules | ui | 36/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/carousel-accessibility.mdc · 428 | Cursor rules | ui | 32/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/chat-window-accessibility.mdc · 428 | Cursor rules | styleui | 24/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/color-contrast-accessibility.mdc · 428 | Cursor rules | lint-formatui | 44/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/color-swatch-accessibility.mdc · 428 | Cursor rules | ui | 40/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/commit-messages.mdc · 428 | Cursor rules | setuplint-formattypesgit | 62/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/css-standards.mdc · 428 | Cursor rules | stylearchuiperformance+3 | 49/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/disclosure-accessibility.mdc · 428 | Cursor rules | ui | 40/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/dropdown-navigation-accessibility.mdc · 428 | Cursor rules | styleui | 36/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/flip-card-accessibility.mdc · 428 | Cursor rules | styleui | 36/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/form-accessibility.mdc · 428 | Cursor rules | ui | 32/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/javascript-standards.mdc · 428 | Cursor rules | stylearchtypesui+2 | 54/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/landmark-accessibility.mdc · 428 | Cursor rules | ui | 40/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/liquid.mdc · 428 | Cursor rules | buildstyletypesdatabase+2 | 77/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/locales.mdc · 428 | Cursor rules | arch | 49/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/localization.mdc · 428 | Cursor rules | style | 54/100 | 3 days ago | |
| Shopify/horizon.cursor/rules/mobile-accessibility-standards.mdc · 428 | Cursor rules | styleui | 36/100 | 3 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/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 Diff against .cursor/rules/mobile-accessibility-standards.mdc
