feat(SW-706): make eslint rule 'formatjs/no-literal-string-in-jsx' pass

This commit is contained in:
Michael Zetterberg
2025-02-07 06:51:36 +01:00
parent e22fc1f3c8
commit 440e1f92df
393 changed files with 4839 additions and 1554 deletions
@@ -63,7 +63,10 @@ export default function Alert({
{phoneContact.phoneNumber}
</Link>
{phoneContact.footnote ? (
<span>. ({phoneContact.footnote})</span>
<>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span>. ({phoneContact.footnote})</span>
</>
) : null}
</>
) : null}
@@ -35,7 +35,9 @@ export function AncillaryCard({ ancillary }: AncillaryCardProps) {
<div className={styles.price}>
<Body color="uiTextHighContrast">
{ancillary.price.included
? intl.formatMessage({ id: "Included" })
? intl.formatMessage({
defaultMessage: "Included",
})
: priceMsg}
</Body>
@@ -46,7 +48,9 @@ export function AncillaryCard({ ancillary }: AncillaryCardProps) {
</div>
<Body textAlign="right" color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{value} points" },
{
defaultMessage: "{value} points",
},
{
value: ancillary.points,
}
@@ -24,7 +24,9 @@ export function BackToTopButton({
>
<MaterialIcon icon="arrow_upward" color="CurrentColor" />
<span className={styles.backToTopButtonText}>
{intl.formatMessage({ id: "Back to top" })}
{intl.formatMessage({
defaultMessage: "Back to top",
})}
</span>
</ButtonRAC>
)
@@ -11,6 +11,7 @@ import {
OverlayArrow,
Popover,
} from "react-aria-components"
import { useIntl } from "react-intl"
import { MaterialIcon } from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { Typography } from "@scandic-hotels/design-system/Typography"
@@ -31,6 +32,8 @@ export default function Breadcrumbs({
color,
size,
}: BreadcrumbsProps) {
const intl = useIntl()
// using a ref instead to detect when the element is available and forcing a render
const [element, attachRef] = useState<HTMLButtonElement | null>(null)
const [isTooltipDisabled, setIsTooltipDisabled] = useState(false)
@@ -67,7 +70,12 @@ export default function Breadcrumbs({
splitBreadcrumbs(breadcrumbs)
return (
<nav aria-label="Breadcrumbs" className={classNames}>
<nav
aria-label={intl.formatMessage({
defaultMessage: "Breadcrumbs",
})}
className={classNames}
>
<AriaBreadcrumbs className={styles.list}>
<Breadcrumb
href={homeBreadcrumb.href}
@@ -92,6 +100,7 @@ export default function Breadcrumbs({
<Breadcrumb className={styles.mobile}>
<DialogTrigger>
<Typography variant="Label/xsRegular">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<Button className={styles.button}></Button>
</Typography>
<Popover>
@@ -56,13 +56,17 @@ export default function CountrySelect({
setValue(name, country ?? "")
}
const selectCountryLabel = intl.formatMessage({ id: "Select a country" })
const selectCountryLabel = intl.formatMessage({
defaultMessage: "Select a country",
})
const collator = new Intl.Collator(lang)
return (
<div className={`${styles.container} ${className}`} ref={setRef}>
<ComboBox
aria-label={intl.formatMessage({ id: "Select country of residence" })}
aria-label={intl.formatMessage({
defaultMessage: "Select country of residence",
})}
isReadOnly={readOnly}
isRequired={!!registerOptions?.required}
name={field.name}
@@ -1,3 +1,5 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import { describe, expect, test } from "@jest/globals" // importing because of type conflict with globals from Cypress
import { render, screen } from "@testing-library/react"
import { type UserEvent, userEvent } from "@testing-library/user-event"
@@ -61,9 +61,15 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
label: `${day}`,
}))
const dayLabel = intl.formatMessage({ id: "Day" })
const monthLabel = intl.formatMessage({ id: "Month" })
const yearLabel = intl.formatMessage({ id: "Year" })
const dayLabel = intl.formatMessage({
defaultMessage: "Day",
})
const monthLabel = intl.formatMessage({
defaultMessage: "Month",
})
const yearLabel = intl.formatMessage({
defaultMessage: "Year",
})
useEffect(() => {
if (formState.isSubmitting) return
@@ -120,7 +126,9 @@ export default function DateSelect({ name, registerOptions = {} }: DateProps) {
return (
<DatePicker
aria-label={intl.formatMessage({ id: "Select date of birth" })}
aria-label={intl.formatMessage({
defaultMessage: "Select date of birth",
})}
isRequired={!!registerOptions.required}
isInvalid={!formState.isValid}
name={name}
@@ -81,7 +81,9 @@ const Input = forwardRef<HTMLInputElement, InputProps>(function Input(
{fieldState.error && !hideError ? (
<Caption className={styles.error} fontOnly>
<MaterialIcon icon="info" color="Icon/Interactive/Accent" />
{intl.formatMessage({ id: fieldState.error.message })}
{intl.formatMessage({
defaultMessage: fieldState.error.message,
})}
</Caption>
) : null}
</TextField>
@@ -67,8 +67,12 @@ export default function PasswordInput({
label={
label ||
(isNewPassword
? intl.formatMessage({ id: "New password" })
: intl.formatMessage({ id: "Password" }))
? intl.formatMessage({
defaultMessage: "New password",
})
: intl.formatMessage({
defaultMessage: "Password",
}))
}
placeholder={placeholder}
type={
@@ -85,7 +89,13 @@ export default function PasswordInput({
intent="tertiary"
onClick={() => setIsPasswordVisible((value) => !value)}
aria-label={
isPasswordVisible ? "Hide password" : "Show password"
isPasswordVisible
? intl.formatMessage({
defaultMessage: "Hide password",
})
: intl.formatMessage({
defaultMessage: "Show password",
})
}
aria-controls={field.name}
className={styles.toggleButton}
@@ -114,7 +124,9 @@ export default function PasswordInput({
<Caption className={styles.error} fontOnly>
<MaterialIcon icon="info" color="Icon/Feedback/Error" />
{fieldState.error &&
intl.formatMessage({ id: fieldState.error.message })}
intl.formatMessage({
defaultMessage: fieldState.error.message,
})}
</Caption>
) : null}
</TextField>
@@ -148,7 +160,7 @@ function NewPasswordValidation({
case "length":
return intl.formatMessage(
{
id: "{min} to {max} characters",
defaultMessage: "{min} to {max} characters",
},
{
min: 10,
@@ -157,19 +169,30 @@ function NewPasswordValidation({
)
case "hasUppercase":
return intl.formatMessage(
{ id: "{count} uppercase letter" },
{
defaultMessage: "{count} uppercase letter",
},
{ count: 1 }
)
case "hasLowercase":
return intl.formatMessage(
{ id: "{count} lowercase letter" },
{
defaultMessage: "{count} lowercase letter",
},
{ count: 1 }
)
case "hasNumber":
return intl.formatMessage({ id: "{count} number" }, { count: 1 })
return intl.formatMessage(
{
defaultMessage: "{count} number",
},
{ count: 1 }
)
case "hasSpecialChar":
return intl.formatMessage(
{ id: "{count} special character" },
{
defaultMessage: "{count} special character",
},
{ count: 1 }
)
}
@@ -106,7 +106,9 @@ export default function Phone({
data-testid="country-selector"
>
<Label required={!!registerOptions.required} size="small">
{intl.formatMessage({ id: "Country code" })}
{intl.formatMessage({
defaultMessage: "Country code",
})}
</Label>
<span className={styles.selectContainer}>
{props.children}
@@ -54,7 +54,8 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
icon="straighten"
color="Icon/Interactive/Placeholder"
/>
<Caption color="uiTextPlaceholder">{room.size} m2</Caption>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<Caption color="uiTextPlaceholder">{room.size} m²</Caption>
</div>
<div className={styles.iconText}>
<MaterialIcon
@@ -64,7 +65,9 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
/>
<Caption color="uiTextPlaceholder">
{intl.formatMessage(
{ id: "max {seatings} pers" },
{
defaultMessage: "max {seatings} pers",
},
{ seatings: maxSeatings }
)}
</Caption>
@@ -89,7 +92,9 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
</Caption>
<Caption color="uiTextHighContrast">
{intl.formatMessage(
{ id: "{number} people" },
{
defaultMessage: "{number} people",
},
{ number: seating.capacity }
)}
</Caption>
@@ -101,12 +106,14 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
<div className={styles.capacity}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({
id: "Location in hotel",
defaultMessage: "Location in hotel",
})}
</Caption>
<Caption color="uiTextHighContrast">
{intl.formatMessage(
{ id: "Floor {floorNumber}" },
{
defaultMessage: "Floor {floorNumber}",
},
{
floorNumber: `${room.floorNumber}`,
}
@@ -116,7 +123,7 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
<div className={styles.capacity}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({
id: "Lighting",
defaultMessage: "Lighting",
})}
</Caption>
<Caption color="uiTextHighContrast">
@@ -127,10 +134,11 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
<div className={styles.capacity}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({
id: "Access size",
defaultMessage: "Access size",
})}
</Caption>
<Caption color="uiTextHighContrast">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{room.doorHeight} x {room.doorWidth} m
</Caption>
</div>
@@ -139,10 +147,11 @@ export default function MeetingRoomCard({ room }: MeetingRoomCardProps) {
<div className={styles.capacity}>
<Caption color="uiTextMediumContrast">
{intl.formatMessage({
id: "Dimensions",
defaultMessage: "Dimensions",
})}
</Caption>
<Caption color="uiTextHighContrast">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{room.length} x {room.width} x {room.height} m
</Caption>
</div>
@@ -6,35 +6,37 @@ export function translateRoomLighting(option: string, intl: IntlShape) {
switch (option) {
case RoomLighting.WindowsNaturalDaylight:
return intl.formatMessage({
id: "Windows with natural daylight",
defaultMessage: "Windows with natural daylight",
})
case RoomLighting.IndoorWindowsExcellentLighting:
return intl.formatMessage({
id: "Indoor windows and excellent lighting",
defaultMessage: "Indoor windows and excellent lighting",
})
case RoomLighting.IndoorWindowsFacingHotel:
return intl.formatMessage({
id: "Indoor windows facing the hotel",
defaultMessage: "Indoor windows facing the hotel",
})
case RoomLighting.NoWindows:
return intl.formatMessage({
id: "No windows",
defaultMessage: "No windows",
})
case RoomLighting.NoWindowsExcellentLighting:
return intl.formatMessage({
id: "No windows but excellent lighting",
defaultMessage: "No windows but excellent lighting",
})
case RoomLighting.WindowsNaturalDaylightBlackoutFacilities:
return intl.formatMessage({
id: "Windows natural daylight and blackout facilities",
defaultMessage: "Windows natural daylight and blackout facilities",
})
case RoomLighting.WindowsNaturalDaylightExcellentView:
return intl.formatMessage({
id: "Windows natural daylight and excellent view",
defaultMessage: "Windows natural daylight and excellent view",
})
default:
console.warn(`Unsupported conference room ligthing option: ${option}`)
return intl.formatMessage({ id: "N/A" })
return intl.formatMessage({
defaultMessage: "N/A",
})
}
}
@@ -42,38 +44,40 @@ export function translateSeatingType(type: string, intl: IntlShape) {
switch (type) {
case SeatingType.Boardroom:
return intl.formatMessage({
id: "Boardroom",
defaultMessage: "Boardroom",
})
case SeatingType.Cabaret:
return intl.formatMessage({
id: "Cabaret seating",
defaultMessage: "Cabaret seating",
})
case SeatingType.Classroom:
return intl.formatMessage({
id: "Classroom",
defaultMessage: "Classroom",
})
case SeatingType.FullCircle:
return intl.formatMessage({
id: "Full circle",
defaultMessage: "Full circle",
})
case SeatingType.HalfCircle:
return intl.formatMessage({
id: "Half circle",
defaultMessage: "Half circle",
})
case SeatingType.StandingTable:
return intl.formatMessage({
id: "Standing table",
defaultMessage: "Standing table",
})
case SeatingType.Theatre:
return intl.formatMessage({
id: "Theatre",
defaultMessage: "Theatre",
})
case SeatingType.UShape:
return intl.formatMessage({
id: "U-shape",
defaultMessage: "U-shape",
})
default:
console.warn(`Unsupported conference room type : ${type}`)
return intl.formatMessage({ id: "N/A" })
return intl.formatMessage({
defaultMessage: "N/A",
})
}
}
@@ -88,6 +88,7 @@ export default function Select({
size={discreet ? "discreet" : "regular"}
>
{label}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{discreet && `:`}
</Label>
{selectedText && (
@@ -30,13 +30,13 @@ export default function ShowMoreButton({
if (!textShowMore) {
textShowMore = intl.formatMessage({
id: "Show more",
defaultMessage: "Show more",
})
}
if (!textShowLess) {
textShowLess = intl.formatMessage({
id: "Show less",
defaultMessage: "Show less",
})
}
@@ -55,7 +55,9 @@ export default function SidePeek({
</Typography>
) : null}
<Button
aria-label={intl.formatMessage({ id: "Close" })}
aria-label={intl.formatMessage({
defaultMessage: "Close",
})}
className={styles.closeButton}
intent="text"
onPress={onClose}