Skip to content

Commit 577dba5

Browse files
committed
Improve Language Selector dropdowns
1 parent be5c643 commit 577dba5

File tree

3 files changed

+79
-59
lines changed

3 files changed

+79
-59
lines changed

src/components/LanguageSelector.tsx

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -186,43 +186,41 @@ const LanguageSelector = () => {
186186
</div>
187187
<span className="selector__arrow" />
188188
</button>
189-
{isOpen && (
190-
<ul
191-
className="selector__dropdown"
192-
role="listbox"
193-
onKeyDown={handleKeyDown}
194-
tabIndex={-1}
195-
>
196-
{fetchedLanguages.map((lang, index) =>
197-
lang.subLanguages.length > 0 ? (
198-
<SubLanguageSelector
199-
key={lang.name}
200-
opened={openedLanguages.includes(lang)}
201-
parentLanguage={lang}
202-
onDropdownToggle={handleToggleSubLanguage}
203-
handleParentSelect={handleSelect}
204-
afterSelect={afterSelect}
205-
/>
206-
) : (
207-
<li
208-
key={lang.name}
209-
role="option"
210-
tabIndex={-1}
211-
onClick={() => handleSelect(lang)}
212-
className={`selector__item ${
213-
language.name === lang.name ? "selected" : ""
214-
} ${focusedIndex === index ? "focused" : ""}`}
215-
aria-selected={language.name === lang.name}
216-
>
217-
<label>
218-
<img src={lang.icon} alt="" />
219-
<span>{lang.name}</span>
220-
</label>
221-
</li>
222-
)
223-
)}
224-
</ul>
225-
)}
189+
<ul
190+
className={`selector__dropdown ${isOpen ? "" : " hidden"}`}
191+
role="listbox"
192+
onKeyDown={handleKeyDown}
193+
tabIndex={-1}
194+
>
195+
{fetchedLanguages.map((lang, index) =>
196+
lang.subLanguages.length > 0 ? (
197+
<SubLanguageSelector
198+
key={lang.name}
199+
opened={openedLanguages.includes(lang)}
200+
parentLanguage={lang}
201+
onDropdownToggle={handleToggleSubLanguage}
202+
handleParentSelect={handleSelect}
203+
afterSelect={afterSelect}
204+
/>
205+
) : (
206+
<li
207+
key={lang.name}
208+
role="option"
209+
tabIndex={-1}
210+
onClick={() => handleSelect(lang)}
211+
className={`selector__item ${
212+
language.name === lang.name ? "selected" : ""
213+
} ${focusedIndex === index ? "focused" : ""}`}
214+
aria-selected={language.name === lang.name}
215+
>
216+
<label>
217+
<img src={lang.icon} alt="" />
218+
<span>{lang.name}</span>
219+
</label>
220+
</li>
221+
)
222+
)}
223+
</ul>
226224
</div>
227225
);
228226
};

src/components/SubLanguageSelector.tsx

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,24 +78,23 @@ const SubLanguageSelector = ({
7878
</label>
7979
</li>
8080

81-
{opened &&
82-
parentLanguage.subLanguages.map((sl) => (
83-
<li
84-
key={sl.name}
85-
role="option"
86-
tabIndex={-1}
87-
className={`selector__item sublanguage__item ${
88-
slugify(subLanguage) === slugify(sl.name) ? "selected" : ""
89-
}`}
90-
aria-selected={slugify(subLanguage) === slugify(sl.name)}
91-
onClick={handleSubLanguageSelect(sl)}
92-
>
93-
<label>
94-
<img src={sl.icon} alt={sl.name} />
95-
<span>{sl.name}</span>
96-
</label>
97-
</li>
98-
))}
81+
{parentLanguage.subLanguages.map((sl) => (
82+
<li
83+
key={sl.name}
84+
role="option"
85+
tabIndex={-1}
86+
className={`selector__item sublanguage__item ${opened ? "" : "hidden"} ${
87+
slugify(subLanguage) === slugify(sl.name) ? "selected" : ""
88+
}`}
89+
aria-selected={slugify(subLanguage) === slugify(sl.name)}
90+
onClick={handleSubLanguageSelect(sl)}
91+
>
92+
<label>
93+
<img src={sl.icon} alt={sl.name} />
94+
<span>{sl.name}</span>
95+
</label>
96+
</li>
97+
))}
9998
</>
10099
);
101100
};

src/styles/main.css

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ abbr {
400400
border-left: 7px solid transparent;
401401
border-right: 7px solid transparent;
402402
border-top: 7px solid var(--clr-text-primary); /* [1] */
403-
transition: transform 100ms ease;
403+
transition: transform 300ms ease;
404404
}
405405

406406
.selector--open .selector__arrow {
@@ -413,7 +413,7 @@ abbr {
413413

414414
position: absolute;
415415
width: 100%;
416-
max-height: 20rem;
416+
height: 20rem;
417417
overflow-y: auto;
418418

419419
background-color: var(--clr-bg-secondary);
@@ -426,10 +426,15 @@ abbr {
426426

427427
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
428428
z-index: 1;
429+
transition: all 300ms ease;
429430
}
430431

431-
.selector__dropdown:focus-within {
432-
border-color: var(--clr-accent);
432+
.selector__dropdown.hidden {
433+
border: none;
434+
padding: 0;
435+
height: 0;
436+
opacity: 0;
437+
overflow: hidden;
433438
}
434439

435440
.selector__item {
@@ -439,10 +444,19 @@ abbr {
439444
gap: 1rem;
440445
align-items: center;
441446
border-radius: var(--br-md);
447+
transition: all 300ms ease;
442448
}
443449

444450
.sublanguage__item {
451+
height: 3rem;
445452
margin-left: 1.5rem;
453+
transition: all 300ms ease;
454+
}
455+
456+
.sublanguage__item.hidden {
457+
height: 0;
458+
opacity: 0;
459+
overflow: hidden;
446460
}
447461

448462
.sublanguage__button{
@@ -462,6 +476,11 @@ abbr {
462476
transform: rotate(-90deg);
463477
transition: transform 100ms ease;
464478
cursor: pointer;
479+
transition: all 200ms ease;
480+
}
481+
482+
.sublanguage__arrow:hover {
483+
border-top-color: var(--clr-accent);
465484
}
466485

467486
[aria-expanded="true"] .sublanguage__arrow {
@@ -472,6 +491,10 @@ abbr {
472491
border-top-color: var(--clr-text-tertiary);
473492
}
474493

494+
.selector__item.selected .sublanguage__arrow:hover {
495+
border-top-color: var(--clr-text-primary);
496+
}
497+
475498
.selector__item label {
476499
width: 100%;
477500
padding: 0.25em 0.75em;

0 commit comments

Comments
 (0)