Skip to content

Commit f939554

Browse files
committedSep 4, 2021
feat(website): improve typings for ComponentTemplate
1 parent d3767ae commit f939554

File tree

6 files changed

+152
-100
lines changed

6 files changed

+152
-100
lines changed
 

‎packages/sankey/src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './Sankey'
22
export * from './ResponsiveSankey'
33
export * from './props'
4+
export * from './types'

‎website/src/@types/file_types.d.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// import { ChartMeta } from '../types'
2+
3+
type ChartMetaFlavors = {
4+
flavor: 'svg' | 'html' | 'canvas' | 'api'
5+
path: string
6+
}[]
7+
8+
declare module '*funnel/meta.yml' {
9+
const meta: {
10+
flavors: ChartMetaFlavors
11+
Funnel: ChartMeta
12+
}
13+
14+
export default meta
15+
}
16+
17+
declare module '*sankey/meta.yml' {
18+
const meta: {
19+
flavors: ChartMetaFlavors
20+
Sankey: ChartMeta
21+
}
22+
23+
export default meta
24+
}

‎website/src/components/components/ComponentTemplate.tsx

+16-12
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import ComponentSettings from './ComponentSettings'
1414
import { Stories } from './Stories'
1515
import { ChartMeta, ChartProperty, Flavor } from '../../types'
1616

17-
interface ComponentTemplateProps<P extends object, D> {
17+
interface ComponentTemplateProps<UnmappedProps extends object, Props extends object, Data> {
1818
name: string
1919
meta: ChartMeta
2020
icon: string
@@ -27,21 +27,25 @@ interface ComponentTemplateProps<P extends object, D> {
2727
name: string
2828
properties: ChartProperty[]
2929
}[]
30-
// initial props of the demo
31-
initialProperties: Partial<P>
30+
// initial props of the demo, unmapped
31+
initialProperties: UnmappedProps
3232
// default props as defined in the package component
33-
defaultProperties?: Partial<P>
34-
propertiesMapper?: Function
33+
defaultProperties?: Partial<Props>
34+
propertiesMapper?: (unmappedProps: UnmappedProps) => Props
3535
codePropertiesMapper?: Function
3636
hasData?: boolean
37-
generateData?: (previousData?: D | null) => D | undefined
37+
generateData?: (previousData?: Data | null) => Data | undefined
3838
dataKey?: string
39-
getDataSize?: (data: D) => number
40-
getTabData?: (data: D) => D
41-
children: (properties: any, data: any, theme: NivoTheme, logAction: any) => JSX.Element
39+
getDataSize?: (data: Data) => number
40+
getTabData?: (data: Data) => Data
41+
children: (properties: Props, data: Data, theme: NivoTheme, logAction: any) => JSX.Element
4242
}
4343

44-
export const ComponentTemplate = <P extends object = any, D = any>({
44+
export const ComponentTemplate = <
45+
UnmappedProps extends object = any,
46+
Props extends object = any,
47+
Data = any
48+
>({
4549
name,
4650
meta,
4751
icon,
@@ -58,7 +62,7 @@ export const ComponentTemplate = <P extends object = any, D = any>({
5862
getDataSize,
5963
getTabData = data => data,
6064
children,
61-
}: ComponentTemplateProps<P, D>) => {
65+
}: ComponentTemplateProps<UnmappedProps, Props, Data>) => {
6266
const theme = useTheme()
6367

6468
const [settings, setSettings] = useState(initialProperties)
@@ -100,7 +104,7 @@ export const ComponentTemplate = <P extends object = any, D = any>({
100104
<ComponentHeader chartClass={name} tags={tags} />
101105
<ComponentFlavorSelector flavors={flavors} current={currentFlavor} />
102106
<ComponentDescription description={meta.description} />
103-
<ComponentTabs<D>
107+
<ComponentTabs<Data>
104108
chartClass={icon}
105109
code={code}
106110
data={hasData ? getTabData(data!) : undefined}

‎website/src/pages/funnel/index.tsx

+47-40
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,17 @@ import meta from '../../data/components/funnel/meta.yml'
66
import mapper from '../../data/components/funnel/mapper'
77
import { groups } from '../../data/components/funnel/props'
88
import { generateLightDataSet } from '../../data/components/funnel/generator'
9+
import { FunnelDatum, FunnelSvgProps } from '@nivo/funnel/dist/types/types'
910

10-
const initialProperties = {
11+
type MappedFunnelProps = Omit<FunnelSvgProps<FunnelDatum>, 'data' | 'width' | 'height'>
12+
type UnmappedFunnelProps = Omit<MappedFunnelProps, 'valueFormat'> & {
13+
valueFormat: {
14+
format: string
15+
enabled: boolean
16+
}
17+
}
18+
19+
const initialProperties: UnmappedFunnelProps = {
1120
margin: {
1221
top: 20,
1322
right: 20,
@@ -21,7 +30,7 @@ const initialProperties = {
2130
spacing: svgDefaultProps.spacing,
2231
valueFormat: { format: '>-.4s', enabled: true },
2332

24-
colors: { scheme: 'spectral' },
33+
colors: { scheme: 'spectral' as const },
2534
fillOpacity: svgDefaultProps.fillOpacity,
2635

2736
borderWidth: 20,
@@ -43,46 +52,44 @@ const initialProperties = {
4352
currentBorderWidth: 40,
4453

4554
animate: true,
46-
motionConfig: 'wobbly',
55+
motionConfig: 'wobbly' as const,
4756
}
4857

49-
const Funnel = () => {
50-
return (
51-
<ComponentTemplate
52-
name="Funnel"
53-
meta={meta.Funnel}
54-
icon="funnel"
55-
flavors={meta.flavors}
56-
currentFlavor="svg"
57-
properties={groups}
58-
initialProperties={initialProperties}
59-
defaultProperties={svgDefaultProps}
60-
propertiesMapper={mapper}
61-
generateData={generateLightDataSet}
62-
>
63-
{(properties, data, theme, logAction) => (
64-
<ResponsiveFunnel
65-
data={data}
66-
{...properties}
67-
theme={merge({}, theme, {
68-
labels: {
69-
text: {
70-
fontSize: 14,
71-
},
58+
const Funnel = () => (
59+
<ComponentTemplate<UnmappedFunnelProps, MappedFunnelProps, FunnelDatum[]>
60+
name="Funnel"
61+
meta={meta.Funnel}
62+
icon="funnel"
63+
flavors={meta.flavors}
64+
currentFlavor="svg"
65+
properties={groups}
66+
initialProperties={initialProperties}
67+
defaultProperties={svgDefaultProps}
68+
propertiesMapper={mapper}
69+
generateData={generateLightDataSet}
70+
>
71+
{(properties, data, theme, logAction) => (
72+
<ResponsiveFunnel
73+
data={data}
74+
{...properties}
75+
theme={merge({}, theme, {
76+
labels: {
77+
text: {
78+
fontSize: 14,
7279
},
73-
})}
74-
onClick={part => {
75-
logAction({
76-
type: 'click',
77-
label: `[part] id: ${part.data.id}, value: ${part.data.value}`,
78-
color: part.color,
79-
data: part.data,
80-
})
81-
}}
82-
/>
83-
)}
84-
</ComponentTemplate>
85-
)
86-
}
80+
},
81+
})}
82+
onClick={part => {
83+
logAction({
84+
type: 'click',
85+
label: `[part] id: ${part.data.id}, value: ${part.formattedValue}`,
86+
color: part.color,
87+
data: part.data,
88+
})
89+
}}
90+
/>
91+
)}
92+
</ComponentTemplate>
93+
)
8794

8895
export default Funnel

‎website/src/pages/sankey/index.tsx

+64-48
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
11
import React from 'react'
22
import omit from 'lodash/omit'
33
import { generateSankeyData } from '@nivo/generators'
4-
import { ResponsiveSankey, svgDefaultProps } from '@nivo/sankey'
4+
import {
5+
ResponsiveSankey,
6+
svgDefaultProps,
7+
SankeySvgProps,
8+
DefaultNode,
9+
DefaultLink,
10+
} from '@nivo/sankey'
511
import { ComponentTemplate } from '../../components/components/ComponentTemplate'
612
import meta from '../../data/components/sankey/meta.yml'
713
import mapper from '../../data/components/sankey/mapper'
814
import { groups } from '../../data/components/sankey/props'
915

10-
const initialProperties = {
16+
type MappedSankeyProps = Omit<SankeySvgProps<DefaultNode, DefaultLink>, 'data' | 'width' | 'height'>
17+
type UnmappedSankeyProps = Omit<MappedSankeyProps, 'valueFormat'> & {
18+
valueFormat: {
19+
format: string
20+
enabled: boolean
21+
}
22+
}
23+
24+
const initialProperties: UnmappedSankeyProps = {
1125
margin: {
1226
top: 40,
1327
right: 160,
@@ -84,52 +98,54 @@ const initialProperties = {
8498

8599
const generateData = () => generateSankeyData({ nodeCount: 6, maxIterations: 8 })
86100

87-
const Sankey = () => {
88-
return (
89-
<ComponentTemplate
90-
name="Sankey"
91-
meta={meta.Sankey}
92-
icon="sankey"
93-
flavors={meta.flavors}
94-
currentFlavor="svg"
95-
properties={groups}
96-
initialProperties={initialProperties}
97-
defaultProperties={svgDefaultProps}
98-
propertiesMapper={mapper}
99-
generateData={generateData}
100-
>
101-
{(properties, data, theme, logAction) => {
102-
return (
103-
<ResponsiveSankey
104-
data={data}
105-
{...properties}
106-
theme={theme}
107-
onClick={node => {
108-
let label
109-
if (node.id) {
110-
label = `[node] ${node.id}: ${node.value}`
111-
} else {
112-
label = `[link] ${node.source.id} > ${node.target.id}: ${node.value}`
113-
}
101+
const Sankey = () => (
102+
<ComponentTemplate<
103+
UnmappedSankeyProps,
104+
MappedSankeyProps,
105+
SankeySvgProps<DefaultNode, DefaultLink>['data']
106+
>
107+
name="Sankey"
108+
meta={meta.Sankey}
109+
icon="sankey"
110+
flavors={meta.flavors}
111+
currentFlavor="svg"
112+
properties={groups}
113+
initialProperties={initialProperties}
114+
defaultProperties={svgDefaultProps}
115+
propertiesMapper={mapper}
116+
generateData={generateData}
117+
>
118+
{(properties, data, theme, logAction) => {
119+
return (
120+
<ResponsiveSankey
121+
data={data}
122+
{...properties}
123+
theme={theme}
124+
onClick={node => {
125+
let label
126+
if ('id' in node) {
127+
label = `[node] ${node.id}: ${node.value}`
128+
} else {
129+
label = `[link] ${node.source.id} > ${node.target.id}: ${node.value}`
130+
}
114131

115-
logAction({
116-
type: 'click',
117-
label,
118-
data: omit(node, [
119-
'sourceLinks',
120-
'targetLinks',
121-
'source.sourceLinks',
122-
'source.targetLinks',
123-
'target.sourceLinks',
124-
'target.targetLinks',
125-
]),
126-
})
127-
}}
128-
/>
129-
)
130-
}}
131-
</ComponentTemplate>
132-
)
133-
}
132+
logAction({
133+
type: 'click',
134+
label,
135+
data: omit(node, [
136+
'sourceLinks',
137+
'targetLinks',
138+
'source.sourceLinks',
139+
'source.targetLinks',
140+
'target.sourceLinks',
141+
'target.targetLinks',
142+
]),
143+
})
144+
}}
145+
/>
146+
)
147+
}}
148+
</ComponentTemplate>
149+
)
134150

135151
export default Sankey

0 commit comments

Comments
 (0)
Please sign in to comment.