diff --git a/apps/docs/app/docs/ReactAPI/constants.ts b/apps/docs/app/docs/ReactAPI/constants.ts index bb2528557..39669aabe 100644 --- a/apps/docs/app/docs/ReactAPI/constants.ts +++ b/apps/docs/app/docs/ReactAPI/constants.ts @@ -104,6 +104,11 @@ interface DiffOptions { // Hide the file header with filename and stats disableFileHeader: false, + // Rethrow rendering errors instead of catching and displaying them + // in the DOM. Useful for testing or custom error handling. + // (default: false) + disableErrorHandling: false, + // Skip syntax highlighting for lines exceeding this length tokenizeMaxLineLength: 1000, @@ -476,6 +481,11 @@ interface FileOptions { // Hide the file header with filename disableFileHeader: false, + // Rethrow rendering errors instead of catching and displaying them + // in the DOM. Useful for testing or custom error handling. + // (default: false) + disableErrorHandling: false, + // Skip syntax highlighting for lines exceeding this length tokenizeMaxLineLength: 1000, diff --git a/apps/docs/app/docs/VanillaAPI/constants.ts b/apps/docs/app/docs/VanillaAPI/constants.ts index 1a810350d..baf5b4129 100644 --- a/apps/docs/app/docs/VanillaAPI/constants.ts +++ b/apps/docs/app/docs/VanillaAPI/constants.ts @@ -176,6 +176,11 @@ const instance = new FileDiff({ // Hide the file header with filename and stats disableFileHeader: false, + // Rethrow rendering errors instead of catching and displaying them + // in the DOM. Useful for testing or custom error handling. + // (default: false) + disableErrorHandling: false, + // Skip syntax highlighting for lines exceeding this length tokenizeMaxLineLength: 1000, @@ -331,6 +336,11 @@ const instance = new File({ // Hide the file header with filename disableFileHeader: false, + // Rethrow rendering errors instead of catching and displaying them + // in the DOM. Useful for testing or custom error handling. + // (default: false) + disableErrorHandling: false, + // Skip syntax highlighting for lines exceeding this length tokenizeMaxLineLength: 1000, diff --git a/bun.lock b/bun.lock index 7d6df1fbb..1e893f7b9 100644 --- a/bun.lock +++ b/bun.lock @@ -281,7 +281,7 @@ "clsx": "2.1.1", "cmdk": "1.1.1", "concurrently": "9.2.1", - "diff": "8.0.2", + "diff": "8.0.3", "eslint": "9.36.0", "eslint-plugin-react-hooks": "7.0.0", "fast-deep-equal": "3.1.3", @@ -1327,7 +1327,7 @@ "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], - "diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], + "diff": ["diff@8.0.3", "", {}, "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ=="], "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], @@ -2637,6 +2637,8 @@ "@tanstack/directive-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], + "@tanstack/router-utils/diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], + "@tanstack/router-utils/pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "@tanstack/server-functions-plugin/@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], @@ -2803,6 +2805,8 @@ "shadcn/cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], + "shadcn/diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], + "shadcn/fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], "shadcn/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], @@ -2835,6 +2839,8 @@ "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], + "tsdown/diff": ["diff@8.0.2", "", {}, "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg=="], + "tsdown/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="], "unenv/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], diff --git a/package.json b/package.json index 2906bd965..3d3612548 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "clsx": "2.1.1", "cmdk": "1.1.1", "concurrently": "9.2.1", - "diff": "8.0.2", + "diff": "8.0.3", "eslint": "9.36.0", "eslint-plugin-react-hooks": "7.0.0", "fast-deep-equal": "3.1.3", diff --git a/packages/diffs/package.json b/packages/diffs/package.json index e602fe64d..997517319 100644 --- a/packages/diffs/package.json +++ b/packages/diffs/package.json @@ -1,6 +1,6 @@ { "name": "@pierre/diffs", - "version": "1.0.7", + "version": "1.0.10", "type": "module", "license": "apache-2.0", "scripts": { diff --git a/packages/diffs/src/components/File.ts b/packages/diffs/src/components/File.ts index 9f4da018f..7286f6110 100644 --- a/packages/diffs/src/components/File.ts +++ b/packages/diffs/src/components/File.ts @@ -61,6 +61,12 @@ export interface FileOptions LineSelectionOptions { disableFileHeader?: boolean; renderCustomMetadata?: RenderFileMetadata; + /** + * When true, errors during rendering are rethrown instead of being caught + * and displayed in the DOM. Useful for testing or when you want to handle + * errors yourself. + */ + disableErrorHandling?: boolean; renderAnnotation?( annotation: LineAnnotation ): HTMLElement | undefined; @@ -280,7 +286,8 @@ export class File { } this.fileRenderer.setLineAnnotations(this.lineAnnotations); - const { disableFileHeader = false } = this.options; + const { disableFileHeader = false, disableErrorHandling = false } = + this.options; if (disableFileHeader) { // Remove existing header from DOM if (this.headerElement != null) { @@ -310,6 +317,10 @@ export class File { this.renderAnnotations(); this.renderHoverUtility(); } catch (error: unknown) { + if (disableErrorHandling) { + throw error; + } + console.error(error); if (error instanceof Error) { this.applyErrorToDOM(error, fileContainer); } diff --git a/packages/diffs/src/components/FileDiff.ts b/packages/diffs/src/components/FileDiff.ts index 9fc38edd0..470cd0c1c 100644 --- a/packages/diffs/src/components/FileDiff.ts +++ b/packages/diffs/src/components/FileDiff.ts @@ -78,6 +78,12 @@ export interface FileDiffOptions ) => HTMLElement | DocumentFragment); disableFileHeader?: boolean; renderHeaderMetadata?: RenderHeaderMetadataCallback; + /** + * When true, errors during rendering are rethrown instead of being caught + * and displayed in the DOM. Useful for testing or when you want to handle + * errors yourself. + */ + disableErrorHandling?: boolean; renderAnnotation?( annotation: DiffLineAnnotation ): HTMLElement | undefined; @@ -404,7 +410,8 @@ export class FileDiff { this.hunksRenderer.setLineAnnotations(this.lineAnnotations); - const { disableFileHeader = false } = this.options; + const { disableFileHeader = false, disableErrorHandling = false } = + this.options; if (disableFileHeader) { // Remove existing header from DOM @@ -436,6 +443,10 @@ export class FileDiff { this.renderAnnotations(); this.renderHoverUtility(); } catch (error: unknown) { + if (disableErrorHandling) { + throw error; + } + console.error(error); if (error instanceof Error) { this.applyErrorToDOM(error, fileContainer); } diff --git a/packages/diffs/src/style.css b/packages/diffs/src/style.css index c753d5a60..aba234b4a 100644 --- a/packages/diffs/src/style.css +++ b/packages/diffs/src/style.css @@ -579,7 +579,7 @@ } } - [data-expand-up] [data-icon] { + [data-expand-down] [data-icon] { transform: scaleY(-1); }