Merged in feat/STAY-140-stepper-accesible (pull request #3432)
feat(STAY-140): make Stepper more accessible * feat(STAY-140): make Stepper more accessible * fix(STAY-140): add aria-valuetext Approved-by: Bianca Widstam
This commit is contained in:
@@ -4,7 +4,7 @@ import { useIntl } from "react-intl"
|
|||||||
|
|
||||||
import { Divider } from "@scandic-hotels/design-system/Divider"
|
import { Divider } from "@scandic-hotels/design-system/Divider"
|
||||||
import { Radio } from "@scandic-hotels/design-system/Radio"
|
import { Radio } from "@scandic-hotels/design-system/Radio"
|
||||||
import Stepper from "@scandic-hotels/design-system/Stepper"
|
import { Stepper } from "@scandic-hotels/design-system/Stepper"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import styles from "./paymentOption.module.css"
|
import styles from "./paymentOption.module.css"
|
||||||
@@ -116,26 +116,39 @@ function InnerPaymentOption({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{selected && (
|
{selected && (
|
||||||
<Stepper
|
<>
|
||||||
count={quantity}
|
<span id="stepper-quantity-label" className="sr-only">
|
||||||
handleOnIncrease={handleOnIncrease}
|
{intl.formatMessage({
|
||||||
handleOnDecrease={handleOnDecrease}
|
id: "ancillaries.label.quantity",
|
||||||
disableDecrease={quantity <= 0}
|
defaultMessage: "Quantity",
|
||||||
disableIncrease={hasReachedMax || quantity >= MAX_NR_ITEMS}
|
})}
|
||||||
disabledMessage={
|
</span>
|
||||||
hasReachedMax
|
<Stepper
|
||||||
? intl.formatMessage({
|
count={quantity}
|
||||||
id: "myPages.myStay.ancillaries.reachedMaxPointsStepperMessage",
|
label={intl.formatMessage({
|
||||||
defaultMessage:
|
id: "ancillaries.label.quantity",
|
||||||
"You’ve reached your points limit and can’t add more items with points.",
|
defaultMessage: "Quantity",
|
||||||
})
|
})}
|
||||||
: intl.formatMessage({
|
ariaLabelledBy="stepper-quantity-label"
|
||||||
id: "myPages.myStay.ancillaries.reachedMaxItemsStepperMessage",
|
handleOnIncrease={handleOnIncrease}
|
||||||
defaultMessage:
|
handleOnDecrease={handleOnDecrease}
|
||||||
"Maximum quantity reached for this item.",
|
disableDecrease={quantity <= 0}
|
||||||
})
|
disableIncrease={hasReachedMax || quantity >= MAX_NR_ITEMS}
|
||||||
}
|
disabledMessage={
|
||||||
/>
|
hasReachedMax
|
||||||
|
? intl.formatMessage({
|
||||||
|
id: "myPages.myStay.ancillaries.reachedMaxPointsStepperMessage",
|
||||||
|
defaultMessage:
|
||||||
|
"You’ve reached your points limit and can’t add more items with points.",
|
||||||
|
})
|
||||||
|
: intl.formatMessage({
|
||||||
|
id: "myPages.myStay.ancillaries.reachedMaxItemsStepperMessage",
|
||||||
|
defaultMessage:
|
||||||
|
"Maximum quantity reached for this item.",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { type ReactNode } from "react"
|
|
||||||
import { RadioGroup } from "react-aria-components"
|
import { RadioGroup } from "react-aria-components"
|
||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
@@ -19,6 +18,8 @@ import { NotEnoughPointsBanner, PaymentOption } from "./PaymentOption"
|
|||||||
|
|
||||||
import styles from "./selectQuantityStep.module.css"
|
import styles from "./selectQuantityStep.module.css"
|
||||||
|
|
||||||
|
import type { ReactNode } from "react"
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
InnerSelectQuantityStepProps,
|
InnerSelectQuantityStepProps,
|
||||||
SelectQuantityStepProps,
|
SelectQuantityStepProps,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import Stepper from "@scandic-hotels/design-system/Stepper"
|
import { Stepper } from "@scandic-hotels/design-system/Stepper"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import styles from "./adult-selector.module.css"
|
import styles from "./adult-selector.module.css"
|
||||||
@@ -42,10 +42,12 @@ export default function AdultSelector({
|
|||||||
variant="Body/Supporting text (caption)/smBold"
|
variant="Body/Supporting text (caption)/smBold"
|
||||||
className={styles.label}
|
className={styles.label}
|
||||||
>
|
>
|
||||||
<p>{adultsLabel}</p>
|
<p id="stepper-adults-label">{adultsLabel}</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Stepper
|
<Stepper
|
||||||
count={currentAdults}
|
count={currentAdults}
|
||||||
|
label={adultsLabel}
|
||||||
|
ariaLabelledBy="stepper-adults-label"
|
||||||
handleOnDecrease={decreaseAdultsCount}
|
handleOnDecrease={decreaseAdultsCount}
|
||||||
handleOnIncrease={increaseAdultsCount}
|
handleOnIncrease={increaseAdultsCount}
|
||||||
disableDecrease={currentAdults == 1}
|
disableDecrease={currentAdults == 1}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useRef } from "react"
|
|||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { useIntl } from "react-intl"
|
import { useIntl } from "react-intl"
|
||||||
|
|
||||||
import Stepper from "@scandic-hotels/design-system/Stepper"
|
import { Stepper } from "@scandic-hotels/design-system/Stepper"
|
||||||
import { Typography } from "@scandic-hotels/design-system/Typography"
|
import { Typography } from "@scandic-hotels/design-system/Typography"
|
||||||
|
|
||||||
import ChildInfoSelector from "./ChildInfoSelector"
|
import ChildInfoSelector from "./ChildInfoSelector"
|
||||||
@@ -61,9 +61,11 @@ export default function ChildSelector({
|
|||||||
variant="Body/Supporting text (caption)/smBold"
|
variant="Body/Supporting text (caption)/smBold"
|
||||||
className={styles.label}
|
className={styles.label}
|
||||||
>
|
>
|
||||||
<p>{childrenLabel}</p>
|
<p id="stepper-children-label">{childrenLabel}</p>
|
||||||
</Typography>
|
</Typography>
|
||||||
<Stepper
|
<Stepper
|
||||||
|
label={childrenLabel}
|
||||||
|
ariaLabelledBy="stepper-children-label"
|
||||||
count={currentChildren.length}
|
count={currentChildren.length}
|
||||||
handleOnDecrease={() => {
|
handleOnDecrease={() => {
|
||||||
decreaseChildrenCount(roomIndex)
|
decreaseChildrenCount(roomIndex)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { useIntl } from "react-intl"
|
||||||
import { IconButton } from "../IconButton"
|
import { IconButton } from "../IconButton"
|
||||||
import { Tooltip } from "../Tooltip"
|
import { Tooltip } from "../Tooltip"
|
||||||
import { Typography } from "../Typography"
|
import { Typography } from "../Typography"
|
||||||
@@ -6,6 +7,8 @@ import styles from "./stepper.module.css"
|
|||||||
|
|
||||||
type StepperProps = {
|
type StepperProps = {
|
||||||
count: number
|
count: number
|
||||||
|
label: string
|
||||||
|
ariaLabelledBy: string
|
||||||
handleOnIncrease: () => void
|
handleOnIncrease: () => void
|
||||||
handleOnDecrease: () => void
|
handleOnDecrease: () => void
|
||||||
disableIncrease: boolean
|
disableIncrease: boolean
|
||||||
@@ -13,28 +16,56 @@ type StepperProps = {
|
|||||||
disabledMessage?: string
|
disabledMessage?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Stepper({
|
export function Stepper({
|
||||||
count,
|
count,
|
||||||
|
label,
|
||||||
|
ariaLabelledBy,
|
||||||
handleOnIncrease,
|
handleOnIncrease,
|
||||||
handleOnDecrease,
|
handleOnDecrease,
|
||||||
disableIncrease,
|
disableIncrease,
|
||||||
disableDecrease,
|
disableDecrease,
|
||||||
disabledMessage,
|
disabledMessage,
|
||||||
}: StepperProps) {
|
}: StepperProps) {
|
||||||
|
const intl = useIntl()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.counterContainer}>
|
<div
|
||||||
|
role="group"
|
||||||
|
aria-labelledby={ariaLabelledBy}
|
||||||
|
className={styles.counterContainer}
|
||||||
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
type="button"
|
||||||
className={styles.counterBtn}
|
className={styles.counterBtn}
|
||||||
onPress={handleOnDecrease}
|
onPress={handleOnDecrease}
|
||||||
variant="Elevated"
|
variant="Elevated"
|
||||||
isDisabled={disableDecrease}
|
isDisabled={disableDecrease}
|
||||||
iconName="remove"
|
iconName="remove"
|
||||||
|
aria-label={intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: "designSystem.stepper.ariaLabel.decrease",
|
||||||
|
defaultMessage: "Decrease {label}",
|
||||||
|
},
|
||||||
|
{ label }
|
||||||
|
)}
|
||||||
|
aria-valuetext={intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: "designSystem.stepper.ariaLabel.currentCount",
|
||||||
|
defaultMessage: "Current {label} {count}",
|
||||||
|
},
|
||||||
|
{ label, count }
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<div className={styles.countDisplay}>
|
<Typography variant="Body/Paragraph/mdRegular">
|
||||||
<Typography variant="Body/Paragraph/mdRegular">
|
<span
|
||||||
<p>{count}</p>
|
aria-live="polite"
|
||||||
</Typography>
|
aria-atomic="true"
|
||||||
</div>
|
className={styles.countDisplay}
|
||||||
|
>
|
||||||
|
{count}
|
||||||
|
</span>
|
||||||
|
</Typography>
|
||||||
|
|
||||||
<Tooltip
|
<Tooltip
|
||||||
text={disabledMessage}
|
text={disabledMessage}
|
||||||
isVisible={Boolean(disabledMessage && disableIncrease)}
|
isVisible={Boolean(disabledMessage && disableIncrease)}
|
||||||
@@ -43,11 +74,26 @@ export default function Stepper({
|
|||||||
isTouchable
|
isTouchable
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
type="button"
|
||||||
className={styles.counterBtn}
|
className={styles.counterBtn}
|
||||||
onPress={handleOnIncrease}
|
onPress={handleOnIncrease}
|
||||||
variant="Elevated"
|
variant="Elevated"
|
||||||
isDisabled={disableIncrease}
|
isDisabled={disableIncrease}
|
||||||
iconName="add"
|
iconName="add"
|
||||||
|
aria-label={intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: "designSystem.stepper.ariaLabel.increase",
|
||||||
|
defaultMessage: "Increase {label}",
|
||||||
|
},
|
||||||
|
{ label }
|
||||||
|
)}
|
||||||
|
aria-valuetext={intl.formatMessage(
|
||||||
|
{
|
||||||
|
id: "designSystem.stepper.ariaLabel.currentCount",
|
||||||
|
defaultMessage: "Current {label} {count}",
|
||||||
|
},
|
||||||
|
{ label, count }
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
gap: var(--Space-x1);
|
gap: var(--Space-x1);
|
||||||
color: var(--Text-Interactive-Default);
|
color: var(--Text-Interactive-Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
.counterBtn {
|
.counterBtn {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|||||||
Reference in New Issue
Block a user