Skip to content

Commit

Permalink
fix: components' props types (#782)
Browse files Browse the repository at this point in the history
* fix: fix components' props types

fix #734, possible fix #741

* ci(size-limit): increase size
  • Loading branch information
dangreen committed Oct 18, 2021
1 parent 74c169a commit eba8a27
Show file tree
Hide file tree
Showing 12 changed files with 326 additions and 214 deletions.
3 changes: 2 additions & 1 deletion .clean-publish
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{
"packageManager": "yarn"
"packageManager": "yarn",
"fields": ["tsd"]
}
20 changes: 20 additions & 0 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,23 @@ jobs:
uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
typings:
runs-on: ubuntu-latest
name: Checking typings
if: "!contains(github.event.head_commit.message, '[ci skip]')"
steps:
- name: Checkout the repository
uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v2
with:
node-version: 12
- name: Install dependencies
uses: bahmutov/npm-install@v1
with:
install-command: yarn --frozen-lockfile --ignore-engines
- name: Prebuild
run: yarn build
- name: Check typings
if: success()
run: yarn test:typings
8 changes: 4 additions & 4 deletions .size-limit
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
},
{
"path": "dist/index.js",
"limit": "9.4 KB",
"import": "ChartComponent"
"limit": "9.5 KB",
"import": "Chart"
},
{
"path": "dist/index.modern.js",
Expand All @@ -18,7 +18,7 @@
},
{
"path": "dist/index.modern.js",
"limit": "9.4 KB",
"import": "ChartComponent"
"limit": "9.5 KB",
"import": "Chart"
}
]
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "React components for Chart.js",
"main": "dist/index.js",
"module": "dist/index.modern.js",
"types": "dist/index.d.ts",
"author": "Jeremy Ayerst",
"homepage": "https://github.com/reactchartjs/react-chartjs-2",
"license": "MIT",
Expand Down Expand Up @@ -31,7 +32,8 @@
"test:unit": "jest -c jest.config.json",
"test:build": "yarn build",
"test:size": "size-limit",
"test": "yarn test:lint && yarn test:unit && yarn test:build && yarn test:size",
"test:typings": "tsd",
"test": "yarn test:lint && yarn test:unit && yarn test:build",
"format": "prettier --write src",
"predeploy": "cd example && yarn && yarn build",
"deploy": "gh-pages -d example/build",
Expand Down Expand Up @@ -96,9 +98,13 @@
"simple-git-hooks": "^2.6.1",
"size-limit": "^6.0.3",
"standard-version": "^9.3.1",
"tsd": "^0.18.0",
"typescript": "^4.4.3",
"webpack": "^5.58.2"
},
"tsd": {
"directory": "./test"
},
"files": [
"dist"
]
Expand Down
73 changes: 41 additions & 32 deletions src/chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,43 @@ import React, {
useMemo,
forwardRef,
} from 'react';
import Chart from 'chart.js/auto';
import type { ChartData } from 'chart.js';
import type { Ref, MouseEvent } from 'react';
import ChartJS from 'chart.js/auto';
import type { ChartData, ChartType, DefaultDataPoint } from 'chart.js';
import merge from 'lodash/merge';
import assign from 'lodash/assign';
import find from 'lodash/find';

import { Props } from './types';
import { Props, ChartJSOrUndefined, TypedChartComponent } from './types';

const ChartComponent = forwardRef<Chart | undefined, Props>((props, ref) => {
const {
id,
className,
function ChartComponent<
TType extends ChartType = ChartType,
TData = DefaultDataPoint<TType>,
TLabel = unknown
>(
{
height = 150,
width = 300,
redraw = false,
type,
data,
options = {},
options,
plugins = [],
getDatasetAtEvent,
getElementAtEvent,
getElementsAtEvent,
fallbackContent,
...rest
} = props;
onClick: onClickProp,
...props
}: Props<TType, TData, TLabel>,
ref: Ref<ChartJS<TType, TData, TLabel>>
) {
type TypedChartJS = ChartJSOrUndefined<TType, TData, TLabel>;
type TypedChartData = ChartData<TType, TData, TLabel>;

const canvas = useRef<HTMLCanvasElement>(null);

const computedData = useMemo<ChartData>(() => {
const computedData = useMemo<TypedChartData>(() => {
if (typeof data === 'function') {
return canvas.current
? data(canvas.current)
Expand All @@ -44,17 +52,15 @@ const ChartComponent = forwardRef<Chart | undefined, Props>((props, ref) => {
} else return merge({}, data);
}, [data, canvas.current]);

const [chart, setChart] = useState<Chart>();
const [chart, setChart] = useState<TypedChartJS>();

useImperativeHandle<Chart | undefined, Chart | undefined>(ref, () => chart, [
chart,
]);
useImperativeHandle<TypedChartJS, TypedChartJS>(ref, () => chart, [chart]);

const renderChart = () => {
if (!canvas.current) return;

setChart(
new Chart(canvas.current, {
new ChartJS(canvas.current, {
type,
data: computedData,
options,
Expand All @@ -63,38 +69,42 @@ const ChartComponent = forwardRef<Chart | undefined, Props>((props, ref) => {
);
};

const onClick = (e: React.MouseEvent<HTMLCanvasElement>) => {
const onClick = (event: MouseEvent<HTMLCanvasElement>) => {
if (onClickProp) {
onClickProp(event);
}

if (!chart) return;

getDatasetAtEvent &&
getDatasetAtEvent(
chart.getElementsAtEventForMode(
e as unknown as Event,
event.nativeEvent,
'dataset',
{ intersect: true },
false
),
e
event
);
getElementAtEvent &&
getElementAtEvent(
chart.getElementsAtEventForMode(
e as unknown as Event,
event.nativeEvent,
'nearest',
{ intersect: true },
false
),
e
event
);
getElementsAtEvent &&
getElementsAtEvent(
chart.getElementsAtEventForMode(
e as unknown as Event,
event.nativeEvent,
'index',
{ intersect: true },
false
),
e
event
);
};

Expand Down Expand Up @@ -128,8 +138,10 @@ const ChartComponent = forwardRef<Chart | undefined, Props>((props, ref) => {
if (!currentDataSet || !newDataSet.data) return { ...newDataSet };

if (!currentDataSet.data) {
// @ts-expect-error Need to refactor
currentDataSet.data = [];
} else {
// @ts-expect-error Need to refactor
currentDataSet.data.length = newDataSet.data.length;
}

Expand Down Expand Up @@ -163,23 +175,20 @@ const ChartComponent = forwardRef<Chart | undefined, Props>((props, ref) => {
} else {
updateChart();
}
}, [props, computedData]);
});

return (
<canvas
{...rest}
ref={canvas}
role='img'
height={height}
width={width}
ref={canvas}
id={id}
className={className}
onClick={onClick}
data-testid='canvas'
role='img'
{...props}
>
{fallbackContent}
</canvas>
);
});
}

export default ChartComponent;
export const Chart = forwardRef(ChartComponent) as TypedChartComponent;
103 changes: 6 additions & 97 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,98 +1,7 @@
import React, { forwardRef } from 'react';
import Chart from 'chart.js/auto';
import { defaults } from 'chart.js';
// @todo Remove these exports
export { default as Chart } from 'chart.js/auto';
export { defaults } from 'chart.js';

import { Props } from './types';
import ChartComponent from './chart';

export const Line = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='line'
ref={ref}
options={props.options || {}}
/>
)
);

export const Bar = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='bar'
ref={ref}
options={props.options || {}}
/>
)
);

export const Radar = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='radar'
ref={ref}
options={props.options || {}}
/>
)
);

export const Doughnut = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='doughnut'
ref={ref}
options={props.options || {}}
/>
)
);

export const PolarArea = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='polarArea'
ref={ref}
options={props.options || {}}
/>
)
);

export const Bubble = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='bubble'
ref={ref}
options={props.options || {}}
/>
)
);

export const Pie = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='pie'
ref={ref}
options={props.options || {}}
/>
)
);

export const Scatter = forwardRef<Chart | undefined, Omit<Props, 'type'>>(
(props, ref) => (
<ChartComponent
{...props}
type='scatter'
ref={ref}
options={props.options || {}}
/>
)
);

export { Chart, defaults };

export default ChartComponent;
// @todo Make named export instead of default
export { Chart as default } from './chart';
export * from './typedCharts';
27 changes: 27 additions & 0 deletions src/typedCharts.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React, { forwardRef } from 'react';
import { ChartType } from 'chart.js';

import { Props, ChartJSOrUndefined, TypedChartComponent } from './types';
import { Chart } from './chart';

function createTypedChart<T extends ChartType>(type: T) {
return forwardRef<ChartJSOrUndefined<T>, Omit<Props<T>, 'type'>>(
(props, ref) => <Chart {...props} ref={ref} type={type} />
) as TypedChartComponent<T, true>;
}

export const Line = createTypedChart('line');

export const Bar = createTypedChart('bar');

export const Radar = createTypedChart('radar');

export const Doughnut = createTypedChart('doughnut');

export const PolarArea = createTypedChart('polarArea');

export const Bubble = createTypedChart('bubble');

export const Pie = createTypedChart('pie');

export const Scatter = createTypedChart('scatter');
Loading

0 comments on commit eba8a27

Please sign in to comment.