Skip to content
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

Replace trip sort select with accessible dropdown #897

Merged
merged 12 commits into from
Jun 5, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion i18n/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ components:
selectDepartureTime: Departure time
selectDuration: Duration
selectWalkTime: Walk time
sortBy: Sort By
sortResults: Sort results
viewAll: View all options
NavLoginButton:
help: Help
Expand Down
30 changes: 10 additions & 20 deletions i18n/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ actions:
No se puede guardar el plan: este plan no se pudo guardar debido a la
falta de capacidad en uno o más vehículos. Por favor, vuelva a planificar
su viaje.
maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados
válidos
maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados válidos
saveItinerariesError: "No se pudieron guardar los itinerarios: {err}"
setDateError: "Error al establecer la fecha:"
setGroupSizeError: "No se pudo establecer el tamaño del grupo:"
Expand All @@ -47,11 +46,9 @@ actions:
authTokenError: Error al obtener un token de autorización.
confirmDeleteMonitoredTrip: ¿Desea eliminar este viaje?
confirmDeletePlace: ¿Quiere eliminar este lugar?
emailVerificationResent: El mensaje de verificación de correo electrónico ha sido
reenviado.
emailVerificationResent: El mensaje de verificación de correo electrónico ha sido reenviado.
genericError: "Se ha encontrado un error: {err}"
itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado
es posible.
itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado es posible.
preferencesSaved: Sus preferencias se han guardado.
smsInvalidCode: El código introducido no es válido. Por favor, inténtelo de nuevo.
smsResendThrottled: >-
Expand Down Expand Up @@ -113,6 +110,7 @@ common:
{co2} de CO₂ en {isMore, select, true {más} other {menos} } que conducir
solo
transfers: "{transfers, plural, =0 {} one {# transferencia} other {# transferencias}}"
linkOpensNewWindow: (Abre una nueva ventana)
modes:
bicycle_rent: Compartir bicicleta
bike: Bicicleta
Expand Down Expand Up @@ -160,7 +158,6 @@ common:
tripDurationFormat: >-
{hours, plural, =0 {} other {# h }}{minutes} min { seconds, plural, =0 {}
other {# s}}
linkOpensNewWindow: (Abre una nueva ventana)
components:
A11yPrefs:
accessibilityRoutingByDefault: Prefiera los viajes accesibles por defecto
Expand Down Expand Up @@ -237,8 +234,7 @@ components:
origin: origen
planTripTooltip: Planificar viaje
settings: Preferencias de viaje
validationMessage: "Por favor, defina los siguientes campos para planificar un\
\ viaje: {issues}"
validationMessage: "Por favor, defina los siguientes campos para planificar un viaje: {issues}"
BeforeSignInScreen:
mainTitle: Iniciando sesión
message: >
Expand Down Expand Up @@ -348,7 +344,6 @@ components:
selectDepartureTime: Hora de salida
selectDuration: Duración
selectWalkTime: Tiempo de caminata
sortBy: Ordenar por
viewAll: Ver todas las opciones
NavLoginButton:
help: Ayuda
Expand All @@ -368,8 +363,7 @@ components:
description: Puede recibir notificaciones sobre los viajes que realiza con frecuencia.
noneSelect: No enviar notificaciones
notificationChannelPrompt: ¿Cómo desea recibir las notificaciones?
notificationEmailDetail: "Los correos electrónicos de notificación se enviarán\
\ a:"
notificationEmailDetail: "Los correos electrónicos de notificación se enviarán a:"
PhoneNumberEditor:
changeNumber: Cambiar número de teléfono
invalidCode: Introduzca 6 dígitos para el código de validación.
Expand Down Expand Up @@ -502,8 +496,7 @@ components:
Opciones
y Preferencias del viaje
SimpleRealtimeAnnotation:
usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo
real
usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo real
StackedPaneDisplay:
savePreferences: Guardar preferencias
StopScheduleTable:
Expand Down Expand Up @@ -565,19 +558,16 @@ components:
travelingAt: Viajando a {milesPerHour}
vehicleName: Vehículo {vehicleNumber}
TripBasicsPane:
checkingItineraryExistence: Comprobación de la existencia de itinerarios para
cada día de la semana…
checkingItineraryExistence: Comprobación de la existencia de itinerarios para cada día de la semana…
selectAtLeastOneDay: Por favor, seleccione al menos un día para el seguimiento.
tripDaysPrompt: ¿Qué días hace este viaje?
tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana
indicados anteriormente.
tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana indicados anteriormente.
tripNamePrompt: "Por favor, indique un nombre para este viaje:"
tripNotAvailableOnDay: El viaje no está disponible el {repeatedDay}
unsavedChangesExistingTrip: >-
Todavía no ha guardado su viaje. Si abandona la página, los cambios se
perderán.
unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página,
se perderá.
unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, se perderá.
TripNotificationsPane:
advancedSettings: Configuración avanzada
altRouteRecommended: Se recomienda una ruta alternativa o un punto de transferencia
Expand Down
1 change: 0 additions & 1 deletion i18n/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@ components:
selectDepartureTime: Heure de départ
selectDuration: Durée
selectWalkTime: Temps de marche
sortBy: Trier par
viewAll: Toutes les options
NavLoginButton:
help: Aide
Expand Down
1 change: 0 additions & 1 deletion i18n/ko.yml
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ components:
selectDepartureTime: 출발 시각
selectDuration: 기간
selectWalkTime: 도보 시간
sortBy: 정렬 기준
viewAll: 모든 옵션 보기
NavLoginButton:
help: 지원
Expand Down
1 change: 0 additions & 1 deletion i18n/vi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,6 @@ components:
selectDepartureTime: Giờ khởi hành
selectDuration: Thời hạn
selectWalkTime: Thời gian đi bộ
sortBy: Sắp xếp theo
viewAll: Xem tất cả các tùy chọn
NavLoginButton:
help: Giúp đỡ
Expand Down
1 change: 0 additions & 1 deletion i18n/zh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ components:
selectDepartureTime: 出发时间
selectDuration: 旅行时长
selectWalkTime: 步行时间
sortBy: 排序方式
viewAll: 查看所有选项
NavLoginButton:
help: 帮助
Expand Down
1 change: 1 addition & 0 deletions lib/components/app/locale-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const LocaleSelector = (props: LocaleSelectorProps): JSX.Element | null => {
id="locale-selector"
label={intl.formatMessage({ id: 'components.SubNav.selectALanguage' })}
listLabel={intl.formatMessage({ id: 'components.SubNav.languages' })}
locale
name={
<span
style={{
Expand Down
63 changes: 22 additions & 41 deletions lib/components/narrative/narrative-itineraries-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import React from 'react'
import styled from 'styled-components'

import { IconWithText, StyledIconWrapper } from '../util/styledIcon'
import { sortOptions } from '../util/sortOptions'
import { UnstyledButton } from '../util/unstyled-button'
import Dropdown from '../util/dropdown'
import InvisibleA11yLabel from '../util/invisible-a11y-label'


amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
import PlanFirstLastButtons from './plan-first-last-buttons'
import SaveTripButton from './save-trip-button'

Expand Down Expand Up @@ -44,7 +48,7 @@ export default function NarrativeItinerariesHeader({
itineraries: unknown[]
itinerary: Itinerary
itineraryIsExpanded: boolean
onSortChange: () => void
onSortChange: (type: string) => VoidFunction
onSortDirChange: () => void
onToggleShowErrors: () => void
onViewAllOptions: () => void
Expand Down Expand Up @@ -146,7 +150,7 @@ export default function NarrativeItinerariesHeader({
style={{
display: 'flex',
float: 'right',
gap: 5,
gap: 7,
marginLeft: showHeaderText ? 'inherit' : 'auto'
}}
>
Expand All @@ -172,48 +176,25 @@ export default function NarrativeItinerariesHeader({
)}
</StyledIconWrapper>
</button>
<select
aria-label={intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.sortBy'
<Dropdown
id="sort-results"
label={intl.formatMessage({
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
id: 'components.NarrativeItinerariesHeader.sortResults'
})}
onBlur={onSortChange}
onChange={onSortChange}
title={intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.sortBy'
name={intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.sortResults'
})}
value={sort.type}
>
<option value="BEST">
{intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.selectBest'
})}
</option>
<option value="DURATION">
{intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.selectDuration'
})}
</option>
<option value="ARRIVALTIME">
{intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.selectArrivalTime'
})}
</option>
<option value="DEPARTURETIME">
{intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.selectDepartureTime'
})}
</option>
<option value="WALKTIME">
{intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.selectWalkTime'
})}
</option>
<option value="COST">
{intl.formatMessage({
id: 'components.NarrativeItinerariesHeader.selectCost'
})}
</option>
</select>
{sortOptions.map((x) => {
return (
<li key={x.value}>
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
<UnstyledButton onClick={() => onSortChange(x.value)}>
<FormattedMessage id={x.locale} />
</UnstyledButton>
</li>
miles-grant-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
)
})}
</Dropdown>
</div>
<PlanFirstLastButtons />
</>
Expand Down
3 changes: 1 addition & 2 deletions lib/components/narrative/narrative-itineraries.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ class NarrativeItineraries extends Component {
setActiveLeg(null, null)
}

_onSortChange = (evt) => {
const { value: type } = evt.target
_onSortChange = (type) => {
const { sort, updateItineraryFilter } = this.props
updateItineraryFilter({ sort: { ...sort, type } })
}
Expand Down
8 changes: 7 additions & 1 deletion lib/components/narrative/narrative.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
}

.otp .options > .header {
margin: 12px 10px;
margin: 15px 25px;
font-size: 16px;
}

@media (max-width: 768px) {
.otp .options > .header {
margin: 1em;
}
}

/* Options scroll bar */
.otp .options > .list::-webkit-scrollbar {
width: 10px;
Expand Down
22 changes: 17 additions & 5 deletions lib/components/util/dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,28 @@ interface Props extends HTMLAttributes<HTMLElement> {
id: string
label?: string
listLabel?: string
name: JSX.Element
locale?: boolean
name: JSX.Element | string
pullRight?: boolean
}

// TODO: make this a button once bootstrap is removed
const DropdownButton = styled.a`
const DropdownButton = styled.a<{ locale?: boolean }>`
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
border: none;
border-radius: ${(props) => (props.locale ? '' : '5px')};
color: inherit;
display: block;
padding: ${(props) => (props.locale ? '' : '3px 7px;')};
transition: all 0.1s ease-in-out;

&:hover {
background: rgba(0, 0, 0, 0.05) !important;
background: ${(props) =>
props.locale ? 'rgba(0, 0, 0, 0.05) !important' : '#fff'};
cursor: pointer;
}
&.active {
background: rgba(0, 0, 0, 0.1) !important;
background: ${(props) =>
props.locale ? 'rgba(0, 0, 0, 0.05) !important' : '#fff'};
}
`
const DropdownMenu = styled.ul`
Expand Down Expand Up @@ -101,6 +106,7 @@ const Dropdown = ({
id,
label,
listLabel,
locale,
name,
pullRight,
style
Expand Down Expand Up @@ -158,10 +164,14 @@ const Dropdown = ({

return (
<DropdownContainer
as={!locale ? 'span' : ''}
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
id={`${id}-wrapper`}
onKeyDown={_handleKeyDown}
ref={containerRef}
style={{ float: pullRight ? 'right' : 'left' }}
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
style={{
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
float: pullRight ? 'right' : 'left',
position: locale ? 'inherit' : 'relative'
}}
>
<DropdownButton
// Only set aria-controls when the dropdown is open
Expand All @@ -170,8 +180,10 @@ const Dropdown = ({
aria-expanded={open}
aria-haspopup="listbox"
aria-label={label}
as={!locale ? 'button' : ''}
className={`${open && 'active'}`}
id={`${id}-label`}
locale={locale}
onClick={toggleOpen}
role="button"
style={style}
Expand Down
26 changes: 26 additions & 0 deletions lib/components/util/sortOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const sortOptions = [
{
locale: 'components.NarrativeItinerariesHeader.selectBest',
amy-corson-ibigroup marked this conversation as resolved.
Show resolved Hide resolved
value: 'BEST'
},
{
locale: 'components.NarrativeItinerariesHeader.selectDuration',
value: 'DURATION'
},
{
locale: 'components.NarrativeItinerariesHeader.selectArrivalTime',
value: 'ARRIVALTIME'
},
{
locale: 'components.NarrativeItinerariesHeader.selectDepartureTime',
value: 'DEPARTURETIME'
},
{
locale: 'components.NarrativeItinerariesHeader.selectWalkTime',
value: 'WALKTIME'
},
{
locale: 'components.NarrativeItinerariesHeader.selectCost',
value: 'COST'
}
]