diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index eb97907..0000000 --- a/.eslintignore +++ /dev/null @@ -1,20 +0,0 @@ - -**/bin -**/coverage -**/dist -**/node_modules -**/patches -**/static -**/vendor -**/.storybook -.github -yarn-error.log -.prettierignore -.prettier.json -.eslintrc.js -.yaml -.git -.eslintcache -**/rollup.config.js -packages/segast/src/filterql.js -**/*.hbs diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 8659105..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,34 +0,0 @@ -module.exports = { - extends: [ - "eslint:recommended", - "plugin:react/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "plugin:@typescript-eslint/recommended", - "plugin:prettier/recommended", - ], - parser: "@typescript-eslint/parser", - parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - project: ["./tsconfig.json", "./packages/*/tsconfig.json"], - }, - rules: { - "prettier/prettier": ["error", { parser: "typescript" }], - "max-len": "off", - "import/extensions": "off", - "import/no-unresolved": "off", - "react/react-in-jsx-scope": "off", - "func-style": ["error", "declaration", { allowArrowFunctions: true }], - "@typescript-eslint/no-unused-vars": "error", - "react/prop-types": "off", - }, - overrides: [ - { - files: ["**/*.stories.*"], - rules: { - "import/no-anonymous-default-export": "off", - }, - }, - ], -}; diff --git a/.github/CI.md b/.github/CI.md index 5ae2d3d..e977438 100644 --- a/.github/CI.md +++ b/.github/CI.md @@ -7,13 +7,13 @@ This project uses GitHub Actions for continuous integration. The CI workflow run The CI workflow (`.github/workflows/ci.yml`) runs the following checks in sequence: 1. **Install dependencies** - `yarn install --frozen-lockfile` -2. **Test** - `yarn test` - Runs all unit tests (currently 39 tests) -3. **Build** - `yarn build` - Verifies all packages build successfully +2. **Lint** - `yarn lint` - Runs Biome linter on all source files +3. **Type check** - `yarn typecheck` - Runs TypeScript type checking across all packages +4. **Test** - `yarn test` - Runs all unit tests (currently 39 tests) +5. **Build** - `yarn build` - Verifies all packages build successfully All checks must pass before code can be merged to `main`. -> **Note:** Linting and type checking will be added after resolving existing type errors and migrating to Biome. - ## Environment - **Node version:** 22.20.0 - **Yarn version:** 1.22.18 @@ -23,12 +23,19 @@ All checks must pass before code can be merged to `main`. Before pushing your changes, you can run the same checks locally: ```bash -# Run all checks +# Run all checks in sequence yarn install --frozen-lockfile +yarn lint +yarn typecheck yarn test yarn build # Or run them individually as needed +yarn lint # Check code quality with Biome +yarn lint:fix # Fix auto-fixable linting issues +yarn typecheck # Check TypeScript types +yarn test # Run unit tests +yarn build # Build all packages ``` ## Troubleshooting diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba8be33..e06ef62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,12 @@ jobs: restore-keys: | ${{ runner.os }}-nx- + - name: Lint + run: yarn lint + + - name: Type check + run: yarn typecheck + - name: Test run: yarn test diff --git a/.lintstagedrc.json b/.lintstagedrc.json index 28fce1f..ff10055 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,4 +1,5 @@ { - "{packages,entrypoints,web-components,viz-service}/**/*.{js,jsx,ts,tsx,json,css,scss,md}": "prettier --write", - "{packages,entrypoints,web-components,viz-service}/**/*.+(js,jsx,ts,tsx,json,css,scss,md)": "eslint" + "{packages}/**/*.{js,jsx,ts,tsx,json,css,md}": [ + "biome check --write --no-errors-on-unmatched --files-ignore-unknown=true" + ] } diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 3077314..0000000 --- a/.prettierignore +++ /dev/null @@ -1,17 +0,0 @@ -**/bin -**/coverage -**/dist -**/node_modules -**/patches -**/vendor -.github -yarn-error.log -.eslintignore -.eslint.json -.yaml -.git -.eslintcache -packages/segast/src/filterql.js -**/*.hbs -**/public -**/static \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 9d8dc7c..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "http://json.schemastore.org/prettierrc", - "arrowParens": "always", - "bracketSpacing": true, - "jsxBracketSameLine": false, - "jsxSingleQuote": false, - "printWidth": 80, - "proseWrap": "always", - "quoteProps": "as-needed", - "semi": true, - "singleQuote": false, - "tabWidth": 2, - "trailingComma": "all", - "useTabs": false -} diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index b964a06..cdd76d3 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -1,11 +1,5 @@ -import React from "react"; - const defaultDecorator = (Story: any, context: any) => { - return ( - <> - - - ); + return ; }; export const decorators = [defaultDecorator]; diff --git a/.storybook/storyshots.test.ts b/.storybook/storyshots.test.ts index 20a5ead..ac174b5 100644 --- a/.storybook/storyshots.test.ts +++ b/.storybook/storyshots.test.ts @@ -1,9 +1,10 @@ /// /// -import { describe, expect, test } from "vitest"; + +import { composeStories, Meta, StoryFn } from "@storybook/react"; import { render, waitForElementToBeRemoved } from "@testing-library/react"; -import { Meta, StoryFn, composeStories } from "@storybook/react"; import { parseISO } from "date-fns"; +import { describe, expect, test } from "vitest"; import * as globalConfig from "./preview"; vi?.useFakeTimers().setSystemTime(parseISO("2020-01-01")); @@ -23,13 +24,13 @@ describe("Storybook Snapshots", async () => { modules .filter((module) => !/skip-storyshots/.test(module.default.title!)) .map((module) => [module.default.title!, module]), - )("%s", (moduleName, module) => { + )("%s", (_moduleName, module) => { test.each( Object.values(composeStories(module, globalConfig)).map((Story) => [ Story.storyName!, Story, ]), - )("%s", async (storyName, Story) => { + )("%s", async (_storyName, Story) => { const { container } = await render(Story({})); if (container.querySelector(".MuiCircularProgress-indeterminate")) { await waitForElementToBeRemoved(() => diff --git a/.storybook/vite.config.ts b/.storybook/vite.config.ts index bc6acf5..7bcec0b 100644 --- a/.storybook/vite.config.ts +++ b/.storybook/vite.config.ts @@ -2,7 +2,6 @@ import { mergeConfig } from "vite"; import { default as base } from "../config/entrypoint/vite.config"; - export default mergeConfig(base, { test: { environment: "happy-dom", diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..d84ddfb --- /dev/null +++ b/biome.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.2.6/schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false, + "experimentalScannerIgnores": [ + "node_modules", + "dist", + "build", + ".nx", + "coverage", + "*.min.js", + "yarn.lock", + "package-lock.json" + ] + }, + "formatter": { + "enabled": true, + "formatWithErrors": false, + "indentStyle": "space", + "indentWidth": 2, + "lineEnding": "lf", + "lineWidth": 80, + "attributePosition": "auto" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "noForEach": "off", + "noStaticOnlyClass": "off" + }, + "style": { + "noNonNullAssertion": "off", + "useImportType": "off", + "useNodejsImportProtocol": "off" + }, + "suspicious": { + "noExplicitAny": "off", + "noArrayIndexKey": "off" + }, + "correctness": { + "useExhaustiveDependencies": "off", + "noUnusedVariables": "error" + }, + "a11y": { + "useKeyWithClickEvents": "off" + } + } + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "always", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false, + "quoteStyle": "double", + "attributePosition": "auto" + } + }, + "overrides": [ + { + "includes": ["*.stories.*", "*.test.*", "*.spec.*"], + "linter": { + "rules": { + "suspicious": { + "noExplicitAny": "off" + } + } + } + } + ] +} diff --git a/package.json b/package.json index 0673371..b5e685f 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,9 @@ "create-entrypoint": "bash -e ./scripts/create-package -e", "create-package": "bash -e ./scripts/create-package", "sync-env": "bash -e ./scripts/sync-env", - "lint": "eslint {packages,entrypoints,web-components,viz-service}/*/src -c .eslintrc.js --ext js,jsx,ts,tsx --fix && yarn eslint {packages,entrypoints,web-components,viz-service}/*/spec -c .eslintrc.js --ext js,jsx,ts,tsx --fix", - "format": "run prettier -w {packages,entrypoints,web-components,viz-service}/*/src/**/*.{ts,js,tsx} && yarn run prettier -w {packages,entrypoints,web-components,viz-service}/*/spec/*.{ts,tsx}", + "lint": "biome check .", + "lint:fix": "biome check --write .", + "format": "biome format --write .", "test": "vitest run --workspace=vitest.workspace.ts", "test:ui": "vitest --workspace=vitest.workspace.ts --ui", "test:watch": "vitest --workspace=vitest.workspace.ts", @@ -40,6 +41,7 @@ "chromatic": "chromatic" }, "devDependencies": { + "@biomejs/biome": "^2.2.6", "@codemirror/lang-javascript": "^6.2.2", "@codemirror/view": "^6.32.0", "@emotion/react": "^11.13.0", @@ -82,7 +84,9 @@ "minimist": "^1.2.8", "qs": "^6.11.2", "string-width": "^4.2.0", - "wrap-ansi": "^7.0.0" + "wrap-ansi": "^7.0.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0" }, "volta": { "node": "22.20.0", diff --git a/packages/experience-editor/main.tsx b/packages/experience-editor/main.tsx index cfb9f7a..d8b5f3a 100644 --- a/packages/experience-editor/main.tsx +++ b/packages/experience-editor/main.tsx @@ -1,6 +1,6 @@ -import r2wc from "react-to-webcomponent"; import React from "react"; import * as ReactDOM from "react-dom/client"; +import r2wc from "react-to-webcomponent"; import WidgetWizard from "./src/App"; const LyticswidgetWizardWC = r2wc(WidgetWizard, React, ReactDOM, { diff --git a/packages/experience-editor/package.json b/packages/experience-editor/package.json index e605de8..f2e73ea 100644 --- a/packages/experience-editor/package.json +++ b/packages/experience-editor/package.json @@ -33,7 +33,7 @@ "yarn": "1.22.18" }, "devDependencies": { - "@types/react": "^19.2.0", - "@types/react-dom": "^19.2.0" + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0" } } diff --git a/packages/experience-editor/src/App.tsx b/packages/experience-editor/src/App.tsx index 0a234a7..7b73bc3 100644 --- a/packages/experience-editor/src/App.tsx +++ b/packages/experience-editor/src/App.tsx @@ -1,9 +1,9 @@ -import React from "react"; import { Box } from "@mui/material"; -import WidgetWizard from "./components/widgetWizard"; -import { createTheme, ThemeProvider, styled } from "@mui/material/styles"; -import { LightBlueGray, DarkestBlueGray } from "./utility/colors"; +import { createTheme, ThemeProvider } from "@mui/material/styles"; import type {} from "@mui/x-date-pickers/themeAugmentation"; +import React from "react"; +import WidgetWizard from "./components/widgetWizard"; +import { DarkestBlueGray, LightBlueGray } from "./utility/colors"; const theme = createTheme({ components: { @@ -135,7 +135,7 @@ const CoreWidgetWizard: React.FC = ({ // url decode the pathfora config try { pathforaconfig = atob(pathforaconfig); - } catch (e) { + } catch (_e) { pathforaconfig = ""; } diff --git a/packages/experience-editor/src/components/branding.tsx b/packages/experience-editor/src/components/branding.tsx index ecce668..d69e19d 100644 --- a/packages/experience-editor/src/components/branding.tsx +++ b/packages/experience-editor/src/components/branding.tsx @@ -1,21 +1,21 @@ -import React, { useEffect, useState } from "react"; -import { SelectInput } from "../components/form/select"; +import { Home } from "@mui/icons-material"; +import React from "react"; import { ColorInput } from "../components/form/color"; -import { NumberedSection } from "../components/form/numberedSection"; import { ColorPicker } from "../components/form/colorPicker"; -import { Home } from "@mui/icons-material"; +import { NumberedSection } from "../components/form/numberedSection"; +import { SelectInput } from "../components/form/select"; import { - theme, - backgroundColor, - textColor, - headlineColor, - closeColor, actionBackgroundColor, actionTextColor, + backgroundColor, cancelBackgroundColor, cancelTextColor, + closeColor, fieldBackgroundColor, + headlineColor, + textColor, + theme, } from "../data/pfa-fields"; interface BrandingSectionProps { diff --git a/packages/experience-editor/src/components/displayRules.tsx b/packages/experience-editor/src/components/displayRules.tsx index 9f2c7d2..25085b7 100644 --- a/packages/experience-editor/src/components/displayRules.tsx +++ b/packages/experience-editor/src/components/displayRules.tsx @@ -1,41 +1,46 @@ +import { RemoveRedEye } from "@mui/icons-material"; +import { + Box, + Checkbox, + FormControlLabel, + FormGroup, + Stack, +} from "@mui/material"; +import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import React from "react"; -import { Stack } from "@mui/material"; -import { SelectInput } from "../components/form/select"; -import { NumberedSection } from "../components/form/numberedSection"; -import { TextInput } from "../components/form/input"; -import { SelectMultipleInput } from "../components/form/selectMultiple"; import { ConditionGroup } from "../components/form/conditionGroup"; +import { TextInput } from "../components/form/input"; +import { NumberedSection } from "../components/form/numberedSection"; import { SectionHeader } from "../components/form/sectionHeader"; -import { EmptyState } from "../utility/emptyState"; -import { RemoveRedEye } from "@mui/icons-material"; +import { SelectInput } from "../components/form/select"; +import { SelectMultipleInput } from "../components/form/selectMultiple"; import { - layout, + dateRangeEnd, + dateRangeIndefinite, + dateRangeStart, displayConditions, hideAfter, - pageVisits, - scrollPercentageToDisplay, - showDelay, - showOnExitIntent, + hideAfterActionCancelHideCount, + hideAfterActionCancelHideDuration, + hideAfterActionClosedHideCount, + hideAfterActionClosedHideDuration, + hideAfterActionConfirmHideCount, + hideAfterActionConfirmHideDuration, impressionsGlobalDuration, impressionsGlobalSession, impressionsGlobalTotal, impressionsWidgetDuration, impressionsWidgetSession, impressionsWidgetTotal, - hideAfterActionClosedHideCount, - hideAfterActionClosedHideDuration, - hideAfterActionConfirmHideCount, - hideAfterActionConfirmHideDuration, - hideAfterActionCancelHideCount, - hideAfterActionCancelHideDuration, - dateRangeStart, - dateRangeEnd, - dateRangeIndefinite, + layout, + pageVisits, + scrollPercentageToDisplay, + showDelay, + showOnExitIntent, } from "../data/pfa-fields"; +import { EmptyState } from "../utility/emptyState"; import { DatePickerInput } from "./form/datePicker"; -import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; -import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns"; -import { Checkbox, FormGroup, Box, FormControlLabel } from "@mui/material"; interface DisplayRulesSectionProps { formValues: { [key: string]: string }; diff --git a/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx b/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx index 9ba1ce1..5880ff6 100644 --- a/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx +++ b/packages/experience-editor/src/components/form/__tests__/radioGroup.test.tsx @@ -1,7 +1,7 @@ -import { describe, it, expect, vi } from "vitest"; -import { render, screen, fireEvent } from "@testing-library/react"; -import { RadioGroupInput } from "../radioGroup"; +import { fireEvent, render, screen } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; import { Field } from "../../../data/pfa-fields"; +import { RadioGroupInput } from "../radioGroup"; describe("RadioGroupInput", () => { const mockField: Field = { diff --git a/packages/experience-editor/src/components/form/callbackFn.tsx b/packages/experience-editor/src/components/form/callbackFn.tsx index 4831170..8ff33e2 100644 --- a/packages/experience-editor/src/components/form/callbackFn.tsx +++ b/packages/experience-editor/src/components/form/callbackFn.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Box, Stack, Typography } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; import { CodeEditor } from "./codeEditor"; diff --git a/packages/experience-editor/src/components/form/checkbox.tsx b/packages/experience-editor/src/components/form/checkbox.tsx index 0ccb0bb..47e22e6 100644 --- a/packages/experience-editor/src/components/form/checkbox.tsx +++ b/packages/experience-editor/src/components/form/checkbox.tsx @@ -1,5 +1,5 @@ +import { Checkbox, FormControlLabel } from "@mui/material"; import React, { useEffect } from "react"; -import { FormControlLabel, Checkbox } from "@mui/material"; import { Field } from "../../data/pfa-fields"; export interface CheckboxInputProps { diff --git a/packages/experience-editor/src/components/form/codeEditor.tsx b/packages/experience-editor/src/components/form/codeEditor.tsx index 8fb26b9..2acb42b 100644 --- a/packages/experience-editor/src/components/form/codeEditor.tsx +++ b/packages/experience-editor/src/components/form/codeEditor.tsx @@ -1,8 +1,8 @@ -import React, { useState, useEffect } from "react"; -import CodeMirror from "@uiw/react-codemirror"; import { javascript } from "@codemirror/lang-javascript"; -import { Box, Chip, LinearProgress } from "@mui/material"; import { CheckCircle } from "@mui/icons-material"; +import { Box, Chip, LinearProgress } from "@mui/material"; +import CodeMirror from "@uiw/react-codemirror"; +import React, { useEffect, useState } from "react"; interface CodeEditorProps { value: string; @@ -26,7 +26,7 @@ export const CodeEditor: React.FC = ({ setCodeString(value); }, [value]); - const onInputChange = React.useCallback((val, viewUpdate) => { + const onInputChange = React.useCallback((val, _viewUpdate) => { setCodeString(val); setIsDirty(true); @@ -41,14 +41,14 @@ export const CodeEditor: React.FC = ({ onChange(val); setShowSaveAlert(true); setIsDirty(false); - const newTimer2 = setTimeout(() => { + const _newTimer2 = setTimeout(() => { setShowSaveAlert(false); }, 1000); - } catch (error) { + } catch (_error) { setProgressColor("error"); setShowErrorAlert(true); setIsDirty(true); - const newTimer2 = setTimeout(() => { + const _newTimer2 = setTimeout(() => { setShowErrorAlert(false); }, 1000); } diff --git a/packages/experience-editor/src/components/form/color.tsx b/packages/experience-editor/src/components/form/color.tsx index ae47ded..05e4205 100644 --- a/packages/experience-editor/src/components/form/color.tsx +++ b/packages/experience-editor/src/components/form/color.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Stack, Typography } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; import { helperTextStyles } from "../styles/inputLabel"; diff --git a/packages/experience-editor/src/components/form/colorPicker.tsx b/packages/experience-editor/src/components/form/colorPicker.tsx index 95562ec..ff3b601 100644 --- a/packages/experience-editor/src/components/form/colorPicker.tsx +++ b/packages/experience-editor/src/components/form/colorPicker.tsx @@ -1,5 +1,5 @@ -import React, { ReactNode } from "react"; import { Grid } from "@mui/material"; // Importing necessary components from Material-UI +import React, { ReactNode } from "react"; interface ColorPickerProps { children: ReactNode | ReactNode[]; diff --git a/packages/experience-editor/src/components/form/conditionGroup.tsx b/packages/experience-editor/src/components/form/conditionGroup.tsx index aea6ab0..2dd7946 100644 --- a/packages/experience-editor/src/components/form/conditionGroup.tsx +++ b/packages/experience-editor/src/components/form/conditionGroup.tsx @@ -1,5 +1,5 @@ -import React, { ReactNode } from "react"; import { Box, Stack } from "@mui/material"; // Importing necessary components from Material-UI +import React, { ReactNode } from "react"; interface ConditionGroupProps { label: string; diff --git a/packages/experience-editor/src/components/form/datePicker.tsx b/packages/experience-editor/src/components/form/datePicker.tsx index 6170c23..b49ea52 100644 --- a/packages/experience-editor/src/components/form/datePicker.tsx +++ b/packages/experience-editor/src/components/form/datePicker.tsx @@ -1,9 +1,8 @@ +import { Typography } from "@mui/material"; +import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; import React from "react"; import { Field } from "../../data/pfa-fields"; -import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; import { helperTextStyles } from "../styles/inputLabel"; -import { Typography } from "@mui/material"; -import { parseISO } from "date-fns"; export interface DatePickerInputProps { field: Field; diff --git a/packages/experience-editor/src/components/form/displayConditionItem.tsx b/packages/experience-editor/src/components/form/displayConditionItem.tsx index 890be1a..944399a 100644 --- a/packages/experience-editor/src/components/form/displayConditionItem.tsx +++ b/packages/experience-editor/src/components/form/displayConditionItem.tsx @@ -1,5 +1,5 @@ -import React, { useEffect } from "react"; -import { Box, Grid, Stack } from "@mui/material"; +import { Box, Stack } from "@mui/material"; +import React from "react"; export interface DisplayConditionItemProps { children: React.ReactNode[]; diff --git a/packages/experience-editor/src/components/form/input.tsx b/packages/experience-editor/src/components/form/input.tsx index 1035bff..a3626b8 100644 --- a/packages/experience-editor/src/components/form/input.tsx +++ b/packages/experience-editor/src/components/form/input.tsx @@ -1,7 +1,6 @@ -import React, { useEffect } from "react"; import { TextField } from "@mui/material"; +import React, { useEffect } from "react"; import { Field } from "../../data/pfa-fields"; -import { helperTextStyles } from "../styles/inputLabel"; export interface TextInputProps { field: Field; diff --git a/packages/experience-editor/src/components/form/numberedSection.tsx b/packages/experience-editor/src/components/form/numberedSection.tsx index cd8dd0f..bbe733a 100644 --- a/packages/experience-editor/src/components/form/numberedSection.tsx +++ b/packages/experience-editor/src/components/form/numberedSection.tsx @@ -1,6 +1,6 @@ -import React from "react"; -import { Avatar, Box, Stack, Typography } from "@mui/material"; import { Label } from "@mui/icons-material"; +import { Avatar, Stack, Typography } from "@mui/material"; +import React from "react"; export interface NumberedSectionProps { icon: React.ReactNode; diff --git a/packages/experience-editor/src/components/form/radioGroup.tsx b/packages/experience-editor/src/components/form/radioGroup.tsx index 2f162e8..ac8109c 100644 --- a/packages/experience-editor/src/components/form/radioGroup.tsx +++ b/packages/experience-editor/src/components/form/radioGroup.tsx @@ -1,12 +1,12 @@ -import React from "react"; import { FormControl, - FormLabel, - FormHelperText, - RadioGroup, FormControlLabel, + FormHelperText, + FormLabel, Radio, + RadioGroup, } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; export interface RadioGroupInputProps { diff --git a/packages/experience-editor/src/components/form/sectionHeader.tsx b/packages/experience-editor/src/components/form/sectionHeader.tsx index 55b1d07..6d0e335 100644 --- a/packages/experience-editor/src/components/form/sectionHeader.tsx +++ b/packages/experience-editor/src/components/form/sectionHeader.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Box, Typography } from "@mui/material"; +import React from "react"; export interface SectionHeaderProps { headline: string; diff --git a/packages/experience-editor/src/components/form/select.tsx b/packages/experience-editor/src/components/form/select.tsx index a613b86..eb1c13b 100644 --- a/packages/experience-editor/src/components/form/select.tsx +++ b/packages/experience-editor/src/components/form/select.tsx @@ -1,4 +1,3 @@ -import React from "react"; import { FormControl, FormHelperText, @@ -6,6 +5,7 @@ import { MenuItem, Select, } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; export interface SelectInputProps { @@ -39,7 +39,7 @@ export const SelectInput: React.FC = ({ required={field.required} renderValue={(selected) => { const selectedOption = field.options?.find( - (option) => option.value === selected + (option) => option.value === selected, ); return selectedOption?.label || ""; }} diff --git a/packages/experience-editor/src/components/form/selectMultiple.tsx b/packages/experience-editor/src/components/form/selectMultiple.tsx index 31ce628..c4a6c99 100644 --- a/packages/experience-editor/src/components/form/selectMultiple.tsx +++ b/packages/experience-editor/src/components/form/selectMultiple.tsx @@ -1,14 +1,14 @@ -import React, { useEffect } from "react"; import { Checkbox, - ListItemText, FormControl, FormHelperText, InputLabel, + ListItemText, MenuItem, Select, SelectChangeEvent, } from "@mui/material"; +import React, { useEffect } from "react"; import { Field } from "../../data/pfa-fields"; export interface SelectMultipleInputProps { @@ -20,10 +20,9 @@ export interface SelectMultipleInputProps { } export const SelectMultipleInput: React.FC = ( - selectMultipleInputProps + selectMultipleInputProps, ) => { - const { field, formValues, handleChange, position, visible } = - selectMultipleInputProps; + const { field, formValues, handleChange, visible } = selectMultipleInputProps; const [activeConditions, setActiveConditions] = React.useState([]); @@ -38,7 +37,7 @@ export const SelectMultipleInput: React.FC = ( }, [formValues]); const handleSelectCheckChange = ( - event: SelectChangeEvent + event: SelectChangeEvent, ) => { const { target: { value }, diff --git a/packages/experience-editor/src/components/form/textarea.tsx b/packages/experience-editor/src/components/form/textarea.tsx index 3a1af3b..ff02c0e 100644 --- a/packages/experience-editor/src/components/form/textarea.tsx +++ b/packages/experience-editor/src/components/form/textarea.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { TextField } from "@mui/material"; +import React from "react"; import { Field } from "../../data/pfa-fields"; export interface TextAreaProps { diff --git a/packages/experience-editor/src/components/form/urlContains.tsx b/packages/experience-editor/src/components/form/urlContains.tsx index a5938da..1354a1f 100644 --- a/packages/experience-editor/src/components/form/urlContains.tsx +++ b/packages/experience-editor/src/components/form/urlContains.tsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import DeleteIcon from "@mui/icons-material/Delete"; import { Box, Button, @@ -10,7 +10,7 @@ import { Stack, TextField, } from "@mui/material"; -import DeleteIcon from "@mui/icons-material/Delete"; +import React, { useEffect, useState } from "react"; import { Field } from "../../data/pfa-fields"; import { PinkHighlight } from "../../utility/colors"; @@ -88,7 +88,8 @@ export const URLContainsBuilder: React.FC = ({ Enter a value that should match the domain and path of your target URL. For example, entering{" "} test.com/my/path will match - https://test.com/my/path + https: + {"//"}test.com/my/path ?query=param ); diff --git a/packages/experience-editor/src/components/formBuilder.tsx b/packages/experience-editor/src/components/formBuilder.tsx index d4082f1..c1e6bdd 100644 --- a/packages/experience-editor/src/components/formBuilder.tsx +++ b/packages/experience-editor/src/components/formBuilder.tsx @@ -1,24 +1,24 @@ -import React, { useEffect, useState } from "react"; +import { + ArrowCircleDown, + ArrowCircleUp, + Delete, + Edit, + EditNote, + Save, +} from "@mui/icons-material"; import { Box, Button, Checkbox, Chip, - FormGroup, FormControlLabel, + FormGroup, IconButton, Stack, TextField, Typography, } from "@mui/material"; -import { - ArrowCircleDown, - ArrowCircleUp, - Delete, - Edit, - Save, - EditNote, -} from "@mui/icons-material"; +import React, { useEffect, useId, useState } from "react"; import { NumberedSection } from "../components/form/numberedSection"; import { formElements as formElementsData } from "../data/pfa-fields"; import { EmptyState } from "../utility/emptyState"; @@ -58,6 +58,9 @@ export const FormNodeEditor: React.FC = ({ onShift, onDelete, }): JSX.Element => { + const nameId = useId(); + const labelId = useId(); + const placeholderId = useId(); const [options, setOptions] = useState([]); const [label, setLabel] = useState(""); const [placeholder, setPlaceholder] = useState(""); @@ -104,7 +107,7 @@ export const FormNodeEditor: React.FC = ({ const handleOptionChange = ( index: number, field: keyof FormValue, - value: string + value: string, ) => { const newOptions = options.map((option, i) => { if (i === index) { @@ -124,7 +127,7 @@ export const FormNodeEditor: React.FC = ({ setOptions(newOptions); }; - const handleOpenToggle = (field: FormElement) => { + const handleOpenToggle = (_field: FormElement) => { setOpen(!open); }; @@ -265,7 +268,7 @@ export const FormNodeEditor: React.FC = ({ {/* Name input */} = ({ {/* Label input */} = ({ {/* Placeholder input */} = ({ {options.map((option, index) => ( - + = ({ - ) : ( - <> - )} + ) : null} )} @@ -484,7 +485,7 @@ export const FormBuilder: React.FC = ({ message={"Add form elements using the buttons to the right."} /> )} - {formElements.map((element, index) => ( + {formElements.map((element, _index) => ( { = ({ formValues, handleChange, formFieldVisibility, - spacing, isFieldSet, }) => { return ( diff --git a/packages/experience-editor/src/components/position.tsx b/packages/experience-editor/src/components/position.tsx index 774e495..455a2f3 100644 --- a/packages/experience-editor/src/components/position.tsx +++ b/packages/experience-editor/src/components/position.tsx @@ -1,21 +1,21 @@ -import React from "react"; -import { Stack } from "@mui/material"; import { ControlCamera } from "@mui/icons-material"; +import { Stack } from "@mui/material"; +import React from "react"; +import { ConditionGroup } from "../components/form/conditionGroup"; import { TextInput } from "../components/form/input"; -import { SelectInput } from "../components/form/select"; import { NumberedSection } from "../components/form/numberedSection"; -import { ConditionGroup } from "../components/form/conditionGroup"; +import { SelectInput } from "../components/form/select"; import { - type, + image, layout, layoutWithOptions, - image, - positionSelector, - position, - positionWithOptions, origin, originWithOptions, + position, + positionSelector, + positionWithOptions, pushDown, + type, } from "../data/pfa-fields"; interface PositionSectionProps { diff --git a/packages/experience-editor/src/components/recommendation.tsx b/packages/experience-editor/src/components/recommendation.tsx index f1f3b73..5dbe17d 100644 --- a/packages/experience-editor/src/components/recommendation.tsx +++ b/packages/experience-editor/src/components/recommendation.tsx @@ -1,27 +1,25 @@ -import React, { useState, useEffect } from "react"; - +import { Recommend } from "@mui/icons-material"; +import { Stack } from "@mui/material"; +import React, { useEffect, useState } from "react"; import { contentCollection, contentCollectionWithOptions, - contentRank, - contentVisited, - contentShuffle, - contentDisplayTitle, - contentDisplayImage, contentDisplayDescription, contentDisplayDescriptionLimit, + contentDisplayImage, + contentDisplayTitle, + contentRank, + contentShuffle, + contentVisited, Field, SelectOption, } from "../data/pfa-fields"; - +import { CheckboxInput } from "./form/checkbox"; import { ConditionGroup } from "./form/conditionGroup"; import { TextInput } from "./form/input"; -import { SelectInput } from "./form/select"; -import { CheckboxInput } from "./form/checkbox"; -import { RadioGroupInput } from "./form/radioGroup"; import { NumberedSection } from "./form/numberedSection"; -import { Recommend } from "@mui/icons-material"; -import { Stack } from "@mui/material"; +import { RadioGroupInput } from "./form/radioGroup"; +import { SelectInput } from "./form/select"; interface RecommendationSectionProps { formValues: { [key: string]: string }; @@ -38,7 +36,7 @@ export const RecommendationSection: React.FC = ({ spacing, collections, }) => { - const [collectionField, setCollectionField] = useState(null); + const [_collectionField, setCollectionField] = useState(null); useEffect(() => { setCollectionField(contentCollectionWithOptions(collections)); diff --git a/packages/experience-editor/src/components/targeting.tsx b/packages/experience-editor/src/components/targeting.tsx index cc2eebd..ca8a2d5 100644 --- a/packages/experience-editor/src/components/targeting.tsx +++ b/packages/experience-editor/src/components/targeting.tsx @@ -1,23 +1,22 @@ +import { AdsClick, FindInPage } from "@mui/icons-material"; import React, { useEffect, useState } from "react"; +import { ConditionGroup } from "../components/form/conditionGroup"; +import { NumberedSection } from "../components/form/numberedSection"; +import { SelectInput } from "../components/form/select"; import { URLContainsBuilder, URLContainsItem, } from "../components/form/urlContains"; -import { SelectInput } from "../components/form/select"; -import { ConditionGroup } from "../components/form/conditionGroup"; import { - type, - urlContains, + attributeRule, audienceWithOptions, Field, + personalizationKeyWithOptions, SelectOption, - Flow, targetMethod, - attributeRule, - personalizationKeyWithOptions, + type, + urlContains, } from "../data/pfa-fields"; -import { NumberedSection } from "../components/form/numberedSection"; -import { AdsClick, FindInPage } from "@mui/icons-material"; import { CallbackFnEditor } from "./form/callbackFn"; interface TargetingSectionProps { diff --git a/packages/experience-editor/src/components/widgetWizard.tsx b/packages/experience-editor/src/components/widgetWizard.tsx index 49d6e9e..6271158 100644 --- a/packages/experience-editor/src/components/widgetWizard.tsx +++ b/packages/experience-editor/src/components/widgetWizard.tsx @@ -1,100 +1,96 @@ +import { Box, Button, Stack, Tab, Tabs } from "@mui/material"; import React, { useEffect, useState } from "react"; -import { Box, Button, Stack, Tab, Tabs, Typography } from "@mui/material"; - import { - Field, - SelectOption, - type, - headline, - layout, - theme, - backgroundColor, - textColor, - headlineColor, - closeColor, actionBackgroundColor, actionTextColor, + attributeRule, + audience, + backgroundColor, + cancelAction, cancelBackgroundColor, - cancelTextColor, - fieldBackgroundColor, - message, - okShow, - okMessage, - cancelShow, cancelMessage, - image, - positionSelector, - position, - origin, - pushDown, - widgetTitle, - widgetDescription, - widgetSlug, - widgetStatus, + cancelShow, + cancelTextColor, + closeAction, + closeColor, + confirmAction, + contentCollection, + contentDisplayDescription, + contentDisplayDescriptionLimit, + contentDisplayImage, + contentDisplayTitle, + contentRank, + contentShuffle, + contentVisited, + dateRangeEnd, + dateRangeIndefinite, + dateRangeStart, displayConditions, + Field, + Flow, + fieldBackgroundColor, + formElements, + headline, + headlineColor, hideAfter, - pageVisits, - scrollPercentageToDisplay, - showDelay, - showOnExitIntent, + hideAfterActionCancelHideCount, + hideAfterActionCancelHideDuration, + hideAfterActionClosedHideCount, + hideAfterActionClosedHideDuration, + hideAfterActionConfirmHideCount, + hideAfterActionConfirmHideDuration, + image, impressionsGlobalDuration, impressionsGlobalSession, impressionsGlobalTotal, impressionsWidgetDuration, impressionsWidgetSession, impressionsWidgetTotal, - hideAfterActionClosedHideCount, - hideAfterActionClosedHideDuration, - hideAfterActionConfirmHideCount, - hideAfterActionConfirmHideDuration, - hideAfterActionCancelHideCount, - hideAfterActionCancelHideDuration, - dateRangeStart, - dateRangeEnd, - dateRangeIndefinite, - urlContains, - confirmAction, - cancelAction, - closeAction, - onInit, - onLoad, - audience, - formElements, - contentCollection, - contentRank, - contentVisited, - contentShuffle, - contentDisplayTitle, - contentDisplayImage, - contentDisplayDescription, - contentDisplayDescriptionLimit, - targetMethod, - attributeRule, - Flow, + layout, + message, okLinkNewTab, - okShowLink, okLinkURL, + okMessage, + okShow, + okShowLink, + onInit, + onLoad, + origin, + pageVisits, personalizationKey, + position, + positionSelector, + pushDown, + SelectOption, + scrollPercentageToDisplay, + showDelay, + showOnExitIntent, + targetMethod, + textColor, + theme, + type, + urlContains, + widgetDescription, + widgetSlug, + widgetStatus, + widgetTitle, } from "../data/pfa-fields"; - -import { TextAreaInput } from "./form/textarea"; +import { findFieldById, shouldApplyDefaultValue } from "../utility/fieldLogic"; +import { getValueByDotNotation, removeEmptyObjects } from "../utility/objects"; +import { PathforaHandler } from "../utility/pathforaInterface"; +import { BrandingSection } from "./branding"; +import { DisplayRulesSection } from "./displayRules"; +import { CallbackFnEditor } from "./form/callbackFn"; +import { CodeEditor } from "./form/codeEditor"; import { TextInput } from "./form/input"; -import { SelectInput } from "./form/select"; import { SectionHeader } from "./form/sectionHeader"; -import { CodeEditor } from "./form/codeEditor"; +import { SelectInput } from "./form/select"; +import { TextAreaInput } from "./form/textarea"; +import { FormBuilder } from "./formBuilder"; import { MessagingSection } from "./messaging"; -import { TargetingSection } from "./targeting"; import { PositionSection } from "./position"; -import { BrandingSection } from "./branding"; -import { DisplayRulesSection } from "./displayRules"; import { RecommendationSection } from "./recommendation"; -import { PathforaHandler } from "../utility/pathforaInterface"; -import { CallbackFnEditor } from "./form/callbackFn"; -import { FormBuilder } from "./formBuilder"; - -import { removeEmptyObjects, getValueByDotNotation } from "../utility/objects"; -import { shouldApplyDefaultValue, findFieldById } from "../utility/fieldLogic"; -import { Visibility } from "@mui/icons-material"; +import { TargetingSection } from "./targeting"; interface WidgetWizardProps { accountid: string; @@ -168,7 +164,7 @@ const WidgetWizard: React.FC = ({ const [pathfora, setPathfora] = useState(); const [audiences, setAudiences] = useState([]); const [collections, setCollections] = useState([]); - const [flows, setFlows] = useState([]); + const [_flows, setFlows] = useState([]); const [personalizationKeys, setPersonalizationKeys] = useState< SelectOption[] >([]); @@ -305,8 +301,7 @@ const WidgetWizard: React.FC = ({ // update source fields when any value changes useEffect(() => { checkSourceLink(); - }), - [formValues]; + }, [formValues]); useEffect(() => { const editConfig = document.getElementById( @@ -318,7 +313,7 @@ const WidgetWizard: React.FC = ({ }, [formValues]); const handlePathforaPreview = () => { - let config = JSON.parse(renderedConfig); + const config = JSON.parse(renderedConfig); const widget = pathfora?.deserializeWidget(config); pathfora?.testWidget(widget); }; @@ -355,17 +350,17 @@ const WidgetWizard: React.FC = ({ }); }; - const handleEditorTypeTabChange = (event, newValue) => { + const handleEditorTypeTabChange = (_event, newValue) => { setEditorTypeTabValue(newValue); }; - const handleBasicEditorTabChange = (event, newValue) => { + const handleBasicEditorTabChange = (event, _newValue) => { const id = event.target.id; const value = tabToValueMapping[id]; setBasicEditorTabValue(value); }; - const handleAdvancedEditorTabChange = (event, newValue) => { + const handleAdvancedEditorTabChange = (_event, newValue) => { setAdvancedEditorTabValue(newValue); }; @@ -411,7 +406,7 @@ const WidgetWizard: React.FC = ({ const renderConfiguration = () => { let config = {}; - let renderedConfigObject; + let renderedConfigObject: any; try { renderedConfigObject = JSON.parse(renderedConfig); @@ -638,9 +633,9 @@ const WidgetWizard: React.FC = ({ if (!value) { return false; } - let callback; + let callback: any; try { - callback = Function('"use strict";return (' + value + ")")(); + callback = Function(`"use strict";return (${value})`)(); } catch (error) { console.warn("Invalid function:", error); return; @@ -659,7 +654,6 @@ const WidgetWizard: React.FC = ({ const callbackFn = renderCallbackFunction(value); if (!callbackFn) { throw new Error("Callback function is not defined."); - return; } callbackFnString = callbackFn.toString(); @@ -671,7 +665,7 @@ const WidgetWizard: React.FC = ({ })); }; - const handleSubmit = (event: React.FormEvent): void => { + const handleSubmit = (_event: React.FormEvent): void => { // no op for now }; diff --git a/packages/experience-editor/src/data/fields/audience.ts b/packages/experience-editor/src/data/fields/audience.ts index 75ba3f5..2a0f7b5 100644 --- a/packages/experience-editor/src/data/fields/audience.ts +++ b/packages/experience-editor/src/data/fields/audience.ts @@ -13,7 +13,7 @@ export const Audience: Field = { }; export const AudienceWithOptions = (audiences: SelectOption[]) => { - let payload = Audience; + const payload = Audience; payload.options = audiences; return payload; }; diff --git a/packages/experience-editor/src/data/fields/layout.ts b/packages/experience-editor/src/data/fields/layout.ts index 7fbee44..2f5aa9e 100644 --- a/packages/experience-editor/src/data/fields/layout.ts +++ b/packages/experience-editor/src/data/fields/layout.ts @@ -15,7 +15,7 @@ const OptionBar: SelectOption = { value: "bar", }; -const OptionButton: SelectOption = { +const _OptionButton: SelectOption = { label: "Button", value: "button", }; @@ -75,7 +75,7 @@ export const Layout: Field = { }; export const LayoutWithOptions: (type: string) => Field = (type: string) => { - let payload = Layout; + const payload = Layout; payload.options = getSelectOptions(type); return payload; }; diff --git a/packages/experience-editor/src/data/fields/okLinkNewTab.ts b/packages/experience-editor/src/data/fields/okLinkNewTab.ts index ea3647d..830f018 100644 --- a/packages/experience-editor/src/data/fields/okLinkNewTab.ts +++ b/packages/experience-editor/src/data/fields/okLinkNewTab.ts @@ -11,8 +11,7 @@ export const OKLinkNewTab: Field = { render: "details.cta.newTab", translate: { render: "config.confirmAction.callback", - renderValue: function (newTab, config) { - return renderConfirmActionCallbackLink(config.details.cta?.url, newTab); - }, + renderValue: (newTab, config) => + renderConfirmActionCallbackLink(config.details.cta?.url, newTab), }, }; diff --git a/packages/experience-editor/src/data/fields/okLinkURL.ts b/packages/experience-editor/src/data/fields/okLinkURL.ts index 77030cb..85edd29 100644 --- a/packages/experience-editor/src/data/fields/okLinkURL.ts +++ b/packages/experience-editor/src/data/fields/okLinkURL.ts @@ -12,8 +12,7 @@ export const OKLinkURL: Field = { render: "details.cta.url", translate: { render: "config.confirmAction.callback", - renderValue: function (value, config) { - return renderConfirmActionCallbackLink(value, config.details.cta?.newTab); - }, + renderValue: (value, config) => + renderConfirmActionCallbackLink(value, config.details.cta?.newTab), }, }; diff --git a/packages/experience-editor/src/data/fields/origin.ts b/packages/experience-editor/src/data/fields/origin.ts index 1463686..56a2316 100644 --- a/packages/experience-editor/src/data/fields/origin.ts +++ b/packages/experience-editor/src/data/fields/origin.ts @@ -38,7 +38,7 @@ export const Origin: Field = { }; export const OriginWithOptions: (type: string) => Field = (type: string) => { - let payload = Origin; + const payload = Origin; payload.options = getSelectOptions(type); return payload; }; diff --git a/packages/experience-editor/src/data/fields/personalizationKeys.ts b/packages/experience-editor/src/data/fields/personalizationKeys.ts index 4befdc1..679c66d 100644 --- a/packages/experience-editor/src/data/fields/personalizationKeys.ts +++ b/packages/experience-editor/src/data/fields/personalizationKeys.ts @@ -14,7 +14,7 @@ export const PersonalizationKey: Field = { }; export const PersonalizationKeyWithOptions = (pk: SelectOption[]) => { - let payload = PersonalizationKey; + const payload = PersonalizationKey; payload.options = pk; return payload; }; diff --git a/packages/experience-editor/src/data/fields/position.ts b/packages/experience-editor/src/data/fields/position.ts index 978c8d1..0566fd8 100644 --- a/packages/experience-editor/src/data/fields/position.ts +++ b/packages/experience-editor/src/data/fields/position.ts @@ -94,7 +94,7 @@ export const Position: Field = { }; export const PositionWithOptions: (type: string) => Field = (type: string) => { - let payload = Position; + const payload = Position; payload.options = getSelectOptions(type); return payload; }; diff --git a/packages/experience-editor/src/data/fields/recommend.ts b/packages/experience-editor/src/data/fields/recommend.ts index 1e44848..86e788a 100644 --- a/packages/experience-editor/src/data/fields/recommend.ts +++ b/packages/experience-editor/src/data/fields/recommend.ts @@ -13,7 +13,7 @@ export const ContentCollection: Field = { }; export const ContentCollectionWithOptions = (collections: SelectOption[]) => { - let payload = ContentCollection; + const payload = ContentCollection; payload.options = collections; return payload; }; diff --git a/packages/experience-editor/src/data/fields/targetFlow.ts b/packages/experience-editor/src/data/fields/targetFlow.ts index ee3190a..3b78980 100644 --- a/packages/experience-editor/src/data/fields/targetFlow.ts +++ b/packages/experience-editor/src/data/fields/targetFlow.ts @@ -19,7 +19,6 @@ export const TargetFlowVersion: Field = { hidden: true, type: "string", method: "select", - fieldsToShow: [TargetFlowStep.id], render: "details.target.flow.version", }; @@ -31,12 +30,11 @@ export const TargetFlow: Field = { hidden: true, type: "string", method: "select", - fieldsToShow: [TargetFlowVersion.id], render: "details.target.flow.id", }; export const TargetFlowWithOptions = (flows: Flow[]) => { - let payload = TargetFlow; + const payload = TargetFlow; payload.options = flows.reduce((acc, flow) => { acc.push({ label: flow.label, value: flow.value }); return acc; @@ -45,7 +43,7 @@ export const TargetFlowWithOptions = (flows: Flow[]) => { }; export const TargetFlowVersionWithOptions = (flows: Flow[], id: string) => { - let payload = TargetFlowVersion; + const payload = TargetFlowVersion; payload.options = flows .find((flow) => flow.value === id) .versions.map((v) => ({ @@ -60,7 +58,7 @@ export const TargetFlowStepWithOptions = ( id: string, version: string, ) => { - let payload = TargetFlowStep; + const payload = TargetFlowStep; payload.options = flows .find((flow) => flow.value === id) .versions.find((v) => v.version.toString() === version).steps; diff --git a/packages/experience-editor/src/data/fields/targetMethod.ts b/packages/experience-editor/src/data/fields/targetMethod.ts index fa0d74a..2d410cc 100644 --- a/packages/experience-editor/src/data/fields/targetMethod.ts +++ b/packages/experience-editor/src/data/fields/targetMethod.ts @@ -1,6 +1,6 @@ import { Field } from "../pfa-fields"; -import { Audience } from "./audience"; import { AttributeRule } from "./attributeRule"; +import { Audience } from "./audience"; import { PersonalizationKey } from "./personalizationKeys"; export const TargetMethod: Field = { diff --git a/packages/experience-editor/src/data/fields/theme.ts b/packages/experience-editor/src/data/fields/theme.ts index b756c60..eea7bb3 100644 --- a/packages/experience-editor/src/data/fields/theme.ts +++ b/packages/experience-editor/src/data/fields/theme.ts @@ -1,14 +1,14 @@ import { Field } from "../pfa-fields"; import { - BackgroundColor, - HeadlineColor, - TextColor, - CloseColor, ActionBackgroundColor, ActionTextColor, + BackgroundColor, CancelBackgroundColor, CancelTextColor, + CloseColor, FieldBackgroundColor, + HeadlineColor, + TextColor, } from "./colors"; export const Theme: Field = { diff --git a/packages/experience-editor/src/data/fields/type.ts b/packages/experience-editor/src/data/fields/type.ts index 1376688..45dd39d 100644 --- a/packages/experience-editor/src/data/fields/type.ts +++ b/packages/experience-editor/src/data/fields/type.ts @@ -1,14 +1,4 @@ import { Field } from "../pfa-fields"; -import { - contentCollection, - contentRank, - contentVisited, - contentShuffle, - contentDisplayTitle, - contentDisplayImage, - contentDisplayDescription, - contentDisplayDescriptionLimit, -} from "../pfa-fields"; export const Type: Field = { id: "type", diff --git a/packages/experience-editor/src/data/fields/widgetStatus.ts b/packages/experience-editor/src/data/fields/widgetStatus.ts index d8a654a..d6719db 100644 --- a/packages/experience-editor/src/data/fields/widgetStatus.ts +++ b/packages/experience-editor/src/data/fields/widgetStatus.ts @@ -1,5 +1,4 @@ -import { Field } from "../pfa-fields"; -import { SelectOption } from "../pfa-fields"; +import { Field, SelectOption } from "../pfa-fields"; const OptionDraft: SelectOption = { label: "Draft", diff --git a/packages/experience-editor/src/data/pfa-fields.ts b/packages/experience-editor/src/data/pfa-fields.ts index 5a7353b..44650c2 100644 --- a/packages/experience-editor/src/data/pfa-fields.ts +++ b/packages/experience-editor/src/data/pfa-fields.ts @@ -1,41 +1,38 @@ -import { Type } from "./fields/type"; -import { Headline } from "./fields/headline"; -import { Layout, LayoutWithOptions } from "./fields/layout"; -import { Theme } from "./fields/theme"; +import { AttributeRule } from "./fields/attributeRule"; +import { Audience, AudienceWithOptions } from "./fields/audience"; +import { CancelAction } from "./fields/callbacks/cancelAction"; +import { CloseAction } from "./fields/callbacks/closeAction"; +import { ConfirmAction } from "./fields/callbacks/confirmAction"; +import { OnInit } from "./fields/callbacks/onInit"; +import { OnLoad } from "./fields/callbacks/onLoad"; +import { CancelMessage } from "./fields/cancelMessage"; +import { CancelShow } from "./fields/cancelShow"; import { - BackgroundColor, - TextColor, - HeadlineColor, - CloseColor, ActionBackgroundColor, ActionTextColor, + BackgroundColor, CancelBackgroundColor, CancelTextColor, + CloseColor, FieldBackgroundColor, + HeadlineColor, + TextColor, } from "./fields/colors"; -import { Message } from "./fields/msg"; -import { OKShow } from "./fields/okShow"; -import { OKShowLink } from "./fields/okShowLink"; -import { OKLinkURL } from "./fields/okLinkURL"; -import { OKLinkNewTab } from "./fields/okLinkNewTab"; -import { OKMessage } from "./fields/okMessage"; -import { CancelShow } from "./fields/cancelShow"; -import { CancelMessage } from "./fields/cancelMessage"; -import { Image } from "./fields/image"; -import { PositionSelector } from "./fields/positionSelector"; -import { Position, PositionWithOptions } from "./fields/position"; -import { Origin, OriginWithOptions } from "./fields/origin"; -import { PushDown } from "./fields/pushDown"; -import { WidgetTitle } from "./fields/widgetTitle"; -import { WidgetDescription } from "./fields/widgetDescription"; -import { WidgetSlug } from "./fields/widgetSlug"; -import { WidgetStatus } from "./fields/widgetStatus"; import { DisplayConditions } from "./fields/displayConditions"; +import { + DateRangeEnd, + DateRangeIndefinite, + DateRangeStart, +} from "./fields/displayConditions/dateRange"; import { HideAfter } from "./fields/displayConditions/hideAfter"; -import { PageVisits } from "./fields/displayConditions/pageVisits"; -import { ScrollPercentageToDisplay } from "./fields/displayConditions/scrollPercentageToDisplay"; -import { ShowDelay } from "./fields/displayConditions/showDelay"; -import { ShowOnExitIntent } from "./fields/displayConditions/showOnExitIntent"; +import { + HideAfterActionCancelHideCount, + HideAfterActionCancelHideDuration, + HideAfterActionClosedHideCount, + HideAfterActionClosedHideDuration, + HideAfterActionConfirmHideCount, + HideAfterActionConfirmHideDuration, +} from "./fields/displayConditions/hideAfterAction"; import { ImpressionsGlobalDuration, ImpressionsGlobalSession, @@ -44,52 +41,55 @@ import { ImpressionsWidgetSession, ImpressionsWidgetTotal, } from "./fields/displayConditions/impressions"; -import { - HideAfterActionClosedHideCount, - HideAfterActionClosedHideDuration, - HideAfterActionConfirmHideCount, - HideAfterActionConfirmHideDuration, - HideAfterActionCancelHideCount, - HideAfterActionCancelHideDuration, -} from "./fields/displayConditions/hideAfterAction"; -import { - DateRangeStart, - DateRangeEnd, - DateRangeIndefinite, -} from "./fields/displayConditions/dateRange"; +import { PageVisits } from "./fields/displayConditions/pageVisits"; +import { ScrollPercentageToDisplay } from "./fields/displayConditions/scrollPercentageToDisplay"; +import { ShowDelay } from "./fields/displayConditions/showDelay"; +import { ShowOnExitIntent } from "./fields/displayConditions/showOnExitIntent"; import { URLContains } from "./fields/displayConditions/urlContains"; -import { ConfirmAction } from "./fields/callbacks/confirmAction"; -import { CancelAction } from "./fields/callbacks/cancelAction"; -import { CloseAction } from "./fields/callbacks/closeAction"; -import { OnInit } from "./fields/callbacks/onInit"; -import { OnLoad } from "./fields/callbacks/onLoad"; -import { Audience, AudienceWithOptions } from "./fields/audience"; import { FormElements } from "./fields/formElements"; -import { TargetMethod } from "./fields/targetMethod"; -import { AttributeRule } from "./fields/attributeRule"; +import { Headline } from "./fields/headline"; +import { Image } from "./fields/image"; +import { Layout, LayoutWithOptions } from "./fields/layout"; +import { Message } from "./fields/msg"; +import { OKLinkNewTab } from "./fields/okLinkNewTab"; +import { OKLinkURL } from "./fields/okLinkURL"; +import { OKMessage } from "./fields/okMessage"; +import { OKShow } from "./fields/okShow"; +import { OKShowLink } from "./fields/okShowLink"; +import { Origin, OriginWithOptions } from "./fields/origin"; +import { + PersonalizationKey, + PersonalizationKeyWithOptions, +} from "./fields/personalizationKeys"; +import { Position, PositionWithOptions } from "./fields/position"; +import { PositionSelector } from "./fields/positionSelector"; +import { PushDown } from "./fields/pushDown"; import { ContentCollection, ContentCollectionWithOptions, - ContentVisited, - ContentShuffle, - ContentDisplayTitle, - ContentDisplayImage, ContentDisplayDescription, ContentDisplayDescriptionLimit, + ContentDisplayImage, + ContentDisplayTitle, ContentRank, + ContentShuffle, + ContentVisited, } from "./fields/recommend"; import { TargetFlow, - TargetFlowVersion, - TargetFlowWithOptions, - TargetFlowVersionWithOptions, TargetFlowStep, TargetFlowStepWithOptions, + TargetFlowVersion, + TargetFlowVersionWithOptions, + TargetFlowWithOptions, } from "./fields/targetFlow"; -import { - PersonalizationKey, - PersonalizationKeyWithOptions, -} from "./fields/personalizationKeys"; +import { TargetMethod } from "./fields/targetMethod"; +import { Theme } from "./fields/theme"; +import { Type } from "./fields/type"; +import { WidgetDescription } from "./fields/widgetDescription"; +import { WidgetSlug } from "./fields/widgetSlug"; +import { WidgetStatus } from "./fields/widgetStatus"; +import { WidgetTitle } from "./fields/widgetTitle"; export interface Field { id: string; diff --git a/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts b/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts index cd70abf..848f6f3 100644 --- a/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts +++ b/packages/experience-editor/src/utility/__tests__/fieldLogic.test.ts @@ -1,6 +1,6 @@ -import { describe, it, expect } from "vitest"; -import { shouldApplyDefaultValue, findFieldById } from "../fieldLogic"; +import { describe, expect, it } from "vitest"; import { Field } from "../../data/pfa-fields"; +import { findFieldById, shouldApplyDefaultValue } from "../fieldLogic"; describe("fieldLogic", () => { describe("shouldApplyDefaultValue", () => { diff --git a/packages/experience-editor/src/utility/__tests__/objects.test.ts b/packages/experience-editor/src/utility/__tests__/objects.test.ts index be5f558..fe72cea 100644 --- a/packages/experience-editor/src/utility/__tests__/objects.test.ts +++ b/packages/experience-editor/src/utility/__tests__/objects.test.ts @@ -1,5 +1,5 @@ -import { describe, it, expect } from "vitest"; -import { removeEmptyObjects, getValueByDotNotation } from "../objects"; +import { describe, expect, it } from "vitest"; +import { getValueByDotNotation, removeEmptyObjects } from "../objects"; describe("objects utility", () => { describe("removeEmptyObjects", () => { diff --git a/packages/experience-editor/src/utility/emptyState.tsx b/packages/experience-editor/src/utility/emptyState.tsx index 60c1996..7733395 100644 --- a/packages/experience-editor/src/utility/emptyState.tsx +++ b/packages/experience-editor/src/utility/emptyState.tsx @@ -1,5 +1,5 @@ -import React from "react"; import { Stack, Typography } from "@mui/material"; +import React from "react"; export interface EmptyStateProps { message: string; diff --git a/packages/experience-editor/src/utility/objects.ts b/packages/experience-editor/src/utility/objects.ts index e6674d8..8c130ae 100644 --- a/packages/experience-editor/src/utility/objects.ts +++ b/packages/experience-editor/src/utility/objects.ts @@ -1,6 +1,6 @@ export const removeEmptyObjects = (object: any) => { for (const key in object) { - if (object.hasOwnProperty(key)) { + if (Object.hasOwn(object, key)) { const value = object[key]; if (value && typeof value === "object") { removeEmptyObjects(value); @@ -22,5 +22,5 @@ export const removeEmptyObjects = (object: any) => { }; export const getValueByDotNotation = (obj, path) => { - return path.split(".").reduce((acc, part) => acc && acc[part], obj); + return path.split(".").reduce((acc, part) => acc?.[part], obj); }; diff --git a/packages/experience-editor/src/utility/pathforaInterface.ts b/packages/experience-editor/src/utility/pathforaInterface.ts index 09217cb..eb509dc 100644 --- a/packages/experience-editor/src/utility/pathforaInterface.ts +++ b/packages/experience-editor/src/utility/pathforaInterface.ts @@ -41,7 +41,7 @@ export class PathforaHandler { } loadJSTAGLibrary(accountid: string): Promise { - return new Promise((resolve, reject) => { + return new Promise((resolve, _reject) => { const jstagShim = { config: { cid: [accountid], @@ -50,7 +50,7 @@ export class PathforaHandler { getid: (callback: (id: string) => void) => { callback("test-lytics-uid"); }, - send: (stream: string, payload: any, callback: () => void) => { + send: (stream: string, _payload: any, _callback: () => void) => { console.log("(MOCK) Lytics JStag send request made.", stream); }, getEntity: (callback: (entity: any) => void) => { @@ -86,7 +86,7 @@ export class PathforaHandler { }, }; - var expires = new Date(new Date().valueOf() + 1000 * 60 * 60 * 1); + var expires = new Date(Date.now() + 1000 * 60 * 60 * 1); document.cookie = "test-seerid=test-lytics-uid; expires=" + expires.toUTCString() + @@ -100,19 +100,19 @@ export class PathforaHandler { serializeWidget(widget: any): any { // confirmAction.callback - if (widget.config.confirmAction && widget.config.confirmAction.callback) { + if (widget.config.confirmAction?.callback) { widget.config.confirmAction.callback = widget.config.confirmAction.callback.toString(); } // cancelAction.callback - if (widget.config.cancelAction && widget.config.cancelAction.callback) { + if (widget.config.cancelAction?.callback) { widget.config.cancelAction.callback = widget.config.cancelAction.callback.toString(); } // closeAction.callback - if (widget.config.closeAction && widget.config.closeAction.callback) { + if (widget.config.closeAction?.callback) { widget.config.closeAction.callback = widget.config.closeAction.callback.toString(); } @@ -203,8 +203,8 @@ export class PathforaHandler { } testWidget(widget): void { - let config = widget.config; - let details = widget.details; + const config = widget.config; + const _details = widget.details; config.id = "test-widget"; @@ -232,7 +232,7 @@ export class PathforaHandler { config.displayConditions.scrollPercentageToDisplay = 0; } - let module; + let module: any; switch (widget.details.type) { case "message": diff --git a/packages/experience-editor/tsconfig.json b/packages/experience-editor/tsconfig.json index 7f32712..cb305ed 100644 --- a/packages/experience-editor/tsconfig.json +++ b/packages/experience-editor/tsconfig.json @@ -1,13 +1,15 @@ { "compilerOptions": { "target": "es5", + "lib": ["es2022", "dom"], "module": "ESNext", "strict": false, "esModuleInterop": true, "allowJs": true, "outDir": "./dist", - "moduleResolution": "node", - "jsx": "react-jsx" + "moduleResolution": "bundler", + "jsx": "react-jsx", + "skipLibCheck": true }, "include": ["src/**/*"] } diff --git a/packages/experience-editor/vite.config.js b/packages/experience-editor/vite.config.js index 1e64c3e..dcec308 100644 --- a/packages/experience-editor/vite.config.js +++ b/packages/experience-editor/vite.config.js @@ -1,7 +1,6 @@ -import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +import { defineConfig, loadEnv } from "vite"; import { createHtmlPlugin } from "vite-plugin-html"; -import { loadEnv } from "vite"; export default defineConfig(({ mode }) => { const env = loadEnv(mode, process.cwd()); diff --git a/packages/experience-editor/vitest.config.ts b/packages/experience-editor/vitest.config.ts index 8508196..c80aef4 100644 --- a/packages/experience-editor/vitest.config.ts +++ b/packages/experience-editor/vitest.config.ts @@ -1,5 +1,5 @@ -import { defineConfig } from "vitest/config"; import react from "@vitejs/plugin-react"; +import { defineConfig } from "vitest/config"; export default defineConfig({ plugins: [react()], diff --git a/packages/recommendation-block/src/api-recommendation.ts b/packages/recommendation-block/src/api-recommendation.ts index 65788fe..b4640b5 100644 --- a/packages/recommendation-block/src/api-recommendation.ts +++ b/packages/recommendation-block/src/api-recommendation.ts @@ -23,12 +23,12 @@ export async function getRecommendation( uid: string, options: RecommendationOptions, ): Promise { - let baseURL = `https://api.lytics.io/api/content/recommend/${accountId}/user/_uid/${uid}`; + const baseURL = `https://api.lytics.io/api/content/recommend/${accountId}/user/_uid/${uid}`; // if (options.segment !== "") { // baseURL = `https://api.lytics.io/api/content/recommend/${accountId}/segment/${options.segment}`; // } - let parts = []; + const parts = []; // add account id if (!accountId) { console.error("Account ID is required to generate recommendations."); diff --git a/packages/recommendation-block/vite.config.js b/packages/recommendation-block/vite.config.js index dd07580..66e5312 100644 --- a/packages/recommendation-block/vite.config.js +++ b/packages/recommendation-block/vite.config.js @@ -1,7 +1,7 @@ // vite.config.ts -import { defineConfig } from "vite"; import path from "path"; +import { defineConfig } from "vite"; export default defineConfig({ build: { @@ -9,7 +9,7 @@ export default defineConfig({ entry: path.resolve(__dirname, "src/index.ts"), formats: ["es"], name: "LyticsRecommendationBlock", - fileName: (format) => `lytics-recommendation-block.js`, + fileName: (_format) => `lytics-recommendation-block.js`, }, outDir: "dist", }, diff --git a/yarn.lock b/yarn.lock index 1aca2dc..782b08c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1062,6 +1062,60 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@biomejs/biome@^2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.2.6.tgz#76d8afbdd609a5dbace84bc982ae974a24b70b62" + integrity sha512-yKTCNGhek0rL5OEW1jbLeZX8LHaM8yk7+3JRGv08my+gkpmtb5dDE+54r2ZjZx0ediFEn1pYBOJSmOdDP9xtFw== + optionalDependencies: + "@biomejs/cli-darwin-arm64" "2.2.6" + "@biomejs/cli-darwin-x64" "2.2.6" + "@biomejs/cli-linux-arm64" "2.2.6" + "@biomejs/cli-linux-arm64-musl" "2.2.6" + "@biomejs/cli-linux-x64" "2.2.6" + "@biomejs/cli-linux-x64-musl" "2.2.6" + "@biomejs/cli-win32-arm64" "2.2.6" + "@biomejs/cli-win32-x64" "2.2.6" + +"@biomejs/cli-darwin-arm64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.6.tgz#b232a7d92c0b28884c1cf99d4348e1a52f95931f" + integrity sha512-UZPmn3M45CjTYulgcrFJFZv7YmK3pTxTJDrFYlNElT2FNnkkX4fsxjExTSMeWKQYoZjvekpH5cvrYZZlWu3yfA== + +"@biomejs/cli-darwin-x64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.6.tgz#3a2d1582037735f8ed5243aa6d3cc4f4082c5f42" + integrity sha512-HOUIquhHVgh/jvxyClpwlpl/oeMqntlteL89YqjuFDiZ091P0vhHccwz+8muu3nTyHWM5FQslt+4Jdcd67+xWQ== + +"@biomejs/cli-linux-arm64-musl@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.6.tgz#2bfe0859c55c840c0648f2b307efccca2527d655" + integrity sha512-TjCenQq3N6g1C+5UT3jE1bIiJb5MWQvulpUngTIpFsL4StVAUXucWD0SL9MCW89Tm6awWfeXBbZBAhJwjyFbRQ== + +"@biomejs/cli-linux-arm64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.6.tgz#aa1817296d84bda6ea972a54b139d1664580c190" + integrity sha512-BpGtuMJGN+o8pQjvYsUKZ+4JEErxdSmcRD/JG3mXoWc6zrcA7OkuyGFN1mDggO0Q1n7qXxo/PcupHk8gzijt5g== + +"@biomejs/cli-linux-x64-musl@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.6.tgz#b65f9191420e3384e287b21a8b1769795ee2c4c1" + integrity sha512-1ZcBux8zVM3JhWN2ZCPaYf0+ogxXG316uaoXJdgoPZcdK/rmRcRY7PqHdAos2ExzvjIdvhQp72UcveI98hgOog== + +"@biomejs/cli-linux-x64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.6.tgz#5c5f07264bed31a436db60577c77ea9f64a62d2b" + integrity sha512-1HaM/dpI/1Z68zp8ZdT6EiBq+/O/z97a2AiHMl+VAdv5/ELckFt9EvRb8hDHpk8hUMoz03gXkC7VPXOVtU7faA== + +"@biomejs/cli-win32-arm64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.6.tgz#a47ef2d6bec694df088ba70ffd6e89839c9c2304" + integrity sha512-h3A88G8PGM1ryTeZyLlSdfC/gz3e95EJw9BZmA6Po412DRqwqPBa2Y9U+4ZSGUAXCsnSQE00jLV8Pyrh0d+jQw== + +"@biomejs/cli-win32-x64@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.6.tgz#cec00e860d9f20d820a48db4a6c7ab3b35c83ac6" + integrity sha512-yx0CqeOhPjYQ5ZXgPfu8QYkgBhVJyvWe36as7jRuPrKPO5ylVDfwVtPQ+K/mooNTADW0IhxOZm3aPu16dP8yNQ== + "@codemirror/autocomplete@^6.0.0": version "6.18.0" resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.0.tgz#5f39b05daca04c95e990b70024144df47b2aa635" @@ -3479,16 +3533,11 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== -"@types/react-dom@^18.0.0": +"@types/react-dom@^18.0.0", "@types/react-dom@^18.2.0": version "18.3.7" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f" integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== -"@types/react-dom@^19.2.0": - version "19.2.0" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.0.tgz#97ebfc8400702db00d1177b06ade6720dda641c1" - integrity sha512-brtBs0MnE9SMx7px208g39lRmC5uHZs96caOJfTjFcYSLHNamvaSMfJNagChVNkup2SdtOxKX1FDBkRSJe1ZAg== - "@types/react-transition-group@^4.4.10": version "4.4.11" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.11.tgz#d963253a611d757de01ebb241143b1017d5d63d5" @@ -3501,21 +3550,14 @@ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== -"@types/react@*", "@types/react@>=16": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.3.tgz#9679020895318b0915d7a3ab004d92d33375c45f" - integrity sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw== +"@types/react@*", "@types/react@>=16", "@types/react@^18.2.0": + version "18.3.26" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.26.tgz#4c5970878d30db3d2a0bca1e4eb5f258e391bbeb" + integrity sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA== dependencies: "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@^19.2.0": - version "19.2.0" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.0.tgz#8412946e7e1efb0de9bb59b3aa87676d96add385" - integrity sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA== - dependencies: - csstype "^3.0.2" - "@types/resolve@^1.20.2": version "1.20.6" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.6.tgz#e6e60dad29c2c8c206c026e6dd8d6d1bdda850b8"