[{"data":1,"prerenderedAt":2975},["ShallowReactive",2],{"site-header-nav":3,"page-\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Fbuilding-accessible-dropdowns-without-external-ui-kits\u002F":156,"content-navigation":2901},[4,66,70],{"title":5,"path":6,"stem":7,"children":8},"Core Accessibility Principles For Modern Frameworks","\u002Fcore-accessibility-principles-for-modern-frameworks","core-accessibility-principles-for-modern-frameworks",[9,12,18,24,36,48,60],{"title":10,"path":6,"stem":11},"Core Accessibility Principles for Modern Frameworks","core-accessibility-principles-for-modern-frameworks\u002Findex",{"title":13,"path":14,"stem":15,"children":16},"Accessible Color Contrast & Theming","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Faccessible-color-contrast-theming","core-accessibility-principles-for-modern-frameworks\u002Faccessible-color-contrast-theming\u002Findex",[17],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":22},"Accessible Form Validation & Error States in Modern Frameworks","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Faccessible-form-validation-error-states","core-accessibility-principles-for-modern-frameworks\u002Faccessible-form-validation-error-states\u002Findex",[23],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":28},"Focus Management Strategies for SPAs","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas","core-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002Findex",[29,30],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":34},"Handling Focus Restoration After Dynamic Route Changes","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002Fhandling-focus-restoration-after-dynamic-route-changes","core-accessibility-principles-for-modern-frameworks\u002Ffocus-management-strategies-for-spas\u002Fhandling-focus-restoration-after-dynamic-route-changes\u002Findex",[35],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":40},"Keyboard Navigation Patterns for Modals","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals","core-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Findex",[41,42],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":46},"Building Accessible Dropdowns Without External UI Kits","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Fbuilding-accessible-dropdowns-without-external-ui-kits","core-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Fbuilding-accessible-dropdowns-without-external-ui-kits\u002Findex",[47],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":52},"Screen Reader Compatibility Testing for Modern Frameworks","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing","core-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing\u002Findex",[53,54],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":58},"Testing ARIA Live Regions with Jest and Testing Library","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing\u002Ftesting-aria-live-regions-with-jest-and-testing-library","core-accessibility-principles-for-modern-frameworks\u002Fscreen-reader-compatibility-testing\u002Ftesting-aria-live-regions-with-jest-and-testing-library\u002Findex",[59],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":64},"Semantic HTML vs ARIA in Component Trees","\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fsemantic-html-vs-aria-in-component-trees","core-accessibility-principles-for-modern-frameworks\u002Fsemantic-html-vs-aria-in-component-trees\u002Findex",[65],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69},"Modern Framework Accessibility","\u002F","index",{"title":71,"path":72,"stem":73,"children":74},"React Nextjs Accessibility Patterns","\u002Freact-nextjs-accessibility-patterns","react-nextjs-accessibility-patterns",[75,78,90,102,108,126,144],{"title":76,"path":72,"stem":77},"React & Next.js Accessibility Patterns","react-nextjs-accessibility-patterns\u002Findex",{"title":79,"path":80,"stem":81,"children":82},"Accessible Component Libraries in React","\u002Freact-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react","react-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react\u002Findex",[83,84],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87,"children":88},"Building Accessible Tabs in React Without Radix UI","\u002Freact-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react\u002Fbuilding-accessible-tabs-in-react-without-radix-ui","react-nextjs-accessibility-patterns\u002Faccessible-component-libraries-in-react\u002Fbuilding-accessible-tabs-in-react-without-radix-ui\u002Findex",[89],{"title":85,"path":86,"stem":87},{"title":91,"path":92,"stem":93,"children":94},"Dynamic Content & State Announcements in React & Next.js","\u002Freact-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements","react-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements\u002Findex",[95,96],{"title":91,"path":92,"stem":93},{"title":97,"path":98,"stem":99,"children":100},"Implementing React Context for Global Accessibility Preferences","\u002Freact-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements\u002Freact-context-for-global-accessibility-preferences","react-nextjs-accessibility-patterns\u002Fdynamic-content-state-announcements\u002Freact-context-for-global-accessibility-preferences\u002Findex",[101],{"title":97,"path":98,"stem":99},{"title":103,"path":104,"stem":105,"children":106},"Form Handling with React Hook Form & Accessibility","\u002Freact-nextjs-accessibility-patterns\u002Fform-handling-with-react-hook-form-a11y","react-nextjs-accessibility-patterns\u002Fform-handling-with-react-hook-form-a11y\u002Findex",[107],{"title":103,"path":104,"stem":105},{"title":109,"path":110,"stem":111,"children":112},"Next.js App Router & A11y: Implementation Guide for Modern Frameworks","\u002Freact-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y","react-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Findex",[113,114,120],{"title":109,"path":110,"stem":111},{"title":115,"path":116,"stem":117,"children":118},"Implementing Skip Links in Next.js App Router: A Step-by-Step Guide","\u002Freact-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fimplementing-skip-links-in-nextjs-app-router","react-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fimplementing-skip-links-in-nextjs-app-router\u002Findex",[119],{"title":115,"path":116,"stem":117},{"title":121,"path":122,"stem":123,"children":124},"Next.js Dynamic Imports and Keyboard Navigation: A Complete A11y Implementation Guide","\u002Freact-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fnextjs-dynamic-imports-and-keyboard-navigation","react-nextjs-accessibility-patterns\u002Fnextjs-app-router-a11y\u002Fnextjs-dynamic-imports-and-keyboard-navigation\u002Findex",[125],{"title":121,"path":122,"stem":123},{"title":127,"path":128,"stem":129,"children":130},"React Hooks for Accessibility: Implementation Patterns & State Management","\u002Freact-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility","react-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Findex",[131,132,138],{"title":127,"path":128,"stem":129},{"title":133,"path":134,"stem":135,"children":136},"Fixing Focus Trap Issues in React Portals","\u002Freact-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Ffixing-focus-trap-issues-in-react-portals","react-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Ffixing-focus-trap-issues-in-react-portals\u002Findex",[137],{"title":133,"path":134,"stem":135},{"title":139,"path":140,"stem":141,"children":142},"Making React useEffect Accessible for Screen Readers","\u002Freact-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Fmaking-react-useeffect-accessible-for-screen-readers","react-nextjs-accessibility-patterns\u002Freact-hooks-for-accessibility\u002Fmaking-react-useeffect-accessible-for-screen-readers\u002Findex",[143],{"title":139,"path":140,"stem":141},{"title":145,"path":146,"stem":147,"children":148},"Server Components & Client-Side Interactivity","\u002Freact-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity","react-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity\u002Findex",[149,150],{"title":145,"path":146,"stem":147},{"title":151,"path":152,"stem":153,"children":154},"Handling Accessible Modals in Next.js 14 Server Components","\u002Freact-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity\u002Fhandling-accessible-modals-in-nextjs-14-server-components","react-nextjs-accessibility-patterns\u002Fserver-components-client-side-interactivity\u002Fhandling-accessible-modals-in-nextjs-14-server-components\u002Findex",[155],{"title":151,"path":152,"stem":153},{"id":157,"title":43,"body":158,"date":2894,"description":2895,"extension":2896,"image":2894,"meta":2897,"modifiedAt":2894,"navigation":762,"noindex":2898,"path":44,"publishedAt":2894,"seo":2899,"stem":45,"updatedAt":2894,"__hash__":2900},"content\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002Fbuilding-accessible-dropdowns-without-external-ui-kits\u002Findex.md",{"type":159,"value":160,"toc":2885},"minimark",[161,165,174,180,205,210,232,237,256,558,563,593,597,615,1162,1166,1189,1193,1208,1802,1806,1828,1832,1839,1892,2056,2060,2078,2082,2085,2780,2784,2799,2803,2845,2849,2862,2868,2881],[162,163,43],"h1",{"id":164},"building-accessible-dropdowns-without-external-ui-kits",[166,167,168,169,173],"p",{},"Implementing a fully accessible dropdown from scratch requires strict adherence to WAI-ARIA specifications and native browser behaviors. Unlike relying on pre-built libraries, custom implementations demand precise state management and event delegation. This guide aligns with ",[170,171,10],"a",{"href":172},"\u002Fcore-accessibility-principles-for-modern-frameworks\u002F"," to ensure your component remains robust across assistive technologies. By mastering the underlying DOM interactions, developers can avoid the bloat and hidden accessibility debt common in third-party UI kits.",[166,175,176],{},[177,178,179],"strong",{},"Mapped WCAG 2.2 Criteria:",[181,182,183,190,195,200],"ul",{},[184,185,186],"li",{},[187,188,189],"code",{},"1.3.1 Info and Relationships",[184,191,192],{},[187,193,194],{},"2.1.1 Keyboard",[184,196,197],{},[187,198,199],{},"2.4.3 Focus Order",[184,201,202],{},[187,203,204],{},"4.1.2 Name, Role, Value",[166,206,207],{},[177,208,209],{},"Implementation Key Points:",[181,211,212,215,218,225],{},[184,213,214],{},"Semantic HTML foundation over ARIA overrides",[184,216,217],{},"Strict keyboard event mapping (Arrow keys, Escape, Enter\u002FSpace)",[184,219,220,221,224],{},"Programmatic focus management and ",[187,222,223],{},"aria-expanded"," synchronization",[184,226,227,228,231],{},"Screen reader announcement via ",[187,229,230],{},"aria-live"," regions",[233,234,236],"h2",{"id":235},"_1-semantic-html-foundation-dom-structure","1. Semantic HTML Foundation & DOM Structure",[166,238,239,240,243,244,247,248,251,252,255],{},"Establish the correct element hierarchy before applying ARIA attributes. Using a native ",[187,241,242],{},"\u003Cbutton>"," as the trigger and a ",[187,245,246],{},"\u003Cul>\u002F\u003Cli>"," structure for options ensures baseline accessibility without heavy scripting. Avoid ",[187,249,250],{},"\u003Cdiv>"," or ",[187,253,254],{},"\u003Cspan>"," for interactive elements, as they require manual keyboard activation and focus management.",[257,258,263],"pre",{"className":259,"code":260,"language":261,"meta":262,"style":262},"language-html shiki shiki-themes github-light github-dark","\u003Cdiv class=\"dropdown-wrapper\">\n \u003Cbutton \n type=\"button\" \n id=\"dropdown-trigger\" \n aria-haspopup=\"listbox\" \n aria-expanded=\"false\" \n aria-controls=\"dropdown-list\">\n Select Option\n \u003C\u002Fbutton>\n \u003Cul \n id=\"dropdown-list\" \n role=\"listbox\" \n aria-labelledby=\"dropdown-trigger\" \n hidden>\n \u003Cli role=\"option\" id=\"opt-1\" tabindex=\"-1\">Option 1\u003C\u002Fli>\n \u003Cli role=\"option\" id=\"opt-2\" tabindex=\"-1\">Option 2\u003C\u002Fli>\n \u003Cli role=\"option\" id=\"opt-3\" tabindex=\"-1\">Option 3\u003C\u002Fli>\n \u003C\u002Ful>\n\u003C\u002Fdiv>\n","html","",[187,264,265,292,304,317,330,343,356,369,375,385,394,405,417,429,437,473,506,539,548],{"__ignoreMap":262},[266,267,270,274,278,282,285,289],"span",{"class":268,"line":269},"line",1,[266,271,273],{"class":272},"sVt8B","\u003C",[266,275,277],{"class":276},"s9eBZ","div",[266,279,281],{"class":280},"sScJk"," class",[266,283,284],{"class":272},"=",[266,286,288],{"class":287},"sZZnC","\"dropdown-wrapper\"",[266,290,291],{"class":272},">\n",[266,293,295,298,301],{"class":268,"line":294},2,[266,296,297],{"class":272}," \u003C",[266,299,300],{"class":276},"button",[266,302,303],{"class":272}," \n",[266,305,307,310,312,315],{"class":268,"line":306},3,[266,308,309],{"class":280}," type",[266,311,284],{"class":272},[266,313,314],{"class":287},"\"button\"",[266,316,303],{"class":272},[266,318,320,323,325,328],{"class":268,"line":319},4,[266,321,322],{"class":280}," id",[266,324,284],{"class":272},[266,326,327],{"class":287},"\"dropdown-trigger\"",[266,329,303],{"class":272},[266,331,333,336,338,341],{"class":268,"line":332},5,[266,334,335],{"class":280}," aria-haspopup",[266,337,284],{"class":272},[266,339,340],{"class":287},"\"listbox\"",[266,342,303],{"class":272},[266,344,346,349,351,354],{"class":268,"line":345},6,[266,347,348],{"class":280}," aria-expanded",[266,350,284],{"class":272},[266,352,353],{"class":287},"\"false\"",[266,355,303],{"class":272},[266,357,359,362,364,367],{"class":268,"line":358},7,[266,360,361],{"class":280}," aria-controls",[266,363,284],{"class":272},[266,365,366],{"class":287},"\"dropdown-list\"",[266,368,291],{"class":272},[266,370,372],{"class":268,"line":371},8,[266,373,374],{"class":272}," Select Option\n",[266,376,378,381,383],{"class":268,"line":377},9,[266,379,380],{"class":272}," \u003C\u002F",[266,382,300],{"class":276},[266,384,291],{"class":272},[266,386,388,390,392],{"class":268,"line":387},10,[266,389,297],{"class":272},[266,391,181],{"class":276},[266,393,303],{"class":272},[266,395,397,399,401,403],{"class":268,"line":396},11,[266,398,322],{"class":280},[266,400,284],{"class":272},[266,402,366],{"class":287},[266,404,303],{"class":272},[266,406,408,411,413,415],{"class":268,"line":407},12,[266,409,410],{"class":280}," role",[266,412,284],{"class":272},[266,414,340],{"class":287},[266,416,303],{"class":272},[266,418,420,423,425,427],{"class":268,"line":419},13,[266,421,422],{"class":280}," aria-labelledby",[266,424,284],{"class":272},[266,426,327],{"class":287},[266,428,303],{"class":272},[266,430,432,435],{"class":268,"line":431},14,[266,433,434],{"class":280}," hidden",[266,436,291],{"class":272},[266,438,440,442,444,446,448,451,453,455,458,461,463,466,469,471],{"class":268,"line":439},15,[266,441,297],{"class":272},[266,443,184],{"class":276},[266,445,410],{"class":280},[266,447,284],{"class":272},[266,449,450],{"class":287},"\"option\"",[266,452,322],{"class":280},[266,454,284],{"class":272},[266,456,457],{"class":287},"\"opt-1\"",[266,459,460],{"class":280}," tabindex",[266,462,284],{"class":272},[266,464,465],{"class":287},"\"-1\"",[266,467,468],{"class":272},">Option 1\u003C\u002F",[266,470,184],{"class":276},[266,472,291],{"class":272},[266,474,476,478,480,482,484,486,488,490,493,495,497,499,502,504],{"class":268,"line":475},16,[266,477,297],{"class":272},[266,479,184],{"class":276},[266,481,410],{"class":280},[266,483,284],{"class":272},[266,485,450],{"class":287},[266,487,322],{"class":280},[266,489,284],{"class":272},[266,491,492],{"class":287},"\"opt-2\"",[266,494,460],{"class":280},[266,496,284],{"class":272},[266,498,465],{"class":287},[266,500,501],{"class":272},">Option 2\u003C\u002F",[266,503,184],{"class":276},[266,505,291],{"class":272},[266,507,509,511,513,515,517,519,521,523,526,528,530,532,535,537],{"class":268,"line":508},17,[266,510,297],{"class":272},[266,512,184],{"class":276},[266,514,410],{"class":280},[266,516,284],{"class":272},[266,518,450],{"class":287},[266,520,322],{"class":280},[266,522,284],{"class":272},[266,524,525],{"class":287},"\"opt-3\"",[266,527,460],{"class":280},[266,529,284],{"class":272},[266,531,465],{"class":287},[266,533,534],{"class":272},">Option 3\u003C\u002F",[266,536,184],{"class":276},[266,538,291],{"class":272},[266,540,542,544,546],{"class":268,"line":541},18,[266,543,380],{"class":272},[266,545,181],{"class":276},[266,547,291],{"class":272},[266,549,551,554,556],{"class":268,"line":550},19,[266,552,553],{"class":272},"\u003C\u002F",[266,555,277],{"class":276},[266,557,291],{"class":272},[166,559,560],{},[177,561,562],{},"Debugging Workflow:",[564,565,566,569,575,582],"ol",{},[184,567,568],{},"Open browser DevTools → Accessibility pane.",[184,570,571,572,574],{},"Verify the trigger exposes ",[187,573,300],{}," role and is natively focusable.",[184,576,577,578,581],{},"Confirm the list is removed from the accessibility tree when ",[187,579,580],{},"hidden"," is applied.",[184,583,584,585,588,589,592],{},"Validate ",[187,586,587],{},"aria-controls"," matches the list container ",[187,590,591],{},"id",".",[233,594,596],{"id":595},"_2-aria-roles-states-and-property-mapping","2. ARIA Roles, States, and Property Mapping",[166,598,599,600,603,604,606,607,610,611,614],{},"Bridge the semantic gap by applying the ",[187,601,602],{},"listbox"," pattern. Correctly mapping ",[187,605,223],{},", ",[187,608,609],{},"aria-haspopup",", and ",[187,612,613],{},"aria-activedescendant"," ensures assistive technologies accurately track component state and virtual focus.",[257,616,620],{"className":617,"code":618,"language":619,"meta":262,"style":262},"language-javascript shiki shiki-themes github-light github-dark","class AccessibleDropdown {\n constructor(trigger, list) {\n this.trigger = trigger;\n this.list = list;\n this.options = Array.from(list.querySelectorAll('[role=\"option\"]'));\n this.activeIndex = -1;\n this.isOpen = false;\n this.init();\n }\n\n init() {\n this.trigger.addEventListener('click', () => this.toggle());\n this.trigger.addEventListener('keydown', (e) => this.handleKeydown(e));\n document.addEventListener('click', (e) => this.handleOutsideClick(e));\n }\n\n toggle() {\n this.isOpen = !this.isOpen;\n this.trigger.setAttribute('aria-expanded', String(this.isOpen));\n this.list.toggleAttribute('hidden', !this.isOpen);\n \n if (this.isOpen) {\n this.activeIndex = 0;\n this.updateFocus();\n } else {\n this.activeIndex = -1;\n this.trigger.focus();\n }\n }\n\n updateFocus() {\n const activeOption = this.options[this.activeIndex];\n if (activeOption) {\n this.trigger.setAttribute('aria-activedescendant', activeOption.id);\n activeOption.scrollIntoView({ block: 'nearest' });\n } else {\n this.trigger.removeAttribute('aria-activedescendant');\n }\n }\n}\n","javascript",[187,621,622,634,654,668,680,709,727,741,753,758,764,772,803,837,865,869,873,880,897,923,949,954,968,982,994,1005,1020,1032,1037,1042,1047,1055,1077,1085,1102,1120,1129,1146,1151,1156],{"__ignoreMap":262},[266,623,624,628,631],{"class":268,"line":269},[266,625,627],{"class":626},"szBVR","class",[266,629,630],{"class":280}," AccessibleDropdown",[266,632,633],{"class":272}," {\n",[266,635,636,639,642,646,648,651],{"class":268,"line":294},[266,637,638],{"class":626}," constructor",[266,640,641],{"class":272},"(",[266,643,645],{"class":644},"s4XuR","trigger",[266,647,606],{"class":272},[266,649,650],{"class":644},"list",[266,652,653],{"class":272},") {\n",[266,655,656,660,663,665],{"class":268,"line":306},[266,657,659],{"class":658},"sj4cs"," this",[266,661,662],{"class":272},".trigger ",[266,664,284],{"class":626},[266,666,667],{"class":272}," trigger;\n",[266,669,670,672,675,677],{"class":268,"line":319},[266,671,659],{"class":658},[266,673,674],{"class":272},".list ",[266,676,284],{"class":626},[266,678,679],{"class":272}," list;\n",[266,681,682,684,687,689,692,695,698,701,703,706],{"class":268,"line":332},[266,683,659],{"class":658},[266,685,686],{"class":272},".options ",[266,688,284],{"class":626},[266,690,691],{"class":272}," Array.",[266,693,694],{"class":280},"from",[266,696,697],{"class":272},"(list.",[266,699,700],{"class":280},"querySelectorAll",[266,702,641],{"class":272},[266,704,705],{"class":287},"'[role=\"option\"]'",[266,707,708],{"class":272},"));\n",[266,710,711,713,716,718,721,724],{"class":268,"line":345},[266,712,659],{"class":658},[266,714,715],{"class":272},".activeIndex ",[266,717,284],{"class":626},[266,719,720],{"class":626}," -",[266,722,723],{"class":658},"1",[266,725,726],{"class":272},";\n",[266,728,729,731,734,736,739],{"class":268,"line":358},[266,730,659],{"class":658},[266,732,733],{"class":272},".isOpen ",[266,735,284],{"class":626},[266,737,738],{"class":658}," false",[266,740,726],{"class":272},[266,742,743,745,747,750],{"class":268,"line":371},[266,744,659],{"class":658},[266,746,592],{"class":272},[266,748,749],{"class":280},"init",[266,751,752],{"class":272},"();\n",[266,754,755],{"class":268,"line":377},[266,756,757],{"class":272}," }\n",[266,759,760],{"class":268,"line":387},[266,761,763],{"emptyLinePlaceholder":762},true,"\n",[266,765,766,769],{"class":268,"line":396},[266,767,768],{"class":280}," init",[266,770,771],{"class":272},"() {\n",[266,773,774,776,779,782,784,787,790,793,795,797,800],{"class":268,"line":407},[266,775,659],{"class":658},[266,777,778],{"class":272},".trigger.",[266,780,781],{"class":280},"addEventListener",[266,783,641],{"class":272},[266,785,786],{"class":287},"'click'",[266,788,789],{"class":272},", () ",[266,791,792],{"class":626},"=>",[266,794,659],{"class":658},[266,796,592],{"class":272},[266,798,799],{"class":280},"toggle",[266,801,802],{"class":272},"());\n",[266,804,805,807,809,811,813,816,819,822,825,827,829,831,834],{"class":268,"line":419},[266,806,659],{"class":658},[266,808,778],{"class":272},[266,810,781],{"class":280},[266,812,641],{"class":272},[266,814,815],{"class":287},"'keydown'",[266,817,818],{"class":272},", (",[266,820,821],{"class":644},"e",[266,823,824],{"class":272},") ",[266,826,792],{"class":626},[266,828,659],{"class":658},[266,830,592],{"class":272},[266,832,833],{"class":280},"handleKeydown",[266,835,836],{"class":272},"(e));\n",[266,838,839,842,844,846,848,850,852,854,856,858,860,863],{"class":268,"line":431},[266,840,841],{"class":272}," document.",[266,843,781],{"class":280},[266,845,641],{"class":272},[266,847,786],{"class":287},[266,849,818],{"class":272},[266,851,821],{"class":644},[266,853,824],{"class":272},[266,855,792],{"class":626},[266,857,659],{"class":658},[266,859,592],{"class":272},[266,861,862],{"class":280},"handleOutsideClick",[266,864,836],{"class":272},[266,866,867],{"class":268,"line":439},[266,868,757],{"class":272},[266,870,871],{"class":268,"line":475},[266,872,763],{"emptyLinePlaceholder":762},[266,874,875,878],{"class":268,"line":508},[266,876,877],{"class":280}," toggle",[266,879,771],{"class":272},[266,881,882,884,886,888,891,894],{"class":268,"line":541},[266,883,659],{"class":658},[266,885,733],{"class":272},[266,887,284],{"class":626},[266,889,890],{"class":626}," !",[266,892,893],{"class":658},"this",[266,895,896],{"class":272},".isOpen;\n",[266,898,899,901,903,906,908,911,913,916,918,920],{"class":268,"line":550},[266,900,659],{"class":658},[266,902,778],{"class":272},[266,904,905],{"class":280},"setAttribute",[266,907,641],{"class":272},[266,909,910],{"class":287},"'aria-expanded'",[266,912,606],{"class":272},[266,914,915],{"class":280},"String",[266,917,641],{"class":272},[266,919,893],{"class":658},[266,921,922],{"class":272},".isOpen));\n",[266,924,926,928,931,934,936,939,941,944,946],{"class":268,"line":925},20,[266,927,659],{"class":658},[266,929,930],{"class":272},".list.",[266,932,933],{"class":280},"toggleAttribute",[266,935,641],{"class":272},[266,937,938],{"class":287},"'hidden'",[266,940,606],{"class":272},[266,942,943],{"class":626},"!",[266,945,893],{"class":658},[266,947,948],{"class":272},".isOpen);\n",[266,950,952],{"class":268,"line":951},21,[266,953,303],{"class":272},[266,955,957,960,963,965],{"class":268,"line":956},22,[266,958,959],{"class":626}," if",[266,961,962],{"class":272}," (",[266,964,893],{"class":658},[266,966,967],{"class":272},".isOpen) {\n",[266,969,971,973,975,977,980],{"class":268,"line":970},23,[266,972,659],{"class":658},[266,974,715],{"class":272},[266,976,284],{"class":626},[266,978,979],{"class":658}," 0",[266,981,726],{"class":272},[266,983,985,987,989,992],{"class":268,"line":984},24,[266,986,659],{"class":658},[266,988,592],{"class":272},[266,990,991],{"class":280},"updateFocus",[266,993,752],{"class":272},[266,995,997,1000,1003],{"class":268,"line":996},25,[266,998,999],{"class":272}," } ",[266,1001,1002],{"class":626},"else",[266,1004,633],{"class":272},[266,1006,1008,1010,1012,1014,1016,1018],{"class":268,"line":1007},26,[266,1009,659],{"class":658},[266,1011,715],{"class":272},[266,1013,284],{"class":626},[266,1015,720],{"class":626},[266,1017,723],{"class":658},[266,1019,726],{"class":272},[266,1021,1023,1025,1027,1030],{"class":268,"line":1022},27,[266,1024,659],{"class":658},[266,1026,778],{"class":272},[266,1028,1029],{"class":280},"focus",[266,1031,752],{"class":272},[266,1033,1035],{"class":268,"line":1034},28,[266,1036,757],{"class":272},[266,1038,1040],{"class":268,"line":1039},29,[266,1041,757],{"class":272},[266,1043,1045],{"class":268,"line":1044},30,[266,1046,763],{"emptyLinePlaceholder":762},[266,1048,1050,1053],{"class":268,"line":1049},31,[266,1051,1052],{"class":280}," updateFocus",[266,1054,771],{"class":272},[266,1056,1058,1061,1064,1067,1069,1072,1074],{"class":268,"line":1057},32,[266,1059,1060],{"class":626}," const",[266,1062,1063],{"class":658}," activeOption",[266,1065,1066],{"class":626}," =",[266,1068,659],{"class":658},[266,1070,1071],{"class":272},".options[",[266,1073,893],{"class":658},[266,1075,1076],{"class":272},".activeIndex];\n",[266,1078,1080,1082],{"class":268,"line":1079},33,[266,1081,959],{"class":626},[266,1083,1084],{"class":272}," (activeOption) {\n",[266,1086,1088,1090,1092,1094,1096,1099],{"class":268,"line":1087},34,[266,1089,659],{"class":658},[266,1091,778],{"class":272},[266,1093,905],{"class":280},[266,1095,641],{"class":272},[266,1097,1098],{"class":287},"'aria-activedescendant'",[266,1100,1101],{"class":272},", activeOption.id);\n",[266,1103,1105,1108,1111,1114,1117],{"class":268,"line":1104},35,[266,1106,1107],{"class":272}," activeOption.",[266,1109,1110],{"class":280},"scrollIntoView",[266,1112,1113],{"class":272},"({ block: ",[266,1115,1116],{"class":287},"'nearest'",[266,1118,1119],{"class":272}," });\n",[266,1121,1123,1125,1127],{"class":268,"line":1122},36,[266,1124,999],{"class":272},[266,1126,1002],{"class":626},[266,1128,633],{"class":272},[266,1130,1132,1134,1136,1139,1141,1143],{"class":268,"line":1131},37,[266,1133,659],{"class":658},[266,1135,778],{"class":272},[266,1137,1138],{"class":280},"removeAttribute",[266,1140,641],{"class":272},[266,1142,1098],{"class":287},[266,1144,1145],{"class":272},");\n",[266,1147,1149],{"class":268,"line":1148},38,[266,1150,757],{"class":272},[266,1152,1154],{"class":268,"line":1153},39,[266,1155,757],{"class":272},[266,1157,1159],{"class":268,"line":1158},40,[266,1160,1161],{"class":272},"}\n",[166,1163,1164],{},[177,1165,562],{},[564,1167,1168,1180,1186],{},[184,1169,1170,1171,1173,1174,68,1177,592],{},"Inspect DOM state after toggling. ",[187,1172,223],{}," must strictly reflect ",[187,1175,1176],{},"true",[187,1178,1179],{},"false",[184,1181,1182,1183,1185],{},"Verify ",[187,1184,613],{}," updates dynamically as you navigate.",[184,1187,1188],{},"Test with VoiceOver (macOS) and NVDA (Windows) to confirm state announcements match visual behavior.",[233,1190,1192],{"id":1191},"_3-keyboard-event-handling-focus-management","3. Keyboard Event Handling & Focus Management",[166,1194,1195,1196,1199,1200,1203,1204,1207],{},"Implement robust keyboard navigation that mirrors native ",[187,1197,1198],{},"\u003Cselect>"," behavior. Intercepting ",[187,1201,1202],{},"keydown"," events requires preventing default browser scrolling while maintaining focus within the component scope. This approach mirrors established ",[170,1205,37],{"href":1206},"\u002Fcore-accessibility-principles-for-modern-frameworks\u002Fkeyboard-navigation-patterns-for-modals\u002F"," regarding event routing and focus restoration.",[257,1209,1211],{"className":617,"code":1210,"language":619,"meta":262,"style":262}," handleKeydown(e) {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!this.isOpen) this.toggle();\n else this.navigate(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!this.isOpen) this.toggle();\n else this.navigate(-1);\n break;\n case 'Enter':\n case ' ':\n e.preventDefault();\n if (!this.isOpen) this.toggle();\n else this.select();\n break;\n case 'Escape':\n e.preventDefault();\n if (this.isOpen) this.toggle();\n break;\n default:\n if (e.key.length === 1) this.handleTypeAhead(e.key);\n }\n }\n\n navigate(direction) {\n this.activeIndex += direction;\n if (this.activeIndex \u003C 0) this.activeIndex = this.options.length - 1;\n if (this.activeIndex >= this.options.length) this.activeIndex = 0;\n this.updateFocus();\n }\n\n select() {\n const selected = this.options[this.activeIndex];\n if (selected) {\n this.trigger.textContent = selected.textContent;\n this.toggle(); \u002F\u002F Closes and returns focus\n }\n }\n\n handleTypeAhead(char) {\n const matchIndex = this.options.findIndex(opt => \n opt.textContent.toLowerCase().startsWith(char.toLowerCase())\n );\n if (matchIndex !== -1) {\n this.activeIndex = matchIndex;\n this.updateFocus();\n }\n }\n",[187,1212,1213,1221,1229,1240,1250,1271,1289,1296,1305,1313,1333,1352,1358,1367,1376,1384,1404,1417,1423,1432,1440,1458,1464,1471,1499,1503,1507,1511,1519,1531,1566,1597,1607,1611,1615,1622,1639,1646,1658,1673,1677,1682,1687,1696,1723,1746,1752,1769,1781,1792,1797],{"__ignoreMap":262},[266,1214,1215,1218],{"class":268,"line":269},[266,1216,1217],{"class":280}," handleKeydown",[266,1219,1220],{"class":272},"(e) {\n",[266,1222,1223,1226],{"class":268,"line":294},[266,1224,1225],{"class":626}," switch",[266,1227,1228],{"class":272}," (e.key) {\n",[266,1230,1231,1234,1237],{"class":268,"line":306},[266,1232,1233],{"class":626}," case",[266,1235,1236],{"class":287}," 'ArrowDown'",[266,1238,1239],{"class":272},":\n",[266,1241,1242,1245,1248],{"class":268,"line":319},[266,1243,1244],{"class":272}," e.",[266,1246,1247],{"class":280},"preventDefault",[266,1249,752],{"class":272},[266,1251,1252,1254,1256,1258,1260,1263,1265,1267,1269],{"class":268,"line":332},[266,1253,959],{"class":626},[266,1255,962],{"class":272},[266,1257,943],{"class":626},[266,1259,893],{"class":658},[266,1261,1262],{"class":272},".isOpen) ",[266,1264,893],{"class":658},[266,1266,592],{"class":272},[266,1268,799],{"class":280},[266,1270,752],{"class":272},[266,1272,1273,1276,1278,1280,1283,1285,1287],{"class":268,"line":345},[266,1274,1275],{"class":626}," else",[266,1277,659],{"class":658},[266,1279,592],{"class":272},[266,1281,1282],{"class":280},"navigate",[266,1284,641],{"class":272},[266,1286,723],{"class":658},[266,1288,1145],{"class":272},[266,1290,1291,1294],{"class":268,"line":358},[266,1292,1293],{"class":626}," break",[266,1295,726],{"class":272},[266,1297,1298,1300,1303],{"class":268,"line":371},[266,1299,1233],{"class":626},[266,1301,1302],{"class":287}," 'ArrowUp'",[266,1304,1239],{"class":272},[266,1306,1307,1309,1311],{"class":268,"line":377},[266,1308,1244],{"class":272},[266,1310,1247],{"class":280},[266,1312,752],{"class":272},[266,1314,1315,1317,1319,1321,1323,1325,1327,1329,1331],{"class":268,"line":387},[266,1316,959],{"class":626},[266,1318,962],{"class":272},[266,1320,943],{"class":626},[266,1322,893],{"class":658},[266,1324,1262],{"class":272},[266,1326,893],{"class":658},[266,1328,592],{"class":272},[266,1330,799],{"class":280},[266,1332,752],{"class":272},[266,1334,1335,1337,1339,1341,1343,1345,1348,1350],{"class":268,"line":396},[266,1336,1275],{"class":626},[266,1338,659],{"class":658},[266,1340,592],{"class":272},[266,1342,1282],{"class":280},[266,1344,641],{"class":272},[266,1346,1347],{"class":626},"-",[266,1349,723],{"class":658},[266,1351,1145],{"class":272},[266,1353,1354,1356],{"class":268,"line":407},[266,1355,1293],{"class":626},[266,1357,726],{"class":272},[266,1359,1360,1362,1365],{"class":268,"line":419},[266,1361,1233],{"class":626},[266,1363,1364],{"class":287}," 'Enter'",[266,1366,1239],{"class":272},[266,1368,1369,1371,1374],{"class":268,"line":431},[266,1370,1233],{"class":626},[266,1372,1373],{"class":287}," ' '",[266,1375,1239],{"class":272},[266,1377,1378,1380,1382],{"class":268,"line":439},[266,1379,1244],{"class":272},[266,1381,1247],{"class":280},[266,1383,752],{"class":272},[266,1385,1386,1388,1390,1392,1394,1396,1398,1400,1402],{"class":268,"line":475},[266,1387,959],{"class":626},[266,1389,962],{"class":272},[266,1391,943],{"class":626},[266,1393,893],{"class":658},[266,1395,1262],{"class":272},[266,1397,893],{"class":658},[266,1399,592],{"class":272},[266,1401,799],{"class":280},[266,1403,752],{"class":272},[266,1405,1406,1408,1410,1412,1415],{"class":268,"line":508},[266,1407,1275],{"class":626},[266,1409,659],{"class":658},[266,1411,592],{"class":272},[266,1413,1414],{"class":280},"select",[266,1416,752],{"class":272},[266,1418,1419,1421],{"class":268,"line":541},[266,1420,1293],{"class":626},[266,1422,726],{"class":272},[266,1424,1425,1427,1430],{"class":268,"line":550},[266,1426,1233],{"class":626},[266,1428,1429],{"class":287}," 'Escape'",[266,1431,1239],{"class":272},[266,1433,1434,1436,1438],{"class":268,"line":925},[266,1435,1244],{"class":272},[266,1437,1247],{"class":280},[266,1439,752],{"class":272},[266,1441,1442,1444,1446,1448,1450,1452,1454,1456],{"class":268,"line":951},[266,1443,959],{"class":626},[266,1445,962],{"class":272},[266,1447,893],{"class":658},[266,1449,1262],{"class":272},[266,1451,893],{"class":658},[266,1453,592],{"class":272},[266,1455,799],{"class":280},[266,1457,752],{"class":272},[266,1459,1460,1462],{"class":268,"line":956},[266,1461,1293],{"class":626},[266,1463,726],{"class":272},[266,1465,1466,1469],{"class":268,"line":970},[266,1467,1468],{"class":626}," default",[266,1470,1239],{"class":272},[266,1472,1473,1475,1478,1481,1484,1487,1489,1491,1493,1496],{"class":268,"line":984},[266,1474,959],{"class":626},[266,1476,1477],{"class":272}," (e.key.",[266,1479,1480],{"class":658},"length",[266,1482,1483],{"class":626}," ===",[266,1485,1486],{"class":658}," 1",[266,1488,824],{"class":272},[266,1490,893],{"class":658},[266,1492,592],{"class":272},[266,1494,1495],{"class":280},"handleTypeAhead",[266,1497,1498],{"class":272},"(e.key);\n",[266,1500,1501],{"class":268,"line":996},[266,1502,757],{"class":272},[266,1504,1505],{"class":268,"line":1007},[266,1506,757],{"class":272},[266,1508,1509],{"class":268,"line":1022},[266,1510,763],{"emptyLinePlaceholder":762},[266,1512,1513,1516],{"class":268,"line":1034},[266,1514,1515],{"class":280}," navigate",[266,1517,1518],{"class":272},"(direction) {\n",[266,1520,1521,1523,1525,1528],{"class":268,"line":1039},[266,1522,659],{"class":658},[266,1524,715],{"class":272},[266,1526,1527],{"class":626},"+=",[266,1529,1530],{"class":272}," direction;\n",[266,1532,1533,1535,1537,1539,1541,1543,1545,1547,1549,1551,1553,1555,1558,1560,1562,1564],{"class":268,"line":1044},[266,1534,959],{"class":626},[266,1536,962],{"class":272},[266,1538,893],{"class":658},[266,1540,715],{"class":272},[266,1542,273],{"class":626},[266,1544,979],{"class":658},[266,1546,824],{"class":272},[266,1548,893],{"class":658},[266,1550,715],{"class":272},[266,1552,284],{"class":626},[266,1554,659],{"class":658},[266,1556,1557],{"class":272},".options.",[266,1559,1480],{"class":658},[266,1561,720],{"class":626},[266,1563,1486],{"class":658},[266,1565,726],{"class":272},[266,1567,1568,1570,1572,1574,1576,1579,1581,1583,1585,1587,1589,1591,1593,1595],{"class":268,"line":1049},[266,1569,959],{"class":626},[266,1571,962],{"class":272},[266,1573,893],{"class":658},[266,1575,715],{"class":272},[266,1577,1578],{"class":626},">=",[266,1580,659],{"class":658},[266,1582,1557],{"class":272},[266,1584,1480],{"class":658},[266,1586,824],{"class":272},[266,1588,893],{"class":658},[266,1590,715],{"class":272},[266,1592,284],{"class":626},[266,1594,979],{"class":658},[266,1596,726],{"class":272},[266,1598,1599,1601,1603,1605],{"class":268,"line":1057},[266,1600,659],{"class":658},[266,1602,592],{"class":272},[266,1604,991],{"class":280},[266,1606,752],{"class":272},[266,1608,1609],{"class":268,"line":1079},[266,1610,757],{"class":272},[266,1612,1613],{"class":268,"line":1087},[266,1614,763],{"emptyLinePlaceholder":762},[266,1616,1617,1620],{"class":268,"line":1104},[266,1618,1619],{"class":280}," select",[266,1621,771],{"class":272},[266,1623,1624,1626,1629,1631,1633,1635,1637],{"class":268,"line":1122},[266,1625,1060],{"class":626},[266,1627,1628],{"class":658}," selected",[266,1630,1066],{"class":626},[266,1632,659],{"class":658},[266,1634,1071],{"class":272},[266,1636,893],{"class":658},[266,1638,1076],{"class":272},[266,1640,1641,1643],{"class":268,"line":1131},[266,1642,959],{"class":626},[266,1644,1645],{"class":272}," (selected) {\n",[266,1647,1648,1650,1653,1655],{"class":268,"line":1148},[266,1649,659],{"class":658},[266,1651,1652],{"class":272},".trigger.textContent ",[266,1654,284],{"class":626},[266,1656,1657],{"class":272}," selected.textContent;\n",[266,1659,1660,1662,1664,1666,1669],{"class":268,"line":1153},[266,1661,659],{"class":658},[266,1663,592],{"class":272},[266,1665,799],{"class":280},[266,1667,1668],{"class":272},"(); ",[266,1670,1672],{"class":1671},"sJ8bj","\u002F\u002F Closes and returns focus\n",[266,1674,1675],{"class":268,"line":1158},[266,1676,757],{"class":272},[266,1678,1680],{"class":268,"line":1679},41,[266,1681,757],{"class":272},[266,1683,1685],{"class":268,"line":1684},42,[266,1686,763],{"emptyLinePlaceholder":762},[266,1688,1690,1693],{"class":268,"line":1689},43,[266,1691,1692],{"class":280}," handleTypeAhead",[266,1694,1695],{"class":272},"(char) {\n",[266,1697,1699,1701,1704,1706,1708,1710,1713,1715,1718,1721],{"class":268,"line":1698},44,[266,1700,1060],{"class":626},[266,1702,1703],{"class":658}," matchIndex",[266,1705,1066],{"class":626},[266,1707,659],{"class":658},[266,1709,1557],{"class":272},[266,1711,1712],{"class":280},"findIndex",[266,1714,641],{"class":272},[266,1716,1717],{"class":644},"opt",[266,1719,1720],{"class":626}," =>",[266,1722,303],{"class":272},[266,1724,1726,1729,1732,1735,1738,1741,1743],{"class":268,"line":1725},45,[266,1727,1728],{"class":272}," opt.textContent.",[266,1730,1731],{"class":280},"toLowerCase",[266,1733,1734],{"class":272},"().",[266,1736,1737],{"class":280},"startsWith",[266,1739,1740],{"class":272},"(char.",[266,1742,1731],{"class":280},[266,1744,1745],{"class":272},"())\n",[266,1747,1749],{"class":268,"line":1748},46,[266,1750,1751],{"class":272}," );\n",[266,1753,1755,1757,1760,1763,1765,1767],{"class":268,"line":1754},47,[266,1756,959],{"class":626},[266,1758,1759],{"class":272}," (matchIndex ",[266,1761,1762],{"class":626},"!==",[266,1764,720],{"class":626},[266,1766,723],{"class":658},[266,1768,653],{"class":272},[266,1770,1772,1774,1776,1778],{"class":268,"line":1771},48,[266,1773,659],{"class":658},[266,1775,715],{"class":272},[266,1777,284],{"class":626},[266,1779,1780],{"class":272}," matchIndex;\n",[266,1782,1784,1786,1788,1790],{"class":268,"line":1783},49,[266,1785,659],{"class":658},[266,1787,592],{"class":272},[266,1789,991],{"class":280},[266,1791,752],{"class":272},[266,1793,1795],{"class":268,"line":1794},50,[266,1796,757],{"class":272},[266,1798,1800],{"class":268,"line":1799},51,[266,1801,757],{"class":272},[166,1803,1804],{},[177,1805,562],{},[564,1807,1808,1814,1821],{},[184,1809,1182,1810,1813],{},[187,1811,1812],{},"e.preventDefault()"," stops viewport scrolling on arrow keys.",[184,1815,1816,1817,1820],{},"Confirm ",[187,1818,1819],{},"Escape"," closes the menu and immediately restores focus to the trigger.",[184,1822,1823,1824,1827],{},"Test rapid key presses to ensure ",[187,1825,1826],{},"activeIndex"," wraps correctly without throwing errors.",[233,1829,1831],{"id":1830},"_4-screen-reader-compatibility-live-regions","4. Screen Reader Compatibility & Live Regions",[166,1833,1834,1835,1838],{},"Dynamic updates (selection, filtering, or state changes) must be announced without disrupting the reading flow. Use ",[187,1836,1837],{},"aria-live=\"polite\""," for non-intrusive feedback and avoid flooding the speech queue during rapid navigation.",[257,1840,1842],{"className":259,"code":1841,"language":261,"meta":262,"style":262},"\u003C!-- Inject once in DOM -->\n\u003Cdiv id=\"dropdown-status\" aria-live=\"polite\" aria-atomic=\"true\" class=\"sr-only\">\u003C\u002Fdiv>\n",[187,1843,1844,1849],{"__ignoreMap":262},[266,1845,1846],{"class":268,"line":269},[266,1847,1848],{"class":1671},"\u003C!-- Inject once in DOM -->\n",[266,1850,1851,1853,1855,1857,1859,1862,1865,1867,1870,1873,1875,1878,1880,1882,1885,1888,1890],{"class":268,"line":294},[266,1852,273],{"class":272},[266,1854,277],{"class":276},[266,1856,322],{"class":280},[266,1858,284],{"class":272},[266,1860,1861],{"class":287},"\"dropdown-status\"",[266,1863,1864],{"class":280}," aria-live",[266,1866,284],{"class":272},[266,1868,1869],{"class":287},"\"polite\"",[266,1871,1872],{"class":280}," aria-atomic",[266,1874,284],{"class":272},[266,1876,1877],{"class":287},"\"true\"",[266,1879,281],{"class":280},[266,1881,284],{"class":272},[266,1883,1884],{"class":287},"\"sr-only\"",[266,1886,1887],{"class":272},">\u003C\u002F",[266,1889,277],{"class":276},[266,1891,291],{"class":272},[257,1893,1895],{"className":617,"code":1894,"language":619,"meta":262,"style":262}," announce(message) {\n const status = document.getElementById('dropdown-status');\n status.textContent = ''; \u002F\u002F Clear for re-announcement\n requestAnimationFrame(() => { status.textContent = message; });\n }\n\n \u002F\u002F Usage inside select()\n select() {\n const selected = this.options[this.activeIndex];\n if (selected) {\n this.announce(`${selected.textContent} selected`);\n this.trigger.textContent = selected.textContent;\n this.toggle();\n }\n }\n",[187,1896,1897,1905,1926,1942,1960,1964,1968,1973,1979,1995,2001,2028,2038,2048,2052],{"__ignoreMap":262},[266,1898,1899,1902],{"class":268,"line":269},[266,1900,1901],{"class":280}," announce",[266,1903,1904],{"class":272},"(message) {\n",[266,1906,1907,1909,1912,1914,1916,1919,1921,1924],{"class":268,"line":294},[266,1908,1060],{"class":626},[266,1910,1911],{"class":658}," status",[266,1913,1066],{"class":626},[266,1915,841],{"class":272},[266,1917,1918],{"class":280},"getElementById",[266,1920,641],{"class":272},[266,1922,1923],{"class":287},"'dropdown-status'",[266,1925,1145],{"class":272},[266,1927,1928,1931,1933,1936,1939],{"class":268,"line":306},[266,1929,1930],{"class":272}," status.textContent ",[266,1932,284],{"class":626},[266,1934,1935],{"class":287}," ''",[266,1937,1938],{"class":272},"; ",[266,1940,1941],{"class":1671},"\u002F\u002F Clear for re-announcement\n",[266,1943,1944,1947,1950,1952,1955,1957],{"class":268,"line":319},[266,1945,1946],{"class":280}," requestAnimationFrame",[266,1948,1949],{"class":272},"(() ",[266,1951,792],{"class":626},[266,1953,1954],{"class":272}," { status.textContent ",[266,1956,284],{"class":626},[266,1958,1959],{"class":272}," message; });\n",[266,1961,1962],{"class":268,"line":332},[266,1963,757],{"class":272},[266,1965,1966],{"class":268,"line":345},[266,1967,763],{"emptyLinePlaceholder":762},[266,1969,1970],{"class":268,"line":358},[266,1971,1972],{"class":1671}," \u002F\u002F Usage inside select()\n",[266,1974,1975,1977],{"class":268,"line":371},[266,1976,1619],{"class":280},[266,1978,771],{"class":272},[266,1980,1981,1983,1985,1987,1989,1991,1993],{"class":268,"line":377},[266,1982,1060],{"class":626},[266,1984,1628],{"class":658},[266,1986,1066],{"class":626},[266,1988,659],{"class":658},[266,1990,1071],{"class":272},[266,1992,893],{"class":658},[266,1994,1076],{"class":272},[266,1996,1997,1999],{"class":268,"line":387},[266,1998,959],{"class":626},[266,2000,1645],{"class":272},[266,2002,2003,2005,2007,2010,2012,2015,2018,2020,2023,2026],{"class":268,"line":396},[266,2004,659],{"class":658},[266,2006,592],{"class":272},[266,2008,2009],{"class":280},"announce",[266,2011,641],{"class":272},[266,2013,2014],{"class":287},"`${",[266,2016,2017],{"class":272},"selected",[266,2019,592],{"class":287},[266,2021,2022],{"class":272},"textContent",[266,2024,2025],{"class":287},"} selected`",[266,2027,1145],{"class":272},[266,2029,2030,2032,2034,2036],{"class":268,"line":407},[266,2031,659],{"class":658},[266,2033,1652],{"class":272},[266,2035,284],{"class":626},[266,2037,1657],{"class":272},[266,2039,2040,2042,2044,2046],{"class":268,"line":419},[266,2041,659],{"class":658},[266,2043,592],{"class":272},[266,2045,799],{"class":280},[266,2047,752],{"class":272},[266,2049,2050],{"class":268,"line":431},[266,2051,757],{"class":272},[266,2053,2054],{"class":268,"line":439},[266,2055,757],{"class":272},[166,2057,2058],{},[177,2059,562],{},[564,2061,2062,2069,2072],{},[184,2063,2064,2065,2068],{},"Enable screen reader speech logging (NVDA: ",[187,2066,2067],{},"Tools > Speech Viewer",").",[184,2070,2071],{},"Verify announcements fire only on selection, not on every arrow key press.",[184,2073,1816,2074,2077],{},[187,2075,2076],{},"requestAnimationFrame"," prevents duplicate announcements in rapid succession.",[233,2079,2081],{"id":2080},"_5-framework-integration-state-management","5. Framework Integration & State Management",[166,2083,2084],{},"Adapt vanilla patterns to modern component lifecycles. Ensure framework-specific reactivity does not break ARIA synchronization or focus management during re-renders. Isolate keyboard handlers to component scope and implement strict cleanup on unmount.",[257,2086,2090],{"className":2087,"code":2088,"language":2089,"meta":262,"style":262},"language-jsx shiki shiki-themes github-light github-dark","\u002F\u002F React Implementation Example\nimport { useEffect, useRef, useState } from 'react';\n\nexport function AccessibleDropdown({ options, onSelect }) {\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState(-1);\n const triggerRef = useRef(null);\n const listRef = useRef(null);\n\n useEffect(() => {\n const handleKeydown = (e) => {\n if (e.key === 'Escape' && isOpen) {\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n };\n document.addEventListener('keydown', handleKeydown);\n return () => document.removeEventListener('keydown', handleKeydown);\n }, [isOpen]);\n\n const handleSelect = (index) => {\n onSelect(options[index]);\n setIsOpen(false);\n setActiveIndex(-1);\n triggerRef.current?.focus();\n };\n\n return (\n \u003Cdiv className=\"dropdown-wrapper\">\n \u003Cbutton\n ref={triggerRef}\n type=\"button\"\n aria-haspopup=\"listbox\"\n aria-expanded={isOpen}\n aria-activedescendant={activeIndex > -1 ? `opt-${activeIndex}` : undefined}\n onClick={() => setIsOpen(!isOpen)}\n >\n Select Option\n \u003C\u002Fbutton>\n \u003Cul\n ref={listRef}\n role=\"listbox\"\n aria-labelledby={triggerRef.current?.id}\n hidden={!isOpen}\n >\n {options.map((opt, i) => (\n \u003Cli\n key={i}\n id={`opt-${i}`}\n role=\"option\"\n aria-selected={i === activeIndex}\n tabIndex={-1}\n onClick={() => handleSelect(i)}\n >\n {opt}\n \u003C\u002Fli>\n ))}\n \u003C\u002Ful>\n \u003C\u002Fdiv>\n );\n}\n","jsx",[187,2091,2092,2097,2112,2116,2140,2169,2196,2215,2232,2236,2247,2265,2283,2294,2303,2307,2312,2325,2346,2351,2355,2374,2382,2392,2405,2413,2417,2421,2428,2443,2450,2460,2469,2478,2487,2523,2544,2549,2553,2561,2568,2577,2585,2594,2608,2612,2636,2643,2653,2670,2679,2694,2710,2726,2731,2737,2746,2752,2761,2770,2775],{"__ignoreMap":262},[266,2093,2094],{"class":268,"line":269},[266,2095,2096],{"class":1671},"\u002F\u002F React Implementation Example\n",[266,2098,2099,2102,2105,2107,2110],{"class":268,"line":294},[266,2100,2101],{"class":626},"import",[266,2103,2104],{"class":272}," { useEffect, useRef, useState } ",[266,2106,694],{"class":626},[266,2108,2109],{"class":287}," 'react'",[266,2111,726],{"class":272},[266,2113,2114],{"class":268,"line":306},[266,2115,763],{"emptyLinePlaceholder":762},[266,2117,2118,2121,2124,2126,2129,2132,2134,2137],{"class":268,"line":319},[266,2119,2120],{"class":626},"export",[266,2122,2123],{"class":626}," function",[266,2125,630],{"class":280},[266,2127,2128],{"class":272},"({ ",[266,2130,2131],{"class":644},"options",[266,2133,606],{"class":272},[266,2135,2136],{"class":644},"onSelect",[266,2138,2139],{"class":272}," }) {\n",[266,2141,2142,2144,2147,2150,2152,2155,2158,2160,2163,2165,2167],{"class":268,"line":332},[266,2143,1060],{"class":626},[266,2145,2146],{"class":272}," [",[266,2148,2149],{"class":658},"isOpen",[266,2151,606],{"class":272},[266,2153,2154],{"class":658},"setIsOpen",[266,2156,2157],{"class":272},"] ",[266,2159,284],{"class":626},[266,2161,2162],{"class":280}," useState",[266,2164,641],{"class":272},[266,2166,1179],{"class":658},[266,2168,1145],{"class":272},[266,2170,2171,2173,2175,2177,2179,2182,2184,2186,2188,2190,2192,2194],{"class":268,"line":345},[266,2172,1060],{"class":626},[266,2174,2146],{"class":272},[266,2176,1826],{"class":658},[266,2178,606],{"class":272},[266,2180,2181],{"class":658},"setActiveIndex",[266,2183,2157],{"class":272},[266,2185,284],{"class":626},[266,2187,2162],{"class":280},[266,2189,641],{"class":272},[266,2191,1347],{"class":626},[266,2193,723],{"class":658},[266,2195,1145],{"class":272},[266,2197,2198,2200,2203,2205,2208,2210,2213],{"class":268,"line":358},[266,2199,1060],{"class":626},[266,2201,2202],{"class":658}," triggerRef",[266,2204,1066],{"class":626},[266,2206,2207],{"class":280}," useRef",[266,2209,641],{"class":272},[266,2211,2212],{"class":658},"null",[266,2214,1145],{"class":272},[266,2216,2217,2219,2222,2224,2226,2228,2230],{"class":268,"line":371},[266,2218,1060],{"class":626},[266,2220,2221],{"class":658}," listRef",[266,2223,1066],{"class":626},[266,2225,2207],{"class":280},[266,2227,641],{"class":272},[266,2229,2212],{"class":658},[266,2231,1145],{"class":272},[266,2233,2234],{"class":268,"line":377},[266,2235,763],{"emptyLinePlaceholder":762},[266,2237,2238,2241,2243,2245],{"class":268,"line":387},[266,2239,2240],{"class":280}," useEffect",[266,2242,1949],{"class":272},[266,2244,792],{"class":626},[266,2246,633],{"class":272},[266,2248,2249,2251,2253,2255,2257,2259,2261,2263],{"class":268,"line":396},[266,2250,1060],{"class":626},[266,2252,1217],{"class":280},[266,2254,1066],{"class":626},[266,2256,962],{"class":272},[266,2258,821],{"class":644},[266,2260,824],{"class":272},[266,2262,792],{"class":626},[266,2264,633],{"class":272},[266,2266,2267,2269,2272,2275,2277,2280],{"class":268,"line":407},[266,2268,959],{"class":626},[266,2270,2271],{"class":272}," (e.key ",[266,2273,2274],{"class":626},"===",[266,2276,1429],{"class":287},[266,2278,2279],{"class":626}," &&",[266,2281,2282],{"class":272}," isOpen) {\n",[266,2284,2285,2288,2290,2292],{"class":268,"line":419},[266,2286,2287],{"class":280}," setIsOpen",[266,2289,641],{"class":272},[266,2291,1179],{"class":658},[266,2293,1145],{"class":272},[266,2295,2296,2299,2301],{"class":268,"line":431},[266,2297,2298],{"class":272}," triggerRef.current?.",[266,2300,1029],{"class":280},[266,2302,752],{"class":272},[266,2304,2305],{"class":268,"line":439},[266,2306,757],{"class":272},[266,2308,2309],{"class":268,"line":475},[266,2310,2311],{"class":272}," };\n",[266,2313,2314,2316,2318,2320,2322],{"class":268,"line":508},[266,2315,841],{"class":272},[266,2317,781],{"class":280},[266,2319,641],{"class":272},[266,2321,815],{"class":287},[266,2323,2324],{"class":272},", handleKeydown);\n",[266,2326,2327,2330,2333,2335,2337,2340,2342,2344],{"class":268,"line":541},[266,2328,2329],{"class":626}," return",[266,2331,2332],{"class":272}," () ",[266,2334,792],{"class":626},[266,2336,841],{"class":272},[266,2338,2339],{"class":280},"removeEventListener",[266,2341,641],{"class":272},[266,2343,815],{"class":287},[266,2345,2324],{"class":272},[266,2347,2348],{"class":268,"line":550},[266,2349,2350],{"class":272}," }, [isOpen]);\n",[266,2352,2353],{"class":268,"line":925},[266,2354,763],{"emptyLinePlaceholder":762},[266,2356,2357,2359,2362,2364,2366,2368,2370,2372],{"class":268,"line":951},[266,2358,1060],{"class":626},[266,2360,2361],{"class":280}," handleSelect",[266,2363,1066],{"class":626},[266,2365,962],{"class":272},[266,2367,69],{"class":644},[266,2369,824],{"class":272},[266,2371,792],{"class":626},[266,2373,633],{"class":272},[266,2375,2376,2379],{"class":268,"line":956},[266,2377,2378],{"class":280}," onSelect",[266,2380,2381],{"class":272},"(options[index]);\n",[266,2383,2384,2386,2388,2390],{"class":268,"line":970},[266,2385,2287],{"class":280},[266,2387,641],{"class":272},[266,2389,1179],{"class":658},[266,2391,1145],{"class":272},[266,2393,2394,2397,2399,2401,2403],{"class":268,"line":984},[266,2395,2396],{"class":280}," setActiveIndex",[266,2398,641],{"class":272},[266,2400,1347],{"class":626},[266,2402,723],{"class":658},[266,2404,1145],{"class":272},[266,2406,2407,2409,2411],{"class":268,"line":996},[266,2408,2298],{"class":272},[266,2410,1029],{"class":280},[266,2412,752],{"class":272},[266,2414,2415],{"class":268,"line":1007},[266,2416,2311],{"class":272},[266,2418,2419],{"class":268,"line":1022},[266,2420,763],{"emptyLinePlaceholder":762},[266,2422,2423,2425],{"class":268,"line":1034},[266,2424,2329],{"class":626},[266,2426,2427],{"class":272}," (\n",[266,2429,2430,2432,2434,2437,2439,2441],{"class":268,"line":1039},[266,2431,297],{"class":272},[266,2433,277],{"class":276},[266,2435,2436],{"class":280}," className",[266,2438,284],{"class":626},[266,2440,288],{"class":287},[266,2442,291],{"class":272},[266,2444,2445,2447],{"class":268,"line":1044},[266,2446,297],{"class":272},[266,2448,2449],{"class":276},"button\n",[266,2451,2452,2455,2457],{"class":268,"line":1049},[266,2453,2454],{"class":280}," ref",[266,2456,284],{"class":626},[266,2458,2459],{"class":272},"{triggerRef}\n",[266,2461,2462,2464,2466],{"class":268,"line":1057},[266,2463,309],{"class":280},[266,2465,284],{"class":626},[266,2467,2468],{"class":287},"\"button\"\n",[266,2470,2471,2473,2475],{"class":268,"line":1079},[266,2472,335],{"class":280},[266,2474,284],{"class":626},[266,2476,2477],{"class":287},"\"listbox\"\n",[266,2479,2480,2482,2484],{"class":268,"line":1087},[266,2481,348],{"class":280},[266,2483,284],{"class":626},[266,2485,2486],{"class":272},"{isOpen}\n",[266,2488,2489,2492,2494,2497,2500,2502,2504,2507,2510,2512,2515,2518,2521],{"class":268,"line":1104},[266,2490,2491],{"class":280}," aria-activedescendant",[266,2493,284],{"class":626},[266,2495,2496],{"class":272},"{activeIndex ",[266,2498,2499],{"class":626},">",[266,2501,720],{"class":626},[266,2503,723],{"class":658},[266,2505,2506],{"class":626}," ?",[266,2508,2509],{"class":287}," `opt-${",[266,2511,1826],{"class":272},[266,2513,2514],{"class":287},"}`",[266,2516,2517],{"class":626}," :",[266,2519,2520],{"class":658}," undefined",[266,2522,1161],{"class":272},[266,2524,2525,2528,2530,2533,2535,2537,2539,2541],{"class":268,"line":1122},[266,2526,2527],{"class":280}," onClick",[266,2529,284],{"class":626},[266,2531,2532],{"class":272},"{() ",[266,2534,792],{"class":626},[266,2536,2287],{"class":280},[266,2538,641],{"class":272},[266,2540,943],{"class":626},[266,2542,2543],{"class":272},"isOpen)}\n",[266,2545,2546],{"class":268,"line":1131},[266,2547,2548],{"class":272}," >\n",[266,2550,2551],{"class":268,"line":1148},[266,2552,374],{"class":272},[266,2554,2555,2557,2559],{"class":268,"line":1153},[266,2556,380],{"class":272},[266,2558,300],{"class":276},[266,2560,291],{"class":272},[266,2562,2563,2565],{"class":268,"line":1158},[266,2564,297],{"class":272},[266,2566,2567],{"class":276},"ul\n",[266,2569,2570,2572,2574],{"class":268,"line":1679},[266,2571,2454],{"class":280},[266,2573,284],{"class":626},[266,2575,2576],{"class":272},"{listRef}\n",[266,2578,2579,2581,2583],{"class":268,"line":1684},[266,2580,410],{"class":280},[266,2582,284],{"class":626},[266,2584,2477],{"class":287},[266,2586,2587,2589,2591],{"class":268,"line":1689},[266,2588,422],{"class":280},[266,2590,284],{"class":626},[266,2592,2593],{"class":272},"{triggerRef.current?.id}\n",[266,2595,2596,2598,2600,2603,2605],{"class":268,"line":1698},[266,2597,434],{"class":280},[266,2599,284],{"class":626},[266,2601,2602],{"class":272},"{",[266,2604,943],{"class":626},[266,2606,2607],{"class":272},"isOpen}\n",[266,2609,2610],{"class":268,"line":1725},[266,2611,2548],{"class":272},[266,2613,2614,2617,2620,2623,2625,2627,2630,2632,2634],{"class":268,"line":1748},[266,2615,2616],{"class":272}," {options.",[266,2618,2619],{"class":280},"map",[266,2621,2622],{"class":272},"((",[266,2624,1717],{"class":644},[266,2626,606],{"class":272},[266,2628,2629],{"class":644},"i",[266,2631,824],{"class":272},[266,2633,792],{"class":626},[266,2635,2427],{"class":272},[266,2637,2638,2640],{"class":268,"line":1754},[266,2639,297],{"class":272},[266,2641,2642],{"class":276},"li\n",[266,2644,2645,2648,2650],{"class":268,"line":1771},[266,2646,2647],{"class":280}," key",[266,2649,284],{"class":626},[266,2651,2652],{"class":272},"{i}\n",[266,2654,2655,2657,2659,2661,2664,2666,2668],{"class":268,"line":1783},[266,2656,322],{"class":280},[266,2658,284],{"class":626},[266,2660,2602],{"class":272},[266,2662,2663],{"class":287},"`opt-${",[266,2665,2629],{"class":272},[266,2667,2514],{"class":287},[266,2669,1161],{"class":272},[266,2671,2672,2674,2676],{"class":268,"line":1794},[266,2673,410],{"class":280},[266,2675,284],{"class":626},[266,2677,2678],{"class":287},"\"option\"\n",[266,2680,2681,2684,2686,2689,2691],{"class":268,"line":1799},[266,2682,2683],{"class":280}," aria-selected",[266,2685,284],{"class":626},[266,2687,2688],{"class":272},"{i ",[266,2690,2274],{"class":626},[266,2692,2693],{"class":272}," activeIndex}\n",[266,2695,2697,2700,2702,2704,2706,2708],{"class":268,"line":2696},52,[266,2698,2699],{"class":280}," tabIndex",[266,2701,284],{"class":626},[266,2703,2602],{"class":272},[266,2705,1347],{"class":626},[266,2707,723],{"class":658},[266,2709,1161],{"class":272},[266,2711,2713,2715,2717,2719,2721,2723],{"class":268,"line":2712},53,[266,2714,2527],{"class":280},[266,2716,284],{"class":626},[266,2718,2532],{"class":272},[266,2720,792],{"class":626},[266,2722,2361],{"class":280},[266,2724,2725],{"class":272},"(i)}\n",[266,2727,2729],{"class":268,"line":2728},54,[266,2730,2548],{"class":272},[266,2732,2734],{"class":268,"line":2733},55,[266,2735,2736],{"class":272}," {opt}\n",[266,2738,2740,2742,2744],{"class":268,"line":2739},56,[266,2741,380],{"class":272},[266,2743,184],{"class":276},[266,2745,291],{"class":272},[266,2747,2749],{"class":268,"line":2748},57,[266,2750,2751],{"class":272}," ))}\n",[266,2753,2755,2757,2759],{"class":268,"line":2754},58,[266,2756,380],{"class":272},[266,2758,181],{"class":276},[266,2760,291],{"class":272},[266,2762,2764,2766,2768],{"class":268,"line":2763},59,[266,2765,380],{"class":272},[266,2767,277],{"class":276},[266,2769,291],{"class":272},[266,2771,2773],{"class":268,"line":2772},60,[266,2774,1751],{"class":272},[266,2776,2778],{"class":268,"line":2777},61,[266,2779,1161],{"class":272},[166,2781,2782],{},[177,2783,562],{},[564,2785,2786,2789,2792],{},[184,2787,2788],{},"Trigger rapid open\u002Fclose cycles to verify focus restoration and event listener cleanup.",[184,2790,2791],{},"Monitor React DevTools for unnecessary re-renders caused by ARIA attribute updates.",[184,2793,2794,2795,2798],{},"Ensure ",[187,2796,2797],{},"useEffect"," cleanup runs on component unmount to prevent memory leaks.",[233,2800,2802],{"id":2801},"common-implementation-pitfalls","Common Implementation Pitfalls",[181,2804,2805,2814,2820,2826,2832,2838],{},[184,2806,2807,2808,2810,2811,2813],{},"Using ",[187,2809,250],{}," for the trigger instead of ",[187,2812,242],{},", breaking native keyboard activation and screen reader interaction.",[184,2815,2816,2817,2819],{},"Failing to synchronize ",[187,2818,223],{}," with visual open\u002Fclose state, causing assistive technology desync.",[184,2821,2822,2823,2825],{},"Implementing rigid focus traps that prevent ",[187,2824,1819],{}," from closing the menu and returning focus.",[184,2827,2828,2829,2831],{},"Overusing ",[187,2830,230],{}," regions, causing screen reader speech queue flooding during rapid navigation.",[184,2833,2834,2835,2837],{},"Ignoring type-ahead filtering, which violates user expectations established by native ",[187,2836,1198],{}," elements.",[184,2839,2840,2841,2844],{},"Applying ",[187,2842,2843],{},"tabindex=\"0\""," to options, forcing keyboard users to tab through every item instead of using arrow keys.",[233,2846,2848],{"id":2847},"frequently-asked-questions","Frequently Asked Questions",[166,2850,2851,2854,2855,2857,2858,2861],{},[177,2852,2853],{},"Should I use the combobox or listbox ARIA pattern for dropdowns?","\nUse the ",[187,2856,602],{}," pattern for simple selection menus where the trigger displays the selected value and no text input is required. Use the ",[187,2859,2860],{},"combobox"," pattern only when the dropdown includes an editable text input for filtering or custom entry.",[166,2863,2864,2867],{},[177,2865,2866],{},"How do I handle focus when the dropdown closes?","\nAlways return focus to the trigger element that opened the dropdown. This maintains a predictable tab order and prevents focus loss, which is critical for keyboard-only users and screen reader navigation.",[166,2869,2870,2876,2877,2880],{},[177,2871,2872,2873,2875],{},"Is ",[187,2874,2843],{}," required on each dropdown option?","\nNo. Use ",[187,2878,2879],{},"tabindex=\"-1\""," on options and manage focus programmatically via JavaScript. This prevents the browser's native tab sequence from trapping users inside the list and ensures arrow keys remain the primary navigation mechanism.",[2882,2883,2884],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}",{"title":262,"searchDepth":294,"depth":294,"links":2886},[2887,2888,2889,2890,2891,2892,2893],{"id":235,"depth":294,"text":236},{"id":595,"depth":294,"text":596},{"id":1191,"depth":294,"text":1192},{"id":1830,"depth":294,"text":1831},{"id":2080,"depth":294,"text":2081},{"id":2801,"depth":294,"text":2802},{"id":2847,"depth":294,"text":2848},null,"Build accessible dropdowns without UI libraries using robust keyboard interactions, ARIA state management, and predictable focus behavior.","md",{},false,{"title":43,"description":2895},"qpS9QM6rHiiwkh62HvaBz2qYaV1gpN-FZDQrxtjlqPM",[2902,2932,2933],{"title":5,"path":6,"stem":7,"children":2903},[2904,2905,2908,2911,2917,2923,2929],{"title":10,"path":6,"stem":11},{"title":13,"path":14,"stem":15,"children":2906},[2907],{"title":13,"path":14,"stem":15},{"title":19,"path":20,"stem":21,"children":2909},[2910],{"title":19,"path":20,"stem":21},{"title":25,"path":26,"stem":27,"children":2912},[2913,2914],{"title":25,"path":26,"stem":27},{"title":31,"path":32,"stem":33,"children":2915},[2916],{"title":31,"path":32,"stem":33},{"title":37,"path":38,"stem":39,"children":2918},[2919,2920],{"title":37,"path":38,"stem":39},{"title":43,"path":44,"stem":45,"children":2921},[2922],{"title":43,"path":44,"stem":45},{"title":49,"path":50,"stem":51,"children":2924},[2925,2926],{"title":49,"path":50,"stem":51},{"title":55,"path":56,"stem":57,"children":2927},[2928],{"title":55,"path":56,"stem":57},{"title":61,"path":62,"stem":63,"children":2930},[2931],{"title":61,"path":62,"stem":63},{"title":67,"path":68,"stem":69},{"title":71,"path":72,"stem":73,"children":2934},[2935,2936,2942,2948,2951,2960,2969],{"title":76,"path":72,"stem":77},{"title":79,"path":80,"stem":81,"children":2937},[2938,2939],{"title":79,"path":80,"stem":81},{"title":85,"path":86,"stem":87,"children":2940},[2941],{"title":85,"path":86,"stem":87},{"title":91,"path":92,"stem":93,"children":2943},[2944,2945],{"title":91,"path":92,"stem":93},{"title":97,"path":98,"stem":99,"children":2946},[2947],{"title":97,"path":98,"stem":99},{"title":103,"path":104,"stem":105,"children":2949},[2950],{"title":103,"path":104,"stem":105},{"title":109,"path":110,"stem":111,"children":2952},[2953,2954,2957],{"title":109,"path":110,"stem":111},{"title":115,"path":116,"stem":117,"children":2955},[2956],{"title":115,"path":116,"stem":117},{"title":121,"path":122,"stem":123,"children":2958},[2959],{"title":121,"path":122,"stem":123},{"title":127,"path":128,"stem":129,"children":2961},[2962,2963,2966],{"title":127,"path":128,"stem":129},{"title":133,"path":134,"stem":135,"children":2964},[2965],{"title":133,"path":134,"stem":135},{"title":139,"path":140,"stem":141,"children":2967},[2968],{"title":139,"path":140,"stem":141},{"title":145,"path":146,"stem":147,"children":2970},[2971,2972],{"title":145,"path":146,"stem":147},{"title":151,"path":152,"stem":153,"children":2973},[2974],{"title":151,"path":152,"stem":153},1778094796151]