Skip to content

Adding accordion for dropdown children #430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions public/app.js

Large diffs are not rendered by default.

15 changes: 10 additions & 5 deletions src/components/Controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,18 @@ export default function Controls({
}}
>
{modes.map(mode => (
<button
<div
className="tsml-dropdown__item"
data-active={state.input.mode === mode}
key={mode}
onClick={e => setMode(e, mode)}
>
{strings.modes[mode]}
</button>
>
<button
className="tsml-dropdown__button"
onClick={e => setMode(e, mode)}
>
{strings.modes[mode]}
</button>
</div>
))}
</div>
)}
Expand Down
86 changes: 63 additions & 23 deletions src/components/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dispatch, Fragment, MouseEvent, SetStateAction } from 'react';
import { Dispatch, Fragment, MouseEvent, SetStateAction, useState } from 'react';

import { useSearchParams } from 'react-router-dom';

Expand All @@ -24,6 +24,21 @@ export default function Dropdown({
const { strings } = useSettings();
const options = state.indexes[filter];
const values = state.input[filter];
const [expanded, setExpanded] = useState<string[]>([]);

//handle expand toggle
const toggleExpanded = (
e: MouseEvent<HTMLButtonElement>,
key: string
) => {
e.preventDefault();
e.stopPropagation();
if (!expanded.includes(key)) {
setExpanded(expanded.concat(key));
} else {
setExpanded(expanded.filter(item => item !== key));
}
}

//set filter: pass it up to parent
const setFilter = (
Expand All @@ -38,7 +53,7 @@ export default function Dropdown({

if (value) {
const index = currentValues.indexOf(value);
if (e.metaKey) {
if (e.metaKey || e.ctrlKey) {
if (index === -1) {
currentValues.push(value);
} else {
Expand Down Expand Up @@ -71,26 +86,45 @@ export default function Dropdown({

const renderDropdownItem = ({ key, name, slugs, children }: Index) => (
<Fragment key={key}>
<button
<div
className="tsml-dropdown__item"
// @ts-expect-error TODO
data-active={values.includes(key)}
onClick={e => setFilter(e, filter, key)}
>
{name}
<span
aria-label={
slugs.length === 1
? strings.match_single
: i18n(strings.match_multiple, {
count: slugs.length,
})
}
>
{slugs.length}
</span>
</button>
<button
className="tsml-dropdown__button"
onClick={e => setFilter(e, filter, key)}
>
{name}
<span
aria-label={
slugs.length === 1
? strings.match_single
: i18n(strings.match_multiple, {
count: slugs.length,
})
}
>
{slugs.length}
</span>
</button>
{!!children?.length && (
<button
className="tsml-dropdown__expand"
data-expanded={expanded.includes(key)}
onClick={(e) => toggleExpanded(e, key)}
aria-label={expanded.includes(key) ? strings.collapse : strings.expand}
>
</button>
)}
</div>
{!!children?.length && (
<div>{children.map(child => renderDropdownItem(child))}</div>
<div
className="tsml-dropdown__children"
data-expanded={expanded.includes(key)}
>
{children.map(child => renderDropdownItem(child))}
</div>
)}
</Fragment>
);
Expand All @@ -117,14 +151,20 @@ export default function Dropdown({
</button>
<div
aria-labelledby={filter}
className="tsml-dropdown"
style={{ display: open ? 'block' : 'none' }}
>
<button
<div
data-active={!values.length}
onClick={e => setFilter(e, filter, undefined)}
>
{defaultValue}
</button>
className="tsml-dropdown__item"
>
<button
className="tsml-dropdown__button"
onClick={e => setFilter(e, filter, undefined)}
>
{defaultValue}
</button>
</div>
{[
options
?.filter(option =>
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const en: Translation = {
address: 'Address / Platform',
appointment: 'Appointment',
back_to_meetings: 'Back to Meetings',
collapse: 'Collapse',
contact_email: 'Email %contact%',
contact_text: 'Text %contact%',
contribute_with: 'Contribute with %service%',
Expand All @@ -25,6 +26,7 @@ export const en: Translation = {
email_public_url: 'Public URL: %url%',
email_subject: 'Meeting Feedback: %name%',
evening: 'Evening',
expand: 'Expand',
feedback: 'Update Meeting Info',
get_directions: 'Get Directions',
in_progress_single: '1 meeting in progress',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const es: Translation = {
address: 'Dirección',
appointment: 'Cita',
back_to_meetings: 'Volver a las reuniones',
collapse: 'Colapso',
contact_email: 'Correo a %contact%',
contact_text: 'Texto %contact%',
contribute_with: 'Contribuya con %service%',
Expand All @@ -25,6 +26,7 @@ export const es: Translation = {
email_public_url: 'URL pública: %url%',
email_subject: 'Comentarios de la reunión: %name%',
evening: 'Noche',
expand: 'Expandir',
feedback: 'Actualizar la información de la reunión',
get_directions: 'Obtener las direcciones',
in_progress_single: '1 reunión en curso',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const fr: Translation = {
address: 'Adresse',
appointment: 'Rendez-vous',
back_to_meetings: 'Retour aux réunions',
collapse: 'Développer',
contact_email: 'E-mail à %contact%',
contact_text: 'Texte %contact%',
contribute_with: 'Contribuer avec %service%',
Expand All @@ -25,6 +26,7 @@ export const fr: Translation = {
email_public_url: 'URL publique : %url%',
email_subject: 'Commentaires sur la réunion : %name%',
evening: 'Soir',
expand: 'Effondrement',
feedback: 'Mettre à jour les informations sur la réunion',
get_directions: 'Obtenir des itinéraires',
in_progress_single: '1 réunion en cours',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const ja: Translation = {
address: '住所・プラットフォーム',
appointment: '予定',
back_to_meetings: 'ミーティング一覧へ戻る',
collapse: "膨らむ",
contact_email: '%contact%にメール',
contact_text: '%contact%にテキスト',
contribute_with: '%service% で献金する',
Expand All @@ -25,6 +26,7 @@ export const ja: Translation = {
email_public_url: '公開URLの掲載依頼をメール: %url%',
email_subject: 'メールする: %name%',
evening: '夕方',
expand: '倒れる',
feedback: 'ミーティング情報の更新',
get_directions: '行き方を調べる',
in_progress_single: '1件のミーティングが進行中です',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const nl: Translation = {
address: 'Addres',
appointment: 'Afspraak',
back_to_meetings: 'Terug naar Meetings',
collapse: 'Instorting',
contact_email: 'E-mail %contact%',
contact_text: 'Tekst %contact%',
contribute_with: 'Bijdragen aan %service%',
Expand All @@ -25,6 +26,7 @@ export const nl: Translation = {
email_public_url: 'Publieke URL: %url%',
email_subject: 'Meeting Feedback: %name%',
evening: 'Avond',
expand: 'Uitbreiden',
feedback: 'Update Meeting Info',
get_directions: 'Krijg Routebeschrijving',
in_progress_single: '1 meeting bezig',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const pt: Translation = {
address: 'Endereço / Plataforma',
appointment: 'Marcação',
back_to_meetings: 'Voltar às Reuniões',
collapse: 'Colapso',
contact_email: 'Email %contact%',
contact_text: 'Texto %contact%',
contribute_with: 'Contribuir com %service%',
Expand All @@ -25,6 +26,7 @@ export const pt: Translation = {
email_public_url: 'URL Público: %url%',
email_subject: 'Feedback da Reunião: %name%',
evening: 'Fim do Dia',
expand: 'Expandir',
feedback: 'Atualizar Informações da Reunião',
get_directions: 'Obter Direcções',
in_progress_single: '1 reunião em progresso',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/sk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const sk: Translation = {
address: 'Adresa / Platforma',
appointment: 'Stretnutie',
back_to_meetings: 'Späť na Stretnutia',
collapse: 'Kolaps',
contact_email: 'Emailovať %contact%',
contact_text: 'Text %contact%',
contribute_with: 'Prispejte spolu s %service%',
Expand All @@ -25,6 +26,7 @@ export const sk: Translation = {
email_public_url: 'Verejná URL: %url%',
email_subject: 'Spätná väzba na stretnutie: %name%',
evening: 'Večer',
expand: 'Rozšíriť',
feedback: 'Aktualizovať informácie o stretnutí',
get_directions: 'Zobraziť trasu',
in_progress_single: '1 stretnutie práve prebieha',
Expand Down
2 changes: 2 additions & 0 deletions src/i18n/sv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const sv: Translation = {
address: 'Adress / Plattform',
appointment: 'Tidsbeställning',
back_to_meetings: 'Tillbaka till möten',
collapse: 'Kollaps',
contact_email: 'Maila %contact%',
contact_text: 'Sms:a %contact%',
contribute_with: 'Bidra med %service%',
Expand All @@ -25,6 +26,7 @@ export const sv: Translation = {
email_public_url: 'Publik URL: %url%',
email_subject: 'Mötes Feedback: %name%',
evening: 'Kväll',
expand: 'Expandera',
feedback: 'Uppdatera Mötesinformation',
get_directions: 'Få Vägbeskrivning',
in_progress_single: '1 möte pågår',
Expand Down
Loading
Loading