1- import React , { useState , useEffect , useRef } from 'react'
2- import { Box , Flex } from 'theme-ui'
1+ import React , {
2+ useState ,
3+ useEffect ,
4+ useRef ,
5+ ReactNode ,
6+ MouseEventHandler ,
7+ } from 'react'
8+ import { Box , Flex , FlexProps , ThemeUIStyleObject , get } from 'theme-ui'
39
10+ type SetClim = ( setter : ( prev : [ number , number ] ) => [ number , number ] ) => any
11+
12+ export interface ColorbarProps extends FlexProps {
13+ colormap : string [ ]
14+ label : ReactNode
15+ clim : [ number , number ]
16+ setClim ?: SetClim
17+ setClimStep ?: number
18+ units : ReactNode
19+ width : string
20+ height : string
21+ format ?: ( d : number ) => ReactNode
22+ discrete ?: boolean
23+ horizontal ?: boolean
24+ bottom ?: boolean
25+ sx ?: ThemeUIStyleObject
26+ sxClim ?: ThemeUIStyleObject
27+ }
428const styles = {
5- clim : ( setClim ) => {
29+ clim : ( setClim ?: SetClim ) : ThemeUIStyleObject & { userSelect : any } => {
630 return {
731 bg : 'unset' ,
832 border : 'none' ,
@@ -25,7 +49,7 @@ const DIMENSIONS = {
2549 height : [ '80px' , '110px' , '110px' , '130px' ] ,
2650}
2751
28- const hexToRgb = ( hex ) => {
52+ const hexToRgb = ( hex : string ) => {
2953 let result = / ^ # ? ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) ( [ a - f \d ] { 2 } ) $ / i. exec ( hex )
3054 return result
3155 ? `${ parseInt ( result [ 1 ] , 16 ) } , ${ parseInt ( result [ 2 ] , 16 ) } , ${ parseInt (
@@ -35,7 +59,16 @@ const hexToRgb = (hex) => {
3559 : null
3660}
3761
38- const Gradient = ( { colormap, discrete, horizontal, width, height } ) => {
62+ const Gradient = ( {
63+ colormap,
64+ discrete,
65+ horizontal,
66+ width,
67+ height,
68+ } : Pick <
69+ ColorbarProps ,
70+ 'colormap' | 'discrete' | 'horizontal' | 'width' | 'height'
71+ > ) => {
3972 const step = ( 1 / colormap . length ) * 100
4073 const isHex = String ( colormap [ 0 ] ) . startsWith ( '#' )
4174 const values = colormap . map ( ( color , i ) => {
@@ -63,20 +96,26 @@ const Gradient = ({ colormap, discrete, horizontal, width, height }) => {
6396 minHeight : height || DIMENSIONS . height ,
6497 } ) ,
6598 mt : horizontal ? [ '1px' , '1px' , '1px' , 0 ] : 0 ,
66- border : ( { colors } ) => `solid 1px ${ colors . hinted } ` ,
99+ border : ( t ) => `solid 1px ${ get ( t , ' colors.hinted' ) } ` ,
67100 background : css ,
68101 } }
69102 />
70103 )
71104}
72105
73- const Label = ( { label, units, horizontal } ) => (
106+ const Label = ( {
107+ label,
108+ units,
109+ horizontal,
110+ } : Pick < ColorbarProps , 'label' | 'units' | 'horizontal' > ) => (
74111 < Box
75112 sx = {
76- ! horizontal && {
77- width : [ '13px' , '17px' , '17px' , '19px' ] ,
78- alignSelf : 'flex-end' ,
79- }
113+ horizontal
114+ ? undefined
115+ : {
116+ width : [ '13px' , '17px' , '17px' , '19px' ] ,
117+ alignSelf : 'flex-end' ,
118+ }
80119 }
81120 >
82121 < Box
@@ -128,24 +167,25 @@ const Colorbar = ({
128167 sx,
129168 sxClim,
130169 ...props
131- } ) => {
170+ } : ColorbarProps ) => {
132171 if ( ! Array . isArray ( colormap ) ) {
133172 throw new Error ( `expected array for colormap, got '${ colormap } '.` )
134173 }
135174
136- const climRef = [ useRef ( ) , useRef ( ) ]
175+ const climRef = [ useRef < HTMLDivElement > ( ) , useRef < HTMLDivElement > ( ) ]
137176 const [ climMinDragging , setClimMinDragging ] = useState ( false )
138177 const [ climMaxDragging , setClimMaxDragging ] = useState ( false )
139178
140- let x ,
141- y ,
142- dx ,
143- dy = 0
144- let id = null
179+ let x : number ,
180+ y : number ,
181+ dx : number ,
182+ dy : number = 0
183+ let id : null | string = null
145184 let init = [ 0 , 0 ]
146185 let scale = setClimStep
147186
148- const draggingFunction = ( e ) => {
187+ const draggingFunction = ( e : MouseEvent ) => {
188+ if ( ! setClim ) return
149189 if ( id === 'min' && ! climMinDragging ) setClimMinDragging ( true )
150190 if ( id === 'max' && ! climMaxDragging ) setClimMaxDragging ( true )
151191 dx = e . pageX - x
@@ -163,10 +203,10 @@ const Colorbar = ({
163203 }
164204 }
165205
166- const handleMouseDown = ( e ) => {
206+ const handleMouseDown : MouseEventHandler < HTMLDivElement > = ( e ) => {
167207 y = e . pageY
168208 x = e . pageX
169- id = e . target . id
209+ id = ( e . target as HTMLDivElement ) . id
170210 init = clim
171211
172212 document . body . setAttribute (
@@ -186,7 +226,9 @@ const Colorbar = ({
186226 window . addEventListener ( 'mouseup' , updater )
187227 }
188228
189- const increment = ( e ) => {
229+ const increment = ( e : KeyboardEvent ) => {
230+ if ( ! setClim ) return
231+
190232 if ( climRef [ 0 ] . current === document . activeElement ) {
191233 e . preventDefault ( )
192234 setClim ( ( prev ) => [ Math . min ( prev [ 0 ] + scale , prev [ 1 ] ) , prev [ 1 ] ] )
@@ -199,7 +241,9 @@ const Colorbar = ({
199241 }
200242 }
201243
202- const decrement = ( e ) => {
244+ const decrement = ( e : KeyboardEvent ) => {
245+ if ( ! setClim ) return
246+
203247 if ( climRef [ 0 ] . current === document . activeElement ) {
204248 e . preventDefault ( )
205249 setClim ( ( prev ) => [ Math . min ( prev [ 0 ] - scale , prev [ 1 ] ) , prev [ 1 ] ] )
@@ -213,7 +257,7 @@ const Colorbar = ({
213257 }
214258
215259 useEffect ( ( ) => {
216- const listener = ( e ) => {
260+ const listener = ( e : KeyboardEvent ) => {
217261 if (
218262 [ 'ArrowUp' , 'ArrowRight' ] . includes ( e . code ) ||
219263 [ 'ArrowUp' , 'ArrowRight' ] . includes ( e . key )
@@ -253,7 +297,7 @@ const Colorbar = ({
253297 mr : horizontal ? [ '2px' , '1px' , '1px' , '2px' ] : 0 ,
254298 mb : horizontal ? 0 : [ '-2px' , '-2px' , '-2px' , '-3px' ] ,
255299 borderBottom : setClim
256- ? ( { colors } ) => `solid 1px ${ colors . primary } `
300+ ? ( t ) => `solid 1px ${ get ( t , ' colors.primary' ) } `
257301 : 'unset' ,
258302 cursor : setClim
259303 ? horizontal
@@ -263,7 +307,7 @@ const Colorbar = ({
263307 ...sxClim ,
264308 } }
265309 onMouseDown = { setClim ? handleMouseDown : ( ) => { } }
266- onClick = { ( ) => climRef [ 0 ] . current . focus ( ) }
310+ onClick = { ( ) => climRef [ 0 ] . current ? .focus ( ) }
267311 >
268312 { format ( clim [ 0 ] ) }
269313 </ Box >
@@ -284,7 +328,7 @@ const Colorbar = ({
284328 : [ '2px' , '1px' , '1px' , '2px' ] ,
285329 mt : horizontal ? 0 : [ '-2px' , '-3px' , '-3px' , '-3px' ] ,
286330 borderBottom : setClim
287- ? ( { colors } ) => `solid 1px ${ colors . primary } `
331+ ? ( t ) => `solid 1px ${ get ( t , ' colors.primary' ) } `
288332 : 'unset' ,
289333 cursor : setClim
290334 ? horizontal
@@ -294,7 +338,7 @@ const Colorbar = ({
294338 ...sxClim ,
295339 } }
296340 onMouseDown = { setClim ? handleMouseDown : ( ) => { } }
297- onClick = { ( ) => climRef [ 1 ] . current . focus ( ) }
341+ onClick = { ( ) => climRef [ 1 ] . current ? .focus ( ) }
298342 >
299343 { format ( clim [ 1 ] ) }
300344 </ Box >
0 commit comments