diff --git a/znai-reactjs/eslint.config.mjs b/znai-reactjs/eslint.config.mjs index 105be7cc1..81efcfd1a 100644 --- a/znai-reactjs/eslint.config.mjs +++ b/znai-reactjs/eslint.config.mjs @@ -9,18 +9,23 @@ import parser from '@typescript-eslint/parser'; export default [ // Ignore patterns { - ignores: ['dist', 'build', 'node_modules', '*.config.js'], + ignores: ['target', 'dist', 'build', 'node_modules', 'public/**/*.js', '*.config.js'], }, // Base JavaScript configuration { - files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'], + files: ['**/*.{js,jsx,mjs,cjs}'], languageOptions: { parser: parser, ecmaVersion: 2020, globals: { ...globals.browser, ...globals.es2020, + populateLocalSearchIndexWithData: 'readonly', + documentationNavigation: 'readonly', + // Add other globals from znai's generated HTML + toc: 'readonly', + znaiSearchData: 'readonly' }, parserOptions: { ecmaVersion: 'latest', @@ -61,13 +66,99 @@ export default [ // React Refresh 'react-refresh/only-export-components': [ - 'warn', + 'off', { allowConstantExport: true }, ], // Custom rules - 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + 'no-unused-vars': ['warn', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_' + }], 'no-console': ['warn', { allow: ['warn', 'error'] }], }, }, + // TypeScript files + { + files: ['**/*.{ts,tsx}'], + languageOptions: { + parser: parser, + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module', + ecmaFeatures: {jsx: true}, + project: './tsconfig.json', // Important for type-aware rules + }, + globals: { + ...globals.browser, + ...globals.es2020, + }, + }, + plugins: { + '@typescript-eslint': typescriptEslint, + react, + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + // ... your existing rules + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'no-type-imports', + disallowTypeAnnotations: false + } + ] + } + }, + // Special config for vitest.config.ts (and other config files) + { + files: ['vitest.config.ts', '*.config.ts'], + languageOptions: { + parser: parser, + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module', + project: './tsconfig.json', // Use node tsconfig + }, + globals: { + ...globals.node, // Node globals instead of browser + }, + }, + plugins: { + '@typescript-eslint': typescriptEslint, + }, + rules: { + ...typescriptEslint.configs.recommended.rules, + 'no-undef': 'off', + '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + } + }, + { + files: ['**/*.test.{js,jsx,ts,tsx}', '**/*.spec.{js,jsx,ts,tsx}'], + languageOptions: { + globals: { + ...globals.node, // Vitest runs in Node + describe: 'readonly', + it: 'readonly', + test: 'readonly', + expect: 'readonly', + beforeEach: 'readonly', + afterEach: 'readonly', + beforeAll: 'readonly', + afterAll: 'readonly', + vi: 'readonly', // Vitest's mock utility + }, + }, rules: { + 'no-console': 'off', + } + }, + { + files: ['src/App.jsx', '**/*.demo.{js,jsx,ts,tsx}', '**/*.stories.{js,jsx,ts,tsx}'], + rules: { + 'no-console': 'off', + 'react-refresh/only-export-components': 'off', + 'react/display-name': 'off', // Often useful for demos too + }, + }, ]; \ No newline at end of file diff --git a/znai-reactjs/package.json b/znai-reactjs/package.json index d5c5b9274..64c1c32da 100644 --- a/znai-reactjs/package.json +++ b/znai-reactjs/package.json @@ -58,6 +58,7 @@ "vite": "npm:rolldown-vite@7.1.14" }, "scripts": { + "prebuild": "npm run lint", "dev": "vite", "build": "vite build", "test": "vitest --config ./vitest.config.ts", diff --git a/znai-reactjs/src/App.jsx b/znai-reactjs/src/App.jsx index 11abcd563..2cf310b71 100644 --- a/znai-reactjs/src/App.jsx +++ b/znai-reactjs/src/App.jsx @@ -19,7 +19,7 @@ import "./App.css"; import "./layout/DocumentationLayout.css"; import "./doc-elements/search/Search.css"; -import React, { Component, useEffect } from "react"; +import React, { useEffect } from "react"; import { ComponentViewer, DropDowns, Registries } from "react-component-viewer"; import { tabsDemo } from "./doc-elements/tabs/Tabs.demo"; diff --git a/znai-reactjs/src/components/Tooltip.tsx b/znai-reactjs/src/components/Tooltip.tsx index 564b37b24..666642990 100644 --- a/znai-reactjs/src/components/Tooltip.tsx +++ b/znai-reactjs/src/components/Tooltip.tsx @@ -169,7 +169,7 @@ export function TooltipRenderer() { left: (clientRect.left + clientRect.right) / 2.0, }; - case "parent-content-block": + case "parent-content-block": { const parentContentBlock = findParentContentBlock(); if (parentContentBlock) { const contentBlockRect = parentContentBlock.getBoundingClientRect(); @@ -183,6 +183,7 @@ export function TooltipRenderer() { console.error("can't find parent-content-block", parentContentBlock); return bottomLeft(); } + } } function bottomLeft() { diff --git a/znai-reactjs/src/diff/PageDiff.test.js b/znai-reactjs/src/diff/PageDiff.test.js index d737c70e5..0f5e5fdcd 100644 --- a/znai-reactjs/src/diff/PageDiff.test.js +++ b/znai-reactjs/src/diff/PageDiff.test.js @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,6 +50,6 @@ describe('Page Diff', () => { right.add('node6', 'of lines') const result = Diff.diffArrays(left.list, right.list, {comparator: compareListEntry}) - console.log(JSON.stringify(result, null, 2)) + console.warn(JSON.stringify(result, null, 2)) }) }) \ No newline at end of file diff --git a/znai-reactjs/src/doc-elements/DefaultElementsLibrary.jsx b/znai-reactjs/src/doc-elements/DefaultElementsLibrary.jsx index 052c8f4be..84b0b4516 100644 --- a/znai-reactjs/src/doc-elements/DefaultElementsLibrary.jsx +++ b/znai-reactjs/src/doc-elements/DefaultElementsLibrary.jsx @@ -91,14 +91,15 @@ import { FootnoteReference } from "./footnote/FootnoteReference"; import { EmbeddedHtml } from "./html/EmbeddedHtml"; import { Asciinema } from "./asciinema/Asciinema"; import { ReadMore } from "./read-more/ReadMore.js"; +import { withDisplayName } from "./components.ts"; const library = {} const presentationElementHandlers = {} library.DocElement = DocElement -library.Emphasis = (props) => () -library.StrongEmphasis = (props) => () -library.StrikeThrough = (props) => () +library.Emphasis = withDisplayName("Emphasis")((props) => ()) +library.StrongEmphasis = withDisplayName("StrongEmphasis")((props) => ()) +library.StrikeThrough = withDisplayName("StrikeThrough")((props) => ()) library.Link = Link library.Anchor = Anchor @@ -116,9 +117,9 @@ presentationElementHandlers.BlockQuote = presentationBlockQuoteHandler library.SimpleText = SimpleText library.InlinedCode = InlinedCode -library.SoftLineBreak = () => -library.HardLineBreak = () =>
-library.ThematicBreak = () =>
+library.SoftLineBreak = withDisplayName("SoftLineBreak")(() => ) +library.HardLineBreak = withDisplayName("HardLineBreak")(() =>
) +library.ThematicBreak = withDisplayName("ThematicBreak")(() =>
) library.ApiLinkedTextBlock = ApiLinkedTextBlock; @@ -127,7 +128,7 @@ presentationElementHandlers.Snippet = presentationSnippetHandler library.CustomReactJSComponent = CustomReactJSComponent -library.EmptyBlock = () => (
) +library.EmptyBlock = withDisplayName("EmptyBlock")(() => (
)) library.LangClass = wrappedInContentBlock(LangClass) library.LangFunction = wrappedInContentBlock(LangFunction) @@ -253,7 +254,12 @@ library.Asciinema = Asciinema * @param Component component to wrap */ function wrappedInContentBlock(Component) { - return (props) =>
+ return withDisplayName(`ContentBlock(${Component.displayName || Component.name || 'Component'})`) ( + (props) => +
+ +
+ ); } themeRegistry.registerAsBase(new Theme({ diff --git a/znai-reactjs/src/doc-elements/DiagramSlidesDemo.jsx b/znai-reactjs/src/doc-elements/DiagramSlidesDemo.jsx index 8aa1db33f..548ed09f4 100644 --- a/znai-reactjs/src/doc-elements/DiagramSlidesDemo.jsx +++ b/znai-reactjs/src/doc-elements/DiagramSlidesDemo.jsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import React, {Component} from "react" +import React from "react" import GraphVizSvg from './graphviz/GraphVizSvg' const testData = { diff --git a/znai-reactjs/src/doc-elements/asciinema/Asciinema.jsx b/znai-reactjs/src/doc-elements/asciinema/Asciinema.jsx index 7cda13e99..f5e4adf9d 100644 --- a/znai-reactjs/src/doc-elements/asciinema/Asciinema.jsx +++ b/znai-reactjs/src/doc-elements/asciinema/Asciinema.jsx @@ -32,13 +32,13 @@ export function Asciinema({src, startAt = 0, poster = undefined, cols = undefine } } - function recreatePlayer() { - destroyPlayer(); - playerRef.current = AsciinemaPlayer.create(src, containerRef.current, - {preload: true, fit: false, startAt, poster, cols, rows, idleTimeLimit, speed}); - } - useEffect(() => { + function recreatePlayer() { + destroyPlayer(); + playerRef.current = AsciinemaPlayer.create(src, containerRef.current, + {preload: true, fit: false, startAt, poster, cols, rows, idleTimeLimit, speed}); + } + if (containerRef.current) { recreatePlayer(); } @@ -49,8 +49,7 @@ export function Asciinema({src, startAt = 0, poster = undefined, cols = undefine playerRef.current = null; } }; - }, [src, startAt, poster, cols, rows, idleTimeLimit, speed, containerRef]); - + }, [src, startAt, poster, cols, rows, idleTimeLimit, speed]); return
; } \ No newline at end of file diff --git a/znai-reactjs/src/doc-elements/bullets/BulletList.jsx b/znai-reactjs/src/doc-elements/bullets/BulletList.jsx index aeb4bd195..9d9eaf4be 100644 --- a/znai-reactjs/src/doc-elements/bullets/BulletList.jsx +++ b/znai-reactjs/src/doc-elements/bullets/BulletList.jsx @@ -65,7 +65,7 @@ const presentationNumberOfSlides = (props) => { } function valueByIdWithWarning(dict, type) { - if (! dict.hasOwnProperty(type)) { + if (! Object.hasOwn(dict, type)) { console.warn("can't find bullets list type: " + type) return NoBullets } @@ -79,12 +79,12 @@ function presentationListType(props) { } function listType(props, key) { - if (! props.hasOwnProperty('meta')) { + if (! Object.hasOwn(props, 'meta')) { return null } const meta = props.meta - if (! meta.hasOwnProperty(key)) { + if (! Object.hasOwn(meta, key)) { return null } diff --git a/znai-reactjs/src/doc-elements/bullets/ListItem.jsx b/znai-reactjs/src/doc-elements/bullets/ListItem.jsx index 738a07410..e8d3ac238 100644 --- a/znai-reactjs/src/doc-elements/bullets/ListItem.jsx +++ b/znai-reactjs/src/doc-elements/bullets/ListItem.jsx @@ -18,7 +18,7 @@ import React from 'react' import { Icon } from '../icons/Icon' -import {startsWithIcon, removeIcon, extractIconProps} from './bulletUtils' +import {startsWithIcon, removeIcon, extractIconProps} from './bulletUtils.js' import './ListItem.css' diff --git a/znai-reactjs/src/doc-elements/bullets/bulletUtils.test.js b/znai-reactjs/src/doc-elements/bullets/bulletUtils.test.js index 7f3d43767..e93e13316 100644 --- a/znai-reactjs/src/doc-elements/bullets/bulletUtils.test.js +++ b/znai-reactjs/src/doc-elements/bullets/bulletUtils.test.js @@ -21,7 +21,7 @@ import { removeIcon, extractTextLinesEmphasisOnly, extractTextLinesEmphasisOrFull, extractIconIds -} from './bulletUtils' +} from './bulletUtils.js' const itemContentWithIcon = buildItemContentWithIcon() const lowerCasedItemContent = buildLowerCasedItemContent() diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/DefaultBulletList.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/DefaultBulletList.jsx index b984d989d..9b67b3d30 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/DefaultBulletList.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/DefaultBulletList.jsx @@ -16,7 +16,7 @@ */ import React from 'react' -import {startsWithIcon} from '../bulletUtils' +import {startsWithIcon} from '../bulletUtils.js' const DefaultBulletList = (props) => { const {tight, content} = props diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/Grid.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/Grid.jsx index 6a5675e1a..35506f57f 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/Grid.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/Grid.jsx @@ -17,7 +17,7 @@ import React from 'react' -import {extractTextLinesEmphasisOrFull} from '../bulletUtils' +import {extractTextLinesEmphasisOrFull} from '../bulletUtils.js' import {isAllAtOnce} from '../../meta/meta' import './Grid.css' diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/HorizontalStripes.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/HorizontalStripes.jsx index 5c08874c7..571b649ce 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/HorizontalStripes.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/HorizontalStripes.jsx @@ -17,7 +17,7 @@ import React from 'react' -import {extractIconIds, extractTextLinesEmphasisOrFull} from '../bulletUtils' +import {extractIconIds, extractTextLinesEmphasisOrFull} from '../bulletUtils.js' import {isAllAtOnce} from '../../meta/meta' import {Icon} from "../../icons/Icon"; diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/LeftRightTimeLine.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/LeftRightTimeLine.jsx index 1247e3236..1534be545 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/LeftRightTimeLine.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/LeftRightTimeLine.jsx @@ -18,7 +18,7 @@ import React from 'react' import SvgWithCalculatedSize from './SvgWithCalculatedSize' -import {extractTextLinesEmphasisOrFull, extractTextLines} from '../bulletUtils' +import {extractTextLinesEmphasisOrFull, extractTextLines} from '../bulletUtils.js' import {isAllAtOnce} from '../../meta/meta' const stepSize = 15 diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/RevealBoxes.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/RevealBoxes.jsx index d0433ca0c..afba230c0 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/RevealBoxes.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/RevealBoxes.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +17,7 @@ import React from 'react' -import {extractTextLinesEmphasisOrFull} from '../bulletUtils' +import {extractTextLinesEmphasisOrFull} from '../bulletUtils.js' import {isAllAtOnce} from '../../meta/meta' import './RevealBoxes.css' diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/Steps.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/Steps.jsx index b924717cc..51cefd06b 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/Steps.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/Steps.jsx @@ -17,7 +17,7 @@ import React from 'react' -import {extractTextLines, extractTextLinesEmphasisOrFull} from '../bulletUtils' +import {extractTextLines, extractTextLinesEmphasisOrFull} from '../bulletUtils.js' import {splitTextIntoLinesUsingThreshold} from '../../../utils/strings' import {isAllAtOnce} from '../../meta/meta' diff --git a/znai-reactjs/src/doc-elements/bullets/kinds/Venn.jsx b/znai-reactjs/src/doc-elements/bullets/kinds/Venn.jsx index 5e5303fff..7744f491a 100644 --- a/znai-reactjs/src/doc-elements/bullets/kinds/Venn.jsx +++ b/znai-reactjs/src/doc-elements/bullets/kinds/Venn.jsx @@ -16,7 +16,7 @@ */ import React from 'react' -import {extractTextLines} from '../bulletUtils' +import {extractTextLines} from '../bulletUtils.js' import SvgWithCalculatedSize from './SvgWithCalculatedSize' diff --git a/znai-reactjs/src/doc-elements/charts/EchartReactWrapper.tsx b/znai-reactjs/src/doc-elements/charts/EchartReactWrapper.tsx index c9d4d5dd8..4a3079273 100644 --- a/znai-reactjs/src/doc-elements/charts/EchartReactWrapper.tsx +++ b/znai-reactjs/src/doc-elements/charts/EchartReactWrapper.tsx @@ -14,9 +14,9 @@ * limitations under the License. */ -import React, {type MutableRefObject, type RefObject, useEffect, useRef } from "react"; +import React, { MutableRefObject, RefObject, useEffect, useRef } from "react"; import {EChartsType} from "echarts/types/dist/shared"; -import { configuredEcharts, type EchartCommonProps } from "./EchartCommon"; +import { configuredEcharts, EchartCommonProps } from "./EchartCommon"; import {PresentationProps} from "../presentation/PresentationProps"; diff --git a/znai-reactjs/src/doc-elements/code-snippets/SimpleCodeSnippet.jsx b/znai-reactjs/src/doc-elements/code-snippets/SimpleCodeSnippet.jsx index b4f47c938..c5010559e 100644 --- a/znai-reactjs/src/doc-elements/code-snippets/SimpleCodeSnippet.jsx +++ b/znai-reactjs/src/doc-elements/code-snippets/SimpleCodeSnippet.jsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import React, { Component } from "react"; +import React from "react"; import { extractTextFromTokens, splitTokensIntoLines } from "./codeUtils"; import LineOfTokens from "./LineOfTokens"; @@ -46,8 +46,17 @@ class SimpleCodeSnippet extends React.Component { } // handles changes during preview - componentWillReceiveProps(nextProps) { - this.processProps(nextProps); + componentDidUpdate(prevProps) { + // Only process props if they actually changed + if ( + prevProps.tokens !== this.props.tokens || + prevProps.linesOfCode !== this.props.linesOfCode || + prevProps.highlight !== this.props.highlight + ) { + this.processProps(this.props); + // If you need to update state based on props changes, you can do it here + // but be careful to avoid infinite loops + } } processProps({ tokens, linesOfCode, highlight }) { diff --git a/znai-reactjs/src/doc-elements/code-snippets/SnippetContainer.jsx b/znai-reactjs/src/doc-elements/code-snippets/SnippetContainer.jsx index fdba8ff20..3c57b63f6 100644 --- a/znai-reactjs/src/doc-elements/code-snippets/SnippetContainer.jsx +++ b/znai-reactjs/src/doc-elements/code-snippets/SnippetContainer.jsx @@ -143,7 +143,7 @@ class SnippetContainer extends React.Component { this.setupClipboard(); } - componentDidUpdate(prevProps, prevState, snapshot) { + componentDidUpdate(prevProps, _prevState, _snapshot) { if (prevProps.collapsed !== this.props.collapsed) { this.setState({ collapsed: this.props.collapsed }); } diff --git a/znai-reactjs/src/doc-elements/code-snippets/codeUtils.test.jsx b/znai-reactjs/src/doc-elements/code-snippets/codeUtils.test.jsx index 95011c831..077d2aeea 100644 --- a/znai-reactjs/src/doc-elements/code-snippets/codeUtils.test.jsx +++ b/znai-reactjs/src/doc-elements/code-snippets/codeUtils.test.jsx @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { describe, it, expect, vi } from 'vitest'; +import { describe, it, expect } from 'vitest'; import { collapseCommentsAboveToMakeCommentOnTheCodeLine, diff --git a/znai-reactjs/src/doc-elements/columns/Columns.tsx b/znai-reactjs/src/doc-elements/columns/Columns.tsx index 63cd700da..e0b4470af 100644 --- a/znai-reactjs/src/doc-elements/columns/Columns.tsx +++ b/znai-reactjs/src/doc-elements/columns/Columns.tsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import React, {type CSSProperties } from "react"; +import React, { CSSProperties } from "react"; import { useIsMobile } from "../../theme/ViewPortContext"; diff --git a/znai-reactjs/src/doc-elements/components.ts b/znai-reactjs/src/doc-elements/components.ts new file mode 100644 index 000000000..5119ecc4c --- /dev/null +++ b/znai-reactjs/src/doc-elements/components.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 znai maintainers + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function withDisplayName(displayName: string) { + return function(ComponentFunction: { displayName: string; }) { + ComponentFunction.displayName = displayName; + return ComponentFunction; + }; +} + +export {withDisplayName}; diff --git a/znai-reactjs/src/doc-elements/custom/CustomReactJSComponent.jsx b/znai-reactjs/src/doc-elements/custom/CustomReactJSComponent.jsx index 76ac1fed6..62c01ba3d 100644 --- a/znai-reactjs/src/doc-elements/custom/CustomReactJSComponent.jsx +++ b/znai-reactjs/src/doc-elements/custom/CustomReactJSComponent.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -21,12 +22,12 @@ import './CustomReactJSComponent.css' const CustomReactJSComponent = ({namespace, name, props}) => { const components = window[namespace] if (! components) { - return No "{namespace}" components namespace found + return No "{namespace}" components namespace found } const CustomComponent = components[name] if (! CustomComponent) { - return No "{name}" component found in "{namespace}" + return No "{name}" component found in "{namespace}" } return diff --git a/znai-reactjs/src/doc-elements/default-elements/SectionTitle.tsx b/znai-reactjs/src/doc-elements/default-elements/SectionTitle.tsx index edaaa5ad5..1c71f8835 100644 --- a/znai-reactjs/src/doc-elements/default-elements/SectionTitle.tsx +++ b/znai-reactjs/src/doc-elements/default-elements/SectionTitle.tsx @@ -57,8 +57,6 @@ export function SectionTitle({ id, title, headingContent, badge, style }: Props)
) : ( - // @ts-ignore - // eslint-disable-next-line jsx-a11y/heading-has-content

); diff --git a/znai-reactjs/src/doc-elements/demo-utils/PresentationDemo.jsx b/znai-reactjs/src/doc-elements/demo-utils/PresentationDemo.jsx index f97f0d1df..24bf56b0f 100644 --- a/znai-reactjs/src/doc-elements/demo-utils/PresentationDemo.jsx +++ b/znai-reactjs/src/doc-elements/demo-utils/PresentationDemo.jsx @@ -20,20 +20,23 @@ import React from 'react' import {elementsLibrary, presentationElementHandlers} from '../DefaultElementsLibrary' import PresentationRegistry from '../presentation/PresentationRegistry' import Presentation from '../presentation/Presentation' +import {withDisplayName} from '../components' const defaultDocMeta = {id: "znai", title: "Znai", type: "User Guide"} export function createPresentationDemo(content, cfg = {docMeta: defaultDocMeta, slideIdx: 0}) { - return () => { - const presentationRegistry = new PresentationRegistry(elementsLibrary, presentationElementHandlers, content) + const PresentationDemoComponent = () => { + const presentationRegistry = new PresentationRegistry(elementsLibrary, presentationElementHandlers, content); return ( ) - } + onPrevPage={noOp}/> + ); + }; + return withDisplayName('PresentationDemo')(PresentationDemoComponent); } function noOp() { diff --git a/znai-reactjs/src/doc-elements/doc-utils/DocUtils.jsx b/znai-reactjs/src/doc-elements/doc-utils/DocUtils.jsx index 93d8f97a4..5c84b4045 100644 --- a/znai-reactjs/src/doc-elements/doc-utils/DocUtils.jsx +++ b/znai-reactjs/src/doc-elements/doc-utils/DocUtils.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +17,7 @@ import React from 'react' +import {withDisplayName} from '../components.ts' import './DocUtils.css' const DocUtilsDesc = WrapperOnly('doc-utils-desc content-block') @@ -38,11 +40,14 @@ function DocUtilsField({elementsLibrary, content}) { } function WrapperOnly(className) { - return ({elementsLibrary, content}) =>
- -
+ return withDisplayName(`WrapperOnly(${className})`)( + ({elementsLibrary, content}) => ( +
+ +
+ ) + ) } - export function registerDocUtilsElements(elementsLibrary) { const components = { DocUtilsDesc, diff --git a/znai-reactjs/src/doc-elements/graphviz/GraphVizFlow.jsx b/znai-reactjs/src/doc-elements/graphviz/GraphVizFlow.jsx index b970fe5b7..a60806acf 100644 --- a/znai-reactjs/src/doc-elements/graphviz/GraphVizFlow.jsx +++ b/znai-reactjs/src/doc-elements/graphviz/GraphVizFlow.jsx @@ -15,10 +15,10 @@ * limitations under the License. */ -import React, { Component } from 'react' +import React from 'react' import GraphVizFlowFullScreen from './GraphVizFlowFullScreen' -import GraphVizFlowAllInfoAtOnce from './GraphVizFlowAllInfoAtOnce' +import DocumentationGraphVizFlow from './DocumentationGraphVizFlow' import './GraphvVizFlow.css' diff --git a/znai-reactjs/src/doc-elements/graphviz/GraphVizReactElementsBuilder.jsx b/znai-reactjs/src/doc-elements/graphviz/GraphVizReactElementsBuilder.jsx index ad571d7bc..2fc4c676f 100644 --- a/znai-reactjs/src/doc-elements/graphviz/GraphVizReactElementsBuilder.jsx +++ b/znai-reactjs/src/doc-elements/graphviz/GraphVizReactElementsBuilder.jsx @@ -22,6 +22,7 @@ import GvText from "./GvText" import GvPath from "./GvPath" import GvGroup from "./GvGroup" import {globalAssets} from "../global-assets/GlobalAssets" +import {withDisplayName} from "../components.ts" export default class GraphVizReactElementsBuilder { constructor({diagram, idsToDisplay, idsToHighlight, urls}) { @@ -176,7 +177,9 @@ export default class GraphVizReactElementsBuilder { case 'text': return GvText case 'path': return GvPath case 'g': return GvGroup - case 'title': return () => + case 'title': { + return withDisplayName('GraphVizTitle')( () => ) + } default: return domNode.tagName } diff --git a/znai-reactjs/src/doc-elements/graphviz/GvPolygon.jsx b/znai-reactjs/src/doc-elements/graphviz/GvPolygon.jsx index c48dfc040..4f41804f5 100644 --- a/znai-reactjs/src/doc-elements/graphviz/GvPolygon.jsx +++ b/znai-reactjs/src/doc-elements/graphviz/GvPolygon.jsx @@ -47,7 +47,7 @@ class GvPolygon extends React.Component { removeCustomPropsNoCopy(cleanedUpProps) // came from circle dot - if (this.props.hasOwnProperty("rx") && + if (Object.hasOwn(this.props, "rx") && (Math.abs(this.props.rx - this.props.ry) < 0.0001)) { return } diff --git a/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizFlow.jsx b/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizFlow.jsx index c434ac7a9..59b8f1f83 100644 --- a/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizFlow.jsx +++ b/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizFlow.jsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import React, { Component } from 'react' +import React from 'react' import GraphVizSvg from './GraphVizSvg' diff --git a/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizSvg.jsx b/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizSvg.jsx index 16f8fa89b..3e0a2adb8 100644 --- a/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizSvg.jsx +++ b/znai-reactjs/src/doc-elements/graphviz/PresentationGraphVizSvg.jsx @@ -26,7 +26,7 @@ const PresentationGraphVizSvg = ({slideIdx, meta, idsToHighlight, ...props}) => return } -function numberOfSlides({data, idsToHighlight, meta}) { +function numberOfSlides({_data, idsToHighlight, meta}) { return (!idsToHighlight || isAllAtOnce(meta)) ? 1 : (idsToHighlight.length + 1) diff --git a/znai-reactjs/src/doc-elements/graphviz/SvgCustomShape.jsx b/znai-reactjs/src/doc-elements/graphviz/SvgCustomShape.jsx index 7a3a26d85..a646c6431 100644 --- a/znai-reactjs/src/doc-elements/graphviz/SvgCustomShape.jsx +++ b/znai-reactjs/src/doc-elements/graphviz/SvgCustomShape.jsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import React, { Component } from 'react' +import React from 'react' class SvgCustomShape extends React.Component { render() { diff --git a/znai-reactjs/src/doc-elements/images/AnnotatedImageEditor.jsx b/znai-reactjs/src/doc-elements/images/AnnotatedImageEditor.jsx index c9e43a3d4..eb7e9d03b 100644 --- a/znai-reactjs/src/doc-elements/images/AnnotatedImageEditor.jsx +++ b/znai-reactjs/src/doc-elements/images/AnnotatedImageEditor.jsx @@ -77,7 +77,7 @@ class AnnotatedImageEditor extends React.Component { this.setState({selectedId: shape.id}) } - onAnnotationChange(shape) { + onAnnotationChange(_shape) { this.forceUpdate() } diff --git a/znai-reactjs/src/doc-elements/images/annotations/Annotations.jsx b/znai-reactjs/src/doc-elements/images/annotations/Annotations.jsx index 64f034c60..eadcdb8cc 100644 --- a/znai-reactjs/src/doc-elements/images/annotations/Annotations.jsx +++ b/znai-reactjs/src/doc-elements/images/annotations/Annotations.jsx @@ -96,7 +96,7 @@ class Annotations { } function handlerForShapeType(shape) { - if (shapesLib.hasOwnProperty(shape.type)) { + if (Object.hasOwn(shapesLib, shape.type)) { return shapesLib[shape.type] } else { console.error("can't find type for shape: " + shape.type) @@ -115,7 +115,7 @@ function staticAnnotationForShape(shape) { function cachedAnnotationForType(cache, shape, createFunc) { const type = shape.type - if (cache.hasOwnProperty(type)) { + if (Object.hasOwn(cache, type)) { return cache[type] } else { const Annotation = createFunc(handlerForShapeType(shape)) diff --git a/znai-reactjs/src/doc-elements/images/annotations/StaticAnnotation.jsx b/znai-reactjs/src/doc-elements/images/annotations/StaticAnnotation.jsx index 05ba1751d..16652083f 100644 --- a/znai-reactjs/src/doc-elements/images/annotations/StaticAnnotation.jsx +++ b/znai-reactjs/src/doc-elements/images/annotations/StaticAnnotation.jsx @@ -17,16 +17,18 @@ import React from 'react' import {styleByName} from '../shapes/styleByName'; +import {withDisplayName} from '../../components.ts' -const staticAnnotation = (shapeHandler) => ({shape, scale}) => { - if (!shapeHandler) { - return - } - - const Body = shapeHandler.body; - return +const staticAnnotation = (shapeHandler) => { + return withDisplayName(`StaticAnnotation(${shapeHandler?.name || 'Unknown'}`)( + ({shape, scale}) => { + if (!shapeHandler) { + return + } + const Body = shapeHandler.body; + return + }); } - function NotFound({x, y, width, height, color}) { const styleScheme = styleByName(color) diff --git a/znai-reactjs/src/doc-elements/jupyter/JupyterHtmlCell.jsx b/znai-reactjs/src/doc-elements/jupyter/JupyterHtmlCell.jsx index 79787be39..1b775d9cf 100644 --- a/znai-reactjs/src/doc-elements/jupyter/JupyterHtmlCell.jsx +++ b/znai-reactjs/src/doc-elements/jupyter/JupyterHtmlCell.jsx @@ -20,7 +20,7 @@ import React from "react"; import { Container } from "../container/Container.js"; import "./JupyterHtmlCell.css"; -const JupyterHtmlCell = ({ html, elementsLibrary, ...props }) => { +const JupyterHtmlCell = ({ html, _elementsLibrary, ...props }) => { return (
diff --git a/znai-reactjs/src/doc-elements/markdown/MarkdownAndResult.jsx b/znai-reactjs/src/doc-elements/markdown/MarkdownAndResult.jsx index 8678d9787..193f5a6e0 100644 --- a/znai-reactjs/src/doc-elements/markdown/MarkdownAndResult.jsx +++ b/znai-reactjs/src/doc-elements/markdown/MarkdownAndResult.jsx @@ -1,5 +1,4 @@ /* - * Copyright 2021 TWO SIGMA OPEN SOURCE, LLC * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/znai-reactjs/src/doc-elements/pageContentProcessor.js b/znai-reactjs/src/doc-elements/pageContentProcessor.js index fdcbe9941..924016410 100644 --- a/znai-reactjs/src/doc-elements/pageContentProcessor.js +++ b/znai-reactjs/src/doc-elements/pageContentProcessor.js @@ -33,6 +33,7 @@ function mergeMetaIntoContent(pageContent, meta) { for (let i = 0, len = pageContent.length; i < len; i++) { const el = pageContent[i] if (el.type === 'Meta') { + // eslint-disable-next-line no-unused-vars const {type, ...meta} = el currentMeta = {...currentMeta, ...meta} } else { diff --git a/znai-reactjs/src/doc-elements/presentation/Presentation.jsx b/znai-reactjs/src/doc-elements/presentation/Presentation.jsx index 6acb88743..87c7a166e 100644 --- a/znai-reactjs/src/doc-elements/presentation/Presentation.jsx +++ b/znai-reactjs/src/doc-elements/presentation/Presentation.jsx @@ -143,11 +143,11 @@ class Presentation extends React.Component { document.removeEventListener("keydown", this.keyDownHandler) } - componentWillReceiveProps(props) { + componentDidUpdate(prevProps) { const {presentationRegistry} = this.props - if (this.scrollToLastWithinPage && presentationRegistry !== props.presentationRegistry) { + if (this.scrollToLastWithinPage && prevProps.presentationRegistry !== presentationRegistry) { this.scrollToLastWithinPage = false - this.setSlideIdx(props.presentationRegistry.numberOfSlides - 1) + this.setSlideIdx(presentationRegistry.numberOfSlides - 1) } } diff --git a/znai-reactjs/src/doc-elements/svg/EmbeddedSvg.jsx b/znai-reactjs/src/doc-elements/svg/EmbeddedSvg.jsx index 4e665a7ea..dbae09166 100644 --- a/znai-reactjs/src/doc-elements/svg/EmbeddedSvg.jsx +++ b/znai-reactjs/src/doc-elements/svg/EmbeddedSvg.jsx @@ -56,7 +56,7 @@ class EmbeddedSvg extends React.Component { this.changeSizeWhenPropIsChanged() } - componentDidUpdate(prevProps, prevState, snapshot) { + componentDidUpdate(_prevProps, _prevState, _snapshot) { this.changeSizeWhenPropIsChanged() } diff --git a/znai-reactjs/src/doc-elements/svg/Svg.jsx b/znai-reactjs/src/doc-elements/svg/Svg.jsx index 7752f9a01..33f872cf7 100644 --- a/znai-reactjs/src/doc-elements/svg/Svg.jsx +++ b/znai-reactjs/src/doc-elements/svg/Svg.jsx @@ -54,7 +54,7 @@ class Svg extends React.Component { this.loadSvg() } - componentDidUpdate(prevProps, prevState, snapshot) { + componentDidUpdate(prevProps, _prevState, _snapshot) { if (prevProps.svgSrc !== this.props.svgSrc) { this.loadSvg() } diff --git a/znai-reactjs/src/doc-elements/tabs/Tabs.jsx b/znai-reactjs/src/doc-elements/tabs/Tabs.jsx index 58ab66be6..73e35184c 100644 --- a/znai-reactjs/src/doc-elements/tabs/Tabs.jsx +++ b/znai-reactjs/src/doc-elements/tabs/Tabs.jsx @@ -15,7 +15,7 @@ * limitations under the License. */ -import React, { Component } from "react"; +import React from "react"; import { tabsRegistration } from "./TabsRegistration"; import { findParentWithScroll } from "../../utils/domNodes"; diff --git a/znai-reactjs/src/doc-elements/test-results/RestPayload.jsx b/znai-reactjs/src/doc-elements/test-results/RestPayload.jsx index 14013c0ed..629318ffe 100644 --- a/znai-reactjs/src/doc-elements/test-results/RestPayload.jsx +++ b/znai-reactjs/src/doc-elements/test-results/RestPayload.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,7 +25,7 @@ const JsonPayload = ({data, checks}) => { ) } -const RestPayload = ({caption, type, data, checks}) => { +const RestPayload = ({caption, _type, data, checks}) => { if (! data) { return null } diff --git a/znai-reactjs/src/doc-elements/text-selection/selectionTestUtils.js b/znai-reactjs/src/doc-elements/text-selection/selectionTestUtils.js index fb539230f..72ffee68e 100644 --- a/znai-reactjs/src/doc-elements/text-selection/selectionTestUtils.js +++ b/znai-reactjs/src/doc-elements/text-selection/selectionTestUtils.js @@ -30,10 +30,10 @@ export function setupDOM(htmlContent) { const document = dom.window.document; const window = dom.window; - global.window = window; - global.document = document; - global.Node = window.Node; - global.NodeFilter = window.NodeFilter; + globalThis.window = window; + globalThis.document = document; + globalThis.Node = window.Node; + globalThis.NodeFilter = window.NodeFilter; const container = document.body; @@ -41,11 +41,11 @@ export function setupDOM(htmlContent) { } export function selectText(startNode, startOffset, endNode, endOffset) { - const range = global.document.createRange(); + const range = globalThis.document.createRange(); range.setStart(startNode, startOffset); range.setEnd(endNode, endOffset); - const selection = global.window.getSelection(); + const selection = globalThis.window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } diff --git a/znai-reactjs/src/doc-elements/text-selection/selectionUtils.js b/znai-reactjs/src/doc-elements/text-selection/selectionUtils.js index ca0d923aa..f41912dca 100644 --- a/znai-reactjs/src/doc-elements/text-selection/selectionUtils.js +++ b/znai-reactjs/src/doc-elements/text-selection/selectionUtils.js @@ -53,7 +53,7 @@ function normalizeRangeBoundary(node, offset, isEnd = false) { // This means looking forward from offset return findTextNodeForward(node, offset); } - } catch (e) { + } catch { return null; } } diff --git a/znai-reactjs/src/doc-elements/tracking/DocumentationTracking.test.ts b/znai-reactjs/src/doc-elements/tracking/DocumentationTracking.test.ts index 1df5ca02f..ff1adfe84 100644 --- a/znai-reactjs/src/doc-elements/tracking/DocumentationTracking.test.ts +++ b/znai-reactjs/src/doc-elements/tracking/DocumentationTracking.test.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { DocumentationTracking, DocumentationTrackingListener } from "./DocumentationTracking"; +import { DocumentationTrackingListener } from "./DocumentationTracking"; +import { DocumentationTracking } from "./DocumentationTracking"; interface CallRecord { method: string; diff --git a/znai-reactjs/src/doc-elements/xml/PresentationXml.jsx b/znai-reactjs/src/doc-elements/xml/PresentationXml.jsx index f27bbb8fc..885dd1852 100644 --- a/znai-reactjs/src/doc-elements/xml/PresentationXml.jsx +++ b/znai-reactjs/src/doc-elements/xml/PresentationXml.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,4 +23,4 @@ const PresentationXml = ({xmlAsJson, paths, slideIdx, ...props}) => { return } -export default {component: PresentationXml, numberOfSlides: ({data, paths}) => paths ? (paths.length + 1): 1} \ No newline at end of file +export default {component: PresentationXml, numberOfSlides: ({_data, paths}) => paths ? (paths.length + 1): 1} \ No newline at end of file diff --git a/znai-reactjs/src/doc-elements/xml/xmlPrinter.js b/znai-reactjs/src/doc-elements/xml/xmlPrinter.js index 040a07480..7c4152a13 100644 --- a/znai-reactjs/src/doc-elements/xml/xmlPrinter.js +++ b/znai-reactjs/src/doc-elements/xml/xmlPrinter.js @@ -157,7 +157,7 @@ class XmlPrinter { } isHighlightedPath(path) { - return this._pathsToHighlight.hasOwnProperty(path) + return Object.hasOwn(this._pathsToHighlight, path) } } diff --git a/znai-reactjs/src/index.jsx b/znai-reactjs/src/index.jsx index 729eea976..155c5db0e 100644 --- a/znai-reactjs/src/index.jsx +++ b/znai-reactjs/src/index.jsx @@ -30,12 +30,12 @@ import {PreviewChangeScreen} from './screens/preview-change-path/PreviewChangeSc import {NotAuthorizedScreen} from './screens/not-authorized/NotAuthorizedScreen' import {Landing} from './screens/landing/Landing' import {themeRegistry} from './theme/ThemeRegistry' -import {documentationNavigation} from './structure/DocumentationNavigation' +import {documentationNavigation} from './structure/DocumentationNavigation.jsx' import {documentationTracking} from './doc-elements/tracking/DocumentationTracking' import {pageTypesRegistry} from './doc-elements/page/PageTypesRegistry' import {mergeDocMeta} from './structure/docMeta' -import { createLocalSearchIndex, populateLocalSearchIndexWithData } from "./doc-elements/search/flexSearch.js"; +import { createLocalSearchIndex, populateLocalSearchIndexWithData } from "./doc-elements/search/flexSearch.ts"; window.React = React window.ReactDOM = ReactDOM @@ -52,7 +52,8 @@ window.mergeDocMeta = mergeDocMeta window.createLocalSearchIndex = createLocalSearchIndex window.populateLocalSearchIndexWithData = populateLocalSearchIndexWithData window.znaiSearchIdx = window.createLocalSearchIndex(); -if (process.env.NODE_ENV !== "production") { +const isDevelopment = import.meta.env.DEV; +if (isDevelopment) { import('./App').then((module) => { const App = module.App; ReactDOM.render( diff --git a/znai-reactjs/src/utils/socket.js b/znai-reactjs/src/utils/socket.js index c5f3b036c..c0af99049 100644 --- a/znai-reactjs/src/utils/socket.js +++ b/znai-reactjs/src/utils/socket.js @@ -16,7 +16,9 @@ */ export function socketUrl(relativeUrl) { - if (process.env.NODE_ENV !== "production") { + const isDevelopment = import.meta.env.DEV + + if (isDevelopment) { return "ws://localhost:3334/preview" } diff --git a/znai-reactjs/tsconfig.json b/znai-reactjs/tsconfig.json index aa7fa8dc7..ff5d675c4 100644 --- a/znai-reactjs/tsconfig.json +++ b/znai-reactjs/tsconfig.json @@ -27,5 +27,5 @@ "noFallthroughCasesInSwitch": true, "noUncheckedSideEffectImports": true }, - "include": ["src", "vite.config.ts"] + "include": ["src", "vite.config.ts", "vitest.config.ts"] }