Merged in chore/add-formatjs-linting-to-booking-flow (pull request #2761)

chore: Add formatjs linting to booking-flow

* Add formatjs linting to booking-flow

* Fix lock file


Approved-by: Joakim Jäderberg
This commit is contained in:
Anton Gunnarsson
2025-09-04 13:52:56 +00:00
parent 55e25d6c75
commit 711589ff5e
11 changed files with 34 additions and 7 deletions

View File

@@ -6,6 +6,7 @@ import js from "@eslint/js"
import typescriptEslint from "@typescript-eslint/eslint-plugin" import typescriptEslint from "@typescript-eslint/eslint-plugin"
import tsParser from "@typescript-eslint/parser" import tsParser from "@typescript-eslint/parser"
import { defineConfig } from "eslint/config" import { defineConfig } from "eslint/config"
import formatjs from "eslint-plugin-formatjs"
import simpleImportSort from "eslint-plugin-simple-import-sort" import simpleImportSort from "eslint-plugin-simple-import-sort"
const compat = new FlatCompat({ const compat = new FlatCompat({
@@ -21,6 +22,7 @@ export default defineConfig([
plugins: { plugins: {
"simple-import-sort": simpleImportSort, "simple-import-sort": simpleImportSort,
"@typescript-eslint": typescriptEslint, "@typescript-eslint": typescriptEslint,
formatjs,
}, },
languageOptions: { languageOptions: {
@@ -99,6 +101,18 @@ export default defineConfig([
}, },
], ],
"formatjs/enforce-default-message": ["error", "literal"],
"formatjs/enforce-placeholders": ["error"],
"formatjs/enforce-plural-rules": ["error"],
"formatjs/no-literal-string-in-jsx": ["error"],
"formatjs/no-multiple-whitespaces": ["error"],
"formatjs/no-multiple-plurals": ["error"],
"formatjs/no-invalid-icu": ["error"],
"formatjs/no-id": ["error"],
"formatjs/no-complex-selectors": ["error"],
"formatjs/no-useless-message": ["error"],
"formatjs/prefer-pound-in-plural": ["error"],
"@typescript-eslint/consistent-type-imports": "error", "@typescript-eslint/consistent-type-imports": "error",
"@typescript-eslint/no-unused-vars": [ "@typescript-eslint/no-unused-vars": [

View File

@@ -34,8 +34,10 @@ export class ErrorBoundary extends React.Component<
return ( return (
<> <>
{hasFallback && this.props.fallback} {hasFallback && this.props.fallback}
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{!hasFallback && <h2>Something went wrong.</h2>} {!hasFallback && <h2>Something went wrong.</h2>}
{process.env.NODE_ENV === "development" && ( {process.env.NODE_ENV === "development" && (
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
<button onClick={() => this.setState({ hasError: false })}> <button onClick={() => this.setState({ hasError: false })}>
Reset Reset
</button> </button>

View File

@@ -128,6 +128,7 @@ export default function ListingHotelCardDialog({
<Subtitle type="two"> <Subtitle type="two">
{publicPrice} {currency} {publicPrice} {currency}
</Subtitle> </Subtitle>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{memberPrice && <Caption>/</Caption>} {memberPrice && <Caption>/</Caption>}
</> </>
) : ( ) : (
@@ -166,7 +167,8 @@ export default function ListingHotelCardDialog({
} }
)} )}
{chequePrice.additionalPricePerStay > 0 {chequePrice.additionalPricePerStay > 0
? " + " + ? // eslint-disable-next-line formatjs/no-literal-string-in-jsx
" + " +
intl.formatMessage( intl.formatMessage(
{ {
defaultMessage: "{price} {currency}", defaultMessage: "{price} {currency}",
@@ -178,6 +180,7 @@ export default function ListingHotelCardDialog({
) )
: null} : null}
<Typography variant="Body/Paragraph/mdRegular"> <Typography variant="Body/Paragraph/mdRegular">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span> <span>
/ /
{intl.formatMessage({ {intl.formatMessage({
@@ -199,6 +202,7 @@ export default function ListingHotelCardDialog({
} }
)} )}
<Typography variant="Body/Paragraph/mdRegular"> <Typography variant="Body/Paragraph/mdRegular">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<span> <span>
/ /
{intl.formatMessage({ {intl.formatMessage({

View File

@@ -80,6 +80,7 @@ export default function FilterContent({
isDisabled={isDisabled} isDisabled={isDisabled}
/> />
{!isDisabled && ( {!isDisabled && (
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
<span>{`(${combinedFiltersCount > 0 ? combinedFiltersCount : filterCount})`}</span> <span>{`(${combinedFiltersCount > 0 ? combinedFiltersCount : filterCount})`}</span>
)} )}
</li> </li>

View File

@@ -101,14 +101,13 @@ export default function SummaryContent({
<MaterialIcon icon="arrow_forward" size={15} color="CurrentColor" /> <MaterialIcon icon="arrow_forward" size={15} color="CurrentColor" />
{dt(input.data?.booking.toDate) {dt(input.data?.booking.toDate)
.locale(lang) .locale(lang)
.format(longDateFormat[lang])}{" "} .format(longDateFormat[lang])}
({nightsLabel}) {/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
{` (${nightsLabel})`}
</p> </p>
</Typography> </Typography>
</header> </header>
<Divider color="Border/Divider/Subtle" /> <Divider color="Border/Divider/Subtle" />
{selectedRates.rates.map((room, idx) => { {selectedRates.rates.map((room, idx) => {
if (!room) { if (!room) {
return null return null
@@ -131,7 +130,6 @@ export default function SummaryContent({
/> />
) )
})} })}
<div> <div>
<div className={styles.entry}> <div className={styles.entry}>
<div> <div>

View File

@@ -12,6 +12,7 @@ import styles from "./rateSummary.module.css"
export function RateSummary() { export function RateSummary() {
return ( return (
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
<ErrorBoundary fallback={<div>Unable to render summary</div>}> <ErrorBoundary fallback={<div>Unable to render summary</div>}>
<InnerRateSummary /> <InnerRateSummary />
</ErrorBoundary> </ErrorBoundary>
@@ -59,6 +60,7 @@ function InnerRateSummary() {
> >
<div className={styles.summary}> <div className={styles.summary}>
<div className={styles.content}> <div className={styles.content}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<ErrorBoundary fallback={<div>Unable to render desktop summary</div>}> <ErrorBoundary fallback={<div>Unable to render desktop summary</div>}>
<DesktopSummary <DesktopSummary
isSubmitting={isSubmitting} isSubmitting={isSubmitting}
@@ -69,6 +71,7 @@ function InnerRateSummary() {
</ErrorBoundary> </ErrorBoundary>
</div> </div>
<div className={styles.mobileSummary}> <div className={styles.mobileSummary}>
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<ErrorBoundary fallback={<div>Unable to render mobile summary</div>}> <ErrorBoundary fallback={<div>Unable to render mobile summary</div>}>
<MobileSummary /> <MobileSummary />
</ErrorBoundary> </ErrorBoundary>

View File

@@ -14,6 +14,7 @@ import styles from "./roomsHeader.module.css"
export function RoomsHeader({ roomIndex }: { roomIndex: number }) { export function RoomsHeader({ roomIndex }: { roomIndex: number }) {
return ( return (
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
<ErrorBoundary fallback={<div>Unable to render rooms header</div>}> <ErrorBoundary fallback={<div>Unable to render rooms header</div>}>
<InnerRoomsHeader roomIndex={roomIndex} /> <InnerRoomsHeader roomIndex={roomIndex} />
</ErrorBoundary> </ErrorBoundary>

View File

@@ -23,6 +23,7 @@ export default function RoomSize({ roomSize }: RoomSizeProps) {
return ( return (
<> <>
<Typography variant="Body/Supporting text (caption)/smBold"> <Typography variant="Body/Supporting text (caption)/smBold">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<p></p> <p></p>
</Typography> </Typography>
<Typography variant="Body/Supporting text (caption)/smBold"> <Typography variant="Body/Supporting text (caption)/smBold">
@@ -41,6 +42,7 @@ export default function RoomSize({ roomSize }: RoomSizeProps) {
return ( return (
<> <>
<Typography variant="Body/Supporting text (caption)/smBold"> <Typography variant="Body/Supporting text (caption)/smBold">
{/* eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
<p></p> <p></p>
</Typography> </Typography>
<Typography variant="Body/Supporting text (caption)/smBold"> <Typography variant="Body/Supporting text (caption)/smBold">

View File

@@ -1,3 +1,4 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import { Button } from "@scandic-hotels/design-system/Button" import { Button } from "@scandic-hotels/design-system/Button"
import { useSelectRateContext } from "./SelectRateContext" import { useSelectRateContext } from "./SelectRateContext"
@@ -33,7 +34,6 @@ export function DebugButton() {
}} }}
onClick={handleClick} onClick={handleClick}
> >
{/* // eslint-disable-next-line formatjs/no-literal-string-in-jsx */}
DEBUG DEBUG
</Button> </Button>
) )

View File

@@ -105,6 +105,7 @@
"@typescript-eslint/parser": "^8.32.0", "@typescript-eslint/parser": "^8.32.0",
"dotenv": "^16.5.0", "dotenv": "^16.5.0",
"eslint": "^9", "eslint": "^9",
"eslint-plugin-formatjs": "^5.3.1",
"eslint-plugin-import": "^2.31.0", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
"typescript": "5.8.3", "typescript": "5.8.3",

View File

@@ -6060,6 +6060,7 @@ __metadata:
dotenv: "npm:^16.5.0" dotenv: "npm:^16.5.0"
downshift: "npm:^9.0.9" downshift: "npm:^9.0.9"
eslint: "npm:^9" eslint: "npm:^9"
eslint-plugin-formatjs: "npm:^5.3.1"
eslint-plugin-import: "npm:^2.31.0" eslint-plugin-import: "npm:^2.31.0"
eslint-plugin-simple-import-sort: "npm:^12.1.1" eslint-plugin-simple-import-sort: "npm:^12.1.1"
fast-deep-equal: "npm:^3.1.0" fast-deep-equal: "npm:^3.1.0"