From 6960bb0caf512a8b12207445fdcd1865256f3b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Utku=20Aky=C3=BCz?= Date: Mon, 25 Aug 2025 15:26:08 +0300 Subject: [PATCH 1/8] chore: package json code format --- package.json | 55 +++++++++++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index a70a756..a90d21b 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,13 @@ { "name": "virtual-react-json-diff", + "type": "module", "version": "1.0.3", "description": "Fast, virtualized React component for visually comparing large JSON objects. Includes search, theming, and minimap.", - "main": "dist/cjs/index.js", - "types": "dist/index.d.ts", - "files": [ - "dist" - ], - "scripts": { - "build": "bun run rollup", - "prepublishOnly": "bun run build", - "rollup": "rollup -c --bundleConfigAsCjs", - "storybook": "storybook dev -p 6006", - "build-storybook": "storybook build" + "author": { + "name": "Utku AkyΓΌz" }, + "license": "MIT", + "homepage": "https://virtual-react-json-diff.netlify.app", "repository": { "type": "git", "url": "https://github.com/utkuakyuz/virtual-react-json-diff" @@ -21,12 +15,6 @@ "bugs": { "url": "https://github.com/utkuakyuz/virtual-react-json-diff/issues" }, - "homepage": "https://virtual-react-json-diff.netlify.app", - "author": { - "name": "Utku AkyΓΌz" - }, - "license": "MIT", - "type": "module", "keywords": [ "react", "json", @@ -42,7 +30,30 @@ "compare json", "react diff viewer" ], + "main": "dist/cjs/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist" + ], + "scripts": { + "build": "bun run rollup", + "prepublishOnly": "bun run build", + "rollup": "rollup -c --bundleConfigAsCjs", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build", + "lint": "eslint", + "lint:fix": "eslint --fix" + }, + "peerDependencies": { + "react": "^18.0.0" + }, + "dependencies": { + "json-diff-kit": "^1.0.32", + "react-window": "^1.8.11" + }, "devDependencies": { + "@antfu/eslint-config": "^5.2.1", + "@eslint-react/eslint-plugin": "^1.52.6", "@fontsource/inter": "^5.1.1", "@rollup/plugin-commonjs": "^25.0.3", "@rollup/plugin-image": "^3.0.3", @@ -59,6 +70,9 @@ "@types/node": "^22.14.1", "@types/react": "^18.2.15", "@types/react-window": "^1.8.8", + "eslint": "^9.33.0", + "eslint-plugin-react-hooks": "^5.2.0", + "eslint-plugin-react-refresh": "^0.4.20", "postcss": "^8.5.1", "prettier": "^2.5.1", "react": "^18.2.0", @@ -69,12 +83,5 @@ "storybook": "8.6.0-alpha.0", "tslib": "^2.6.0", "typescript": "^5.1.6" - }, - "peerDependencies": { - "react": "^18.0.0" - }, - "dependencies": { - "json-diff-kit": "^1.0.32", - "react-window": "^1.8.11" } } From 1aa9a95b69bfa23e6c1f3ce3f52904b5821f140a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Utku=20Aky=C3=BCz?= Date: Mon, 25 Aug 2025 15:54:48 +0300 Subject: [PATCH 2/8] feat!: antfu eslint configuration created and lint stage enabled --- .gitignore | 4 +--- .vscode/settings.json | 52 +++++++++++++++++++++++++++++++++++++++++++ eslint.config.js | 26 ++++++++++++++++++++++ package.json | 9 ++++++++ 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 eslint.config.js diff --git a/.gitignore b/.gitignore index 8f7d792..00c36cd 100644 --- a/.gitignore +++ b/.gitignore @@ -12,11 +12,9 @@ dist dist-ssr *.local *-lock.json +pnpm-lock.yaml # Editor directories and files -.vscode -.vscode/* -!.vscode/extensions.json .idea .DS_Store *.suo diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a9d8561 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,52 @@ +{ + "cSpell.words": ["Iconify", "persistor"], + // Disable the default formatter, use eslint instead + "prettier.enable": false, + "editor.formatOnSave": false, + + // Auto fix + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + + // Silent the stylistic rules in you IDE, but still auto fix them + "eslint.rules.customizations": [ + { "rule": "style/*", "severity": "off", "fixable": true }, + { "rule": "format/*", "severity": "off", "fixable": true }, + { "rule": "*-indent", "severity": "off", "fixable": true }, + { "rule": "*-spacing", "severity": "off", "fixable": true }, + { "rule": "*-spaces", "severity": "off", "fixable": true }, + { "rule": "*-order", "severity": "off", "fixable": true }, + { "rule": "*-dangle", "severity": "off", "fixable": true }, + { "rule": "*-newline", "severity": "off", "fixable": true }, + { "rule": "*quotes", "severity": "off", "fixable": true }, + { "rule": "*semi", "severity": "off", "fixable": true } + ], + + // Enable eslint for all supported languages + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact", + "vue", + "html", + "markdown", + "json", + "json5", + "jsonc", + "yaml", + "toml", + "xml", + "gql", + "graphql", + "astro", + "svelte", + "css", + "less", + "scss", + "pcss", + "postcss" + ] +} diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..eb5827a --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,26 @@ +import antfu from "@antfu/eslint-config"; + +export default antfu({ + type: "app", + typescript: true, + formatters: true, + stylistic: { + indent: 2, + semi: true, + quotes: "double", + }, +}, { + rules: { + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }], + "no-unused-vars": "warn", + "ts/no-redeclare": "off", + "ts/consistent-type-definitions": ["error", "type"], + "no-console": ["warn"], + "antfu/no-top-level-await": ["off"], + "node/prefer-global/process": ["off"], + "node/no-process-env": ["error"], + "perfectionist/sort-imports": ["error", { + tsconfigRootDir: ".", + }], + }, +}); diff --git a/package.json b/package.json index a90d21b..1d885a1 100644 --- a/package.json +++ b/package.json @@ -71,8 +71,10 @@ "@types/react": "^18.2.15", "@types/react-window": "^1.8.8", "eslint": "^9.33.0", + "eslint-plugin-format": "^1.0.1", "eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-refresh": "^0.4.20", + "lint-staged": "^16.1.5", "postcss": "^8.5.1", "prettier": "^2.5.1", "react": "^18.2.0", @@ -80,8 +82,15 @@ "rollup-plugin-dts": "^5.3.0", "rollup-plugin-peer-deps-external": "^2.2.4", "rollup-plugin-postcss": "^4.0.2", + "simple-git-hooks": "^2.13.1", "storybook": "8.6.0-alpha.0", "tslib": "^2.6.0", "typescript": "^5.1.6" + }, + "simple-git-hooks": { + "pre-commit": "pnpm lint-staged" + }, + "lint-staged": { + "*": "eslint --fix" } } From 350ff31cc847f8a78d84fc584f2ecc3fb37bb3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Utku=20Aky=C3=BCz?= Date: Mon, 25 Aug 2025 15:55:07 +0300 Subject: [PATCH 3/8] refactor: lint auto fix and other corrections with code format --- .storybook/document.tsx | 21 - .storybook/main.ts | 26 +- .storybook/manager.ts | 3 +- .storybook/preview.css | 2 +- .storybook/preview.tsx | 171 ++--- .storybook/theme.ts | 62 +- README.md | 11 +- rollup.config.js | 44 +- src/components/DiffViewer/Diff.stories.tsx | 445 ++++++------- .../DiffViewer/components/DiffMinimap.tsx | 457 ++++++------- .../components/VirtualizedDiffViewer.tsx | 604 +++++++++--------- .../DiffViewer/styles/JsonDiffCustomTheme.css | 42 +- src/components/DiffViewer/types/index.ts | 102 +-- .../DiffViewer/utils/diffSearchUtils.ts | 62 +- .../DiffViewer/utils/preprocessDiff.ts | 301 ++++----- src/components/SearchIcon.tsx | 20 +- src/image.d.ts | 8 +- tailwind.config.js | 10 +- tsconfig.json | 18 +- 19 files changed, 1211 insertions(+), 1198 deletions(-) delete mode 100644 .storybook/document.tsx diff --git a/.storybook/document.tsx b/.storybook/document.tsx deleted file mode 100644 index 1cab29a..0000000 --- a/.storybook/document.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from "react"; -import { DocsPage, DocsContainer } from "@storybook/addon-docs"; -import { Source } from "@storybook/blocks"; - -const CustomDocsPage = (props) => { - const { context } = props; - - const importStatement = ` - // Import statement - import <> from '@react-noxui'; - `; - - return ( - - - - - ); -}; - -export default CustomDocsPage; diff --git a/.storybook/main.ts b/.storybook/main.ts index d730b22..84f5700 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,19 +1,19 @@ import type { StorybookConfig } from "@storybook/react-vite"; const config: StorybookConfig = { - stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], - addons: [ - "@storybook/addon-onboarding", - "@storybook/addon-essentials", - "@storybook/addon-interactions", - "@storybook/addon-styling-webpack", - ], - framework: { - name: "@storybook/react-vite", - options: {}, - }, - staticDirs: ["../public"], - previewHead: (head) => ` + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"], + addons: [ + "@storybook/addon-onboarding", + "@storybook/addon-essentials", + "@storybook/addon-interactions", + "@storybook/addon-styling-webpack", + ], + framework: { + name: "@storybook/react-vite", + options: {}, + }, + staticDirs: ["../public"], + previewHead: head => ` ${head} ${` { - const { args } = context; - const { oldValue, newValue } = args; +function withJsonEditor(Story, context) { + const { args } = context; + const { oldValue, newValue } = args; - const [oldJson, setOldJson] = useState(JSON.stringify(oldValue, null, 2)); - const [newJson, setNewJson] = useState(JSON.stringify(newValue, null, 2)); - const [oldJsonError, setOldJsonError] = useState(""); - const [newJsonError, setNewJsonError] = useState(""); - const [parsedOldValue, setParsedOldValue] = useState(oldValue); - const [parsedNewValue, setParsedNewValue] = useState(newValue); + const [oldJson, setOldJson] = useState(JSON.stringify(oldValue, null, 2)); + const [newJson, setNewJson] = useState(JSON.stringify(newValue, null, 2)); + const [oldJsonError, setOldJsonError] = useState(""); + const [newJsonError, setNewJsonError] = useState(""); + const [parsedOldValue, setParsedOldValue] = useState(oldValue); + const [parsedNewValue, setParsedNewValue] = useState(newValue); - const validateJson = (jsonString: string) => { - try { - return { error: "", parsed: JSON.parse(jsonString) }; - } catch (error) { - return { error: "Invalid JSON format", parsed: null }; - } - }; + const validateJson = (jsonString: string) => { + try { + return { error: "", parsed: JSON.parse(jsonString) }; + } + catch { + return { error: "Invalid JSON format", parsed: null }; + } + }; - useEffect(() => { - const { error, parsed } = validateJson(oldJson); - setOldJsonError(error); - if (!error) { - setParsedOldValue(parsed); - } - }, [oldJson]); + useEffect(() => { + const { error, parsed } = validateJson(oldJson); + setOldJsonError(error); + if (!error) { + setParsedOldValue(parsed); + } + }, [oldJson]); - useEffect(() => { - const { error, parsed } = validateJson(newJson); - setNewJsonError(error); - if (!error) { - setParsedNewValue(parsed); - } - }, [newJson]); + useEffect(() => { + const { error, parsed } = validateJson(newJson); + setNewJsonError(error); + if (!error) { + setParsedNewValue(parsed); + } + }, [newJson]); - return ( -
-
-
-

Old Value

-