Merged in fix/book-115-hidden-focus-indicators (pull request #2925)

Fix/book 115 hidden focus indicators

* added focus ring to "how it works" text and close button in modal

* fix(BOOK-115): added focus ring to Hotel Sidepeek close button

* fix(BOOK-115): enabled selecting ancillaries with keyboard nav

* fix(BOOK-115): added focus indicator to "View and print receipt" in Manage Stay

* fix(BOOK-105 & BOOK-115): combined the two radio groups in payment selection to one, fixes focus indicator issue

* fix(BOOK-115): added focus indicator to shortcut links

* fix(BOOK-115): updated ancillaries keyboard selection

* fix(BOOK-115): removed tabIndex from Link component

* fix(BOOK-115): fixed single payment radio button not focusable

* fix(BOOK-115): updated  to onKeyDown

* added id to "credit card"

* removed toUpperCase() on lables

* removed brackets

* moved the focus indicator to the DS Button component

* removed !important from ButtonLink css

* changed <label> to <fieldset> and <legend> and added aria-label to PaymentOptionGroup

* removed css class from sidepeek that was previously removed

* reverted changes and synced Guarantee radiogroup with Payment radiogroup to use same semantics

* removed duplicate label

* removed old sub heading


Approved-by: Erik Tiekstra
This commit is contained in:
Matilda Haneling
2025-11-07 07:58:14 +00:00
parent fdf124bd0c
commit 2d237b8d14
14 changed files with 124 additions and 121 deletions

View File

@@ -2,7 +2,6 @@
import { Label, RadioGroup } from 'react-aria-components'
import { useController, useFormContext } from 'react-hook-form'
import type { ReactNode } from 'react'
import { Typography } from '../../../components/Typography'
@@ -11,6 +10,7 @@ interface PaymentOptionsGroupProps {
label?: string
children: ReactNode
className?: string
initalValue?: string
onChange?: (newValue: string) => void
}
@@ -20,6 +20,7 @@ export function PaymentOptionsGroup({
children,
className,
onChange,
initalValue,
}: PaymentOptionsGroupProps) {
const { control } = useFormContext()
@@ -36,7 +37,11 @@ export function PaymentOptionsGroup({
}
return (
<RadioGroup value={value} onChange={handleChange} className={className}>
<RadioGroup
value={initalValue || value}
onChange={handleChange}
className={className}
>
{label ? (
<Typography variant="Title/Overline/sm">
<Label>{label}</Label>

View File

@@ -1,7 +1,9 @@
import { useIntl } from 'react-intl'
import { Label } from 'react-aria-components'
import { PaymentOptionsGroup } from '../PaymentOption/PaymentOptionsGroup'
import { PaymentOption } from '../PaymentOption/PaymentOption'
import { Typography } from '../../../components/Typography'
import styles from './selectPaymentMethod.module.css'
@@ -29,34 +31,71 @@ export function SelectPaymentMethod({
formName,
}: SelectPaymentMethodProps) {
const intl = useIntl()
const mySavedCardsLabel = intl.formatMessage({
id: 'payment.mySavedCards',
defaultMessage: 'My saved cards',
})
const mySavedCardsLabel = paymentMethods.length
? intl.formatMessage({
id: 'payment.mySavedCards',
defaultMessage: 'My saved cards',
})
: undefined
const otherCardLabel = paymentMethods.length
? intl.formatMessage({
id: 'common.other',
defaultMessage: 'Other',
})
: undefined
const hasSavedCards = paymentMethods.length > 0
return (
<section className={styles.section}>
<PaymentOptionsGroup
name={formName}
label={mySavedCardsLabel}
className={styles.paymentOptionContainer}
onChange={onChange}
initalValue={
//set credit card as default checked if user has no saved cards
!hasSavedCards ? PAYMENT_METHOD_TITLES.card : undefined
}
>
{paymentMethods?.map((paymentMethods) => {
const label =
PAYMENT_METHOD_TITLES[paymentMethods.cardType] ||
paymentMethods.alias ||
paymentMethods.cardType
<Label className="sr-only">
{intl.formatMessage({
id: 'enterDetails.guarantee.cardOptions',
defaultMessage: 'Card options',
})}
</Label>
{hasSavedCards ? (
<>
<Typography variant="Title/Overline/sm">
<span>{mySavedCardsLabel}</span>
</Typography>
{paymentMethods?.map((paymentMethods) => {
const label =
PAYMENT_METHOD_TITLES[paymentMethods.cardType] ||
paymentMethods.alias ||
paymentMethods.cardType
return (
<PaymentOption
key={paymentMethods.id}
value={paymentMethods.id as PaymentMethodEnum}
label={label}
cardNumber={paymentMethods.truncatedNumber}
/>
)
})}
return (
<PaymentOption
key={paymentMethods.id}
value={paymentMethods.id as PaymentMethodEnum}
label={label}
cardNumber={paymentMethods.truncatedNumber}
/>
)
})}
<Typography variant="Title/Overline/sm">
<span>{otherCardLabel}</span>
</Typography>
</>
) : null}
<PaymentOption
value={PAYMENT_METHOD_TITLES.card as PaymentMethodEnum}
label={intl.formatMessage({
id: 'common.creditCard',
defaultMessage: 'Credit card',
})}
/>
</PaymentOptionsGroup>
</section>
)