1+ const container = document . querySelector ( '#tabs' )
2+ const primary = container . querySelector ( '.primary' )
3+ const primaryItems = container . querySelectorAll ( '.primary > li:not(.-more)' )
4+ container . classList . add ( 'has-js' )
5+
6+ // insert "more" button and duplicate the list
7+
8+ primary . insertAdjacentHTML ( 'beforeend' , `
9+ <li class="-more">
10+ <button type="button" aria-haspopup="true" aria-expanded="false">
11+ More <i class="fa-light fa-chevron-down"></i>
12+ </button>
13+ <ul class="-secondary">
14+ ${ primary . innerHTML }
15+ </ul>
16+ </li>
17+ ` )
18+ const secondary = container . querySelector ( '.-secondary' )
19+ const secondaryItems = secondary . querySelectorAll ( 'li' )
20+ const allItems = container . querySelectorAll ( 'li' )
21+ const moreLi = primary . querySelector ( '.-more' )
22+ const moreBtn = moreLi . querySelector ( 'button' )
23+ moreBtn . addEventListener ( 'click' , ( e ) => {
24+ e . preventDefault ( )
25+ container . classList . toggle ( '--show-secondary' )
26+ moreBtn . setAttribute ( 'aria-expanded' , container . classList . contains ( '--show-secondary' ) )
27+ } )
28+
29+ // adapt tabs
30+
31+ const doAdapt = ( ) => {
32+ // reveal all items for the calculation
33+ allItems . forEach ( ( item ) => {
34+ item . classList . remove ( '--hidden' )
35+ } )
36+
37+ // hide items that won't fit in the Primary
38+ let stopWidth = moreBtn . offsetWidth
39+ let hiddenItems = [ ]
40+ const primaryWidth = primary . offsetWidth
41+ primaryItems . forEach ( ( item , i ) => {
42+ if ( primaryWidth >= stopWidth + item . offsetWidth ) {
43+ stopWidth += item . offsetWidth
44+ } else {
45+ item . classList . add ( '--hidden' )
46+ hiddenItems . push ( i )
47+ }
48+ } )
49+
50+ // toggle the visibility of More button and items in Secondary
51+ if ( ! hiddenItems . length ) {
52+ moreLi . classList . add ( '--hidden' )
53+ container . classList . remove ( '--show-secondary' )
54+ moreBtn . setAttribute ( 'aria-expanded' , false )
55+ }
56+ else {
57+ secondaryItems . forEach ( ( item , i ) => {
58+ if ( ! hiddenItems . includes ( i ) ) {
59+ item . classList . add ( '--hidden' )
60+ }
61+ } )
62+ }
63+ }
64+
65+ doAdapt ( ) // adapt immediately on load
66+ window . addEventListener ( 'resize' , doAdapt ) // adapt on window resize
67+
68+ // hide Secondary on the outside click
69+ document . addEventListener ( 'click' , ( e ) => {
70+ let el = e . target
71+ while ( el ) {
72+ if ( el === moreBtn ) {
73+ return ;
74+ }
75+ el = el . parentNode
76+ }
77+ container . classList . remove ( '--show-secondary' )
78+ moreBtn . setAttribute ( 'aria-expanded' , false )
79+ } )
0 commit comments