diff --git a/extensions/ql-vscode/.storybook/main.ts b/extensions/ql-vscode/.storybook/main.ts index ba5a9176155..b3c76eaf6a8 100644 --- a/extensions/ql-vscode/.storybook/main.ts +++ b/extensions/ql-vscode/.storybook/main.ts @@ -3,6 +3,7 @@ import type { StorybookConfig } from "@storybook/react-vite"; const config: StorybookConfig = { stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], addons: [ + "@storybook/addon-docs", "@storybook/addon-links", "@storybook/addon-a11y", "./vscode-theme-addon/preset.ts", diff --git a/extensions/ql-vscode/.storybook/vscode-theme-addon/preset.ts b/extensions/ql-vscode/.storybook/vscode-theme-addon/preset.ts index 1336a545f9d..d5512769d40 100644 --- a/extensions/ql-vscode/.storybook/vscode-theme-addon/preset.ts +++ b/extensions/ql-vscode/.storybook/vscode-theme-addon/preset.ts @@ -1,7 +1,12 @@ +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + export function previewAnnotations(entry = []) { - return [...entry, require.resolve("./preview.ts")]; + return [...entry, join(__dirname, "preview.ts")]; } export function managerEntries(entry = []) { - return [...entry, require.resolve("./manager.tsx")]; + return [...entry, join(__dirname, "manager.tsx")]; } diff --git a/extensions/ql-vscode/package-lock.json b/extensions/ql-vscode/package-lock.json index 7f928b276f1..a0ba0993511 100644 --- a/extensions/ql-vscode/package-lock.json +++ b/extensions/ql-vscode/package-lock.json @@ -59,6 +59,7 @@ "@microsoft/eslint-formatter-sarif": "^3.1.0", "@playwright/test": "^1.50.1", "@storybook/addon-a11y": "^10.1.11", + "@storybook/addon-docs": "^10.1.11", "@storybook/addon-links": "^10.1.11", "@storybook/components": "^8.6.14", "@storybook/csf": "^0.1.13", @@ -5259,6 +5260,24 @@ "@lit-labs/ssr-dom-shim": "^1.2.0" } }, + "node_modules/@mdx-js/react": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", + "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdx": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, "node_modules/@microsoft/applicationinsights-web-snippet": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@microsoft/applicationinsights-web-snippet/-/applicationinsights-web-snippet-1.0.1.tgz", @@ -6823,6 +6842,29 @@ "storybook": "^10.1.11" } }, + "node_modules/@storybook/addon-docs": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/addon-docs/-/addon-docs-10.1.11.tgz", + "integrity": "sha512-Jwm291Fhim2eVcZIVlkG1B2skb0ZI9oru6nqMbJxceQZlvZmcIa4oxvS1oaMTKw2DJnCv97gLm57P/YvRZ8eUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@mdx-js/react": "^3.0.0", + "@storybook/csf-plugin": "10.1.11", + "@storybook/icons": "^2.0.0", + "@storybook/react-dom-shim": "10.1.11", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "ts-dedent": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^10.1.11" + } + }, "node_modules/@storybook/addon-links": { "version": "10.1.11", "resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-10.1.11.tgz", @@ -6866,7 +6908,31 @@ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" } }, - "node_modules/@storybook/builder-vite/node_modules/@storybook/csf-plugin": { + "node_modules/@storybook/components": { + "version": "8.6.14", + "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.14.tgz", + "integrity": "sha512-HNR2mC5I4Z5ek8kTrVZlIY/B8gJGs5b3XdZPBPBopTIN6U/YHXiDyOjY3JlaS4fSG1fVhp/Qp1TpMn1w/9m1pw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" + } + }, + "node_modules/@storybook/csf": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", + "integrity": "sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^2.19.0" + } + }, + "node_modules/@storybook/csf-plugin": { "version": "10.1.11", "resolved": "https://registry.npmjs.org/@storybook/csf-plugin/-/csf-plugin-10.1.11.tgz", "integrity": "sha512-Ant0NhgqHKzQsseeVTSetZCuDHHs0W2HRkHt51Kg/sUl0T/sDtfVA+fWZT8nGzGZqYSFkxqYPWjauPmIhPtaRw==", @@ -6901,59 +6967,6 @@ } } }, - "node_modules/@storybook/builder-vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/@storybook/builder-vite/node_modules/unplugin": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", - "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "acorn": "^8.15.0", - "picomatch": "^4.0.3", - "webpack-virtual-modules": "^0.6.2" - }, - "engines": { - "node": ">=18.12.0" - } - }, - "node_modules/@storybook/components": { - "version": "8.6.14", - "resolved": "https://registry.npmjs.org/@storybook/components/-/components-8.6.14.tgz", - "integrity": "sha512-HNR2mC5I4Z5ek8kTrVZlIY/B8gJGs5b3XdZPBPBopTIN6U/YHXiDyOjY3JlaS4fSG1fVhp/Qp1TpMn1w/9m1pw==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "storybook": "^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0" - } - }, - "node_modules/@storybook/csf": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", - "integrity": "sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^2.19.0" - } - }, "node_modules/@storybook/global": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", @@ -6998,6 +7011,22 @@ } } }, + "node_modules/@storybook/react-dom-shim": { + "version": "10.1.11", + "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.1.11.tgz", + "integrity": "sha512-o8WPhRlZbORUWG9lAgDgJP0pi905VHJUFJr1Kp8980gHqtlemtnzjPxKy5vFwj6glNhAlK8SS8OOYzWP7hloTQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "storybook": "^10.1.11" + } + }, "node_modules/@storybook/react-vite": { "version": "10.1.11", "resolved": "https://registry.npmjs.org/@storybook/react-vite/-/react-vite-10.1.11.tgz", @@ -7049,22 +7078,6 @@ "node": ">=6" } }, - "node_modules/@storybook/react/node_modules/@storybook/react-dom-shim": { - "version": "10.1.11", - "resolved": "https://registry.npmjs.org/@storybook/react-dom-shim/-/react-dom-shim-10.1.11.tgz", - "integrity": "sha512-o8WPhRlZbORUWG9lAgDgJP0pi905VHJUFJr1Kp8980gHqtlemtnzjPxKy5vFwj6glNhAlK8SS8OOYzWP7hloTQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/storybook" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "storybook": "^10.1.11" - } - }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -7765,6 +7778,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", @@ -26602,6 +26622,35 @@ "node": ">= 10.0.0" } }, + "node_modules/unplugin": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-2.3.11.tgz", + "integrity": "sha512-5uKD0nqiYVzlmCRs01Fhs2BdkEgBS3SAVP6ndrBsuK42iC2+JHyxM05Rm9G8+5mkmRtzMZGY8Ct5+mliZxU/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "acorn": "^8.15.0", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/unplugin/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/unrs-resolver": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", diff --git a/extensions/ql-vscode/package.json b/extensions/ql-vscode/package.json index a6be8d8a222..f197db0c4e3 100644 --- a/extensions/ql-vscode/package.json +++ b/extensions/ql-vscode/package.json @@ -2110,6 +2110,7 @@ "@microsoft/eslint-formatter-sarif": "^3.1.0", "@playwright/test": "^1.50.1", "@storybook/addon-a11y": "^10.1.11", + "@storybook/addon-docs": "^10.1.11", "@storybook/addon-links": "^10.1.11", "@storybook/components": "^8.6.14", "@storybook/csf": "^0.1.13", diff --git a/extensions/ql-vscode/src/stories/Overview.mdx b/extensions/ql-vscode/src/stories/Overview.mdx index 7d9939cb4d9..189d35b65dd 100644 --- a/extensions/ql-vscode/src/stories/Overview.mdx +++ b/extensions/ql-vscode/src/stories/Overview.mdx @@ -1,4 +1,4 @@ -import { Canvas, Meta, Story } from '@storybook/blocks'; +import { Canvas, Meta, Story } from '@storybook/addon-docs/blocks'; import iframeImage from './images/update-css-variables-iframe.png'; import stylesImage from './images/update-css-variables-styles.png'; diff --git a/extensions/ql-vscode/src/view/common/CodePaths/CodeFlowsDropdown.tsx b/extensions/ql-vscode/src/view/common/CodePaths/CodeFlowsDropdown.tsx index cc232060f0a..12af1de42d2 100644 --- a/extensions/ql-vscode/src/view/common/CodePaths/CodeFlowsDropdown.tsx +++ b/extensions/ql-vscode/src/view/common/CodePaths/CodeFlowsDropdown.tsx @@ -1,4 +1,4 @@ -import type { ChangeEvent, SetStateAction } from "react"; +import type { SetStateAction } from "react"; import { useCallback } from "react"; import { VscodeOption, @@ -25,8 +25,8 @@ export const CodeFlowsDropdown = ({ setSelectedCodeFlow, }: CodeFlowsDropdownProps) => { const handleChange = useCallback( - (e: ChangeEvent) => { - const selectedOption = e.target; + (e: Event) => { + const selectedOption = e.target as HTMLSelectElement; const selectedIndex = parseInt(selectedOption.value); setSelectedCodeFlow(codeFlows[selectedIndex]); }, diff --git a/extensions/ql-vscode/src/view/common/DataGrid.tsx b/extensions/ql-vscode/src/view/common/DataGrid.tsx index a8bce90b0a3..2dc3bfa95ad 100644 --- a/extensions/ql-vscode/src/view/common/DataGrid.tsx +++ b/extensions/ql-vscode/src/view/common/DataGrid.tsx @@ -83,7 +83,7 @@ export const DataGridRow = forwardRef( "data-testid": testId, onClick, }: DataGridRowProps, - ref?: React.Ref, + ref?: React.Ref, ) => ( , + ref?: React.Ref, ) => { return ( ` +const StyledButton = styled.button<{ $size?: Size }>` background: none; color: var(--vscode-textLink-foreground); border: none; diff --git a/extensions/ql-vscode/src/view/model-alerts/ModelAlertsSort.tsx b/extensions/ql-vscode/src/view/model-alerts/ModelAlertsSort.tsx index e5d4e9f2eb6..c2053575587 100644 --- a/extensions/ql-vscode/src/view/model-alerts/ModelAlertsSort.tsx +++ b/extensions/ql-vscode/src/view/model-alerts/ModelAlertsSort.tsx @@ -20,7 +20,7 @@ type Props = { export const ModelAlertsSort = ({ value, onChange, className }: Props) => { const handleInput = useCallback( - (e: InputEvent) => { + (e: Event) => { const target = e.target as HTMLSelectElement; onChange(target.value as SortKey); diff --git a/extensions/ql-vscode/src/view/model-editor/MethodRow.tsx b/extensions/ql-vscode/src/view/model-editor/MethodRow.tsx index 03a1abdd44c..c3c6b646f79 100644 --- a/extensions/ql-vscode/src/view/model-editor/MethodRow.tsx +++ b/extensions/ql-vscode/src/view/model-editor/MethodRow.tsx @@ -85,7 +85,7 @@ export type MethodRowProps = { export const MethodRow = (props: MethodRowProps) => { const { method, methodCanBeModeled, revealedMethodSignature } = props; - const ref = useRef(undefined); + const ref = useRef(null); useEffect(() => { if (method.signature === revealedMethodSignature) { @@ -103,7 +103,7 @@ export const MethodRow = (props: MethodRowProps) => { } }; -const ModelableMethodRow = forwardRef( +const ModelableMethodRow = forwardRef( (props: MethodRowProps, ref) => { const { method, @@ -359,39 +359,38 @@ const ModelableMethodRow = forwardRef( ); ModelableMethodRow.displayName = "ModelableMethodRow"; -const UnmodelableMethodRow = forwardRef< - HTMLElement | undefined, - MethodRowProps ->((props: MethodRowProps, ref) => { - const { method, viewState, revealedMethodSignature } = props; - - const jumpToMethod = useCallback( - () => sendJumpToMethodMessage(method), - [method], - ); - - return ( - - - - - - - {viewState.mode === Mode.Application && ( - - {method.usages.length} - - )} - View - - - Method already modeled - - ); -}); +const UnmodelableMethodRow = forwardRef( + (props: MethodRowProps, ref) => { + const { method, viewState, revealedMethodSignature } = props; + + const jumpToMethod = useCallback( + () => sendJumpToMethodMessage(method), + [method], + ); + + return ( + + + + + + + {viewState.mode === Mode.Application && ( + + {method.usages.length} + + )} + View + + + Method already modeled + + ); + }, +); UnmodelableMethodRow.displayName = "UnmodelableMethodRow"; function sendJumpToMethodMessage(method: Method) { diff --git a/extensions/ql-vscode/src/view/model-editor/ModelTypeTextbox.tsx b/extensions/ql-vscode/src/view/model-editor/ModelTypeTextbox.tsx index 69f9a0829b9..e9ba55c9a8a 100644 --- a/extensions/ql-vscode/src/view/model-editor/ModelTypeTextbox.tsx +++ b/extensions/ql-vscode/src/view/model-editor/ModelTypeTextbox.tsx @@ -1,4 +1,3 @@ -import type { ChangeEvent } from "react"; import { useCallback, useEffect, useState } from "react"; import type { ModeledMethod, @@ -33,8 +32,8 @@ export const ModelTypeTextbox = ({ setValue(modeledMethod[typeInfo]); }, [modeledMethod, typeInfo]); - const handleChange = useCallback((e: ChangeEvent) => { - const target = e.target as HTMLSelectElement; + const handleChange = useCallback((e: Event) => { + const target = e.target as HTMLInputElement; setValue(target.value); }, []); diff --git a/extensions/ql-vscode/src/view/variant-analysis/RepoRow.tsx b/extensions/ql-vscode/src/view/variant-analysis/RepoRow.tsx index 19edad08cc2..06fa7ec8705 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/RepoRow.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/RepoRow.tsx @@ -1,4 +1,3 @@ -import type { ChangeEvent } from "react"; import { useCallback, useEffect, useState } from "react"; import { styled } from "styled-components"; import { VscodeCheckbox } from "@vscode-elements/react-elements"; @@ -229,9 +228,10 @@ export const RepoRow = ({ e.stopPropagation(); }, []); const onChangeCheckbox = useCallback( - (e: ChangeEvent) => { + (e: Event) => { + const target = e.target as HTMLInputElement; // This is called on first render, but we don't really care about this value - if (e.target.checked === undefined) { + if (target.checked === undefined) { return; } @@ -239,7 +239,7 @@ export const RepoRow = ({ return; } - onSelectedChange?.(repository.id, e.target.checked); + onSelectedChange?.(repository.id, target.checked); }, [onSelectedChange, repository], ); diff --git a/extensions/ql-vscode/src/view/variant-analysis/RepositoriesFilter.tsx b/extensions/ql-vscode/src/view/variant-analysis/RepositoriesFilter.tsx index 206b33586fb..8605296bcac 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/RepositoriesFilter.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/RepositoriesFilter.tsx @@ -20,7 +20,7 @@ type Props = { export const RepositoriesFilter = ({ value, onChange, className }: Props) => { const handleInput = useCallback( - (e: InputEvent) => { + (e: Event) => { const target = e.target as HTMLSelectElement; onChange(target.value as FilterKey); diff --git a/extensions/ql-vscode/src/view/variant-analysis/RepositoriesResultFormat.tsx b/extensions/ql-vscode/src/view/variant-analysis/RepositoriesResultFormat.tsx index 380599017eb..cc7455bab25 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/RepositoriesResultFormat.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/RepositoriesResultFormat.tsx @@ -24,7 +24,7 @@ export const RepositoriesResultFormat = ({ className, }: Props) => { const handleInput = useCallback( - (e: InputEvent) => { + (e: Event) => { const target = e.target as HTMLSelectElement; onChange(target.value as ResultFormat); diff --git a/extensions/ql-vscode/src/view/variant-analysis/RepositoriesSort.tsx b/extensions/ql-vscode/src/view/variant-analysis/RepositoriesSort.tsx index 96ec4c43dd4..b067b68d110 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/RepositoriesSort.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/RepositoriesSort.tsx @@ -20,7 +20,7 @@ type Props = { export const RepositoriesSort = ({ value, onChange, className }: Props) => { const handleInput = useCallback( - (e: InputEvent) => { + (e: Event) => { const target = e.target as HTMLSelectElement; onChange(target.value as SortKey); diff --git a/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisActions.tsx b/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisActions.tsx index abec9443946..bf7261d5149 100644 --- a/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisActions.tsx +++ b/extensions/ql-vscode/src/view/variant-analysis/VariantAnalysisActions.tsx @@ -102,7 +102,6 @@ export const VariantAnalysisActions = ({ })}