diff --git a/packages/d3-state-visualizer/src/charts/tree/tree.ts b/packages/d3-state-visualizer/src/charts/tree/tree.ts index e7eb7ac5..894eceb4 100644 --- a/packages/d3-state-visualizer/src/charts/tree/tree.ts +++ b/packages/d3-state-visualizer/src/charts/tree/tree.ts @@ -12,7 +12,7 @@ import d3tooltip from 'd3tooltip'; interface InputOptions { // eslint-disable-next-line @typescript-eslint/ban-types - state?: {}; + state?: {} | null; // eslint-disable-next-line @typescript-eslint/ban-types tree?: NodeWithId | {}; @@ -50,7 +50,7 @@ interface InputOptions { interface Options { // eslint-disable-next-line @typescript-eslint/ban-types - state?: {}; + state?: {} | null; // eslint-disable-next-line @typescript-eslint/ban-types tree?: NodeWithId | {}; diff --git a/packages/redux-devtools-chart-monitor/.babelrc b/packages/redux-devtools-chart-monitor/.babelrc index 2d8ea82b..0d42ef44 100644 --- a/packages/redux-devtools-chart-monitor/.babelrc +++ b/packages/redux-devtools-chart-monitor/.babelrc @@ -1,7 +1,8 @@ { - "presets": ["@babel/preset-env", "@babel/preset-react"], - "plugins": [ - "@babel/plugin-proposal-class-properties", - "@babel/plugin-proposal-export-default-from" - ] + "presets": [ + "@babel/preset-env", + "@babel/preset-react", + "@babel/preset-typescript" + ], + "plugins": ["@babel/plugin-proposal-class-properties"] } diff --git a/packages/redux-devtools-chart-monitor/.eslintignore b/packages/redux-devtools-chart-monitor/.eslintignore new file mode 100644 index 00000000..a65b4177 --- /dev/null +++ b/packages/redux-devtools-chart-monitor/.eslintignore @@ -0,0 +1 @@ +lib diff --git a/packages/redux-devtools-chart-monitor/.eslintrc.js b/packages/redux-devtools-chart-monitor/.eslintrc.js new file mode 100644 index 00000000..e98ddf18 --- /dev/null +++ b/packages/redux-devtools-chart-monitor/.eslintrc.js @@ -0,0 +1,13 @@ +module.exports = { + extends: '../../.eslintrc', + overrides: [ + { + files: ['*.ts', '*.tsx'], + extends: '../../eslintrc.ts.react.base.json', + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig.json'], + }, + }, + ], +}; diff --git a/packages/redux-devtools-chart-monitor/package.json b/packages/redux-devtools-chart-monitor/package.json index 37e9a9c1..291d3a0f 100644 --- a/packages/redux-devtools-chart-monitor/package.json +++ b/packages/redux-devtools-chart-monitor/package.json @@ -2,21 +2,6 @@ "name": "redux-devtools-chart-monitor", "version": "1.7.2", "description": "Chart monitor for Redux DevTools", - "main": "lib/index.js", - "scripts": { - "clean": "rimraf lib", - "build": "babel src --out-dir lib", - "prepare": "npm run build", - "prepublishOnly": "npm run clean && npm run build" - }, - "files": [ - "lib", - "src" - ], - "repository": { - "type": "git", - "url": "https://github.com/reduxjs/redux-devtools.git" - }, "keywords": [ "redux", "devtools", @@ -24,32 +9,52 @@ "react", "chart" ], - "author": "romseguy", - "license": "MIT", + "homepage": "https://github.com/reduxjs/redux-devtools/tree/master/packages/redux-devtools-chart-monitor", "bugs": { "url": "https://github.com/reduxjs/redux-devtools/issues" }, - "homepage": "https://github.com/reduxjs/redux-devtools", - "devDependencies": { - "@babel/cli": "^7.10.5", - "@babel/core": "^7.11.1", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-export-default-from": "^7.10.4", - "@babel/preset-env": "^7.11.0", - "@babel/preset-react": "^7.10.4", - "babel-loader": "^8.1.0", - "rimraf": "^3.0.2" + "license": "MIT", + "author": "romseguy", + "files": [ + "lib", + "src" + ], + "main": "lib/index.js", + "types": "lib/index.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/reduxjs/redux-devtools.git" }, - "peerDependencies": { - "react": "^16.3.0", - "react-dom": "^16.3.0", - "redux-devtools": "^3.0.0" + "scripts": { + "build": "npm run build:types && npm run build:js", + "build:types": "tsc --emitDeclarationOnly", + "build:js": "babel src --out-dir lib --extensions \".ts,.tsx\" --source-maps inline", + "clean": "rimraf lib", + "lint": "eslint . --ext .ts,.tsx", + "lint:fix": "eslint . --ext .ts,.tsx --fix", + "type-check": "tsc --noEmit", + "type-check:watch": "npm run type-check -- --watch", + "preversion": "npm run type-check && npm run lint", + "prepublishOnly": "npm run clean && npm run build" }, "dependencies": { + "@types/prop-types": "^15.7.3", + "@types/redux-devtools-themes": "^1.0.0", "d3-state-visualizer": "^1.3.4", "deepmerge": "^4.2.2", "prop-types": "^15.7.2", - "react-pure-render": "^1.0.2", "redux-devtools-themes": "^1.0.0" + }, + "devDependencies": { + "@types/react": "^16.9.46", + "react": "^16.13.1", + "redux": "^4.0.5", + "redux-devtools": "^3.7.0" + }, + "peerDependencies": { + "@types/react": "^16.3.18", + "react": "^16.3.0", + "redux": "^3.4.0 || ^4.0.0", + "redux-devtools": "^3.0.0" } } diff --git a/packages/redux-devtools-chart-monitor/src/Chart.js b/packages/redux-devtools-chart-monitor/src/Chart.tsx similarity index 55% rename from packages/redux-devtools-chart-monitor/src/Chart.js rename to packages/redux-devtools-chart-monitor/src/Chart.tsx index 5cfac370..8b646f58 100644 --- a/packages/redux-devtools-chart-monitor/src/Chart.js +++ b/packages/redux-devtools-chart-monitor/src/Chart.tsx @@ -1,13 +1,44 @@ import React, { Component, createRef } from 'react'; import PropTypes from 'prop-types'; import { tree } from 'd3-state-visualizer'; +import { Action, Dispatch } from 'redux'; +import { LiftedAction, LiftedState } from 'redux-devtools-instrument'; +import * as themes from 'redux-devtools-themes'; +import { Base16Theme } from 'react-base16-styling'; +import { ChartMonitorState } from './reducers'; +import { Primitive } from 'd3'; const wrapperStyle = { width: '100%', height: '100%', }; -class Chart extends Component { +export interface Props> + extends LiftedState { + dispatch: Dispatch>; + preserveScrollTop: boolean; + select: (state: S) => unknown; + theme: keyof typeof themes | Base16Theme; + invertTheme: boolean; + + state: S | null; + isSorted: boolean; + heightBetweenNodesCoeff: number; + widthBetweenNodesCoeff: number; + tooltipOptions: { + disabled: boolean; + offset: { + left: number; + top: number; + }; + indentationSize: number; + style: { [key: string]: Primitive } | undefined; + }; + style: { [key: string]: Primitive } | undefined; + defaultIsVisible?: boolean; +} + +class Chart> extends Component> { static propTypes = { state: PropTypes.object, rootKeyName: PropTypes.string, @@ -60,21 +91,25 @@ class Chart extends Component { }), }; - divRef = createRef(); + divRef = createRef(); + // eslint-disable-next-line @typescript-eslint/ban-types + renderChart?: (state?: {} | null | undefined) => void; componentDidMount() { const { select, state, defaultIsVisible } = this.props; - this.renderChart = tree(this.divRef.current, this.props); + this.renderChart = tree(this.divRef.current!, this.props); if (defaultIsVisible) { - this.renderChart(select(state)); + // eslint-disable-next-line @typescript-eslint/ban-types + this.renderChart(select(state!) as {} | null | undefined); } } - UNSAFE_componentWillReceiveProps(nextProps) { + UNSAFE_componentWillReceiveProps(nextProps: Props) { const { state, select, monitorState } = nextProps; if (monitorState.isVisible !== false) { - this.renderChart(select(state)); + // eslint-disable-next-line @typescript-eslint/ban-types + this.renderChart!(select(state!) as {} | null | undefined); } } diff --git a/packages/redux-devtools-chart-monitor/src/ChartMonitor.js b/packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx similarity index 62% rename from packages/redux-devtools-chart-monitor/src/ChartMonitor.js rename to packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx index df45d93c..8fe44c64 100644 --- a/packages/redux-devtools-chart-monitor/src/ChartMonitor.js +++ b/packages/redux-devtools-chart-monitor/src/ChartMonitor.tsx @@ -1,15 +1,18 @@ -import React, { Component } from 'react'; +import React, { CSSProperties, PureComponent } from 'react'; import PropTypes from 'prop-types'; -import shouldPureComponentUpdate from 'react-pure-render/function'; import * as themes from 'redux-devtools-themes'; -import { ActionCreators } from 'redux-devtools'; +import { ActionCreators, LiftedAction, LiftedState } from 'redux-devtools'; import deepmerge from 'deepmerge'; +import { Action, Dispatch } from 'redux'; +import { Base16Theme } from 'react-base16-styling'; -import reducer from './reducers'; -import Chart from './Chart'; +import reducer, { ChartMonitorState } from './reducers'; +import Chart, { Props } from './Chart'; +import { Primitive } from 'd3'; +// eslint-disable-next-line @typescript-eslint/unbound-method const { reset, rollback, commit, sweep, toggleAction } = ActionCreators; -const styles = { +const styles: { container: CSSProperties } = { container: { fontFamily: 'monaco, Consolas, Lucida Console, monospace', position: 'relative', @@ -20,7 +23,7 @@ const styles = { }, }; -function invertColors(theme) { +function invertColors(theme: Base16Theme) { return { ...theme, base00: theme.base07, @@ -34,7 +37,43 @@ function invertColors(theme) { }; } -class ChartMonitor extends Component { +export interface ChartMonitorProps> + extends LiftedState { + dispatch: Dispatch>; + preserveScrollTop: boolean; + select: (state: S) => unknown; + theme: keyof typeof themes | Base16Theme; + invertTheme: boolean; + + state: S | null; + isSorted: boolean; + heightBetweenNodesCoeff: number; + widthBetweenNodesCoeff: number; + tooltipOptions: unknown; + style: { + width: number; + height: number; + node: { + colors: { + default: string; + collapsed: string; + parent: string; + }; + radius: number; + }; + text: { + colors: { + default: string; + hover: string; + }; + }; + }; + defaultIsVisible?: boolean; +} + +class ChartMonitor> extends PureComponent< + ChartMonitorProps +> { static update = reducer; static propTypes = { @@ -55,45 +94,34 @@ class ChartMonitor extends Component { }; static defaultProps = { - select: (state) => state, + select: (state: unknown) => state, theme: 'nicinabox', preserveScrollTop: true, invertTheme: false, }; - shouldComponentUpdate = shouldPureComponentUpdate; - - constructor(props) { - super(props); - this.handleToggleAction = this.handleToggleAction.bind(this); - this.handleReset = this.handleReset.bind(this); - this.handleRollback = this.handleRollback.bind(this); - this.handleSweep = this.handleSweep.bind(this); - this.handleCommit = this.handleCommit.bind(this); - } - - handleRollback() { + handleRollback = () => { this.props.dispatch(rollback()); - } + }; - handleSweep() { + handleSweep = () => { this.props.dispatch(sweep()); - } + }; - handleCommit() { + handleCommit = () => { this.props.dispatch(commit()); - } + }; - handleToggleAction(id) { + handleToggleAction = (id: number) => { this.props.dispatch(toggleAction(id)); - } + }; - handleReset() { + handleReset = () => { this.props.dispatch(reset()); - } + }; getTheme() { - let { theme, invertTheme } = this.props; + const { theme, invertTheme } = this.props; if (typeof theme !== 'string') { return invertTheme ? invertColors(theme) : theme; } @@ -102,7 +130,6 @@ class ChartMonitor extends Component { return invertTheme ? invertColors(themes[theme]) : themes[theme]; } - // eslint-disable-next-line no-console console.warn( 'DevTools theme ' + theme + ' not found, defaulting to nicinabox' ); @@ -132,7 +159,7 @@ class ChartMonitor extends Component { }; } - getChartOptions(props = this.props) { + getChartOptions(props = this.props): Props { const { computedStates } = props; const theme = this.getTheme(); @@ -156,7 +183,9 @@ class ChartMonitor extends Component { heightBetweenNodesCoeff: 1, widthBetweenNodesCoeff: 1.3, tooltipOptions, - style: this.getChartStyle(), + style: (this.getChartStyle() as unknown) as + | { [key: string]: Primitive } + | undefined, }; return deepmerge(defaultOptions, props); @@ -165,9 +194,10 @@ class ChartMonitor extends Component { render() { const theme = this.getTheme(); + const ChartAsAny = Chart as any; return (
- +
); } diff --git a/packages/redux-devtools-chart-monitor/src/actions.js b/packages/redux-devtools-chart-monitor/src/actions.js deleted file mode 100644 index 0eefa3a9..00000000 --- a/packages/redux-devtools-chart-monitor/src/actions.js +++ /dev/null @@ -1,2 +0,0 @@ -export const TOGGLE_VISIBILITY = - '@@redux-devtools-log-monitor/TOGGLE_VISIBILITY'; diff --git a/packages/redux-devtools-chart-monitor/src/actions.ts b/packages/redux-devtools-chart-monitor/src/actions.ts new file mode 100644 index 00000000..062215ed --- /dev/null +++ b/packages/redux-devtools-chart-monitor/src/actions.ts @@ -0,0 +1,6 @@ +export const TOGGLE_VISIBILITY = + '@@redux-devtools-log-monitor/TOGGLE_VISIBILITY'; +interface ToggleVisibilityAction { + type: typeof TOGGLE_VISIBILITY; +} +export type ChartMonitorAction = ToggleVisibilityAction; diff --git a/packages/redux-devtools-chart-monitor/src/index.js b/packages/redux-devtools-chart-monitor/src/index.js deleted file mode 100644 index 47f35f02..00000000 --- a/packages/redux-devtools-chart-monitor/src/index.js +++ /dev/null @@ -1 +0,0 @@ -export default from './ChartMonitor'; diff --git a/packages/redux-devtools-chart-monitor/src/index.ts b/packages/redux-devtools-chart-monitor/src/index.ts new file mode 100644 index 00000000..c1fa1959 --- /dev/null +++ b/packages/redux-devtools-chart-monitor/src/index.ts @@ -0,0 +1 @@ +export { default } from './ChartMonitor'; diff --git a/packages/redux-devtools-chart-monitor/src/reducers.js b/packages/redux-devtools-chart-monitor/src/reducers.js deleted file mode 100644 index 93479d63..00000000 --- a/packages/redux-devtools-chart-monitor/src/reducers.js +++ /dev/null @@ -1,19 +0,0 @@ -import { TOGGLE_VISIBILITY } from './actions'; - -function toggleVisibility(props, state = props.defaultIsVisible, action) { - if (action.type === TOGGLE_VISIBILITY) { - return !state; - } - - if (props.defaultIsVisible !== undefined) { - return props.defaultIsVisible; - } - - return true; -} - -export default function reducer(props, state = {}, action) { - return { - isVisible: toggleVisibility(props, state.isVisible, action), - }; -} diff --git a/packages/redux-devtools-chart-monitor/src/reducers.ts b/packages/redux-devtools-chart-monitor/src/reducers.ts new file mode 100644 index 00000000..d335beb6 --- /dev/null +++ b/packages/redux-devtools-chart-monitor/src/reducers.ts @@ -0,0 +1,33 @@ +import { Action } from 'redux'; +import { ChartMonitorAction, TOGGLE_VISIBILITY } from './actions'; +import { ChartMonitorProps } from './ChartMonitor'; + +function toggleVisibility>( + props: ChartMonitorProps, + state = props.defaultIsVisible, + action: ChartMonitorAction +): boolean { + if (action.type === TOGGLE_VISIBILITY) { + return !state; + } + + if (props.defaultIsVisible !== undefined) { + return props.defaultIsVisible; + } + + return true; +} + +export interface ChartMonitorState { + isVisible?: boolean; +} + +export default function reducer>( + props: ChartMonitorProps, + state: ChartMonitorState | undefined = {}, + action: ChartMonitorAction +) { + return { + isVisible: toggleVisibility(props, state.isVisible, action), + }; +} diff --git a/packages/redux-devtools-chart-monitor/tsconfig.json b/packages/redux-devtools-chart-monitor/tsconfig.json new file mode 100644 index 00000000..7b7d1492 --- /dev/null +++ b/packages/redux-devtools-chart-monitor/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.react.base.json", + "compilerOptions": { + "outDir": "lib" + }, + "include": ["src"] +}