diff --git a/.github/workflows/automated-linting.yml b/.github/workflows/automated-linting.yml index af94fa5e..2e81722b 100644 --- a/.github/workflows/automated-linting.yml +++ b/.github/workflows/automated-linting.yml @@ -24,14 +24,14 @@ jobs: # This is a temporary fix to allow the workflow continue providing # autofixes while these errors are being addressed. continue-on-error: true - - run: pnpm run prettier - name: Running prettier + - run: pnpm run fmt + name: Running formatter - name: Push changes id: push-changes uses: EndBug/add-and-commit@v9 with: - message: "Automated linting/prettier update" + message: "Automated linting/formatter update" add: "*" push: true pull: --rebase --autostash @@ -42,7 +42,7 @@ jobs: uses: actions/github-script@v3 with: script: | - core.setFailed('Linting/Prettier changes were made. A new commit with autofixes was pushed.') + core.setFailed('Linting/formatter changes were made. A new commit with autofixes was pushed.') - name: Fail job on linting error if: steps.oxlint.outcome == 'failure' uses: actions/github-script@v3 diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 00000000..757fd64c --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,3 @@ +{ + "trailingComma": "es5" +} diff --git a/.oxlintrc.json b/.oxlintrc.json index 34ac41e2..761004ac 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,14 +1,6 @@ { "rules": { - "no-unused-vars": [ - "error", - { "caughtErrorsIgnorePattern": "^_", "argsIgnorePattern": "^_" } - ] + "no-unused-vars": ["error", { "caughtErrorsIgnorePattern": "^_", "argsIgnorePattern": "^_" }] }, - "ignorePatterns": [ - "**/*/dist", - "!.storybook", - "**/*/storybook-static/**", - "test-sites/**" - ] + "ignorePatterns": ["**/*/dist", "!.storybook", "**/*/storybook-static/**", "test-sites/**"] } diff --git a/package.json b/package.json index 7cf8d6ec..2a481172 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "scripts": { "build": "pnpm -r run build", "test": "pnpm -r run test", - "prettier": "prettier --write --cache .", + "fmt": "oxfmt", "lint": "oxlint --fix", - "autofix": "npm run lint && npm run prettier", + "autofix": "npm run lint && npm run fmt", "generate-notices": "generate-license-file --input package.json --output ./THIRD-PARTY-NOTICES --overwrite", "ci-verify-publish": "tsx scripts/verifyPublish.ts", "release": "tsx scripts/release.ts" @@ -23,19 +23,19 @@ "generate-license-file": "^2.0.0", "lint-staged": "^13.2.3", "minimist": "^1.2.8", - "oxlint": "^1.26.0", + "oxfmt": "^0.21.0", + "oxlint": "^1.36.0", "picocolors": "^1.0.0", - "prettier": "^3.2.5", "prompts": "^2.4.2", "semver": "^7.5.4", "tsx": "^4.19.3" }, - "engines": { - "node": ">=14.0.0" - }, - "packageManager": "pnpm@9.12.3", "lint-staged": { - "*": "prettier --write --cache --ignore-unknown", + "*": "oxfmt", "*.{ts,js,tsx,jsx}": "oxlint --fix" - } + }, + "engines": { + "node": "^20 || ^22 || ^24" + }, + "packageManager": "pnpm@9.12.3" } diff --git a/packages/pages-components/.storybook/preview.tsx b/packages/pages-components/.storybook/preview.tsx index 5642081b..a0a5f6c6 100644 --- a/packages/pages-components/.storybook/preview.tsx +++ b/packages/pages-components/.storybook/preview.tsx @@ -24,8 +24,9 @@ const preview: Preview = { // Store the real DateTime const originalLuxonSettings = useRef(Settings); - const mockedLuxonDateTimeFromParams = context.parameters - .mockedLuxonDateTime as DateTime | undefined; + const mockedLuxonDateTimeFromParams = context.parameters.mockedLuxonDateTime as + | DateTime + | undefined; const overrideDateTime = useCallback(() => { if (mockedLuxonDateTimeFromParams) { diff --git a/packages/pages-components/.storybook/snapshots/test-runner.ts b/packages/pages-components/.storybook/snapshots/test-runner.ts index 690af31e..a26411cb 100644 --- a/packages/pages-components/.storybook/snapshots/test-runner.ts +++ b/packages/pages-components/.storybook/snapshots/test-runner.ts @@ -1,9 +1,5 @@ import { Page } from "playwright-core"; -import { - TestRunnerConfig, - waitForPageReady, - TestContext, -} from "@storybook/test-runner"; +import { TestRunnerConfig, waitForPageReady, TestContext } from "@storybook/test-runner"; import { toMatchImageSnapshot } from "jest-image-snapshot"; const customSnapshotsDir = `${process.cwd()}/.storybook/snapshots/__snapshots__`; diff --git a/packages/pages-components/CHANGELOG.md b/packages/pages-components/CHANGELOG.md index 70ab27fc..82ac13cb 100644 --- a/packages/pages-components/CHANGELOG.md +++ b/packages/pages-components/CHANGELOG.md @@ -2,20 +2,20 @@ ##### New Features -* swap to tsup for builds ([#139](https://github.com/yext/js/pull/139)) ([43a77a0b](https://github.com/yext/js/commit/43a77a0bec7554670c0ccb525d05b4de4dc9f1ad)) -* support React 19 ([#138](https://github.com/yext/js/pull/138)) ([5f5bfaf3](https://github.com/yext/js/commit/5f5bfaf3b711d8f28e4a4500e40d030da4e40495)) +- swap to tsup for builds ([#139](https://github.com/yext/js/pull/139)) ([43a77a0b](https://github.com/yext/js/commit/43a77a0bec7554670c0ccb525d05b4de4dc9f1ad)) +- support React 19 ([#138](https://github.com/yext/js/pull/138)) ([5f5bfaf3](https://github.com/yext/js/commit/5f5bfaf3b711d8f28e4a4500e40d030da4e40495)) ##### Bug Fixes -* storybook env parsing vulnerability ([#140](https://github.com/yext/js/pull/140)) ([c69d6912](https://github.com/yext/js/commit/c69d69126157a17e5944037e19bc0187e91d1328)) -* exports resolution ([#136](https://github.com/yext/js/pull/136)) ([80f77284](https://github.com/yext/js/commit/80f77284ab5243fb8112377441083566a60d6b23)) -* release script ([00f0f279](https://github.com/yext/js/commit/00f0f279e42e0678ec51a9438a520fb68c5ffe74)) +- storybook env parsing vulnerability ([#140](https://github.com/yext/js/pull/140)) ([c69d6912](https://github.com/yext/js/commit/c69d69126157a17e5944037e19bc0187e91d1328)) +- exports resolution ([#136](https://github.com/yext/js/pull/136)) ([80f77284](https://github.com/yext/js/commit/80f77284ab5243fb8112377441083566a60d6b23)) +- release script ([00f0f279](https://github.com/yext/js/commit/00f0f279e42e0678ec51a9438a520fb68c5ffe74)) ##### Other Changes -* drop Node 18 support ([#137](https://github.com/yext/js/pull/137)) ([69a1ec05](https://github.com/yext/js/commit/69a1ec05d40869a812bfc89c88f3963632597bfc)) -* drop support for React 17 ([#134](https://github.com/yext/js/pull/134)) ([1e812b55](https://github.com/yext/js/commit/1e812b55d12a6324d987c814724d9af7e309b2a9)) -* drop LexicalRichText and LegacyRichText ([#133](https://github.com/yext/js/pull/133)) ([57eb25e6](https://github.com/yext/js/commit/57eb25e69b1a1b5bf81cabebcb0b942932c1162d)) +- drop Node 18 support ([#137](https://github.com/yext/js/pull/137)) ([69a1ec05](https://github.com/yext/js/commit/69a1ec05d40869a812bfc89c88f3963632597bfc)) +- drop support for React 17 ([#134](https://github.com/yext/js/pull/134)) ([1e812b55](https://github.com/yext/js/commit/1e812b55d12a6324d987c814724d9af7e309b2a9)) +- drop LexicalRichText and LegacyRichText ([#133](https://github.com/yext/js/pull/133)) ([57eb25e6](https://github.com/yext/js/commit/57eb25e69b1a1b5bf81cabebcb0b942932c1162d)) #### 1.2.3 (2025-12-22) diff --git a/packages/pages-components/package.json b/packages/pages-components/package.json index 9a745a33..9b924437 100644 --- a/packages/pages-components/package.json +++ b/packages/pages-components/package.json @@ -2,25 +2,26 @@ "name": "@yext/pages-components", "version": "2.0.0", "description": "A React component library that supports Yext Pages development", - "author": "sumo@yext.com", - "license": "BSD-3-Clause", "keywords": [ - "Yext", - "React" + "React", + "Yext" ], + "license": "BSD-3-Clause", + "author": "sumo@yext.com", "repository": { "type": "git", "url": "https://github.com/yext/js.git" }, - "sideEffects": [ - "**/*.css" - ], - "type": "module", "files": [ "dist", "THIRD-PARTY-NOTICES" ], + "type": "module", + "sideEffects": [ + "**/*.css" + ], "module": "./dist/index.js", + "types": "dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", @@ -29,10 +30,6 @@ }, "./style.css": "./dist/index.css" }, - "types": "dist/index.d.ts", - "engines": { - "node": "^20 || ^22 || ^24" - }, "scripts": { "dev": "pnpm run storybook", "build:vite": "tsc && vite build", @@ -46,11 +43,11 @@ "prepare": "pnpm build", "update-snapshots": "test-storybook -c .storybook/snapshots -u" }, - "peerDependencies": { - "lexical": "~0.38.2", - "mapbox-gl": "^2.9.2", - "react": "^18.2.0 || ^19.2.3", - "react-dom": "^18.2.0 || ^19.2.3" + "dependencies": { + "@yext/analytics": "^1.0.0", + "browser-or-node": "^3.0.0", + "classnames": "^2.5.1", + "luxon": "^3.7.2" }, "devDependencies": { "@playwright/test": "^1.55.1", @@ -95,10 +92,13 @@ "vite-tsconfig-paths": "^4.2.2", "vitest": "^3.0.5" }, - "dependencies": { - "@yext/analytics": "^1.0.0", - "browser-or-node": "^3.0.0", - "classnames": "^2.5.1", - "luxon": "^3.7.2" + "peerDependencies": { + "lexical": "~0.38.2", + "mapbox-gl": "^2.9.2", + "react": "^18.2.0 || ^19.2.3", + "react-dom": "^18.2.0 || ^19.2.3" + }, + "engines": { + "node": "^20 || ^22 || ^24" } } diff --git a/packages/pages-components/src/components/address/address.stories.tsx b/packages/pages-components/src/components/address/address.stories.tsx index fccb9cd9..4f79a475 100644 --- a/packages/pages-components/src/components/address/address.stories.tsx +++ b/packages/pages-components/src/components/address/address.stories.tsx @@ -20,9 +20,7 @@ const meta: Meta = { export default meta; -const Template: StoryFn = (args) => ( - -); +const Template: StoryFn = (args) => ; // Address in the United States @@ -35,8 +33,7 @@ Address.args = { // Address to Yext Arlington Office -export const Address_Arlington: StoryFn = - Template.bind({}); +export const Address_Arlington: StoryFn = Template.bind({}); Address_Arlington.args = { address: Arlington, @@ -44,9 +41,7 @@ Address_Arlington.args = { // Address to Yext Berlin Office -export const Address_Berlin: StoryFn = Template.bind( - {} -); +export const Address_Berlin: StoryFn = Template.bind({}); Address_Berlin.args = { address: Berlin, @@ -54,9 +49,7 @@ Address_Berlin.args = { // Address to Yext Chicago Office -export const Address_Chicago: StoryFn = Template.bind( - {} -); +export const Address_Chicago: StoryFn = Template.bind({}); Address_Chicago.args = { address: Chicago, @@ -64,9 +57,7 @@ Address_Chicago.args = { // Address to Yext London Office -export const Address_London: StoryFn = Template.bind( - {} -); +export const Address_London: StoryFn = Template.bind({}); Address_London.args = { address: London, @@ -74,9 +65,7 @@ Address_London.args = { // Address to Yext Miami Office -export const Address_Miami: StoryFn = Template.bind( - {} -); +export const Address_Miami: StoryFn = Template.bind({}); Address_Miami.args = { address: Miami, @@ -84,9 +73,7 @@ Address_Miami.args = { // Address to Yext New York Office -export const Address_NewYork: StoryFn = Template.bind( - {} -); +export const Address_NewYork: StoryFn = Template.bind({}); Address_NewYork.args = { address: NewYork, @@ -94,9 +81,7 @@ Address_NewYork.args = { // Address to Yext Paris Office -export const Address_Paris: StoryFn = Template.bind( - {} -); +export const Address_Paris: StoryFn = Template.bind({}); Address_Paris.args = { address: Paris, @@ -104,8 +89,7 @@ Address_Paris.args = { // Address to Yext San Francisco Office -export const Address_SanFrancisco: StoryFn = - Template.bind({}); +export const Address_SanFrancisco: StoryFn = Template.bind({}); Address_SanFrancisco.args = { address: SanFrancisco, diff --git a/packages/pages-components/src/components/address/address.tsx b/packages/pages-components/src/components/address/address.tsx index aec6dead..7ec899f1 100644 --- a/packages/pages-components/src/components/address/address.tsx +++ b/packages/pages-components/src/components/address/address.tsx @@ -20,22 +20,10 @@ import "./address.css"; * * @public */ -export const Address = ({ - address, - lines, - separator = ",", - ...props -}: AddressProps) => { - const renderedLines = (lines || localeAddressFormat(address.countryCode)).map( - (line) => ( - - ) - ); +export const Address = ({ address, lines, separator = ",", ...props }: AddressProps) => { + const renderedLines = (lines || localeAddressFormat(address.countryCode)).map((line) => ( + + )); return (
@@ -44,19 +32,13 @@ export const Address = ({ ); }; -const AddressLine = ({ - address, - line, - separator, -}: AddressLineProps): React.ReactElement => { +const AddressLine = ({ address, line, separator }: AddressLineProps): React.ReactElement => { const addressDOM: React.ReactElement[] = []; let separatorCount = 0; for (const field of line) { if (field === ",") { - addressDOM.push( - {separator} - ); + addressDOM.push({separator}); continue; } diff --git a/packages/pages-components/src/components/address/i18n.ts b/packages/pages-components/src/components/address/i18n.ts index f8a31a04..493cd79c 100644 --- a/packages/pages-components/src/components/address/i18n.ts +++ b/packages/pages-components/src/components/address/i18n.ts @@ -60,14 +60,7 @@ export function localeAddressFormat(locale: string): AddressLine[] { return [["line1"], ["line2"], ["postalCode", "city"], ["countryCode"]]; case "AF": case "IR": - return [ - ["line1"], - ["line2"], - ["city"], - ["region"], - ["postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city"], ["region"], ["postalCode"], ["countryCode"]]; case "AG": case "AO": case "AW": @@ -105,12 +98,7 @@ export function localeAddressFormat(locale: string): AddressLine[] { case "IS": return [["line1"], ["line2"], ["postalCode", "city"]]; case "AR": - return [ - ["line1"], - ["line2"], - ["postalCode", "city", ",", "region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["postalCode", "city", ",", "region"], ["countryCode"]]; case "AS": case "BB": case "BD": @@ -148,20 +136,10 @@ export function localeAddressFormat(locale: string): AddressLine[] { case "SZ": case "US": case "VI": - return [ - ["line1"], - ["line2"], - ["city", ",", "region", "postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city", ",", "region", "postalCode"], ["countryCode"]]; case "BE": case "PE": - return [ - ["line1"], - ["line2"], - ["postalCode", "sublocality", "city"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["postalCode", "sublocality", "city"], ["countryCode"]]; case "BF": case "BI": case "BQ": @@ -201,27 +179,12 @@ export function localeAddressFormat(locale: string): AddressLine[] { case "OM": case "SK": case "VA": - return [ - ["line1"], - ["line2"], - ["postalCode", "city", "region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["postalCode", "city", "region"], ["countryCode"]]; case "CL": case "PF": - return [ - ["line1"], - ["line2"], - ["city", "postalCode", "region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city", "postalCode", "region"], ["countryCode"]]; case "CN": - return [ - ["region", "city", "sublocality"], - ["line1"], - ["line2"], - ["countryCode"], - ]; + return [["region", "city", "sublocality"], ["line1"], ["line2"], ["countryCode"]]; case "CO": case "ID": case "IQ": @@ -230,12 +193,7 @@ export function localeAddressFormat(locale: string): AddressLine[] { case "NP": case "PW": case "UA": - return [ - ["line1"], - ["line2"], - ["city", "region", "postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city", "region", "postalCode"], ["countryCode"]]; case "EG": return [ ["line1"], @@ -245,44 +203,19 @@ export function localeAddressFormat(locale: string): AddressLine[] { ]; case "ES": case "IL": - return [ - ["line1"], - ["line2"], - ["city", "postalCode"], - ["region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city", "postalCode"], ["region"], ["countryCode"]]; case "GB": case "MN": case "ZA": - return [ - ["line1"], - ["line2"], - ["sublocality", "city", "postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["sublocality", "city", "postalCode"], ["countryCode"]]; case "GG": case "IM": case "JE": - return [ - ["line1"], - ["line2"], - ["sublocality"], - ["city"], - ["postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["sublocality"], ["city"], ["postalCode"], ["countryCode"]]; case "GN": return [["line1", "line2", "city"], ["countryCode"]]; case "HK": - return [ - ["line1"], - ["line2"], - ["sublocality"], - ["city"], - ["region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["sublocality"], ["city"], ["region"], ["countryCode"]]; case "HR": return [["line1"], ["postalCode", "city", "region"], ["countryCode"]]; case "HU": @@ -298,13 +231,7 @@ export function localeAddressFormat(locale: string): AddressLine[] { ]; case "IN": case "VE": - return [ - ["line1"], - ["line2"], - ["city", "postalCode"], - ["region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city", "postalCode"], ["region"], ["countryCode"]]; case "JP": return [ ["line2"], @@ -323,23 +250,13 @@ export function localeAddressFormat(locale: string): AddressLine[] { case "KY": return [["line1"], ["line2"], ["postalCode"], ["countryCode"]]; case "LT": - return [ - ["line1"], - ["postalCode", "city", "sublocality", "region"], - ["countryCode"], - ]; + return [["line1"], ["postalCode", "city", "sublocality", "region"], ["countryCode"]]; case "LV": return [["line1"], ["city", ",", "postalCode"], ["countryCode"]]; case "MO": return [["line1"], ["line2"], ["sublocality"], ["city"], ["countryCode"]]; case "MU": - return [ - ["line1"], - ["line2"], - ["city"], - ["region", "postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["city"], ["region", "postalCode"], ["countryCode"]]; case "MX": return [ ["line1"], @@ -350,23 +267,9 @@ export function localeAddressFormat(locale: string): AddressLine[] { ]; case "NE": case "SD": - return [ - ["line1"], - ["line2"], - ["postalCode"], - ["city"], - ["region"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["postalCode"], ["city"], ["region"], ["countryCode"]]; case "NZ": - return [ - ["line1"], - ["line2"], - ["sublocality"], - ["city"], - ["postalCode"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["sublocality"], ["city"], ["postalCode"], ["countryCode"]]; case "PH": case "TW": case "VN": @@ -388,20 +291,10 @@ export function localeAddressFormat(locale: string): AddressLine[] { return [["line1"], ["line2"], ["city", ",", "region"], ["countryCode"]]; case "TH": case "TR": - return [ - ["line1"], - ["line2"], - ["sublocality"], - ["postalCode", "city"], - ["countryCode"], - ]; + return [["line1"], ["line2"], ["sublocality"], ["postalCode", "city"], ["countryCode"]]; case "UZ": return [["line1"], ["line2"], ["region", "postalCode"], ["countryCode"]]; } - return [ - ["line1", "line2"], - ["city", "region", "postalCode"], - ["countryCode"], - ]; + return [["line1", "line2"], ["city", "region", "postalCode"], ["countryCode"]]; } diff --git a/packages/pages-components/src/components/address/methods.test.ts b/packages/pages-components/src/components/address/methods.test.ts index e8a251a3..4c887c93 100644 --- a/packages/pages-components/src/components/address/methods.test.ts +++ b/packages/pages-components/src/components/address/methods.test.ts @@ -41,16 +41,14 @@ const sampleListings: ListingType[] = [ const sampleListingsLowerCase: ListingType[] = [ { listingUrl: "https://maps.google.com/maps?cid=3287244376840534043", - publisher: - ListingPublisherOption.GOOGLEMYBUSINESS.toLowerCase() as "GOOGLEMYBUSINESS", + publisher: ListingPublisherOption.GOOGLEMYBUSINESS.toLowerCase() as "GOOGLEMYBUSINESS", }, ]; const sampleListingsUpperCase: ListingType[] = [ { listingUrl: "https://maps.google.com/maps?cid=3287244376840534043", - publisher: - ListingPublisherOption.GOOGLEMYBUSINESS.toUpperCase() as "GOOGLEMYBUSINESS", + publisher: ListingPublisherOption.GOOGLEMYBUSINESS.toUpperCase() as "GOOGLEMYBUSINESS", }, ]; @@ -121,9 +119,7 @@ describe("getDirections()", () => { }); it("returns URL to Google Maps Place ID with route", () => { - expect( - getDirections(undefined, undefined, "someID", { route: true }) - ).toEqual( + expect(getDirections(undefined, undefined, "someID", { route: true })).toEqual( "https://maps.google.com/maps/dir/?api=1&destination_place_id=someID&destination=direct" ); }); @@ -135,38 +131,18 @@ describe("getDirections()", () => { }); it("returns URL to Apple Maps coordinates query", () => { expect( - getDirections( - undefined, - undefined, - undefined, - { provider: "apple" }, - sampleCoordinate - ) + getDirections(undefined, undefined, undefined, { provider: "apple" }, sampleCoordinate) ).toEqual("https://maps.apple.com/?address=32.747594,-97.082073"); }); it("returns URL to Bing Maps coordinates query", () => { expect( - getDirections( - undefined, - undefined, - undefined, - { provider: "bing" }, - sampleCoordinate - ) + getDirections(undefined, undefined, undefined, { provider: "bing" }, sampleCoordinate) ).toEqual("https://bing.com/maps/default.aspx?where1=32.747594,-97.082073"); }); it("returns URL to Google Maps coordinates query", () => { expect( - getDirections( - undefined, - undefined, - undefined, - { provider: "google" }, - sampleCoordinate - ) - ).toEqual( - "https://maps.google.com/maps/search/?api=1&query=32.747594,-97.082073" - ); + getDirections(undefined, undefined, undefined, { provider: "google" }, sampleCoordinate) + ).toEqual("https://maps.google.com/maps/search/?api=1&query=32.747594,-97.082073"); }); }); diff --git a/packages/pages-components/src/components/address/methods.ts b/packages/pages-components/src/components/address/methods.ts index 94376fd4..9a5aafa5 100644 --- a/packages/pages-components/src/components/address/methods.ts +++ b/packages/pages-components/src/components/address/methods.ts @@ -66,16 +66,11 @@ export const getDirections = ( switch (config.provider) { case MapProviderOption.APPLE: { if (!!coordinate?.latitude && !!coordinate?.longitude) { - return getDirectionsApple( - `${coordinate.latitude},${coordinate.longitude}`, - config.route - ); + return getDirectionsApple(`${coordinate.latitude},${coordinate.longitude}`, config.route); } // Apple Maps requires a query string if (!query) { - console.warn( - `${NO_QUERY_WARNING} Check that you've provided a valid Yext Address.` - ); + console.warn(`${NO_QUERY_WARNING} Check that you've provided a valid Yext Address.`); break; } @@ -83,25 +78,14 @@ export const getDirections = ( } case MapProviderOption.BING: { if (!!coordinate?.latitude && !!coordinate?.longitude) { - return getDirectionsBing( - `${coordinate.latitude},${coordinate.longitude}`, - config.route - ); + return getDirectionsBing(`${coordinate.latitude},${coordinate.longitude}`, config.route); } query = - address && - encodeArray([ - address.line1, - address.city, - address.region, - address.postalCode, - ]); + address && encodeArray([address.line1, address.city, address.region, address.postalCode]); // Bing Maps requires a query if (!query) { - console.warn( - `${NO_QUERY_WARNING} Check that you've provided a valid Yext Address.` - ); + console.warn(`${NO_QUERY_WARNING} Check that you've provided a valid Yext Address.`); break; } @@ -109,15 +93,10 @@ export const getDirections = ( } default: { if (!!coordinate?.latitude && !!coordinate?.longitude) { - return getDirectionsGoogle( - `${coordinate.latitude},${coordinate.longitude}`, - config.route - ); + return getDirectionsGoogle(`${coordinate.latitude},${coordinate.longitude}`, config.route); } const gmbListing = listings.find( - (listing) => - listing?.publisher?.toUpperCase() === - ListingPublisherOption.GOOGLEMYBUSINESS + (listing) => listing?.publisher?.toUpperCase() === ListingPublisherOption.GOOGLEMYBUSINESS ); if (gmbListing?.listingUrl) { @@ -179,11 +158,7 @@ const getDirectionsBing = (query: string, route?: boolean): string => { * @param route - Enable driving directions * @returns Google maps url */ -const getDirectionsGooglePlaceID = ( - placeId: string, - query?: string, - route?: boolean -): string => { +const getDirectionsGooglePlaceID = (placeId: string, query?: string, route?: boolean): string => { const queryParam = query ? `&query=${query}` : ``; if (route) { return `https://maps.google.com/maps/dir/?api=1${queryParam}&destination_place_id=${placeId}&destination=direct`; diff --git a/packages/pages-components/src/components/address/types.ts b/packages/pages-components/src/components/address/types.ts index 2f09ead6..9d044c86 100644 --- a/packages/pages-components/src/components/address/types.ts +++ b/packages/pages-components/src/components/address/types.ts @@ -55,8 +55,7 @@ export const ListingPublisherOption = { * * @public */ -export type ListingPublisher = - (typeof ListingPublisherOption)[keyof typeof ListingPublisherOption]; +export type ListingPublisher = (typeof ListingPublisherOption)[keyof typeof ListingPublisherOption]; /** * The type definition for a Listing @@ -84,8 +83,7 @@ export const MapProviderOption = { * * @public */ -export type MapProvider = - (typeof MapProviderOption)[keyof typeof MapProviderOption]; +export type MapProvider = (typeof MapProviderOption)[keyof typeof MapProviderOption]; /** * The Yext profile fields used to create a getDirections URL diff --git a/packages/pages-components/src/components/analytics/Analytics.ts b/packages/pages-components/src/components/analytics/Analytics.ts index 0d4c80c5..07933356 100644 --- a/packages/pages-components/src/components/analytics/Analytics.ts +++ b/packages/pages-components/src/components/analytics/Analytics.ts @@ -67,17 +67,12 @@ export class Analytics implements AnalyticsMethods { } // Don't fire analytics for non-production domains, unless debug enabled - if ( - !isProduction(...(this.productionDomains ?? [])) && - !this.getDebugEnabled() - ) { + if (!isProduction(...(this.productionDomains ?? [])) && !this.getDebugEnabled()) { console.warn("Yext Analytics disabled for non-production domains"); return; } - const region = getPartition( - this.templateData.document.businessId - ) as Region; + const region = getPartition(this.templateData.document.businessId) as Region; const config: AnalyticsConfig = { authorizationType: "apiKey", @@ -102,11 +97,7 @@ export class Analytics implements AnalyticsMethods { } private canTrack(): boolean { - return ( - getRuntime().name === "browser" && - this._optedIn && - !!this._analyticsEventService - ); + return getRuntime().name === "browser" && this._optedIn && !!this._analyticsEventService; } /** {@inheritDoc AnalyticsMethods.identify} */ @@ -149,16 +140,8 @@ export class Analytics implements AnalyticsMethods { return Promise.resolve(); } - const { - action, - scope, - eventName, - currency, - amount, - destinationUrl, - customTags, - customValues, - } = props; + const { action, scope, eventName, currency, amount, destinationUrl, customTags, customValues } = + props; let value; if (amount) { diff --git a/packages/pages-components/src/components/analytics/analytics.test.tsx b/packages/pages-components/src/components/analytics/analytics.test.tsx index f404933d..96f36559 100644 --- a/packages/pages-components/src/components/analytics/analytics.test.tsx +++ b/packages/pages-components/src/components/analytics/analytics.test.tsx @@ -1,13 +1,4 @@ -import { - describe, - it, - expect, - vi, - beforeAll, - afterAll, - afterEach, - Mock, -} from "vitest"; +import { describe, it, expect, vi, beforeAll, afterAll, afterEach, Mock } from "vitest"; import { render, screen, fireEvent } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { TemplateProps } from "./types.js"; @@ -99,12 +90,7 @@ describe("Analytics", () => { it("should not fire a page view when opt in is required", () => { render( - + ); expect(global.fetch).toHaveBeenCalledTimes(0); @@ -112,12 +98,7 @@ describe("Analytics", () => { it("should track a click", () => { render( - + Click Me ); @@ -240,12 +221,7 @@ describe("Analytics", () => { it("overrides AnalyticsScopeProvider", () => { render( - + @@ -269,12 +245,7 @@ describe("Analytics", () => { it("should throw when apiKey not set", () => { expect(() => render( - + ) ).toThrowError("API Key is required for AnalyticsProvider"); }); @@ -296,12 +267,7 @@ describe("Analytics", () => { }; render( - + - - ); - } - )} + {Object.entries(getEventsGroupedByName()).map(([originalEventName, events], idx) => { + const key = `${originalEventName}_${idx}`; + + return ( +
  • + +
  • + ); + })}
    ); @@ -436,17 +414,10 @@ function TooltipHandler(props: TooltipHandlerProps) { } // Find tooltip position that is in the window bounds and doesn't overlap with other tooltips. -function setTooltipPosition( - item: TooltipsRefItem, - instances: HTMLDivElement[] -) { +function setTooltipPosition(item: TooltipsRefItem, instances: HTMLDivElement[]) { for (let i = 0; i < 9; i++) { // Get base position and position the tooltip. - const position = positionFinder( - item.tooltip.elem.getBoundingClientRect(), - item.el, - i - ); + const position = positionFinder(item.tooltip.elem.getBoundingClientRect(), item.el, i); item.el.style.inset = `${position.top} auto auto ${position.left}`; // Check if tooltip is in the window bounds. @@ -471,10 +442,7 @@ function setTooltipPosition( } // Check if two tooltips are overlapping with each other. -function isOverlapping( - tooltip: HTMLDivElement, - futureNeighbor: HTMLDivElement -): boolean { +function isOverlapping(tooltip: HTMLDivElement, futureNeighbor: HTMLDivElement): boolean { const y1 = tooltip.getBoundingClientRect().top + window.scrollY; const x1 = tooltip.getBoundingClientRect().left; const y2 = y1 + tooltip.clientHeight; @@ -503,20 +471,12 @@ function isOverlapping( ); }; - return ( - check(x1, y1, a1, b1, x2, y2, a2, b2) || - check(a1, b1, x1, y1, a2, b2, x2, y2) - ); + return check(x1, y1, a1, b1, x2, y2, a2, b2) || check(a1, b1, x1, y1, a2, b2, x2, y2); } // Check if a tooltip is within the window bounds. function inWindowBounds(x1: number, y1: number, x2: number, y2: number) { - return ( - x1 < 0 || - x2 > window.innerWidth || - y1 < 0 || - y2 > document.documentElement.scrollHeight - ); + return x1 < 0 || x2 > window.innerWidth || y1 < 0 || y2 > document.documentElement.scrollHeight; } // Possible positions for a given tooltip around it's target element. diff --git a/packages/pages-components/src/components/analytics/provider.tsx b/packages/pages-components/src/components/analytics/provider.tsx index d3fc5760..4b66a325 100644 --- a/packages/pages-components/src/components/analytics/provider.tsx +++ b/packages/pages-components/src/components/analytics/provider.tsx @@ -1,11 +1,4 @@ -import { - PropsWithChildren, - useRef, - lazy, - Suspense, - useEffect, - useState, -} from "react"; +import { PropsWithChildren, useRef, lazy, Suspense, useEffect, useState } from "react"; import { getRuntime } from "../../util/index.js"; import { Analytics } from "./Analytics.js"; import { AnalyticsMethods, AnalyticsProviderProps } from "./interfaces.js"; @@ -72,9 +65,7 @@ export function AnalyticsProvider( return ( <> - - {children} - + {children} {isClient && (enableDebugging || debuggingParamDetected()) && getRuntime().name === "browser" ? ( diff --git a/packages/pages-components/src/components/analytics/scope.tsx b/packages/pages-components/src/components/analytics/scope.tsx index a92dc03f..d8a30f3f 100644 --- a/packages/pages-components/src/components/analytics/scope.tsx +++ b/packages/pages-components/src/components/analytics/scope.tsx @@ -1,10 +1,4 @@ -import { - createContext, - useContext, - useState, - PropsWithChildren, - useEffect, -} from "react"; +import { createContext, useContext, useState, PropsWithChildren, useEffect } from "react"; import { concatScopes } from "./helpers.js"; import { AnalyticsScopeProps } from "./interfaces.js"; import { useAnalytics } from "./hooks.js"; @@ -46,16 +40,10 @@ export function AnalyticsScopeProvider( if (debugEnabled && isClient) { return (
    - - {props.children} - + {props.children}
    ); } - return ( - - {props.children} - - ); + return {props.children}; } diff --git a/packages/pages-components/src/components/hours/hours.tsx b/packages/pages-components/src/components/hours/hours.tsx index a6241f7b..b961ed76 100644 --- a/packages/pages-components/src/components/hours/hours.tsx +++ b/packages/pages-components/src/components/hours/hours.tsx @@ -1,12 +1,5 @@ import { DateTime } from "luxon"; -import { - Day, - DayType, - HolidayType, - HoursType, - IntervalType, - WeekType, -} from "./types.js"; +import { Day, DayType, HolidayType, HoursType, IntervalType, WeekType } from "./types.js"; export function luxonDateToDay(d: DateTime): Day { const dayMap: Record = { @@ -74,9 +67,7 @@ export class HoursInterval { [interval.start, interval.end].forEach((time) => { if (time.split(":").length !== 2) { - throw new Error( - `expected interval start and end data to be in the format "HH:MM"` - ); + throw new Error(`expected interval start and end data to be in the format "HH:MM"`); } }); @@ -162,8 +153,7 @@ export class HoursInterval { is24h(): boolean { const startIs00 = this.start.minute === 0 && this.start.hour === 0; const endIs00 = this.end.minute === 0 && this.end.hour === 0; - const daysAreConsecutive = - this.end.day - this.start.day === 1 || this.end.day === 1; + const daysAreConsecutive = this.end.day - this.start.day === 1 || this.end.day === 1; return startIs00 && endIs00 && daysAreConsecutive; } } @@ -202,11 +192,7 @@ export class Hours { if (hours && !hours.isClosed) { for (const interval of hours.openIntervals || []) { - const hoursInterval = new HoursInterval( - hoursDate, - interval, - this.timezone - ); + const hoursInterval = new HoursInterval(hoursDate, interval, this.timezone); if (hoursInterval.contains(date)) { return hoursInterval; @@ -276,8 +262,7 @@ export class Hours { if (hours?.openIntervals && !hours.isClosed) { intervalsList.push( ...hours.openIntervals.map( - (interval: IntervalType) => - new HoursInterval(theDate, interval, this.timezone) + (interval: IntervalType) => new HoursInterval(theDate, interval, this.timezone) ) ); } @@ -296,9 +281,7 @@ export class Hours { return null; } - return ( - this.holidayHoursByDate[(date.toISO() || "").replace(/T.*/, "")] || null - ); + return this.holidayHoursByDate[(date.toISO() || "").replace(/T.*/, "")] || null; } /** @@ -405,10 +388,7 @@ export function arrayShift(arr: Array, n: number): Array { /** * @returns boolean whether the two intervals lists are equal */ -export function intervalsListsAreEqual( - il1: HoursInterval[], - il2: HoursInterval[] -): boolean { +export function intervalsListsAreEqual(il1: HoursInterval[], il2: HoursInterval[]): boolean { if (il1.length !== il2.length) { return false; } diff --git a/packages/pages-components/src/components/hours/hoursStatus.stories.tsx b/packages/pages-components/src/components/hours/hoursStatus.stories.tsx index 89d469e5..9837fda0 100644 --- a/packages/pages-components/src/components/hours/hoursStatus.stories.tsx +++ b/packages/pages-components/src/components/hours/hoursStatus.stories.tsx @@ -201,9 +201,7 @@ export const IndividualTemplatesOverrideOpen: Story = { timeTemplate: () => <>, dayOfWeekTemplate: (s: StatusParams) => ( - {s.isOpen - ? s.currentInterval?.getEndTime() - : s.futureInterval?.getStartTime()} + {s.isOpen ? s.currentInterval?.getEndTime() : s.futureInterval?.getStartTime()} ), separatorTemplate: () => " :: ", @@ -229,9 +227,7 @@ export const IndividualTemplatesOverrideClosed: Story = { timeTemplate: () => <>, dayOfWeekTemplate: (s: StatusParams) => ( - {s.isOpen - ? s.currentInterval?.getEndTime() - : s.futureInterval?.getStartTime()} + {s.isOpen ? s.currentInterval?.getEndTime() : s.futureInterval?.getStartTime()} ), separatorTemplate: () => " :: ", @@ -253,8 +249,7 @@ export const IndividualTemplatesOverrideClosed: Story = { export const CompleteTemplateOverrideOpen: Story = { args: { hours: HoursData, - statusTemplate: (s: StatusParams) => - s.isOpen ? "We are open" : "We are closed", + statusTemplate: (s: StatusParams) => (s.isOpen ? "We are open" : "We are closed"), }, parameters: { mockedLuxonDateTime: DateTime.fromObject( @@ -266,8 +261,7 @@ export const CompleteTemplateOverrideOpen: Story = { export const CompleteTemplateOverrideClosed: Story = { args: { hours: HoursData, - statusTemplate: (s: StatusParams) => - s.isOpen ? "We are open" : "We are closed", + statusTemplate: (s: StatusParams) => (s.isOpen ? "We are open" : "We are closed"), }, parameters: { mockedLuxonDateTime: DateTime.fromObject( diff --git a/packages/pages-components/src/components/hours/hoursStatus.tsx b/packages/pages-components/src/components/hours/hoursStatus.tsx index 01abed42..1c34d41a 100644 --- a/packages/pages-components/src/components/hours/hoursStatus.tsx +++ b/packages/pages-components/src/components/hours/hoursStatus.tsx @@ -2,11 +2,7 @@ import React, { useEffect, useState } from "react"; import c from "classnames"; import { Hours } from "./hours.js"; import { DateTime } from "luxon"; -import { - HoursStatusProps, - StatusParams, - StatusTemplateParams, -} from "./types.js"; +import { HoursStatusProps, StatusParams, StatusTemplateParams } from "./types.js"; function isOpen24h(params: StatusParams): boolean { return params?.currentInterval?.is24h?.() || false; @@ -23,11 +19,7 @@ function defaultCurrentTemplate(params: StatusParams): React.ReactNode { if (isIndefinitelyClosed(params)) { return Temporarily Closed; } - return ( - - {params.isOpen ? "Open Now" : "Closed"} - - ); + return {params.isOpen ? "Open Now" : "Closed"}; } function defaultSeparatorTemplate(params: StatusParams): React.ReactNode { @@ -41,11 +33,7 @@ function defaultFutureTemplate(params: StatusParams): React.ReactNode { if (isOpen24h(params) || isIndefinitelyClosed(params)) { return null; } - return ( - - {params.isOpen ? "Closes at" : "Opens at"} - - ); + return {params.isOpen ? "Closes at" : "Opens at"}; } function defaultTimeTemplate(params: StatusParams): React.ReactNode { @@ -75,12 +63,10 @@ function defaultDayOfWeekTemplate(params: StatusParams): React.ReactNode { let dayOfWeek = ""; if (params.isOpen) { const interval = params.currentInterval; - dayOfWeek += - interval?.end?.setLocale("en-US").toLocaleString(dayOptions) || ""; + dayOfWeek += interval?.end?.setLocale("en-US").toLocaleString(dayOptions) || ""; } else { const interval = params.futureInterval; - dayOfWeek += - interval?.start?.setLocale("en-US").toLocaleString(dayOptions) || ""; + dayOfWeek += interval?.start?.setLocale("en-US").toLocaleString(dayOptions) || ""; } return {dayOfWeek}; } @@ -90,12 +76,10 @@ function defaultStatusTemplate( props?: HoursStatusProps ): React.ReactNode { const currentTemplate = params.currentTemplate || defaultCurrentTemplate; - const separatorTemplate = - params.separatorTemplate || defaultSeparatorTemplate; + const separatorTemplate = params.separatorTemplate || defaultSeparatorTemplate; const futureTemplate = params.futureTemplate || defaultFutureTemplate; const timeTemplate = params.timeTemplate || defaultTimeTemplate; - const dayOfWeekTemplate = - params.dayOfWeekTemplate || defaultDayOfWeekTemplate; + const dayOfWeekTemplate = params.dayOfWeekTemplate || defaultDayOfWeekTemplate; return (
    @@ -165,10 +149,7 @@ const HoursStatus: React.FC = (props) => { {isClient ? ( statusTemplateFn(statusParams, props) ) : ( -
    +
    )} ); diff --git a/packages/pages-components/src/components/hours/hoursTable.tsx b/packages/pages-components/src/components/hours/hoursTable.tsx index 1e45c6e8..a7e18dcc 100644 --- a/packages/pages-components/src/components/hours/hoursTable.tsx +++ b/packages/pages-components/src/components/hours/hoursTable.tsx @@ -67,10 +67,7 @@ export function collapseDays( return { ...day, dayOfWeek: "Collapsed", - dayName: - day.startDay === day.endDay - ? `${startDayName}` - : `${startDayName} - ${endDayName}`, + dayName: day.startDay === day.endDay ? `${startDayName}` : `${startDayName} - ${endDayName}`, }; }); } @@ -81,8 +78,7 @@ function defaultIntervalStringsBuilder( translations?: HoursTableIntervalTranslations ): string[] { const intervalStrings: string[] = []; - const isOpen24h = - dayData.intervals.length > 0 && dayData.intervals[0].is24h(); + const isOpen24h = dayData.intervals.length > 0 && dayData.intervals[0].is24h(); if (dayData.intervals.length === 0) { intervalStrings.push(translations?.isClosed || "Closed"); } else if (isOpen24h) { @@ -93,10 +89,7 @@ function defaultIntervalStringsBuilder( translations?.timeFormatLocale || "en-US", timeOptions ); - const endTime = interval.getEndTime( - translations?.timeFormatLocale || "en-US", - timeOptions - ); + const endTime = interval.getEndTime(translations?.timeFormatLocale || "en-US", timeOptions); intervalStrings.push(`${startTime} - ${endTime}`); }); } @@ -156,32 +149,19 @@ const HoursTable: React.FC = (props) => { } return ( - <> - {isClient ? ( - - ) : ( - - )} - + <>{isClient ? : } ); }; export const ClientSideHoursTable: React.FC = (props) => { - const h = new Hours( - props.hours, - Intl.DateTimeFormat().resolvedOptions().timeZone - ); + const h = new Hours(props.hours, Intl.DateTimeFormat().resolvedOptions().timeZone); const now = DateTime.now(); // Fetch intervals for the next 7 days const allIntervals = h.getIntervalsForNDays(7, now); // Split intervals into buckets by day of week - const hoursDays = intervalsToHoursDays( - allIntervals, - now, - props.dayOfWeekNames - ); + const hoursDays = intervalsToHoursDays(allIntervals, now, props.dayOfWeekNames); return ; }; @@ -203,33 +183,24 @@ export const ServerSideHoursTable: React.FC = (props) => { }; }); - const holidayHoursData: HoursTableDayData[] | undefined = - hours.holidayHours?.map((holiday) => { - const date = DateTime.fromFormat(holiday.date, "yyyy-MM-dd"); - const day = luxonDateToDay(date); - return { - dayName: date - .setLocale(intervalTranslations?.timeFormatLocale || "en-US") - .toLocaleString(), - isToday: false, - startDay: day, - endDay: day, - intervals: - (holiday.isRegularHours - ? holiday.openIntervals?.map( - (interval) => new HoursInterval(date, interval, "UTC") - ) - : hoursTableData.find((d) => d.startDay === day)?.intervals) ?? [], - }; - }); + const holidayHoursData: HoursTableDayData[] | undefined = hours.holidayHours?.map((holiday) => { + const date = DateTime.fromFormat(holiday.date, "yyyy-MM-dd"); + const day = luxonDateToDay(date); + return { + dayName: date.setLocale(intervalTranslations?.timeFormatLocale || "en-US").toLocaleString(), + isToday: false, + startDay: day, + endDay: day, + intervals: + (holiday.isRegularHours + ? holiday.openIntervals?.map((interval) => new HoursInterval(date, interval, "UTC")) + : hoursTableData.find((d) => d.startDay === day)?.intervals) ?? [], + }; + }); return ( <> - + {holidayHoursData && holidayHoursData.length > 0 && ( { // Sort the days const startIndex = days.indexOf( - startOfWeekOptionToDay( - isClient || startOfWeek !== "today" ? startOfWeek : "sunday" - ) + startOfWeekOptionToDay(isClient || startOfWeek !== "today" ? startOfWeek : "sunday") ); const sortOrder = arrayShift(days, 7 - startIndex); if (!isHolidayHours) { - hoursData.sort( - (d1, d2) => - sortOrder.indexOf(d1.startDay) - sortOrder.indexOf(d2.startDay) - ); + hoursData.sort((d1, d2) => sortOrder.indexOf(d1.startDay) - sortOrder.indexOf(d2.startDay)); if (props.collapseDays) { hoursData = collapseDays(hoursData, dayOfWeekNames); } @@ -310,13 +276,8 @@ const HoursTableComponent = (props: HoursTableComponentProps) => { return (
    {hoursData.map((dayData) => { - const builderFn = - intervalStringsBuilderFn || defaultIntervalStringsBuilder; - const intervalStrings = builderFn( - dayData, - timeOptions, - intervalTranslations - ); + const builderFn = intervalStringsBuilderFn || defaultIntervalStringsBuilder; + const intervalStrings = builderFn(dayData, timeOptions, intervalTranslations); return (
    string[]; + intervalStringsBuilderFn?: (h: HoursTableDayData, t?: Intl.DateTimeFormatOptions) => string[]; /** Override values for hardcoded strings */ intervalTranslations?: HoursTableIntervalTranslations; className?: string; diff --git a/packages/pages-components/src/components/image/fileUrl.test.ts b/packages/pages-components/src/components/image/fileUrl.test.ts index 4a577596..4c7df6d7 100644 --- a/packages/pages-components/src/components/image/fileUrl.test.ts +++ b/packages/pages-components/src/components/image/fileUrl.test.ts @@ -25,8 +25,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.mktgcdn.com/f/1234/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.mktgcdn.com/f/1234/contentHash.pdf/width=126,height=164", }, { name: "ProdEU", @@ -51,8 +50,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.eu.mktgcdn.com/f/100001234/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.eu.mktgcdn.com/f/100001234/contentHash.pdf/width=126,height=164", }, { name: "ProdEUAccountZero", @@ -65,8 +63,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.eu.mktgcdn.com/f/0/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.eu.mktgcdn.com/f/0/contentHash.pdf/width=126,height=164", }, { name: "USSandbox", @@ -78,8 +75,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.mktgcdn.com/f-sandbox/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.mktgcdn.com/f-sandbox/contentHash.pdf/width=126,height=164", }, { name: "USSandboxAccount", @@ -92,8 +88,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.mktgcdn.com/f-sandbox/1234/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.mktgcdn.com/f-sandbox/1234/contentHash.pdf/width=126,height=164", }, { name: "EUQA", @@ -105,8 +100,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.eu.mktgcdn.com/f-qa/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.eu.mktgcdn.com/f-qa/contentHash.pdf/width=126,height=164", }, { name: "EUQAAccount", @@ -119,8 +113,7 @@ const validCases = [ contentHash: "contentHash", extension: ".pdf", } as FileUrl, - dynUrl: - "https://dyn.eu.mktgcdn.com/f-qa/100001234/contentHash.pdf/width=126,height=164", + dynUrl: "https://dyn.eu.mktgcdn.com/f-qa/100001234/contentHash.pdf/width=126,height=164", }, { name: "USDevNoExtension", @@ -145,8 +138,7 @@ const validCases = [ extension: ".pdf", } as FileUrl, imageTransformations: { format: "avif" } as ImageTransformations, - dynUrl: - "https://dyn.eu.mktgcdn.com/f/contentHash.pdf/width=126,height=164,format=avif", + dynUrl: "https://dyn.eu.mktgcdn.com/f/contentHash.pdf/width=126,height=164,format=avif", }, ]; @@ -155,9 +147,9 @@ describe("parseFileUrl valid", () => { `returns valid parsedFileUrl for $name - $input`, ({ input, want, dynUrl, imageTransformations }) => { expect(parseFileUrl(input)).toEqual(want); - expect( - fileUrlToDynString(parseFileUrl(input)!, 126, 164, imageTransformations) - ).toEqual(dynUrl); + expect(fileUrlToDynString(parseFileUrl(input)!, 126, 164, imageTransformations)).toEqual( + dynUrl + ); } ); }); @@ -202,10 +194,7 @@ const invalidCases = [ ]; describe("parseFileUrl invalid", () => { - test.each(invalidCases)( - `returns invalid parsedFileUrl for $name - $input`, - ({ input }) => { - expect(parseFileUrl(input)).toEqual(undefined); - } - ); + test.each(invalidCases)(`returns invalid parsedFileUrl for $name - $input`, ({ input }) => { + expect(parseFileUrl(input)).toEqual(undefined); + }); }); diff --git a/packages/pages-components/src/components/image/fileUrl.ts b/packages/pages-components/src/components/image/fileUrl.ts index 9ca32b01..bcd3135d 100644 --- a/packages/pages-components/src/components/image/fileUrl.ts +++ b/packages/pages-components/src/components/image/fileUrl.ts @@ -1,10 +1,5 @@ import { ImageTransformations } from "./types.js"; -import { - Env, - getImageTransformationsString, - isValidHttpUrl, - Partition, -} from "./url.js"; +import { Env, getImageTransformationsString, isValidHttpUrl, Partition } from "./url.js"; // FileURL is a URL for a file stored in the Yext CDN. // @@ -138,8 +133,7 @@ export const convertFileUrl = (parsedUrl: URL): FileUrl | undefined => { } const extAndContentHash = pathParts[pathParts.length - 1].split("."); - const extension = - extAndContentHash.length === 2 ? `.${extAndContentHash[1]}` : ""; + const extension = extAndContentHash.length === 2 ? `.${extAndContentHash[1]}` : ""; const contentHash = extAndContentHash[0]; return { @@ -176,11 +170,9 @@ export const fileUrlToDynString = ( } } - const accountId = - fileUrl.accountId !== undefined ? `${fileUrl.accountId}/` : ""; + const accountId = fileUrl.accountId !== undefined ? `${fileUrl.accountId}/` : ""; - const imageTransformationsString = - getImageTransformationsString(imageTransformations); + const imageTransformationsString = getImageTransformationsString(imageTransformations); return `${dynUrl}/${bucket}/${accountId}${fileUrl.contentHash}${ fileUrl.extension diff --git a/packages/pages-components/src/components/image/image.test.tsx b/packages/pages-components/src/components/image/image.test.tsx index d1d852f1..f08dde9d 100644 --- a/packages/pages-components/src/components/image/image.test.tsx +++ b/packages/pages-components/src/components/image/image.test.tsx @@ -1,10 +1,5 @@ import { describe, it, expect, vi } from "vitest"; -import { - Image, - validateRequiredProps, - handleLayout, - getImageSizeForFixedLayout, -} from "./image.js"; +import { Image, validateRequiredProps, handleLayout, getImageSizeForFixedLayout } from "./image.js"; import { ImageLayoutOption } from "./types.js"; import { render, screen } from "@testing-library/react"; @@ -43,10 +38,7 @@ describe("Image", () => { expect(screen.getByRole("img").style.objectFit).toEqual(overrideObjectFit); expect(screen.getByRole("img")).toHaveProperty("src", overrideSrc); - expect(screen.getByRole("img")).toHaveProperty( - "alt", - image.image.alternateText - ); + expect(screen.getByRole("img")).toHaveProperty("alt", image.image.alternateText); }); it("properly renders non-complex image field", () => { @@ -66,10 +58,7 @@ describe("Image", () => { expect(screen.getByRole("img").style.objectFit).toEqual(overrideObjectFit); expect(screen.getByRole("img")).toHaveProperty("src", overrideSrc); - expect(screen.getByRole("img")).toHaveProperty( - "alt", - simpleImage.alternateText - ); + expect(screen.getByRole("img")).toHaveProperty("alt", simpleImage.alternateText); }); it("properly renders non-complex image field with EU url", () => { @@ -92,10 +81,7 @@ describe("Image", () => { expect(screen.getByRole("img").style.objectFit).toEqual(overrideObjectFit); expect(screen.getByRole("img")).toHaveProperty("src", overrideSrc); - expect(screen.getByRole("img")).toHaveProperty( - "alt", - simpleImage.alternateText - ); + expect(screen.getByRole("img")).toHaveProperty("alt", simpleImage.alternateText); }); it("properly renders the placeholder before the image is loaded", () => { @@ -104,11 +90,7 @@ describe("Image", () => { const onLoad = vi.fn(); render( - onLoad() }} - /> + onLoad() }} /> ); expect(screen.getByText(placeholderText)).toBeTruthy(); @@ -202,14 +184,7 @@ describe("Image", () => { }); it("properly renders the sizes for a fixed width", () => { - render( - - ); + render(); const img = screen.getByRole("img", { name: /alt text/i, @@ -294,9 +269,7 @@ describe("handleLayout", () => { undefined ); - expect(src).toEqual( - `https://dyn.mktgcdn.com/p/${imgUUID}/width=${width},height=${height}` - ); + expect(src).toEqual(`https://dyn.mktgcdn.com/p/${imgUUID}/width=${width},height=${height}`); expect(imgStyle.width).toEqual(width); expect(imgStyle.height).toEqual(height); expect(widths).toEqual([width]); @@ -459,36 +432,32 @@ describe("validateRequiredProps", () => { ); expect(logMock.mock.calls.length).toBe(1); - expect(logMock.mock.calls[0][0]).toBe( - `Invalid image width: ${invalidImgWidth}.` - ); + expect(logMock.mock.calls[0][0]).toBe(`Invalid image width: ${invalidImgWidth}.`); vi.clearAllMocks(); }); }); describe("getImageSizeForFixedLayout", () => { it("properly sets fixedWidth and fixedHeight", () => { - expect( - getImageSizeForFixedLayout( - imgWidth, - imgHeight, - widths, - undefined, - undefined - ) - ).toEqual({ + expect(getImageSizeForFixedLayout(imgWidth, imgHeight, widths, undefined, undefined)).toEqual({ fixedWidth: imgWidth, fixedHeight: imgHeight, fixedWidths: widths, }); - expect( - getImageSizeForFixedLayout(imgWidth, imgHeight, widths, width, undefined) - ).toEqual({ fixedWidth: width, fixedHeight: height, fixedWidths: [width] }); - expect( - getImageSizeForFixedLayout(imgWidth, imgHeight, widths, undefined, height) - ).toEqual({ fixedWidth: width, fixedHeight: height, fixedWidths: [width] }); - expect( - getImageSizeForFixedLayout(imgWidth, imgHeight, widths, width, height) - ).toEqual({ fixedWidth: width, fixedHeight: height, fixedWidths: [width] }); + expect(getImageSizeForFixedLayout(imgWidth, imgHeight, widths, width, undefined)).toEqual({ + fixedWidth: width, + fixedHeight: height, + fixedWidths: [width], + }); + expect(getImageSizeForFixedLayout(imgWidth, imgHeight, widths, undefined, height)).toEqual({ + fixedWidth: width, + fixedHeight: height, + fixedWidths: [width], + }); + expect(getImageSizeForFixedLayout(imgWidth, imgHeight, widths, width, height)).toEqual({ + fixedWidth: width, + fixedHeight: height, + fixedWidths: [width], + }); }); }); diff --git a/packages/pages-components/src/components/image/image.tsx b/packages/pages-components/src/components/image/image.tsx index 270c26cd..140c262e 100644 --- a/packages/pages-components/src/components/image/image.tsx +++ b/packages/pages-components/src/components/image/image.tsx @@ -1,11 +1,6 @@ import * as React from "react"; import { useEffect, useRef, useState } from "react"; -import { - ImageProps, - ImageLayout, - ImageLayoutOption, - ImageTransformations, -} from "./types.js"; +import { ImageProps, ImageLayout, ImageLayoutOption, ImageTransformations } from "./types.js"; import { getImageUrl, isValidHttpUrl } from "./url.js"; /** @@ -44,14 +39,7 @@ export const Image = ({ } }, []); - validateRequiredProps( - layout, - imageData.width, - imageData.height, - width, - height, - aspectRatio - ); + validateRequiredProps(layout, imageData.width, imageData.height, width, height, aspectRatio); const imgWidth = Math.abs(imageData.width); if (!imgWidth) { @@ -95,9 +83,7 @@ export const Image = ({ const maxWidthBreakpoints = [640, 768, 1024, 1280, 1536]; const sizes: string = widths .map((w, i) => - i === widths.length - 1 - ? `${w}px` - : `(max-width: ${maxWidthBreakpoints[i]}px) ${w}px` + i === widths.length - 1 ? `${w}px` : `(max-width: ${maxWidthBreakpoints[i]}px) ${w}px` ) .join(", "); @@ -140,9 +126,7 @@ export const validateRequiredProps = ( if (layout === ImageLayoutOption.FIXED) { if (!width && !height) { - console.warn( - "Using fixed layout but neither width nor height is passed as props." - ); + console.warn("Using fixed layout but neither width nor height is passed as props."); return; } @@ -165,9 +149,7 @@ export const validateRequiredProps = ( } if (layout === ImageLayoutOption.ASPECT && !aspectRatio) { - console.warn( - "Using aspect layout but aspectRatio is not passed as a prop." - ); + console.warn("Using aspect layout but aspectRatio is not passed as a prop."); } }; @@ -192,16 +174,9 @@ export const handleLayout = ( updatedImageTransformations: ImageTransformations; } => { let widths: number[] = [100, 320, 640, 960, 1280, 1920]; - let src = getImageUrl( - imgUrl, - 500, - aspectRatio ? 500 / aspectRatio : 500, - imageTransformations - ); + let src = getImageUrl(imgUrl, 500, aspectRatio ? 500 / aspectRatio : 500, imageTransformations); const imgStyle = { ...style }; - const updatedImageTransformations = imageTransformations - ? { ...imageTransformations } - : {}; + const updatedImageTransformations = imageTransformations ? { ...imageTransformations } : {}; imgStyle.objectFit = imgStyle.objectFit || "cover"; imgStyle.objectPosition = imgStyle.objectPosition || "center"; @@ -210,45 +185,32 @@ export const handleLayout = ( // Don't let image be wider than its intrinsic width imgStyle.maxWidth = imgWidth; imgStyle.width = "100%"; - imgStyle.aspectRatio = aspectRatio - ? `${aspectRatio}` - : `${imgWidth} / ${imgHeight}`; + imgStyle.aspectRatio = aspectRatio ? `${aspectRatio}` : `${imgWidth} / ${imgHeight}`; break; case ImageLayoutOption.FIXED: { - const { fixedWidth, fixedHeight, fixedWidths } = - getImageSizeForFixedLayout( - imgWidth, - imgHeight, - widths, - absWidth, - absHeight - ); + const { fixedWidth, fixedHeight, fixedWidths } = getImageSizeForFixedLayout( + imgWidth, + imgHeight, + widths, + absWidth, + absHeight + ); imgStyle.width = fixedWidth; imgStyle.height = fixedHeight; widths = fixedWidths; - src = getImageUrl( - imgUrl, - fixedWidth, - fixedHeight, - updatedImageTransformations - ); + src = getImageUrl(imgUrl, fixedWidth, fixedHeight, updatedImageTransformations); break; } case ImageLayoutOption.ASPECT: - imgStyle.aspectRatio = aspectRatio - ? `${aspectRatio}` - : `${imgWidth} / ${imgHeight}`; - updatedImageTransformations.fit = - updatedImageTransformations?.fit || "cover"; + imgStyle.aspectRatio = aspectRatio ? `${aspectRatio}` : `${imgWidth} / ${imgHeight}`; + updatedImageTransformations.fit = updatedImageTransformations?.fit || "cover"; break; case ImageLayoutOption.FILL: imgStyle.width = "100%"; - imgStyle.aspectRatio = aspectRatio - ? `${aspectRatio}` - : `${imgWidth} / ${imgHeight}`; + imgStyle.aspectRatio = aspectRatio ? `${aspectRatio}` : `${imgWidth} / ${imgHeight}`; break; default: diff --git a/packages/pages-components/src/components/image/photoUrl.test.ts b/packages/pages-components/src/components/image/photoUrl.test.ts index 7e4ae9ad..df4001db 100644 --- a/packages/pages-components/src/components/image/photoUrl.test.ts +++ b/packages/pages-components/src/components/image/photoUrl.test.ts @@ -52,8 +52,7 @@ const validCases = [ name: "126x164", extension: ".jpg", } as PhotoUrl, - dynUrl: - "https://dyn.mktgcdn.com/p-sandbox/contentHash/width=126,height=164", + dynUrl: "https://dyn.mktgcdn.com/p-sandbox/contentHash/width=126,height=164", }, { name: "CDN Params", @@ -70,8 +69,7 @@ const validCases = [ format: "avif", fit: "contain", } as ImageTransformations, - dynUrl: - "https://dyn.mktgcdn.com/p/contentHash/width=126,height=164,format=avif,fit=contain", + dynUrl: "https://dyn.mktgcdn.com/p/contentHash/width=126,height=164,format=avif,fit=contain", }, ]; @@ -80,14 +78,9 @@ describe("parsePhotoUrl valid", () => { `returns valid parsedPhotoUrl for $name - $input`, ({ input, want, dynUrl, imageTransformations }) => { expect(parsePhotoUrl(input)).toEqual(want); - expect( - photoUrlToDynString( - parsePhotoUrl(input)!, - 126, - 164, - imageTransformations - ) - ).toEqual(dynUrl); + expect(photoUrlToDynString(parsePhotoUrl(input)!, 126, 164, imageTransformations)).toEqual( + dynUrl + ); } ); }); @@ -119,16 +112,12 @@ const invalidCases = [ }, { name: "InvalidPath", - input: - "https://a.mktgcdn.com/p/1234/too/many/segments/contentHash/126x164.jpg", + input: "https://a.mktgcdn.com/p/1234/too/many/segments/contentHash/126x164.jpg", }, ]; describe("parsePhotoUrl invalid", () => { - test.each(invalidCases)( - `returns invalid parsedPhotoUrl for $name - $input`, - ({ input }) => { - expect(parsePhotoUrl(input)).toEqual(undefined); - } - ); + test.each(invalidCases)(`returns invalid parsedPhotoUrl for $name - $input`, ({ input }) => { + expect(parsePhotoUrl(input)).toEqual(undefined); + }); }); diff --git a/packages/pages-components/src/components/image/photoUrl.ts b/packages/pages-components/src/components/image/photoUrl.ts index 2ba3d690..43e08ffe 100644 --- a/packages/pages-components/src/components/image/photoUrl.ts +++ b/packages/pages-components/src/components/image/photoUrl.ts @@ -169,8 +169,7 @@ export const photoUrlToDynString = ( } } - const imageTransformationsString = - getImageTransformationsString(imageTransformations); + const imageTransformationsString = getImageTransformationsString(imageTransformations); return `${dynUrl}/${bucket}/${photoUrl.contentHash}/width=${Math.round( width diff --git a/packages/pages-components/src/components/image/types.ts b/packages/pages-components/src/components/image/types.ts index 07ecf8de..1f3deb61 100644 --- a/packages/pages-components/src/components/image/types.ts +++ b/packages/pages-components/src/components/image/types.ts @@ -67,8 +67,7 @@ export const ImageLayoutOption = { * * @public */ -export type ImageLayout = - (typeof ImageLayoutOption)[keyof typeof ImageLayoutOption]; +export type ImageLayout = (typeof ImageLayoutOption)[keyof typeof ImageLayoutOption]; /** * The shape of the data passed to {@link Image}. diff --git a/packages/pages-components/src/components/image/url.test.ts b/packages/pages-components/src/components/image/url.test.ts index 84005428..6f88e55f 100644 --- a/packages/pages-components/src/components/image/url.test.ts +++ b/packages/pages-components/src/components/image/url.test.ts @@ -39,17 +39,13 @@ describe("getImageUrl", () => { it("converts Yext CDN file URLs", () => { const yextFileUrl = "https://a.mktgcdn.com/f/contentHash.jpg"; const result = getImageUrl(yextFileUrl, width, height); - expect(result).toBe( - "https://dyn.mktgcdn.com/f/contentHash.jpg/width=800,height=600" - ); + expect(result).toBe("https://dyn.mktgcdn.com/f/contentHash.jpg/width=800,height=600"); }); it("converts Yext CDN EU URLs", () => { const yextEuUrl = "https://a.eu.mktgcdn.com/f/contentHash.jpg"; const result = getImageUrl(yextEuUrl, width, height); - expect(result).toBe( - "https://dyn.eu.mktgcdn.com/f/contentHash.jpg/width=800,height=600" - ); + expect(result).toBe("https://dyn.eu.mktgcdn.com/f/contentHash.jpg/width=800,height=600"); }); it("returns Unsplash URLs as-is without conversion", () => { diff --git a/packages/pages-components/src/components/image/url.ts b/packages/pages-components/src/components/image/url.ts index 4d43f898..f1942e87 100644 --- a/packages/pages-components/src/components/image/url.ts +++ b/packages/pages-components/src/components/image/url.ts @@ -75,7 +75,5 @@ export const getImageTransformationsString = ( .map(([key, value]) => `${key}=${value}`) .join(","); - return imageTransformationsString.length > 0 - ? `,${imageTransformationsString}` - : ""; + return imageTransformationsString.length > 0 ? `,${imageTransformationsString}` : ""; }; diff --git a/packages/pages-components/src/components/link/link.test.tsx b/packages/pages-components/src/components/link/link.test.tsx index bcefb922..bc3c2382 100644 --- a/packages/pages-components/src/components/link/link.test.tsx +++ b/packages/pages-components/src/components/link/link.test.tsx @@ -13,11 +13,7 @@ describe("Link", () => { }); it("renders component when given full cta prop and no children", () => { - render( - - ); + render(); }); it("renders component when given full cta prop, no children, and just a link", () => { diff --git a/packages/pages-components/src/components/link/link.tsx b/packages/pages-components/src/components/link/link.tsx index c06ab347..2c6d6a30 100644 --- a/packages/pages-components/src/components/link/link.tsx +++ b/packages/pages-components/src/components/link/link.tsx @@ -22,98 +22,89 @@ import { Action } from "@yext/analytics"; * * @public */ -export const Link = forwardRef( - function Link(props, ref) { - const { - children, - onClick, - className, - eventName, - scope, - currency, - amount, - cta, - obfuscate, - customTags, - customValues, - ...rest - } = props; +export const Link = forwardRef(function Link(props, ref) { + const { + children, + onClick, + className, + eventName, + scope, + currency, + amount, + cta, + obfuscate, + customTags, + customValues, + ...rest + } = props; - const resolvedCta: CTA = resolveCTA(props); - const action: Action = resolveAction(resolvedCta, !!cta); - const resolvedEventName = determineEvent( - eventName, - resolvedCta.linkType, - !!cta - ); - const analytics = useAnalytics(); + const resolvedCta: CTA = resolveCTA(props); + const action: Action = resolveAction(resolvedCta, !!cta); + const resolvedEventName = determineEvent(eventName, resolvedCta.linkType, !!cta); + const analytics = useAnalytics(); - const isObfuscate = - obfuscate || (obfuscate !== false && resolvedCta.linkType === "EMAIL"); + const isObfuscate = obfuscate || (obfuscate !== false && resolvedCta.linkType === "EMAIL"); - const handleClick = async (e: React.MouseEvent) => { - const currentTarget = e.currentTarget; - let decodedLink = ""; + const handleClick = async (e: React.MouseEvent) => { + const currentTarget = e.currentTarget; + let decodedLink = ""; - if (isObfuscate) { - // must happen before the async call - e.preventDefault(); + if (isObfuscate) { + // must happen before the async call + e.preventDefault(); - const encodedLink = currentTarget.href.split("/").at(-1); - if (encodedLink) { - decodedLink = atob(encodedLink); - } - } - - if (analytics !== null) { - try { - await analytics.track({ - action: action, - scope: scope, - eventName: resolvedEventName, - currency: currency, - amount: amount, - destinationUrl: decodedLink || currentTarget.href, - customTags: customTags, - customValues: customValues, - }); - } catch (_) { - console.error("Failed to report click Analytics Event"); - } + const encodedLink = currentTarget.href.split("/").at(-1); + if (encodedLink) { + decodedLink = atob(encodedLink); } + } - if (onClick) { - onClick(e); + if (analytics !== null) { + try { + await analytics.track({ + action: action, + scope: scope, + eventName: resolvedEventName, + currency: currency, + amount: amount, + destinationUrl: decodedLink || currentTarget.href, + customTags: customTags, + customValues: customValues, + }); + } catch (_) { + console.error("Failed to report click Analytics Event"); } + } - if (decodedLink) { - window.location.href = decodedLink; - } - }; + if (onClick) { + onClick(e); + } - const renderedLink = isObfuscate - ? "Obfuscated, set a label or child" - : resolvedCta.link; + if (decodedLink) { + window.location.href = decodedLink; + } + }; - const attributes: any = { - className: classNames("Link", className), - href: isObfuscate ? btoa(resolvedCta.link) : resolvedCta.link, - onClick: handleClick, - rel: props.target && !props.rel ? "noopener" : props.rel, - ref: ref, - }; + const renderedLink = isObfuscate ? "Obfuscated, set a label or child" : resolvedCta.link; - if (analytics?.getDebugEnabled()) { - attributes["data-ya-action"] = action; - attributes["data-ya-scopeoverride"] = scope; - attributes["data-ya-eventname"] = resolvedEventName; - } + const attributes: any = { + className: classNames("Link", className), + href: isObfuscate ? btoa(resolvedCta.link) : resolvedCta.link, + onClick: handleClick, + rel: props.target && !props.rel ? "noopener" : props.rel, + ref: ref, + }; - // hydration warnings suppressed because they will show when the xYextDebug query param is used - return ( - - {children || resolvedCta.label || renderedLink} - - ); + if (analytics?.getDebugEnabled()) { + attributes["data-ya-action"] = action; + attributes["data-ya-scopeoverride"] = scope; + attributes["data-ya-eventname"] = resolvedEventName; } -); + + // hydration warnings suppressed because they will show when the xYextDebug query param is used + return ( + + {children || resolvedCta.label || renderedLink} + + ); +}); diff --git a/packages/pages-components/src/components/link/methods.test.ts b/packages/pages-components/src/components/link/methods.test.ts index b91c9b5b..215f2c44 100644 --- a/packages/pages-components/src/components/link/methods.test.ts +++ b/packages/pages-components/src/components/link/methods.test.ts @@ -108,9 +108,7 @@ test.each<[string | undefined, LinkType | undefined, string]>([ [undefined, "BadLinkType" as LinkType, LEGACY_LINK_EVENT], [undefined, undefined, LEGACY_CTA_EVENT], ])(`determineEvent: %s %s`, (inputEventName, linkType, outputEventName) => { - expect(determineEvent(inputEventName, linkType, false)).toEqual( - outputEventName - ); + expect(determineEvent(inputEventName, linkType, false)).toEqual(outputEventName); }); // determineEvent cta true @@ -125,9 +123,7 @@ test.each<[string | undefined, LinkType | undefined, string]>([ [undefined, "BadLinkType" as LinkType, CTA_EVENT], [undefined, undefined, LEGACY_CTA_EVENT], ])(`determineEvent: %s %s`, (inputEventName, linkType, outputEventName) => { - expect(determineEvent(inputEventName, linkType, true)).toEqual( - outputEventName - ); + expect(determineEvent(inputEventName, linkType, true)).toEqual(outputEventName); }); // resolveAction cta false diff --git a/packages/pages-components/src/components/link/types.ts b/packages/pages-components/src/components/link/types.ts index 5a71eaa4..f70c9e00 100644 --- a/packages/pages-components/src/components/link/types.ts +++ b/packages/pages-components/src/components/link/types.ts @@ -30,11 +30,10 @@ export interface CTA { /** * Configuration options available for any usages of the Link component. */ -interface LinkConfig - extends React.DetailedHTMLProps< - React.AnchorHTMLAttributes, - HTMLAnchorElement - > { +interface LinkConfig extends React.DetailedHTMLProps< + React.AnchorHTMLAttributes, + HTMLAnchorElement +> { /** Obfuscates the href and label. */ obfuscate?: boolean; /** The custom name of the event. */ diff --git a/packages/pages-components/src/components/locationmap/locationmap.stories.tsx b/packages/pages-components/src/components/locationmap/locationmap.stories.tsx index 8c8f6b21..950ec198 100644 --- a/packages/pages-components/src/components/locationmap/locationmap.stories.tsx +++ b/packages/pages-components/src/components/locationmap/locationmap.stories.tsx @@ -23,10 +23,7 @@ const sampleAddress = { export const Map_With_Default_Icon = () => { return ( - + ); }; @@ -34,10 +31,7 @@ export const Map_With_Default_Icon = () => { export const Map_With_No_Link = () => { return ( - + { onHover={handleHover} > {hovered ? ( - + - + ) : ( { coordinate={{ latitude: 38.8974, longitude: -97.0638 }} pinUrl="https://yext.com" > - + - + ); diff --git a/packages/pages-components/src/components/locationmap/locationmap.tsx b/packages/pages-components/src/components/locationmap/locationmap.tsx index f2beda12..4b186749 100644 --- a/packages/pages-components/src/components/locationmap/locationmap.tsx +++ b/packages/pages-components/src/components/locationmap/locationmap.tsx @@ -25,11 +25,7 @@ export const LocationMap = ({ hasPinUrl={(pinUrl || "")?.length > 0} > {pinUrl ? ( - + {children} ) : children ? ( diff --git a/packages/pages-components/src/components/map/clusterer.tsx b/packages/pages-components/src/components/map/clusterer.tsx index 2284bb92..f26ede38 100644 --- a/packages/pages-components/src/components/map/clusterer.tsx +++ b/packages/pages-components/src/components/map/clusterer.tsx @@ -1,10 +1,4 @@ -import React, { - createContext, - useContext, - useEffect, - useState, - Fragment, -} from "react"; +import React, { createContext, useContext, useEffect, useState, Fragment } from "react"; import { MapContext } from "./map.js"; import { Marker } from "./marker.js"; import type { @@ -20,27 +14,10 @@ import { GeoBounds } from "../../map/geoBounds.js"; const defaultClusterTemplate = ({ count }: ClusterTemplateProps) => { return ( - + - - + + {count} @@ -50,17 +27,13 @@ const defaultClusterTemplate = ({ count }: ClusterTemplateProps) => { ); }; -export const ClustererContext = createContext( - null -); +export const ClustererContext = createContext(null); export function useClusterContext() { const ctx = useContext(ClustererContext); if (!ctx) { - throw new Error( - "Attempted to call useClustererContext() outside of ." - ); + throw new Error("Attempted to call useClustererContext() outside of ."); } return ctx; @@ -75,9 +48,7 @@ export const Clusterer = ({ const [pinStore, setPinStore] = useState([]); const [clusters, setClusters] = useState(); const [clusterIds, setClusterIds] = useState([]); - const [clustersToRender, setClustersToRender] = useState< - React.ReactElement[] - >([]); + const [clustersToRender, setClustersToRender] = useState([]); // Recalculate the clusters when either the pin store is updated or the map zoom level changes. useEffect(() => { @@ -161,11 +132,7 @@ export const Clusterer = ({ * @param clusterRadius - pixels from the center of the cluster, and each cluster * has at least one pin. */ -const _generateClusters = ( - pins: PinStoreType[], - zoom: number, - clusterRadius: number -) => { +const _generateClusters = (pins: PinStoreType[], zoom: number, clusterRadius: number) => { const clusterRadiusRadians = (clusterRadius * Math.PI) / 2 ** (zoom + 7); const pinsInRadius = pins.map((_, index) => [index]); const pinClusters = []; @@ -220,10 +187,7 @@ const _generateClusters = ( cluster.push(pins[index]); pinsInRadius[index] = []; pinGroup.forEach((otherIndex) => - pinsInRadius[otherIndex].splice( - pinsInRadius[otherIndex].indexOf(index), - 1 - ) + pinsInRadius[otherIndex].splice(pinsInRadius[otherIndex].indexOf(index), 1) ); } diff --git a/packages/pages-components/src/components/map/map.stories.tsx b/packages/pages-components/src/components/map/map.stories.tsx index ad5b3522..70d2569b 100644 --- a/packages/pages-components/src/components/map/map.stories.tsx +++ b/packages/pages-components/src/components/map/map.stories.tsx @@ -59,12 +59,9 @@ export const Map_With_Current_Center_And_Zoom = () => { mapRef={mapRef} panHandler={panHandler} > -
    +
    - lat: {currentCenter.latitude.toFixed(2)}, long:{" "} - {currentCenter.longitude.toFixed(2)} + lat: {currentCenter.latitude.toFixed(2)}, long: {currentCenter.longitude.toFixed(2)}
    zoom: {currentZoom}
    @@ -89,20 +86,14 @@ export const Multiple_Maps = () => { bounds={[{ latitude: 38.8974, longitude: -77.0638 }]} singleZoom={16} > - + - +
    ); @@ -137,12 +128,8 @@ export const Map_With_Single_Interactive_Marker = () => { coordinate={{ latitude: 38.8954, longitude: -77.0698 }} id="123" onClick={(id: string) => setClicked(id)} - onFocus={(focused: boolean, id: string) => - setFocused(focused ? id : "") - } - onHover={(hovered: boolean, id: string) => - setHovered(hovered ? id : "") - } + onFocus={(focused: boolean, id: string) => setFocused(focused ? id : "")} + onHover={(hovered: boolean, id: string) => setHovered(hovered ? id : "")} > { x="50%" y="40%" d="M30 15.0882C30 23.4212 23.3333 30.7353 15 38C7.22222 31.2941 0 23.4212 0 15.0882C0 6.75523 6.71573 0 15 0C23.2843 0 30 6.75523 30 15.0882Z" - stroke={ - location.id === focusedId || location.id === hoveredId - ? "white" - : "none" - } + stroke={location.id === focusedId || location.id === hoveredId ? "white" : "none"} /> { it("renders with Markers", async () => { render( - + ); }); @@ -56,14 +53,8 @@ describe("Map", () => { render( - - + + ); diff --git a/packages/pages-components/src/components/map/map.tsx b/packages/pages-components/src/components/map/map.tsx index d1a44b2e..97ec72cc 100644 --- a/packages/pages-components/src/components/map/map.tsx +++ b/packages/pages-components/src/components/map/map.tsx @@ -1,10 +1,4 @@ -import React, { - createContext, - useContext, - useEffect, - useRef, - useState, -} from "react"; +import React, { createContext, useContext, useEffect, useRef, useState } from "react"; import classnames from "classnames"; import { GoogleMaps } from "../../map/providers/google.js"; import { Map as MapType, MapOptions } from "../../map/map.js"; @@ -88,8 +82,7 @@ export const Map = ({ // window object to fix the issue. const iframeWindow = !!iframeId && typeof document !== "undefined" - ? ((document.getElementById(iframeId) as HTMLIFrameElement) - ?.contentWindow ?? undefined) + ? ((document.getElementById(iframeId) as HTMLIFrameElement)?.contentWindow ?? undefined) : undefined; const newMap = new MapOptions() @@ -142,11 +135,7 @@ export const Map = ({ ref={wrapper} data-testid="map" > - {map && ( - - {children} - - )} + {map && {children}}
    ); }; diff --git a/packages/pages-components/src/components/map/marker.tsx b/packages/pages-components/src/components/map/marker.tsx index 069a714b..b444c7b5 100644 --- a/packages/pages-components/src/components/map/marker.tsx +++ b/packages/pages-components/src/components/map/marker.tsx @@ -8,13 +8,7 @@ import { HTMLProviderPin } from "../../map/providerPin.js"; import { Coordinate } from "../../map/coordinate.js"; const defaultMarkerIcon = ( - + - pinStore.filter((pin) => pin.id !== id) - ); + cluster.setPinStore((pinStore) => pinStore.filter((pin) => pin.id !== id)); } }; }, []); diff --git a/packages/pages-components/src/components/schema/schemaTypes/FAQPage.test.ts b/packages/pages-components/src/components/schema/schemaTypes/FAQPage.test.ts index 7e3b8917..eaefc988 100644 --- a/packages/pages-components/src/components/schema/schemaTypes/FAQPage.test.ts +++ b/packages/pages-components/src/components/schema/schemaTypes/FAQPage.test.ts @@ -100,10 +100,7 @@ describe("FAQPage", () => { name: "What are your business hours?", acceptedAnswer: { "@type": "Answer", - text: - "Monday - Friday: 9 AM - 5 PM" + - "Saturday: 10 AM - 2 PM" + - "Sunday: Closed", + text: "Monday - Friday: 9 AM - 5 PM" + "Saturday: 10 AM - 2 PM" + "Sunday: Closed", }, }, ], diff --git a/packages/pages-components/src/components/schema/schemaTypes/FAQPage.tsx b/packages/pages-components/src/components/schema/schemaTypes/FAQPage.tsx index 62ef3fbb..ebdaf10f 100644 --- a/packages/pages-components/src/components/schema/schemaTypes/FAQPage.tsx +++ b/packages/pages-components/src/components/schema/schemaTypes/FAQPage.tsx @@ -31,10 +31,7 @@ const validateRichTextFAQ = (faq: any): faq is RichTextFAQ => { return false; }; -function getTextNodesFromJson( - rtfObject: Record, - textNodes: string[] -) { +function getTextNodesFromJson(rtfObject: Record, textNodes: string[]) { for (const key in rtfObject) { if (typeof rtfObject[key] === "object") { if (Array.isArray(rtfObject[key])) { diff --git a/packages/pages-components/src/components/schema/schemaTypes/LocalBusiness.test.ts b/packages/pages-components/src/components/schema/schemaTypes/LocalBusiness.test.ts index 72cd0b5b..1c931d38 100644 --- a/packages/pages-components/src/components/schema/schemaTypes/LocalBusiness.test.ts +++ b/packages/pages-components/src/components/schema/schemaTypes/LocalBusiness.test.ts @@ -108,10 +108,7 @@ describe("LocalBusiness", () => { "@context": "https://schema.org", "@type": "LocalBusiness", name: "Test Business", - image: [ - "https://example.com/image1.jpg", - "https://example.com/image2.jpg", - ], + image: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"], }); }); @@ -170,10 +167,7 @@ describe("LocalBusiness", () => { addressCountry: "US", }, openingHours: ["Mo,Tu,We,Th,Fr 09:00-17:00", "Sa,Su 00:00-00:00"], - image: [ - "https://example.com/image1.jpg", - "https://example.com/image2.jpg", - ], + image: ["https://example.com/image1.jpg", "https://example.com/image2.jpg"], description: "This is a comprehensive test business.", telephone: "987-654-3210", email: "comprehensive@example.com", diff --git a/packages/pages-components/src/components/schema/schemaTypes/Product.test.tsx b/packages/pages-components/src/components/schema/schemaTypes/Product.test.tsx index 57784a60..324d601c 100644 --- a/packages/pages-components/src/components/schema/schemaTypes/Product.test.tsx +++ b/packages/pages-components/src/components/schema/schemaTypes/Product.test.tsx @@ -57,10 +57,7 @@ describe("Product", () => { "@context": "https://schema.org", "@type": "Product", name: "Test Product", - image: [ - "https://example.com/product-image1.jpg", - "https://example.com/product-image2.jpg", - ], + image: ["https://example.com/product-image1.jpg", "https://example.com/product-image2.jpg"], }); }); @@ -190,10 +187,7 @@ describe("Product", () => { "@context": "https://schema.org", "@type": "Product", name: "Comprehensive Product", - image: [ - "https://example.com/product-image1.jpg", - "https://example.com/product-image2.jpg", - ], + image: ["https://example.com/product-image1.jpg", "https://example.com/product-image2.jpg"], review: { "@type": "Review", reviewRating: { diff --git a/packages/pages-components/src/components/schema/yextFields/address.test.ts b/packages/pages-components/src/components/schema/yextFields/address.test.ts index c45e3725..0757ae8e 100644 --- a/packages/pages-components/src/components/schema/yextFields/address.test.ts +++ b/packages/pages-components/src/components/schema/yextFields/address.test.ts @@ -1,10 +1,5 @@ import { describe, it, expect } from "vitest"; -import { - AddressSchema, - LocationSchema, - validateAddress, - validateLocation, -} from "./address.js"; +import { AddressSchema, LocationSchema, validateAddress, validateLocation } from "./address.js"; const address = { city: "Arlington", @@ -18,17 +13,13 @@ const address = { describe("validateLocation", () => { it("returns true for valid locations", () => { - expect(validateLocation({ name: "Business Name", address: address })).toBe( - true - ); + expect(validateLocation({ name: "Business Name", address: address })).toBe(true); expect(validateLocation({ name: "Business Name" })).toBe(true); expect(validateLocation({ address: address })).toBe(true); }); it("returns false for invalid locations", () => { - expect( - validateLocation('{ name: "Business Name", address: address }') - ).toBe(false); + expect(validateLocation('{ name: "Business Name", address: address }')).toBe(false); expect(validateLocation(undefined)).toBe(false); expect(validateLocation(1)).toBe(false); expect(validateLocation({ key: "value" })).toBe(false); diff --git a/packages/pages-components/src/components/schema/yextFields/hours.test.ts b/packages/pages-components/src/components/schema/yextFields/hours.test.ts index 219767ec..2b803f57 100644 --- a/packages/pages-components/src/components/schema/yextFields/hours.test.ts +++ b/packages/pages-components/src/components/schema/yextFields/hours.test.ts @@ -221,9 +221,7 @@ describe("OpeningHoursSpecificationSchema", () => { // 2026-01-01 (isRegularHours: true) is correctly omitted ]; - expect(result.openingHoursSpecification).toEqual( - expect.arrayContaining(expectedRegularHours) - ); + expect(result.openingHoursSpecification).toEqual(expect.arrayContaining(expectedRegularHours)); expect(result.specialOpeningHoursSpecification).toEqual( expect.arrayContaining(expectedSpecialHours) ); diff --git a/packages/pages-components/src/components/schema/yextFields/hours.tsx b/packages/pages-components/src/components/schema/yextFields/hours.tsx index 0a709ffb..a9097e3a 100644 --- a/packages/pages-components/src/components/schema/yextFields/hours.tsx +++ b/packages/pages-components/src/components/schema/yextFields/hours.tsx @@ -39,9 +39,7 @@ export const validateDayType = (hours: any): hours is DayType => { hours.openIntervals.length ) { return hours.openIntervals.every((interval: any) => { - return ( - typeof interval === "object" && "start" in interval && "end" in interval - ); + return typeof interval === "object" && "start" in interval && "end" in interval; }); } @@ -119,12 +117,9 @@ export const OpeningHoursSpecificationSchema = ( openingHoursSpecification: specifications, }; - const holidayHoursSpecifications = getHolidayHoursSpecification( - hours.holidayHours - ); + const holidayHoursSpecifications = getHolidayHoursSpecification(hours.holidayHours); if (holidayHoursSpecifications?.length) { - openingHoursSpecificationSchema.specialOpeningHoursSpecification = - holidayHoursSpecifications; + openingHoursSpecificationSchema.specialOpeningHoursSpecification = holidayHoursSpecifications; } return openingHoursSpecificationSchema; @@ -190,8 +185,7 @@ export const getHoursByDay = ( } for (let i = 0; i < hours.openIntervals.length; i++) { - const interval = - hours.openIntervals[i].start + "-" + hours.openIntervals[i].end; + const interval = hours.openIntervals[i].start + "-" + hours.openIntervals[i].end; const days = hoursMap.get(interval) ?? []; days.push(day); hoursMap.set(interval, days); diff --git a/packages/pages-components/src/components/schema/yextFields/index.ts b/packages/pages-components/src/components/schema/yextFields/index.ts index 50b986fe..ecdc1fcc 100644 --- a/packages/pages-components/src/components/schema/yextFields/index.ts +++ b/packages/pages-components/src/components/schema/yextFields/index.ts @@ -1,19 +1,8 @@ export { AddressSchema, LocationSchema, type Location } from "./address.js"; -export { - OpeningHoursSchema, - OpeningHoursSpecificationSchema, -} from "./hours.js"; +export { OpeningHoursSchema, OpeningHoursSpecificationSchema } from "./hours.js"; export { OfferSchema, type Offer } from "./offers.js"; -export { - PerformerSchema, - OrganizationSchema, - type Organization, -} from "./people.js"; -export { - type PhotoGallery, - PhotoGallerySchema, - PhotoSchema, -} from "./photoGallery.js"; +export { PerformerSchema, OrganizationSchema, type Organization } from "./people.js"; +export { type PhotoGallery, PhotoGallerySchema, PhotoSchema } from "./photoGallery.js"; export { AggregateRatingSchema, ReviewSchema, diff --git a/packages/pages-components/src/components/schema/yextFields/people.test.ts b/packages/pages-components/src/components/schema/yextFields/people.test.ts index ad55a5b5..e0191fb8 100644 --- a/packages/pages-components/src/components/schema/yextFields/people.test.ts +++ b/packages/pages-components/src/components/schema/yextFields/people.test.ts @@ -16,9 +16,7 @@ describe("validateOrganization", () => { it("should return true for valid organizations", () => { expect(validateOrganization({ name: "Google" })).toBe(true); - expect( - validateOrganization({ name: "Google", url: "https://google.com" }) - ).toBe(true); + expect(validateOrganization({ name: "Google", url: "https://google.com" })).toBe(true); }); }); diff --git a/packages/pages-components/src/components/schema/yextFields/photoGallery.test.ts b/packages/pages-components/src/components/schema/yextFields/photoGallery.test.ts index 8f6288db..3965fafe 100644 --- a/packages/pages-components/src/components/schema/yextFields/photoGallery.test.ts +++ b/packages/pages-components/src/components/schema/yextFields/photoGallery.test.ts @@ -1,8 +1,4 @@ -import { - PhotoGallerySchema, - PhotoSchema, - validatePhoto, -} from "./photoGallery.js"; +import { PhotoGallerySchema, PhotoSchema, validatePhoto } from "./photoGallery.js"; describe("validatePhoto", () => { it("returns false for invalid photo objects", () => { @@ -14,9 +10,7 @@ describe("validatePhoto", () => { }); it("should return true for valid photo objects", () => { - expect( - validatePhoto({ image: { url: "https://example.com/image.jpg" } }) - ).toBe(true); + expect(validatePhoto({ image: { url: "https://example.com/image.jpg" } })).toBe(true); expect( validatePhoto({ image: { @@ -57,10 +51,7 @@ describe("PhotoGallerySchema", () => { }, ]; expect(PhotoGallerySchema(gallery)).toEqual({ - image: [ - "https://example.com/photo1.jpg", - "https://example.com/photo2.png", - ], + image: ["https://example.com/photo1.jpg", "https://example.com/photo2.png"], }); }); diff --git a/packages/pages-components/src/components/schema/yextFields/review.test.ts b/packages/pages-components/src/components/schema/yextFields/review.test.ts index ac44d14b..01b9283d 100644 --- a/packages/pages-components/src/components/schema/yextFields/review.test.ts +++ b/packages/pages-components/src/components/schema/yextFields/review.test.ts @@ -39,9 +39,7 @@ describe("validateAggregateRating", () => { }); it("should return true for valid aggregate rating objects", () => { - expect( - validateAggregateRating({ ratingValue: "4.2", reviewCount: "50" }) - ).toBe(true); + expect(validateAggregateRating({ ratingValue: "4.2", reviewCount: "50" })).toBe(true); }); }); diff --git a/packages/pages-components/src/map/coordinate.ts b/packages/pages-components/src/map/coordinate.ts index 3ed4ef58..48a3287c 100644 --- a/packages/pages-components/src/map/coordinate.ts +++ b/packages/pages-components/src/map/coordinate.ts @@ -1,9 +1,4 @@ -import { - Unit, - Projection, - EARTH_RADIUS_MILES, - EARTH_RADIUS_KILOMETERS, -} from "./constants.js"; +import { Unit, Projection, EARTH_RADIUS_MILES, EARTH_RADIUS_KILOMETERS } from "./constants.js"; /** * An array of property names to check in a Coordinate-like object for a value of or function that evaluates to degrees latitude @@ -78,9 +73,7 @@ function haversineDistance(source: Coordinate, dest: Coordinate): number { const a = Math.pow(Math.sin(deltaLat / 2), 2) + - Math.cos(lat1Rads) * - Math.cos(lat2Rads) * - Math.pow(Math.sin(deltaLon / 2), 2); + Math.cos(lat1Rads) * Math.cos(lat2Rads) * Math.pow(Math.sin(deltaLon / 2), 2); return 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); } @@ -92,10 +85,7 @@ function haversineDistance(source: Coordinate, dest: Coordinate): number { * @param latitudeB - The destination latitude in degrees * @returns Distance in radians of longitude */ -function mercatorLatDistanceInRadians( - latitudeA: number, - latitudeB: number -): number { +function mercatorLatDistanceInRadians(latitudeA: number, latitudeB: number): number { const aTan = Math.tan((Math.PI / 360) * (latitudeA + 90)); const bTan = Math.tan((Math.PI / 360) * (latitudeB + 90)); @@ -196,14 +186,9 @@ class Coordinate { unit = Unit.DEGREE, projection = Projection.SPHERICAL ): void { - if ( - projection === Projection.MERCATOR && - (unit === Unit.DEGREE || unit === Unit.RADIAN) - ) { - const latDistRad = - unit === Unit.DEGREE ? degreesToRadians(latDist) : latDist; - const lonDistDeg = - unit === Unit.DEGREE ? lonDist : radiansToDegrees(lonDist); + if (projection === Projection.MERCATOR && (unit === Unit.DEGREE || unit === Unit.RADIAN)) { + const latDistRad = unit === Unit.DEGREE ? degreesToRadians(latDist) : latDist; + const lonDistDeg = unit === Unit.DEGREE ? lonDist : radiansToDegrees(lonDist); this.latitude = mercatorLatAddRadians(this.latitude, latDistRad); this.longitude += lonDistDeg; @@ -243,23 +228,11 @@ class Coordinate { * @param projection - The projection of Earth (not relevant when using a physical distance unit, e.g. Mile) * @returns Distance in the requested unit */ - distanceTo( - coordinate: Coordinate, - unit = Unit.MILE, - projection = Projection.SPHERICAL - ): number { - if ( - projection === Projection.MERCATOR && - (unit === Unit.DEGREE || unit === Unit.RADIAN) - ) { - const latDist = mercatorLatDistanceInRadians( - this.latitude, - coordinate.latitude - ); + distanceTo(coordinate: Coordinate, unit = Unit.MILE, projection = Projection.SPHERICAL): number { + if (projection === Projection.MERCATOR && (unit === Unit.DEGREE || unit === Unit.RADIAN)) { + const latDist = mercatorLatDistanceInRadians(this.latitude, coordinate.latitude); const absoluteLonDist = Math.abs(coordinate.normalLon - this.normalLon); - const lonDist = degreesToRadians( - Math.min(absoluteLonDist, 360 - absoluteLonDist) - ); + const lonDist = degreesToRadians(Math.min(absoluteLonDist, 360 - absoluteLonDist)); const radianDist = Math.sqrt(Math.pow(latDist, 2) + Math.pow(lonDist, 2)); @@ -294,9 +267,7 @@ class Coordinate { */ equals(coordinate: Coordinate): boolean { return ( - coordinate && - coordinate.latitude === this.latitude && - coordinate.longitude === this.longitude + coordinate && coordinate.latitude === this.latitude && coordinate.longitude === this.longitude ); } diff --git a/packages/pages-components/src/map/geoBounds.ts b/packages/pages-components/src/map/geoBounds.ts index badbabbc..8e66fbe7 100644 --- a/packages/pages-components/src/map/geoBounds.ts +++ b/packages/pages-components/src/map/geoBounds.ts @@ -22,19 +22,14 @@ class GeoBounds { // East/West bounds need to be chosen to minimize the area that fits all pins // Choose them by finding the largest area with no pins - const longitudes = coordinates - .map((coordinate) => coordinate.normalLon) - .sort((i, j) => i - j); + const longitudes = coordinates.map((coordinate) => coordinate.normalLon).sort((i, j) => i - j); const splitIndex = longitudes .map((longitude, i) => { - const next = - i < longitudes.length - 1 ? longitudes[i + 1] : longitudes[0] + 360; + const next = i < longitudes.length - 1 ? longitudes[i + 1] : longitudes[0] + 360; return { distance: next - longitude, index: i }; }) - .reduce((max, distance) => - distance.distance > max.distance ? distance : max - ).index; + .reduce((max, distance) => (distance.distance > max.distance ? distance : max)).index; const east = longitudes[splitIndex]; const west = longitudes[(splitIndex + 1) % longitudes.length]; @@ -80,15 +75,12 @@ class GeoBounds { */ contains(coordinate: Coordinate): boolean { const withinLatitude = - this._sw.latitude <= coordinate.latitude && - coordinate.latitude <= this._ne.latitude; + this._sw.latitude <= coordinate.latitude && coordinate.latitude <= this._ne.latitude; const longitudeSpansGlobe = this._ne.longitude - this._sw.longitude >= 360; const withinNormalLon = this._sw.normalLon <= this._ne.normalLon - ? this._sw.normalLon <= coordinate.normalLon && - coordinate.normalLon <= this._ne.normalLon - : this._sw.normalLon <= coordinate.normalLon || - coordinate.normalLon <= this._ne.normalLon; + ? this._sw.normalLon <= coordinate.normalLon && coordinate.normalLon <= this._ne.normalLon + : this._sw.normalLon <= coordinate.normalLon || coordinate.normalLon <= this._ne.normalLon; return withinLatitude && (longitudeSpansGlobe || withinNormalLon); } @@ -101,10 +93,8 @@ class GeoBounds { this._sw.latitude = Math.min(this._sw.latitude, coordinate.latitude); if (!this.contains(coordinate)) { - const eastDist = - (((coordinate.longitude - this._ne.longitude) % 360) + 360) % 360; - const westDist = - (((this._sw.longitude - coordinate.longitude) % 360) + 360) % 360; + const eastDist = (((coordinate.longitude - this._ne.longitude) % 360) + 360) % 360; + const westDist = (((this._sw.longitude - coordinate.longitude) % 360) + 360) % 360; if (eastDist < westDist) { this._ne.longitude += eastDist; @@ -123,8 +113,7 @@ class GeoBounds { const nw = new Coordinate(this._ne.latitude, this._sw.longitude); const latDist = this._sw.distanceTo(nw, Unit.DEGREE, projection); const newLon = - (nw.longitude + this._ne.longitude) / 2 + - (this._ne.longitude < nw.longitude ? 180 : 0); + (nw.longitude + this._ne.longitude) / 2 + (this._ne.longitude < nw.longitude ? 180 : 0); nw.add(-latDist / 2, 0, Unit.DEGREE, projection); nw.longitude = newLon; diff --git a/packages/pages-components/src/map/map.ts b/packages/pages-components/src/map/map.ts index 7fad6e5f..0cf7460a 100644 --- a/packages/pages-components/src/map/map.ts +++ b/packages/pages-components/src/map/map.ts @@ -1,22 +1,14 @@ import { Unit, Projection } from "./constants.js"; import { Coordinate } from "./coordinate.js"; import { GeoBounds } from "./geoBounds.js"; -import { - Type, - assertType, - assertInstance, - assertElement, -} from "./util/assertions.js"; +import { Type, assertType, assertInstance, assertElement } from "./util/assertions.js"; import { MapPin, MapPinOptions } from "./mapPin.js"; import { MapProvider } from "./mapProvider.js"; import { ProviderMap, ProviderMapOptions } from "./providerMap.js"; export type PaddingFunction = () => number; -export type PanHandler = ( - previousBounds?: GeoBounds, - currentBounds?: GeoBounds -) => void; +export type PanHandler = (previousBounds?: GeoBounds, currentBounds?: GeoBounds) => void; export type PanStartHandler = (currentBounds?: GeoBounds) => void; @@ -43,10 +35,7 @@ const MAX_PADDING = 0.98; * @param basis - The pixel measurement that the padding will be a fraction of * @returns The padding value as a fraction of basis */ -function normalizePadding( - value: number | PaddingFunction | undefined, - basis: number -): number { +function normalizePadding(value: number | PaddingFunction | undefined, basis: number): number { return Math.max(value instanceof Function ? value() : value || 0, 0) / basis; } @@ -316,12 +305,7 @@ class Map { maxZoom: number = this._singlePinZoom ) { if (coordinates.length) { - this.setBounds( - GeoBounds.fit(coordinates), - animated, - this._padding, - maxZoom - ); + this.setBounds(GeoBounds.fit(coordinates), animated, this._padding, maxZoom); } else { this.setZoomCenter(this._defaultZoom, this._defaultCenter, animated); } @@ -344,18 +328,8 @@ class Map { const height = pixelHeight * degreesPerPixel; this._cachedBounds = new GeoBounds(center, center); - this._cachedBounds.ne.add( - height / 2, - width / 2, - Unit.DEGREE, - Projection.MERCATOR - ); - this._cachedBounds.sw.add( - -height / 2, - -width / 2, - Unit.DEGREE, - Projection.MERCATOR - ); + this._cachedBounds.ne.add(height / 2, width / 2, Unit.DEGREE, Projection.MERCATOR); + this._cachedBounds.sw.add(-height / 2, -width / 2, Unit.DEGREE, Projection.MERCATOR); this.moving().then(() => (this._cachedBounds = null)); } @@ -544,11 +518,9 @@ class Map { // Fit the bounds within the area of the map like object-fit:contain then extend the bounds // to fill the remaining area within the padding. let newHeight = - Math.max(height, (width * paddingInnerHeight) / paddingInnerWidth) / - (1 - verticalPadding); + Math.max(height, (width * paddingInnerHeight) / paddingInnerWidth) / (1 - verticalPadding); let newWidth = - Math.max(width, (height * paddingInnerWidth) / paddingInnerHeight) / - (1 - horizontalPadding); + Math.max(width, (height * paddingInnerWidth) / paddingInnerHeight) / (1 - horizontalPadding); // Calculate the zoom based on the pixel width of the map and the degree width of the bounds. let zoom = Math.log2((pixelWidth * 360) / newWidth) - 8; @@ -640,9 +612,7 @@ class Map { */ _setIdle() { this._resolveMoving(); - this._movingPromise = new Promise( - (resolve) => (this._resolveMoving = resolve) - ); + this._movingPromise = new Promise((resolve) => (this._resolveMoving = resolve)); this._resolveIdle(); } diff --git a/packages/pages-components/src/map/mapPin.ts b/packages/pages-components/src/map/mapPin.ts index 3e53e105..bc6b09ca 100644 --- a/packages/pages-components/src/map/mapPin.ts +++ b/packages/pages-components/src/map/mapPin.ts @@ -62,9 +62,7 @@ class MapPinOptions { return this; } - withPropertiesForStatus( - propertiesForStatus: PropertiesForStatus - ): MapPinOptions { + withPropertiesForStatus(propertiesForStatus: PropertiesForStatus): MapPinOptions { assertType(propertiesForStatus, Type.FUNCTION); this.propertiesForStatus = propertiesForStatus; diff --git a/packages/pages-components/src/map/providerMap.ts b/packages/pages-components/src/map/providerMap.ts index c302f7e1..da111181 100644 --- a/packages/pages-components/src/map/providerMap.ts +++ b/packages/pages-components/src/map/providerMap.ts @@ -1,9 +1,4 @@ -import { - Type, - assertType, - assertInstance, - assertElement, -} from "./util/assertions.js"; +import { Type, assertType, assertInstance, assertElement } from "./util/assertions.js"; import { MapProvider } from "./mapProvider.js"; import { PanHandler, PanStartHandler } from "./map.js"; import { Coordinate } from "./coordinate.js"; diff --git a/packages/pages-components/src/map/providerPin.ts b/packages/pages-components/src/map/providerPin.ts index e36947e6..ba20dbbb 100644 --- a/packages/pages-components/src/map/providerPin.ts +++ b/packages/pages-components/src/map/providerPin.ts @@ -1,11 +1,6 @@ import { Type, assertType, assertInstance } from "./util/assertions.js"; import { MapProvider } from "./mapProvider.js"; -import { - PinClickHandler, - PinFocusHandler, - PinHoverHandler, - PinProperties, -} from "./mapPin.js"; +import { PinClickHandler, PinFocusHandler, PinHoverHandler, PinProperties } from "./mapPin.js"; import { Coordinate } from "./coordinate.js"; import { Map } from "./map.js"; @@ -204,15 +199,9 @@ class HTMLProviderPin extends ProviderPin { if (this._wrapper) { this._wrapper.addEventListener("click", () => this._clickHandler()); this._wrapper.addEventListener("focusin", () => this._focusHandler(true)); - this._wrapper.addEventListener("focusout", () => - this._focusHandler(false) - ); - this._wrapper.addEventListener("mouseover", () => - this._hoverHandler(true) - ); - this._wrapper.addEventListener("mouseout", () => - this._hoverHandler(false) - ); + this._wrapper.addEventListener("focusout", () => this._focusHandler(false)); + this._wrapper.addEventListener("mouseover", () => this._hoverHandler(true)); + this._wrapper.addEventListener("mouseout", () => this._hoverHandler(false)); } } diff --git a/packages/pages-components/src/map/providers/baidu.ts b/packages/pages-components/src/map/providers/baidu.ts index 3a2788b0..69a187ea 100644 --- a/packages/pages-components/src/map/providers/baidu.ts +++ b/packages/pages-components/src/map/providers/baidu.ts @@ -65,8 +65,7 @@ async function gcj02ToBD09(coordinates: Coordinate[]): Promise { const coordinates: Coordinate[] = ([] as Coordinate[]).concat( ...requests.map((request) => request.coordinates) ); - const callback = - gcj02ToBD09GlobalCallback + "_" + gcj02ToBD09CallbackCounter++; + const callback = gcj02ToBD09GlobalCallback + "_" + gcj02ToBD09CallbackCounter++; const script = document.createElement("script"); window[callback] = (data: { @@ -83,17 +82,12 @@ async function gcj02ToBD09(coordinates: Coordinate[]): Promise { requests.forEach((request) => request.reject(err)); } - const convertedCoords = data.result.map( - (point) => new Coordinate(point.y, point.x) - ); + const convertedCoords = data.result.map((point) => new Coordinate(point.y, point.x)); let currentIndex = 0; requests.forEach((request) => { request.resolve( - convertedCoords.slice( - currentIndex, - (currentIndex += request.coordinates.length) - ) + convertedCoords.slice(currentIndex, (currentIndex += request.coordinates.length)) ); }); @@ -106,9 +100,7 @@ async function gcj02ToBD09(coordinates: Coordinate[]): Promise { ak, callback, coords: coordinates - .map( - (coordinate) => `${coordinate.longitude},${coordinate.latitude}` - ) + .map((coordinate) => `${coordinate.longitude},${coordinate.latitude}`) .join(";"), from: 3, to: 5, @@ -202,10 +194,7 @@ class BaiduMap extends ProviderMap { */ setCenter(coordinate: Coordinate, animated: boolean) { this._centerReady = gcj02ToBD09([coordinate]).then(([convertedCoord]) => { - const point = new BMap.Point( - convertedCoord.longitude, - convertedCoord.latitude - ); + const point = new BMap.Point(convertedCoord.longitude, convertedCoord.latitude); this.map.panTo(point, { noAnimation: !animated }); }); } @@ -267,8 +256,7 @@ class BaiduPin extends HTMLProviderPin { if (this.pin._wrapper) { this.pin._wrapper.style.zIndex = this.pin._zIndex.toString(); - this.pin._originalWrapperClass = - this.pin._wrapper.getAttribute("class") ?? ""; + this.pin._originalWrapperClass = this.pin._wrapper.getAttribute("class") ?? ""; this.pin._wrapper.setAttribute("class", this.pin._getClass()); this.pin._wrapper.appendChild(this.pin._element); this.pin.addListeners(); @@ -318,25 +306,21 @@ class BaiduPin extends HTMLProviderPin { * {@inheritDoc HTMLProviderPin.setCoordinate} */ setCoordinate(coordinate: Coordinate) { - this._coordinateReady = gcj02ToBD09([coordinate]).then( - ([convertedCoord]) => { - // To avoid Baidu's glitched rendering of pins with negative longitude, this will set the pin to a - // longitude exactly halfway around the world, and CSS will translate it to its correct position. - this._negativeLngFix = convertedCoord.longitude < 0; - this.pin.setPosition( - new BMap.Point( - convertedCoord.longitude + (this._negativeLngFix ? 180 : 0), - convertedCoord.latitude - ) - ); - - if (this._wrapper) { - this._wrapper.classList[this._negativeLngFix ? "add" : "remove"]( - negativeLngPinClass - ); - } + this._coordinateReady = gcj02ToBD09([coordinate]).then(([convertedCoord]) => { + // To avoid Baidu's glitched rendering of pins with negative longitude, this will set the pin to a + // longitude exactly halfway around the world, and CSS will translate it to its correct position. + this._negativeLngFix = convertedCoord.longitude < 0; + this.pin.setPosition( + new BMap.Point( + convertedCoord.longitude + (this._negativeLngFix ? 180 : 0), + convertedCoord.latitude + ) + ); + + if (this._wrapper) { + this._wrapper.classList[this._negativeLngFix ? "add" : "remove"](negativeLngPinClass); } - ); + }); } /** diff --git a/packages/pages-components/src/map/providers/bing.ts b/packages/pages-components/src/map/providers/bing.ts index 533ff413..a41fad5a 100644 --- a/packages/pages-components/src/map/providers/bing.ts +++ b/packages/pages-components/src/map/providers/bing.ts @@ -48,10 +48,8 @@ function initPinOverlayClass() { } onLoad() { - this._viewChangeEventHandler = Microsoft.Maps.Events.addHandler( - this._map, - "viewchange", - () => this.updatePinPositions() + this._viewChangeEventHandler = Microsoft.Maps.Events.addHandler(this._map, "viewchange", () => + this.updatePinPositions() ); this.updatePinPositions(); } @@ -120,12 +118,8 @@ class BingMap extends ProviderMap { this.pinOverlay = new PinOverlay(this.map); this.map.layers.insert(this.pinOverlay); - Microsoft.Maps.Events.addHandler(this.map, "viewchangestart", () => - this._panStartHandler() - ); - Microsoft.Maps.Events.addHandler(this.map, "viewchangeend", () => - this._panHandler() - ); + Microsoft.Maps.Events.addHandler(this.map, "viewchangestart", () => this._panStartHandler()); + Microsoft.Maps.Events.addHandler(this.map, "viewchangeend", () => this._panHandler()); } /** @@ -146,10 +140,7 @@ class BingMap extends ProviderMap { * {@inheritDoc ProviderMap.setCenter} */ setCenter(coordinate: Coordinate, _: boolean) { - const center = new Microsoft.Maps.Location( - coordinate.latitude, - coordinate.longitude - ); + const center = new Microsoft.Maps.Location(coordinate.latitude, coordinate.longitude); this.map?.setView({ center }); this.pinOverlay.updatePinPositions(); } @@ -190,15 +181,10 @@ class BingPin extends HTMLProviderPin { * {@inheritDoc HTMLProviderPin.setCoordinate} */ setCoordinate(coordinate: Coordinate) { - this._location = new Microsoft.Maps.Location( - coordinate.latitude, - coordinate.longitude - ); + this._location = new Microsoft.Maps.Location(coordinate.latitude, coordinate.longitude); if (this._map) { - (this._map.getProviderMap() as BingMap).pinOverlay.updatePinPosition( - this - ); + (this._map.getProviderMap() as BingMap).pinOverlay.updatePinPosition(this); } } @@ -234,12 +220,7 @@ const baseUrl = "https://www.bing.com/api/maps/mapcontrol"; * options.params=\{\} - Additional API params * @see ProviderLoadFunction */ -function load( - resolve: () => void, - _: () => void, - apiKey: string, - { params = {} } = {} -) { +function load(resolve: () => void, _: () => void, apiKey: string, { params = {} } = {}) { window[globalCallback] = () => { initPinOverlayClass(); resolve(); diff --git a/packages/pages-components/src/map/providers/google.ts b/packages/pages-components/src/map/providers/google.ts index a3bfe5c0..59d3f37e 100644 --- a/packages/pages-components/src/map/providers/google.ts +++ b/packages/pages-components/src/map/providers/google.ts @@ -69,10 +69,7 @@ class GoogleMap extends ProviderMap { * {@inheritDoc ProviderMap.setCenter} */ setCenter(coordinate: Coordinate, animated: boolean) { - const latLng = new google.maps.LatLng( - coordinate.latitude, - coordinate.longitude - ); + const latLng = new google.maps.LatLng(coordinate.latitude, coordinate.longitude); if (animated) { this.map?.panTo(latLng); @@ -122,9 +119,7 @@ class GooglePin extends HTMLProviderPin { this.pin = pin; } draw() { - const position = this.getProjection()?.fromLatLngToDivPixel( - this.pin._latLng ?? null - ); + const position = this.getProjection()?.fromLatLngToDivPixel(this.pin._latLng ?? null); if (position && this.pin._wrapper) { this.pin._wrapper.style.left = position.x + "px"; @@ -150,10 +145,7 @@ class GooglePin extends HTMLProviderPin { * {@inheritDoc HTMLProviderPin.setCoordinate} */ setCoordinate(coordinate: Coordinate) { - this._latLng = new google.maps.LatLng( - coordinate.latitude, - coordinate.longitude - ); + this._latLng = new google.maps.LatLng(coordinate.latitude, coordinate.longitude); this.pin.draw(); } diff --git a/packages/pages-components/src/map/providers/leaflet.ts b/packages/pages-components/src/map/providers/leaflet.ts index 54a3b1fe..99f79464 100644 --- a/packages/pages-components/src/map/providers/leaflet.ts +++ b/packages/pages-components/src/map/providers/leaflet.ts @@ -172,12 +172,7 @@ class LeafletPin extends ProviderPin { * options.version='1.7.1' - API version * @see ProviderLoadFunction */ -function load( - resolve: () => void, - _: () => void, - apiKey: string, - { version = "1.7.1" } = {} -) { +function load(resolve: () => void, _: () => void, apiKey: string, { version = "1.7.1" } = {}) { const baseUrl = `https://unpkg.com/leaflet@${version}/dist/leaflet`; LeafletMap.apiKey = apiKey; diff --git a/packages/pages-components/src/map/providers/mapQuest.ts b/packages/pages-components/src/map/providers/mapQuest.ts index 595821b4..48ba29bf 100644 --- a/packages/pages-components/src/map/providers/mapQuest.ts +++ b/packages/pages-components/src/map/providers/mapQuest.ts @@ -43,12 +43,7 @@ class MapQuestPin extends LeafletPin {} * options.version='v1.3.2' - API version * @see ProviderLoadFunction */ -function load( - resolve: () => void, - _: () => void, - apiKey: string, - { version = "v1.3.2" } = {} -) { +function load(resolve: () => void, _: () => void, apiKey: string, { version = "v1.3.2" } = {}) { const baseUrl = `https://api.mqcdn.com/sdk/mapquest-js/${version}/mapquest-maps`; const mapStyle = document.createElement("link"); diff --git a/packages/pages-components/src/map/providers/mapbox.ts b/packages/pages-components/src/map/providers/mapbox.ts index a2680f1e..06e45829 100644 --- a/packages/pages-components/src/map/providers/mapbox.ts +++ b/packages/pages-components/src/map/providers/mapbox.ts @@ -17,8 +17,7 @@ class MapboxMap extends ProviderMap { super(options); const mapboxInstance = - (options?.iframeWindow as Window & { mapboxgl?: typeof mapboxgl }) - ?.mapboxgl ?? mapboxgl; + (options?.iframeWindow as Window & { mapboxgl?: typeof mapboxgl })?.mapboxgl ?? mapboxgl; mapboxInstance.accessToken = options?.apiKey ?? ""; this.instance = mapboxInstance; @@ -63,10 +62,7 @@ class MapboxMap extends ProviderMap { * {@inheritDoc ProviderMap.setCenter} */ setCenter(coordinate: Coordinate, animated: boolean) { - const center = new this.instance.LngLat( - coordinate.longitude, - coordinate.latitude - ); + const center = new this.instance.LngLat(coordinate.longitude, coordinate.latitude); if (this.map) { this.map[animated ? "panTo" : "setCenter"](center); @@ -88,10 +84,7 @@ class MapboxMap extends ProviderMap { * {@inheritDoc ProviderMap.zetZoomCenter} */ setZoomCenter(zoom: number, coordinate: Coordinate, animated: boolean) { - const center = new this.instance.LngLat( - coordinate.longitude, - coordinate.latitude - ); + const center = new this.instance.LngLat(coordinate.longitude, coordinate.latitude); // Our standard zoom: at level 0, the world is 256 pixels wide and doubles each level // Mapbox zoom: at level 0, the world is 512 pixels wide and doubles each level @@ -121,9 +114,7 @@ class MapboxPin extends HTMLProviderPin { * {@inheritDoc HTMLProviderPin.setCoordinate} */ setCoordinate(coordinate: Coordinate) { - this.pin?.setLngLat( - new mapboxgl.LngLat(coordinate.longitude, coordinate.latitude) - ); + this.pin?.setLngLat(new mapboxgl.LngLat(coordinate.longitude, coordinate.latitude)); } /** @@ -153,12 +144,7 @@ class MapboxPin extends HTMLProviderPin { * options.version='v1.13.0' - API version * @see ProviderLoadFunction */ -function load( - resolve: () => void, - _: () => void, - _apiKey: string, - { version = "v1.13.0" } = {} -) { +function load(resolve: () => void, _: () => void, _apiKey: string, { version = "v1.13.0" } = {}) { const baseUrl = `https://api.mapbox.com/mapbox-gl-js/${version}/mapbox-gl`; const mapStyle = document.createElement("link"); diff --git a/packages/pages-components/src/map/util/assertions.ts b/packages/pages-components/src/map/util/assertions.ts index 6d6d29ca..aa0889fd 100644 --- a/packages/pages-components/src/map/util/assertions.ts +++ b/packages/pages-components/src/map/util/assertions.ts @@ -22,9 +22,7 @@ function assertType(object: any, type: string) { } if (typeof object !== type) { - throw new Error( - `Expected an object of type '${type}' but received '${typeof object}'` - ); + throw new Error(`Expected an object of type '${type}' but received '${typeof object}'`); } } @@ -43,9 +41,7 @@ function assertElement(value: any): asserts value is HTMLElement { typeof value.tagName === "string"; if (!isValidElement) { - throw new Error( - `Value with name ${value.constructor.name} is not a valid HTMLElement.` - ); + throw new Error(`Value with name ${value.constructor.name} is not a valid HTMLElement.`); } } @@ -60,9 +56,7 @@ function assertInstance(object: object, instanceClass: any) { try { isInstance = object instanceof instanceClass; } catch (_) { - throw new Error( - "Assertion error: 'instanceClass' is not a valid constructor" - ); + throw new Error("Assertion error: 'instanceClass' is not a valid constructor"); } if (!isInstance) { diff --git a/packages/pages-components/vite.config.ts b/packages/pages-components/vite.config.ts index 2ddfe5c9..51dd7083 100644 --- a/packages/pages-components/vite.config.ts +++ b/packages/pages-components/vite.config.ts @@ -14,13 +14,7 @@ export default defineConfig(() => ({ formats: ["es"] as LibraryFormats[], // typescript is unhappy without this forced type definition }, rollupOptions: { - external: [ - "react", - "react-dom", - "mapbox-gl", - "react/jsx-runtime", - "react/jsx-dev-runtime", - ], + external: ["react", "react-dom", "mapbox-gl", "react/jsx-runtime", "react/jsx-dev-runtime"], output: { globals: { react: "React", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 106c7c49..dbe1eafe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,15 +38,15 @@ importers: minimist: specifier: ^1.2.8 version: 1.2.8 + oxfmt: + specifier: ^0.21.0 + version: 0.21.0 oxlint: - specifier: ^1.26.0 - version: 1.26.0 + specifier: ^1.36.0 + version: 1.36.0 picocolors: specifier: ^1.0.0 version: 1.1.1 - prettier: - specifier: ^3.2.5 - version: 3.5.1 prompts: specifier: ^2.4.2 version: 2.4.2 @@ -1253,43 +1253,83 @@ packages: resolution: {integrity: sha512-cJXiUlycdizQwvqE1iaAb4VRUM3RX09/8q46zjvy+ct9GhfZRWd7jXYVc1tn/CfRlGPVkX/u4sstRlepsm7hfw==} engines: {node: ^18.17.0 || >=20.5.0} - '@oxlint/darwin-arm64@1.26.0': - resolution: {integrity: sha512-kTmm1opqyn7iZopWHO3Ml4D/44pA5eknZBepgxCnTaPrW8XgCEUI85Q5AvOOvoNve8NziTYb8ax+CyuGJIgn/Q==} + '@oxfmt/darwin-arm64@0.21.0': + resolution: {integrity: sha512-defgGcchFCq2F7f5Nr3E4VXYW1sUhBGmIejgcPZ1gSsc8FAeT+vP5cSeGnDv+kcX+OKFDt89C67c31qZ6yZBsQ==} + cpu: [arm64] + os: [darwin] + + '@oxfmt/darwin-x64@0.21.0': + resolution: {integrity: sha512-rYJinOZRabPF2V3kn0TWX4vcYHV2F+DkGewNP8HZ/OXQ3CEJKP+E7KCnEz/x614g3/S5J7cahr9l5Mr3AEZigA==} + cpu: [x64] + os: [darwin] + + '@oxfmt/linux-arm64-gnu@0.21.0': + resolution: {integrity: sha512-ILTv8stX3r2gK+pgSc2alJrbpI4i8zlLXzuuhUsjeEN/Ti//Z38MDi6kTov3pzcaBEnQ/xEMgQyczokp7jpyyQ==} + cpu: [arm64] + os: [linux] + + '@oxfmt/linux-arm64-musl@0.21.0': + resolution: {integrity: sha512-kFZ0vPJzsGjkrwq2MPEpp8TjV7/Znv9kCEwLF+HcFwvfcSt75dWloGmTRRrViH0ACaCM7YBSDUOV8E4nyLvxPA==} + cpu: [arm64] + os: [linux] + + '@oxfmt/linux-x64-gnu@0.21.0': + resolution: {integrity: sha512-VH8ZcS2TkTBE0v9cLxjNGX++vB9Xvx/7VTFrbwHYzY/fYypYTwQ+n1KplUQoU+LrMC0nKqwPWYzvA5/cAfo5zg==} + cpu: [x64] + os: [linux] + + '@oxfmt/linux-x64-musl@0.21.0': + resolution: {integrity: sha512-qleaVEFHw/kmbvNj3hjobX1kwbP2/d7SVJzQjyEFULou1v3EZj7jWbblIu7GmDCSspdiEk1j/pZDYH801Dn8QA==} + cpu: [x64] + os: [linux] + + '@oxfmt/win32-arm64@0.21.0': + resolution: {integrity: sha512-JLZUo5qEyJfxhoj6KEU/CqI8FQlzIP8rBq7qGTq0kCJ2yZJC9tysBqJYZXvX88ShiNe89/T/H3khodaKGBBNgg==} + cpu: [arm64] + os: [win32] + + '@oxfmt/win32-x64@0.21.0': + resolution: {integrity: sha512-DYNpbuPzUhTuWUIqDhwSaV1mK+VcknD4ANaEON+/ygaNGriSZ4pRUt1BTRcXfcOF9GZ4BO9udjv31S0bAEsFeQ==} + cpu: [x64] + os: [win32] + + '@oxlint/darwin-arm64@1.36.0': + resolution: {integrity: sha512-MJkj82GH+nhvWKJhSIM6KlZ8tyGKdogSQXtNdpIyP02r/tTayFJQaAEWayG2Jhsn93kske+nimg5MYFhwO/rlg==} cpu: [arm64] os: [darwin] - '@oxlint/darwin-x64@1.26.0': - resolution: {integrity: sha512-/hMfZ9j7ZzVPRmMm02PHNc6MIMk0QYv5VowZJRIp40YLqLPvFfGNGZBj8e1fDVgZMFEGWDQK3yrt1uBKxXAK4Q==} + '@oxlint/darwin-x64@1.36.0': + resolution: {integrity: sha512-VvEhfkqj/99dCTqOcfkyFXOSbx4lIy5u2m2GHbK4WCMDySokOcMTNRHGw8fH/WgQ5cDrDMSTYIGQTmnBGi9tiQ==} cpu: [x64] os: [darwin] - '@oxlint/linux-arm64-gnu@1.26.0': - resolution: {integrity: sha512-iv4wdrwdCa8bhJxOpKlvfxqTs0LgW5tKBUMvH9B13zREHm1xT9JRZ8cQbbKiyC6LNdggwu5S6TSvODgAu7/DlA==} + '@oxlint/linux-arm64-gnu@1.36.0': + resolution: {integrity: sha512-EMx92X5q+hHc3olTuj/kgkx9+yP0p/AVs4yvHbUfzZhBekXNpUWxWvg4hIKmQWn+Ee2j4o80/0ACGO0hDYJ9mg==} cpu: [arm64] os: [linux] - '@oxlint/linux-arm64-musl@1.26.0': - resolution: {integrity: sha512-a3gTbnN1JzedxqYeGTkg38BAs/r3Krd2DPNs/MF7nnHthT3RzkPUk47isMePLuNc4e/Weljn7m2m/Onx22tiNg==} + '@oxlint/linux-arm64-musl@1.36.0': + resolution: {integrity: sha512-7YCxtrPIctVYLqWrWkk8pahdCxch6PtsaucfMLC7TOlDt4nODhnQd4yzEscKqJ8Gjrw1bF4g+Ngob1gB+Qr9Fw==} cpu: [arm64] os: [linux] - '@oxlint/linux-x64-gnu@1.26.0': - resolution: {integrity: sha512-cCAyqyuKpFImjlgiBuuwSF+aDBW2h19/aCmHMTMSp6KXwhoQK7/Xx7/EhZKP5wiQJzVUYq5fXr0D8WmpLGsjRg==} + '@oxlint/linux-x64-gnu@1.36.0': + resolution: {integrity: sha512-lnaJVlx5r3NWmoOMesfQXJSf78jHTn8Z+sdAf795Kgteo72+qGC1Uax2SToCJVN2J8PNG3oRV5bLriiCNR2i6Q==} cpu: [x64] os: [linux] - '@oxlint/linux-x64-musl@1.26.0': - resolution: {integrity: sha512-8VOJ4vQo0G1tNdaghxrWKjKZGg73tv+FoMDrtNYuUesqBHZN68FkYCsgPwEsacLhCmtoZrkF3ePDWDuWEpDyAg==} + '@oxlint/linux-x64-musl@1.36.0': + resolution: {integrity: sha512-AhuEU2Qdl66lSfTGu/Htirq8r/8q2YnZoG3yEXLMQWnPMn7efy8spD/N1NA7kH0Hll+cdfwgQkQqC2G4MS2lPQ==} cpu: [x64] os: [linux] - '@oxlint/win32-arm64@1.26.0': - resolution: {integrity: sha512-N8KUtzP6gfEHKvaIBZCS9g8wRfqV5v55a/B8iJjIEhtMehcEM+UX+aYRsQ4dy5oBCrK3FEp4Yy/jHgb0moLm3Q==} + '@oxlint/win32-arm64@1.36.0': + resolution: {integrity: sha512-GlWCBjUJY2QgvBFuNRkiRJu7K/djLmM0UQKfZV8IN+UXbP/JbjZHWKRdd4LXlQmzoz7M5Hd6p+ElCej8/90FCg==} cpu: [arm64] os: [win32] - '@oxlint/win32-x64@1.26.0': - resolution: {integrity: sha512-7tCyG0laduNQ45vzB9blVEGq/6DOvh7AFmiUAana8mTp0zIKQQmwJ21RqhazH0Rk7O6lL7JYzKcu+zaJHGpRLA==} + '@oxlint/win32-x64@1.36.0': + resolution: {integrity: sha512-J+Vc00Utcf8p77lZPruQgb0QnQXuKnFogN88kCnOqs2a83I+vTBB8ILr0+L9sTwVRvIDMSC0pLdeQH4svWGFZg==} cpu: [x64] os: [win32] @@ -4546,12 +4586,17 @@ packages: resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} deprecated: This package is no longer supported. - oxlint@1.26.0: - resolution: {integrity: sha512-KRpL+SMi07JQyggv5ldIF+wt2pnrKm8NLW0B+8bK+0HZsLmH9/qGA+qMWie5Vf7lnlMBllJmsuzHaKFEGY3rIA==} + oxfmt@0.21.0: + resolution: {integrity: sha512-EXK5pd1kGbI8hp9Ld69oy/ObAoe+gfH3dYHBviKqwSAHNkAHiqxWF1hnrWj5oun1GnQ8bVpqBMMVXJESMx6/+g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + oxlint@1.36.0: + resolution: {integrity: sha512-IicUdXfXgI8OKrDPnoSjvBfeEF8PkKtm+CoLlg4LYe4ypc8U+T4r7730XYshdBGZdelg+JRw8GtCb2w/KaaZvw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: - oxlint-tsgolint: '>=0.4.0' + oxlint-tsgolint: '>=0.10.0' peerDependenciesMeta: oxlint-tsgolint: optional: true @@ -5528,6 +5573,10 @@ packages: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} + tinypool@2.0.0: + resolution: {integrity: sha512-/RX9RzeH2xU5ADE7n2Ykvmi9ED3FBGPAjw9u3zucrNNaEBIO0HPSYgL0NT7+3p147ojeSdaVu08F6hjpv31HJg==} + engines: {node: ^20.0.0 || >=22.0.0} + tinyqueue@2.0.3: resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==} @@ -7137,28 +7186,52 @@ snapshots: - bluebird - supports-color - '@oxlint/darwin-arm64@1.26.0': + '@oxfmt/darwin-arm64@0.21.0': optional: true - '@oxlint/darwin-x64@1.26.0': + '@oxfmt/darwin-x64@0.21.0': optional: true - '@oxlint/linux-arm64-gnu@1.26.0': + '@oxfmt/linux-arm64-gnu@0.21.0': optional: true - '@oxlint/linux-arm64-musl@1.26.0': + '@oxfmt/linux-arm64-musl@0.21.0': optional: true - '@oxlint/linux-x64-gnu@1.26.0': + '@oxfmt/linux-x64-gnu@0.21.0': optional: true - '@oxlint/linux-x64-musl@1.26.0': + '@oxfmt/linux-x64-musl@0.21.0': optional: true - '@oxlint/win32-arm64@1.26.0': + '@oxfmt/win32-arm64@0.21.0': optional: true - '@oxlint/win32-x64@1.26.0': + '@oxfmt/win32-x64@0.21.0': + optional: true + + '@oxlint/darwin-arm64@1.36.0': + optional: true + + '@oxlint/darwin-x64@1.36.0': + optional: true + + '@oxlint/linux-arm64-gnu@1.36.0': + optional: true + + '@oxlint/linux-arm64-musl@1.36.0': + optional: true + + '@oxlint/linux-x64-gnu@1.36.0': + optional: true + + '@oxlint/linux-x64-musl@1.36.0': + optional: true + + '@oxlint/win32-arm64@1.36.0': + optional: true + + '@oxlint/win32-x64@1.36.0': optional: true '@pkgjs/parseargs@0.11.0': @@ -11095,16 +11168,29 @@ snapshots: os-homedir: 1.0.2 os-tmpdir: 1.0.2 - oxlint@1.26.0: + oxfmt@0.21.0: + dependencies: + tinypool: 2.0.0 + optionalDependencies: + '@oxfmt/darwin-arm64': 0.21.0 + '@oxfmt/darwin-x64': 0.21.0 + '@oxfmt/linux-arm64-gnu': 0.21.0 + '@oxfmt/linux-arm64-musl': 0.21.0 + '@oxfmt/linux-x64-gnu': 0.21.0 + '@oxfmt/linux-x64-musl': 0.21.0 + '@oxfmt/win32-arm64': 0.21.0 + '@oxfmt/win32-x64': 0.21.0 + + oxlint@1.36.0: optionalDependencies: - '@oxlint/darwin-arm64': 1.26.0 - '@oxlint/darwin-x64': 1.26.0 - '@oxlint/linux-arm64-gnu': 1.26.0 - '@oxlint/linux-arm64-musl': 1.26.0 - '@oxlint/linux-x64-gnu': 1.26.0 - '@oxlint/linux-x64-musl': 1.26.0 - '@oxlint/win32-arm64': 1.26.0 - '@oxlint/win32-x64': 1.26.0 + '@oxlint/darwin-arm64': 1.36.0 + '@oxlint/darwin-x64': 1.36.0 + '@oxlint/linux-arm64-gnu': 1.36.0 + '@oxlint/linux-arm64-musl': 1.36.0 + '@oxlint/linux-x64-gnu': 1.36.0 + '@oxlint/linux-x64-musl': 1.36.0 + '@oxlint/win32-arm64': 1.36.0 + '@oxlint/win32-x64': 1.36.0 p-limit@2.3.0: dependencies: @@ -11349,7 +11435,8 @@ snapshots: preact@10.28.0: {} - prettier@3.5.1: {} + prettier@3.5.1: + optional: true pretty-format@27.5.1: dependencies: @@ -12166,6 +12253,8 @@ snapshots: tinypool@1.0.2: {} + tinypool@2.0.0: {} + tinyqueue@2.0.3: {} tinyrainbow@1.2.0: {} diff --git a/prettier.config.js b/prettier.config.js deleted file mode 100644 index 01ee396e..00000000 --- a/prettier.config.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import("prettier").Config} */ -const config = { - trailingComma: "es5", -}; - -export default config; diff --git a/scripts/releaseUtils.ts b/scripts/releaseUtils.ts index 13078418..0c6615ef 100644 --- a/scripts/releaseUtils.ts +++ b/scripts/releaseUtils.ts @@ -78,10 +78,7 @@ export async function dryRun( args: string[], opts?: ExecaOptions ): Promise { - return console.log( - colors.blue(`[dryrun] ${bin} ${args.join(" ")}`), - opts || "" - ); + return console.log(colors.blue(`[dryrun] ${bin} ${args.join(" ")}`), opts || ""); } export const runIfNotDry = isDryRun ? dryRun : run; @@ -178,9 +175,7 @@ export async function getLatestTag(pkgName: string): Promise { const allTags = result.stdout.trim().split(/\n/).filter(Boolean); const packageTags = allTags.filter((tag) => tag.startsWith(`${pkgName}@`)); // Strip the package name prefix to get clean version strings. - const versionStrings = packageTags.map((tag) => - tag.replace(`${pkgName}@`, "") - ); + const versionStrings = packageTags.map((tag) => tag.replace(`${pkgName}@`, "")); const sortedVersions = semver.rsort(versionStrings); return `${pkgName}@${sortedVersions[0]}`; @@ -201,14 +196,7 @@ export async function logRecentCommits(pkgName: string): Promise { ); await run( "git", - [ - "--no-pager", - "log", - `${sha}..HEAD`, - "--oneline", - "--", - `packages/${pkgName}`, - ], + ["--no-pager", "log", `${sha}..HEAD`, "--oneline", "--", `packages/${pkgName}`], { stdio: "inherit" } ); console.log(); diff --git a/test-sites/pages-components-starter/package.json b/test-sites/pages-components-starter/package.json index 5d9832c7..c1d16057 100644 --- a/test-sites/pages-components-starter/package.json +++ b/test-sites/pages-components-starter/package.json @@ -2,8 +2,8 @@ "name": "pages-components-starter", "version": "0.0.0", "description": "A consumer of @yext/pages-components to test React/Node matrices", - "author": "sumo@yext.com", "license": "BSD-3-Clause", + "author": "sumo@yext.com", "type": "module", "scripts": { "dev": "pages dev --local --no-prod-url --noInit", @@ -12,9 +12,6 @@ "smoke": "./scripts/test-matrix-local.sh", "test": "playwright test" }, - "engines": { - "node": "^20.2.0 || ^22 || ^24" - }, "dependencies": { "@yext/pages-components": "workspace:*", "react": "^18.2.0", @@ -29,5 +26,8 @@ "@yext/pages": "^1.2.7", "typescript": "^5.3.3", "vite": "^5.4.19" + }, + "engines": { + "node": "^20.2.0 || ^22 || ^24" } } diff --git a/test-sites/pages-components-starter/src/templates/location.tsx b/test-sites/pages-components-starter/src/templates/location.tsx index 31a72c9e..366bf28b 100644 --- a/test-sites/pages-components-starter/src/templates/location.tsx +++ b/test-sites/pages-components-starter/src/templates/location.tsx @@ -62,11 +62,7 @@ export const getHeadConfig: GetHeadConfig = ({ }; }; -const Location: Template = ({ - relativePrefixToRoot, - document, - __meta, -}) => { +const Location: Template = ({ relativePrefixToRoot, document, __meta }) => { const { address, c_subfieldRTFTest } = document; return ( @@ -86,9 +82,7 @@ const Location: Template = ({
    LRT via HTML:{" "} {c_subfieldRTFTest?.rtf?.html && ( -
    +
    )}
    diff --git a/test-sites/pages-components-starter/tests/smoke.spec.ts b/test-sites/pages-components-starter/tests/smoke.spec.ts index d298d18a..bfa39b1a 100644 --- a/test-sites/pages-components-starter/tests/smoke.spec.ts +++ b/test-sites/pages-components-starter/tests/smoke.spec.ts @@ -2,7 +2,5 @@ import { test, expect } from "@playwright/test"; test("starter local dev loads successfully", async ({ page }) => { await page.goto("/location/location6"); - await expect(page.getByRole("heading", { level: 1 })).toHaveText( - "Hello Pages Components" - ); + await expect(page.getByRole("heading", { level: 1 })).toHaveText("Hello Pages Components"); });