1
- import { css } from "@emotion/css" ;
2
- import { useTheme , type Interpolation , type Theme } from "@emotion/react" ;
3
- import Tooltip from "@mui/material/Tooltip" ;
4
- import { forwardRef , type HTMLProps , type ReactNode } from "react" ;
1
+ import type { Interpolation , Theme } from "@emotion/react" ;
2
+ import { type ButtonHTMLAttributes , forwardRef , type HTMLProps } from "react" ;
5
3
6
- export type BarColor = {
7
- border : string ;
4
+ export type BarColors = {
5
+ stroke : string ;
8
6
fill : string ;
9
7
} ;
10
8
11
- type BarProps = Omit < HTMLProps < HTMLDivElement > , "size" | "color" > & {
12
- width : number ;
13
- children ?: ReactNode ;
9
+ type BaseBarProps < T > = Omit < T , "size" | "color" > & {
14
10
/**
15
- * Color scheme for the bar. If not passed the default gray color will be
16
- * used.
17
- */
18
- color ?: BarColor ;
19
- /**
20
- * Label to be displayed adjacent to the bar component.
11
+ * The width of the bar component.
21
12
*/
22
- afterLabel ?: ReactNode ;
13
+ size : number ;
23
14
/**
24
15
* The X position of the bar component.
25
16
*/
26
- x ? : number ;
17
+ offset : number ;
27
18
/**
28
- * The tooltip content for the bar.
19
+ * Color scheme for the bar. If not passed the default gray color will be
20
+ * used.
29
21
*/
30
- tooltip ?: ReactNode ;
22
+ colors ?: BarColors ;
31
23
} ;
32
24
25
+ type BarProps = BaseBarProps < HTMLProps < HTMLDivElement > > ;
26
+
33
27
export const Bar = forwardRef < HTMLDivElement , BarProps > (
34
- ( { color, width, afterLabel, children, x, tooltip, ...htmlProps } , ref ) => {
35
- const theme = useTheme ( ) ;
36
- const row = (
37
- < div
38
- ref = { ref }
39
- css = { [ styles . row , { transform : `translateX(${ x } px)` } ] }
40
- { ...htmlProps }
41
- >
42
- < button
43
- type = "button"
44
- css = { [
45
- styles . bar ,
46
- {
47
- width,
48
- backgroundColor : color ?. fill ,
49
- borderColor : color ?. border ,
50
- } ,
51
- ] }
52
- disabled = { htmlProps . disabled }
53
- aria-labelledby = { htmlProps [ "aria-labelledby" ] }
54
- >
55
- { children }
56
- </ button >
57
- { afterLabel }
58
- </ div >
28
+ ( { colors, size, children, offset, ...htmlProps } , ref ) => {
29
+ return (
30
+ < div css = { barCss ( { colors, size, offset } ) } { ...htmlProps } ref = { ref } />
59
31
) ;
32
+ } ,
33
+ ) ;
60
34
61
- if ( tooltip ) {
62
- return (
63
- < Tooltip
64
- placement = "top-start"
65
- classes = { {
66
- tooltip : css ( {
67
- backgroundColor : theme . palette . background . default ,
68
- border : `1px solid ${ theme . palette . divider } ` ,
69
- width : 220 ,
70
- } ) ,
71
- } }
72
- title = { tooltip }
73
- >
74
- { row }
75
- </ Tooltip >
76
- ) ;
77
- }
35
+ type ClickableBarProps = BaseBarProps < ButtonHTMLAttributes < HTMLButtonElement > > ;
78
36
79
- return row ;
37
+ export const ClickableBar = forwardRef < HTMLButtonElement , ClickableBarProps > (
38
+ ( { colors, size, offset, ...htmlProps } , ref ) => {
39
+ return (
40
+ < button
41
+ type = "button"
42
+ css = { [ ...barCss ( { colors, size, offset } ) , styles . clickable ] }
43
+ { ...htmlProps }
44
+ ref = { ref }
45
+ />
46
+ ) ;
80
47
} ,
81
48
) ;
82
49
50
+ export const barCss = ( { size, colors, offset } : BaseBarProps < unknown > ) => {
51
+ return [
52
+ styles . bar ,
53
+ {
54
+ width : size ,
55
+ backgroundColor : colors ?. fill ,
56
+ borderColor : colors ?. stroke ,
57
+ marginLeft : offset ,
58
+ } ,
59
+ ] ;
60
+ } ;
61
+
83
62
const styles = {
84
- row : {
85
- // Stack children horizontally for adjacent labels
86
- display : "flex" ,
87
- alignItems : "center" ,
88
- width : "fit-content" ,
89
- gap : 8 ,
90
- cursor : "pointer" ,
91
- } ,
92
63
bar : ( theme ) => ( {
93
64
border : "1px solid" ,
94
65
borderColor : theme . palette . divider ,
@@ -98,14 +69,13 @@ const styles = {
98
69
display : "flex" ,
99
70
padding : 0 ,
100
71
minWidth : 8 ,
72
+ } ) ,
73
+ clickable : {
74
+ cursor : "pointer" ,
101
75
102
- "&:not(:disabled)" : {
103
- cursor : "pointer" ,
104
-
105
- "&:focus, &:hover, &:active" : {
106
- outline : "none" ,
107
- borderColor : "#38BDF8" ,
108
- } ,
76
+ "&:focus, &:hover, &:active" : {
77
+ outline : "none" ,
78
+ borderColor : "#38BDF8" ,
109
79
} ,
110
- } ) ,
80
+ } ,
111
81
} satisfies Record < string , Interpolation < Theme > > ;
0 commit comments