1
+ import CircularProgress , {
2
+ type CircularProgressProps ,
3
+ } from "@mui/material/CircularProgress" ;
4
+ import { type Interpolation , type Theme } from "@emotion/react" ;
1
5
import {
2
6
type FC ,
7
+ forwardRef ,
8
+ type HTMLAttributes ,
3
9
type ReactNode ,
4
10
useMemo ,
5
- forwardRef ,
6
- HTMLAttributes ,
7
11
} from "react" ;
8
- import { useTheme , type Interpolation , type Theme } from "@emotion/react" ;
9
12
import type { ThemeRole } from "theme/experimental" ;
10
- import CircularProgress , {
11
- CircularProgressProps ,
12
- } from "@mui/material/CircularProgress" ;
13
-
14
- export type PillType = ThemeRole | keyof typeof themeOverrides ;
15
13
16
14
export type PillProps = HTMLAttributes < HTMLDivElement > & {
17
15
icon ?: ReactNode ;
18
- type ?: PillType ;
16
+ type ?: ThemeRole ;
19
17
} ;
20
18
21
- const themeOverrides = {
22
- neutral : ( theme ) => ( {
23
- backgroundColor : theme . experimental . l1 . background ,
24
- borderColor : theme . experimental . l1 . outline ,
25
- } ) ,
26
- } satisfies Record < string , Interpolation < Theme > > ;
27
-
28
19
const themeStyles = ( type : ThemeRole ) => ( theme : Theme ) => {
29
20
const palette = theme . experimental . roles [ type ] ;
30
21
return {
@@ -39,43 +30,13 @@ const PILL_ICON_SPACING = (PILL_HEIGHT - PILL_ICON_SIZE) / 2;
39
30
40
31
export const Pill : FC < PillProps > = forwardRef < HTMLDivElement , PillProps > (
41
32
( props , ref ) => {
42
- const { icon, type = "neutral" , children, ...divProps } = props ;
43
- const theme = useTheme ( ) ;
44
- const typeStyles = useMemo ( ( ) => {
45
- if ( type in themeOverrides ) {
46
- return themeOverrides [ type as keyof typeof themeOverrides ] ;
47
- }
48
- return themeStyles ( type as ThemeRole ) ;
49
- } , [ type ] ) ;
33
+ const { icon, type = "inactive" , children, ...divProps } = props ;
34
+ const typeStyles = useMemo ( ( ) => themeStyles ( type ) , [ type ] ) ;
50
35
51
36
return (
52
37
< div
53
38
ref = { ref }
54
- css = { [
55
- {
56
- fontSize : 12 ,
57
- color : theme . experimental . l1 . text ,
58
- cursor : "default" ,
59
- display : "inline-flex" ,
60
- alignItems : "center" ,
61
- whiteSpace : "nowrap" ,
62
- fontWeight : 400 ,
63
- borderWidth : 1 ,
64
- borderStyle : "solid" ,
65
- borderRadius : 99999 ,
66
- lineHeight : 1 ,
67
- height : PILL_HEIGHT ,
68
- gap : PILL_ICON_SPACING ,
69
- paddingRight : 12 ,
70
- paddingLeft : icon ? PILL_ICON_SPACING : 12 ,
71
-
72
- "& svg" : {
73
- width : PILL_ICON_SIZE ,
74
- height : PILL_ICON_SIZE ,
75
- } ,
76
- } ,
77
- typeStyles ,
78
- ] }
39
+ css = { [ styles . pill , icon && styles . pillWithIcon , typeStyles ] }
79
40
{ ...divProps }
80
41
>
81
42
{ icon }
@@ -85,18 +46,45 @@ export const Pill: FC<PillProps> = forwardRef<HTMLDivElement, PillProps>(
85
46
} ,
86
47
) ;
87
48
88
- export const PillSpinner = ( props : CircularProgressProps ) => {
49
+ export const PillSpinner : FC < CircularProgressProps > = ( props ) => {
89
50
return (
90
- < CircularProgress
91
- size = { PILL_ICON_SIZE }
92
- css = { ( theme ) => ( {
93
- color : theme . experimental . l1 . text ,
94
- // It is necessary to align it with the MUI Icons internal padding
95
- "& svg" : {
96
- transform : "scale(.75)" ,
97
- } ,
98
- } ) }
99
- { ...props }
100
- />
51
+ < CircularProgress size = { PILL_ICON_SIZE } css = { styles . spinner } { ...props } />
101
52
) ;
102
53
} ;
54
+
55
+ const styles = {
56
+ pill : ( theme ) => ( {
57
+ fontSize : 12 ,
58
+ color : theme . experimental . l1 . text ,
59
+ cursor : "default" ,
60
+ display : "inline-flex" ,
61
+ alignItems : "center" ,
62
+ whiteSpace : "nowrap" ,
63
+ fontWeight : 400 ,
64
+ borderWidth : 1 ,
65
+ borderStyle : "solid" ,
66
+ borderRadius : 99999 ,
67
+ lineHeight : 1 ,
68
+ height : PILL_HEIGHT ,
69
+ gap : PILL_ICON_SPACING ,
70
+ paddingLeft : 12 ,
71
+ paddingRight : 12 ,
72
+
73
+ "& svg" : {
74
+ width : PILL_ICON_SIZE ,
75
+ height : PILL_ICON_SIZE ,
76
+ } ,
77
+ } ) ,
78
+
79
+ pillWithIcon : {
80
+ paddingLeft : PILL_ICON_SPACING ,
81
+ } ,
82
+
83
+ spinner : ( theme ) => ( {
84
+ color : theme . experimental . l1 . text ,
85
+ // It is necessary to align it with the MUI Icons internal padding
86
+ "& svg" : {
87
+ transform : "scale(.75)" ,
88
+ } ,
89
+ } ) ,
90
+ } satisfies Record < string , Interpolation < Theme > > ;
0 commit comments