rouse-ui-kit 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +5465 -0
- package/dist/index.umd.cjs +103 -0
- package/package.json +40 -0
- package/src/App.tsx +435 -0
- package/src/components/Button/ButtonContained.tsx +37 -0
- package/src/components/Button/ButtonOutlined.tsx +37 -0
- package/src/components/Button/ButtonText.tsx +36 -0
- package/src/components/Button/index.ts +3 -0
- package/src/components/Checkbox/Checkbox.tsx +41 -0
- package/src/components/Checkbox/index.ts +1 -0
- package/src/components/Chip/ChipFilled.tsx +110 -0
- package/src/components/Chip/ChipOutlined.tsx +107 -0
- package/src/components/Chip/ChipStatus.tsx +59 -0
- package/src/components/Chip/ChipStatusOutlined.tsx +59 -0
- package/src/components/Chip/index.ts +7 -0
- package/src/components/IconButton/IconButtonOutlined.tsx +67 -0
- package/src/components/IconButton/index.ts +1 -0
- package/src/components/Label/LabelFilled.tsx +84 -0
- package/src/components/Label/LabelOutlined.tsx +85 -0
- package/src/components/Label/index.ts +3 -0
- package/src/components/Menu/Menu.tsx +205 -0
- package/src/components/Menu/index.ts +2 -0
- package/src/components/Select/SelectOutlined.tsx +77 -0
- package/src/components/Select/index.ts +1 -0
- package/src/components/TextField/TextFieldOutlined.tsx +104 -0
- package/src/components/TextField/index.ts +1 -0
- package/src/design-tokens.ts +120 -0
- package/src/index.ts +32 -0
- package/src/main.tsx +13 -0
- package/src/theme.ts +220 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import CloseIcon from "@mui/icons-material/Close";
|
|
2
|
+
import { Box, Chip } from "@mui/material";
|
|
3
|
+
|
|
4
|
+
export type ChipColor = "primary" | "secondary";
|
|
5
|
+
|
|
6
|
+
const colorConfig = {
|
|
7
|
+
primary: {
|
|
8
|
+
enabled: { bg: "#e5e5e5", text: "#191919" }, // --light/gray/10, --light/text/primary
|
|
9
|
+
hovered: { bg: "#4c4c4c", text: "#ffffff" }, // --light/primary/main
|
|
10
|
+
selected: { bg: "#191919", text: "#ffffff" }, // --light/primary/dark
|
|
11
|
+
disabled: { bg: "#e5e5e5", text: "#999999" },
|
|
12
|
+
},
|
|
13
|
+
secondary: {
|
|
14
|
+
enabled: { bg: "#eef1fc", text: "#2c4d9e" }, // --light/secondary/tint/main
|
|
15
|
+
hovered: { bg: "#2c4d9e", text: "#eef1fc" }, // --light/secondary/main
|
|
16
|
+
selected: { bg: "#00215f", text: "#eef1fc" }, // --light/secondary/dark
|
|
17
|
+
disabled: { bg: "#e5e5e5", text: "#999999" },
|
|
18
|
+
},
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
type ChipFilledProps = {
|
|
22
|
+
label?: string;
|
|
23
|
+
color?: ChipColor;
|
|
24
|
+
selected?: boolean;
|
|
25
|
+
deletable?: boolean;
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
onClick?: () => void;
|
|
28
|
+
onDelete?: () => void;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default function ChipFilled({
|
|
32
|
+
label = "Chip",
|
|
33
|
+
color = "primary",
|
|
34
|
+
selected = false,
|
|
35
|
+
deletable = false,
|
|
36
|
+
disabled = false,
|
|
37
|
+
onClick,
|
|
38
|
+
onDelete,
|
|
39
|
+
}: ChipFilledProps) {
|
|
40
|
+
const cfg = colorConfig[color];
|
|
41
|
+
const stateBg = disabled ? cfg.disabled.bg : selected ? cfg.selected.bg : cfg.enabled.bg;
|
|
42
|
+
const stateText = disabled ? cfg.disabled.text : selected ? cfg.selected.text : cfg.enabled.text;
|
|
43
|
+
const hoverBg = cfg.hovered.bg;
|
|
44
|
+
const hoverText = cfg.hovered.text;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
// Outer pill: shows #dee0ff background on keyboard focus (Figma "Focused" state)
|
|
48
|
+
<Box
|
|
49
|
+
sx={{
|
|
50
|
+
display: "inline-flex",
|
|
51
|
+
borderRadius: "100px",
|
|
52
|
+
"&:focus-within": {
|
|
53
|
+
bgcolor: "#dee0ff", // --light/blue/10
|
|
54
|
+
},
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
<Chip
|
|
58
|
+
label={label}
|
|
59
|
+
size="small"
|
|
60
|
+
disabled={disabled}
|
|
61
|
+
onClick={onClick}
|
|
62
|
+
onDelete={deletable ? onDelete : undefined}
|
|
63
|
+
deleteIcon={<CloseIcon />}
|
|
64
|
+
sx={{
|
|
65
|
+
height: "auto",
|
|
66
|
+
borderRadius: "100px",
|
|
67
|
+
bgcolor: stateBg,
|
|
68
|
+
// Hover: skip when disabled or already selected
|
|
69
|
+
...(!disabled && !selected && {
|
|
70
|
+
"&:hover": {
|
|
71
|
+
bgcolor: `${hoverBg} !important`,
|
|
72
|
+
"& .MuiChip-label": { color: hoverText },
|
|
73
|
+
"& .MuiChip-deleteIcon": { color: `${hoverText} !important` },
|
|
74
|
+
},
|
|
75
|
+
}),
|
|
76
|
+
// Keyboard focus: chip itself becomes transparent (bg shown by outer Box)
|
|
77
|
+
"&:focus-visible": {
|
|
78
|
+
bgcolor: "transparent",
|
|
79
|
+
boxShadow: "none",
|
|
80
|
+
outline: "none",
|
|
81
|
+
},
|
|
82
|
+
// Disabled: restore opacity so colors aren't dimmed by MUI
|
|
83
|
+
"&.Mui-disabled": {
|
|
84
|
+
opacity: 1,
|
|
85
|
+
bgcolor: cfg.disabled.bg,
|
|
86
|
+
"& .MuiChip-label": { color: cfg.disabled.text },
|
|
87
|
+
"& .MuiChip-deleteIcon": { color: `${cfg.disabled.text} !important` },
|
|
88
|
+
},
|
|
89
|
+
// Label
|
|
90
|
+
"& .MuiChip-label": {
|
|
91
|
+
px: "10px",
|
|
92
|
+
py: "3px",
|
|
93
|
+
fontSize: 13,
|
|
94
|
+
fontWeight: 400,
|
|
95
|
+
lineHeight: "18px",
|
|
96
|
+
letterSpacing: "0.16px",
|
|
97
|
+
color: stateText,
|
|
98
|
+
},
|
|
99
|
+
// Close icon
|
|
100
|
+
"& .MuiChip-deleteIcon": {
|
|
101
|
+
fontSize: 14,
|
|
102
|
+
color: `${stateText} !important`,
|
|
103
|
+
mr: "10px",
|
|
104
|
+
ml: 0,
|
|
105
|
+
},
|
|
106
|
+
}}
|
|
107
|
+
/>
|
|
108
|
+
</Box>
|
|
109
|
+
);
|
|
110
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import CloseIcon from "@mui/icons-material/Close";
|
|
2
|
+
import { Chip } from "@mui/material";
|
|
3
|
+
import type { ChipColor } from "./ChipFilled";
|
|
4
|
+
|
|
5
|
+
const colorConfig = {
|
|
6
|
+
primary: {
|
|
7
|
+
border: "#b2b2b2", // --light/gray/30
|
|
8
|
+
borderDisabled: "rgba(0, 0, 0, 0.23)", // --light/other/outlined-border
|
|
9
|
+
text: "#191919", // --light/text/primary
|
|
10
|
+
textDisabled: "#999999",
|
|
11
|
+
hoverBg: "rgba(0, 0, 0, 0.04)", // --light/light/hover
|
|
12
|
+
selectedBg: "rgba(0, 0, 0, 0.08)", // --light/light/selected
|
|
13
|
+
focusBg: "#dee0ff", // --light/blue/10
|
|
14
|
+
},
|
|
15
|
+
secondary: {
|
|
16
|
+
border: "#6f8de3", // --light/secondary/light
|
|
17
|
+
borderDisabled: "rgba(0, 0, 0, 0.23)",
|
|
18
|
+
text: "#2c4d9e", // --light/secondary/main
|
|
19
|
+
textDisabled: "#999999",
|
|
20
|
+
hoverBg: "rgba(44, 77, 158, 0.04)", // --light/secondary/shade/4p
|
|
21
|
+
selectedBg: "rgba(44, 77, 158, 0.12)", // --light/secondary/shade/12p
|
|
22
|
+
focusBg: "#dee0ff",
|
|
23
|
+
},
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
type ChipOutlinedProps = {
|
|
27
|
+
label?: string;
|
|
28
|
+
color?: ChipColor;
|
|
29
|
+
selected?: boolean;
|
|
30
|
+
deletable?: boolean;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
onClick?: () => void;
|
|
33
|
+
onDelete?: () => void;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default function ChipOutlined({
|
|
37
|
+
label = "Chip",
|
|
38
|
+
color = "primary",
|
|
39
|
+
selected = false,
|
|
40
|
+
deletable = false,
|
|
41
|
+
disabled = false,
|
|
42
|
+
onClick,
|
|
43
|
+
onDelete,
|
|
44
|
+
}: ChipOutlinedProps) {
|
|
45
|
+
const cfg = colorConfig[color];
|
|
46
|
+
const borderColor = disabled ? cfg.borderDisabled : cfg.border;
|
|
47
|
+
const textColor = disabled ? cfg.textDisabled : cfg.text;
|
|
48
|
+
const bgColor = selected ? cfg.selectedBg : "transparent";
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Chip
|
|
52
|
+
label={label}
|
|
53
|
+
size="small"
|
|
54
|
+
variant="outlined"
|
|
55
|
+
disabled={disabled}
|
|
56
|
+
onClick={onClick}
|
|
57
|
+
onDelete={deletable ? onDelete : undefined}
|
|
58
|
+
deleteIcon={<CloseIcon />}
|
|
59
|
+
sx={{
|
|
60
|
+
height: "auto",
|
|
61
|
+
borderRadius: "100px",
|
|
62
|
+
border: `1px solid ${borderColor}`,
|
|
63
|
+
bgcolor: bgColor,
|
|
64
|
+
color: textColor,
|
|
65
|
+
// Hover
|
|
66
|
+
...(!disabled && {
|
|
67
|
+
"&:hover": {
|
|
68
|
+
bgcolor: `${cfg.hoverBg} !important`,
|
|
69
|
+
border: `1px solid ${cfg.border}`,
|
|
70
|
+
},
|
|
71
|
+
}),
|
|
72
|
+
// Keyboard focus — bg directly on the chip (no outer wrapper needed)
|
|
73
|
+
"&:focus-visible": {
|
|
74
|
+
bgcolor: `${cfg.focusBg} !important`,
|
|
75
|
+
border: `1px solid ${cfg.border}`,
|
|
76
|
+
boxShadow: "none",
|
|
77
|
+
outline: "none",
|
|
78
|
+
},
|
|
79
|
+
// Disabled
|
|
80
|
+
"&.Mui-disabled": {
|
|
81
|
+
opacity: 1,
|
|
82
|
+
bgcolor: "transparent",
|
|
83
|
+
border: `1px solid ${cfg.borderDisabled}`,
|
|
84
|
+
"& .MuiChip-label": { color: cfg.textDisabled },
|
|
85
|
+
"& .MuiChip-deleteIcon": { color: `${cfg.textDisabled} !important` },
|
|
86
|
+
},
|
|
87
|
+
// Label slot
|
|
88
|
+
"& .MuiChip-label": {
|
|
89
|
+
px: "10px",
|
|
90
|
+
py: "3px",
|
|
91
|
+
fontSize: 13,
|
|
92
|
+
fontWeight: 400,
|
|
93
|
+
lineHeight: "18px",
|
|
94
|
+
letterSpacing: "0.16px",
|
|
95
|
+
color: textColor,
|
|
96
|
+
},
|
|
97
|
+
// Close icon slot
|
|
98
|
+
"& .MuiChip-deleteIcon": {
|
|
99
|
+
fontSize: 14,
|
|
100
|
+
color: `${textColor} !important`,
|
|
101
|
+
mr: "10px",
|
|
102
|
+
ml: 0,
|
|
103
|
+
},
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import SignalCellularAltIcon from "@mui/icons-material/SignalCellularAlt";
|
|
2
|
+
import { Box, Typography } from "@mui/material";
|
|
3
|
+
import type { ElementType } from "react";
|
|
4
|
+
|
|
5
|
+
export type ChipStatusColor = "default" | "primary" | "secondary";
|
|
6
|
+
|
|
7
|
+
const colorConfig: Record<ChipStatusColor, { bg: string; text: string }> = {
|
|
8
|
+
default: { bg: "#e5e5e5", text: "#191919" }, // --light/gray/10, --light/text/primary
|
|
9
|
+
primary: { bg: "#4c4c4c", text: "#ffffff" }, // --light/primary/main
|
|
10
|
+
secondary: { bg: "#eef1fc", text: "#2c4d9e" }, // --light/secondary/tint, --light/secondary/main
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type ChipStatusProps = {
|
|
14
|
+
label?: string;
|
|
15
|
+
color?: ChipStatusColor;
|
|
16
|
+
icon?: boolean;
|
|
17
|
+
iconComponent?: ElementType;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default function ChipStatus({
|
|
21
|
+
label = "Chip",
|
|
22
|
+
color = "default",
|
|
23
|
+
icon = false,
|
|
24
|
+
iconComponent: Icon = SignalCellularAltIcon,
|
|
25
|
+
}: ChipStatusProps) {
|
|
26
|
+
const { bg, text } = colorConfig[color];
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Box
|
|
30
|
+
sx={{
|
|
31
|
+
display: "inline-flex",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
gap: icon ? "4px" : 0,
|
|
34
|
+
px: "10px",
|
|
35
|
+
py: "3px",
|
|
36
|
+
borderRadius: "24px",
|
|
37
|
+
bgcolor: bg,
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<Typography
|
|
41
|
+
sx={{
|
|
42
|
+
fontFamily: "Roboto, sans-serif",
|
|
43
|
+
fontWeight: 400,
|
|
44
|
+
fontSize: 13,
|
|
45
|
+
lineHeight: "18px",
|
|
46
|
+
letterSpacing: "0.16px",
|
|
47
|
+
color: text,
|
|
48
|
+
whiteSpace: "nowrap",
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{label}
|
|
52
|
+
</Typography>
|
|
53
|
+
|
|
54
|
+
{icon && (
|
|
55
|
+
<Icon sx={{ fontSize: 14, color: text, display: "block", flexShrink: 0 }} />
|
|
56
|
+
)}
|
|
57
|
+
</Box>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import SignalCellularAltIcon from "@mui/icons-material/SignalCellularAlt";
|
|
2
|
+
import { Box, Typography } from "@mui/material";
|
|
3
|
+
import type { ElementType } from "react";
|
|
4
|
+
|
|
5
|
+
export type ChipStatusOutlinedColor = "primary" | "secondary";
|
|
6
|
+
|
|
7
|
+
const colorConfig: Record<ChipStatusOutlinedColor, { border: string; text: string }> = {
|
|
8
|
+
primary: { border: "#b2b2b2", text: "#191919" }, // --light/gray/30, --light/text/primary
|
|
9
|
+
secondary: { border: "#6f8de3", text: "#2c4d9e" }, // --light/secondary/light, --light/secondary/main
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type ChipStatusOutlinedProps = {
|
|
13
|
+
label?: string;
|
|
14
|
+
color?: ChipStatusOutlinedColor;
|
|
15
|
+
icon?: boolean;
|
|
16
|
+
iconComponent?: ElementType;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export default function ChipStatusOutlined({
|
|
20
|
+
label = "Chip",
|
|
21
|
+
color = "primary",
|
|
22
|
+
icon = false,
|
|
23
|
+
iconComponent: Icon = SignalCellularAltIcon,
|
|
24
|
+
}: ChipStatusOutlinedProps) {
|
|
25
|
+
const { border, text } = colorConfig[color];
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Box
|
|
29
|
+
sx={{
|
|
30
|
+
display: "inline-flex",
|
|
31
|
+
alignItems: "center",
|
|
32
|
+
gap: icon ? "4px" : 0,
|
|
33
|
+
px: "10px",
|
|
34
|
+
py: "3px",
|
|
35
|
+
borderRadius: "24px",
|
|
36
|
+
border: `1px solid ${border}`,
|
|
37
|
+
bgcolor: "transparent",
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
<Typography
|
|
41
|
+
sx={{
|
|
42
|
+
fontFamily: "Roboto, sans-serif",
|
|
43
|
+
fontWeight: 400,
|
|
44
|
+
fontSize: 13,
|
|
45
|
+
lineHeight: "18px",
|
|
46
|
+
letterSpacing: "0.16px",
|
|
47
|
+
color: text,
|
|
48
|
+
whiteSpace: "nowrap",
|
|
49
|
+
}}
|
|
50
|
+
>
|
|
51
|
+
{label}
|
|
52
|
+
</Typography>
|
|
53
|
+
|
|
54
|
+
{icon && (
|
|
55
|
+
<Icon sx={{ fontSize: 14, color: text, display: "block", flexShrink: 0 }} />
|
|
56
|
+
)}
|
|
57
|
+
</Box>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as ChipFilled } from "./ChipFilled";
|
|
2
|
+
export { default as ChipOutlined } from "./ChipOutlined";
|
|
3
|
+
export { default as ChipStatus } from "./ChipStatus";
|
|
4
|
+
export { default as ChipStatusOutlined } from "./ChipStatusOutlined";
|
|
5
|
+
export type { ChipColor } from "./ChipFilled";
|
|
6
|
+
export type { ChipStatusColor } from "./ChipStatus";
|
|
7
|
+
export type { ChipStatusOutlinedColor } from "./ChipStatusOutlined";
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { IconButton } from "@mui/material";
|
|
2
|
+
import type { ElementType } from "react";
|
|
3
|
+
|
|
4
|
+
type Size = "large" | "medium" | "small" | "xSmall";
|
|
5
|
+
|
|
6
|
+
const sizeConfig: Record<Size, { buttonSize: number; iconSize: number }> = {
|
|
7
|
+
large: { buttonSize: 48, iconSize: 28 },
|
|
8
|
+
medium: { buttonSize: 42, iconSize: 24 },
|
|
9
|
+
small: { buttonSize: 32, iconSize: 20 },
|
|
10
|
+
xSmall: { buttonSize: 28, iconSize: 16 },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type IconButtonOutlinedProps = {
|
|
14
|
+
icon: ElementType;
|
|
15
|
+
size?: Size;
|
|
16
|
+
disabled?: boolean;
|
|
17
|
+
onClick?: () => void;
|
|
18
|
+
"aria-label"?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default function IconButtonOutlined({
|
|
22
|
+
icon: Icon,
|
|
23
|
+
size = "large",
|
|
24
|
+
disabled = false,
|
|
25
|
+
onClick,
|
|
26
|
+
"aria-label": ariaLabel,
|
|
27
|
+
}: IconButtonOutlinedProps) {
|
|
28
|
+
const { buttonSize, iconSize } = sizeConfig[size];
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<IconButton
|
|
32
|
+
disabled={disabled}
|
|
33
|
+
onClick={onClick}
|
|
34
|
+
aria-label={ariaLabel}
|
|
35
|
+
sx={{
|
|
36
|
+
width: buttonSize,
|
|
37
|
+
height: buttonSize,
|
|
38
|
+
padding: 0,
|
|
39
|
+
borderRadius: "48px",
|
|
40
|
+
border: disabled
|
|
41
|
+
? "1px solid rgba(0, 0, 0, 0.12)" // --light/other/divider
|
|
42
|
+
: "1px solid rgba(0, 0, 0, 0.23)", // --light/other/outlined-border
|
|
43
|
+
color: "#4c4c4c",
|
|
44
|
+
backgroundColor: disabled
|
|
45
|
+
? "rgba(76, 76, 76, 0.04)" // --light/primary/shade/4p
|
|
46
|
+
: "transparent",
|
|
47
|
+
"&:hover": {
|
|
48
|
+
backgroundColor: "rgba(76, 76, 76, 0.08)", // --light/primary/shade/8p
|
|
49
|
+
},
|
|
50
|
+
"&:focus-visible": {
|
|
51
|
+
backgroundColor: "#dee0ff", // --light/blue/10
|
|
52
|
+
outline: "none",
|
|
53
|
+
},
|
|
54
|
+
"&.Mui-disabled": {
|
|
55
|
+
color: "rgba(0, 0, 0, 0.26)",
|
|
56
|
+
border: "1px solid rgba(0, 0, 0, 0.12)",
|
|
57
|
+
backgroundColor: "rgba(76, 76, 76, 0.04)",
|
|
58
|
+
},
|
|
59
|
+
"& .MuiSvgIcon-root": {
|
|
60
|
+
fontSize: iconSize,
|
|
61
|
+
},
|
|
62
|
+
}}
|
|
63
|
+
>
|
|
64
|
+
<Icon />
|
|
65
|
+
</IconButton>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as IconButtonOutlined } from "./IconButtonOutlined";
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import SellIcon from "@mui/icons-material/Sell";
|
|
2
|
+
import { Box, Typography } from "@mui/material";
|
|
3
|
+
import type { ElementType } from "react";
|
|
4
|
+
|
|
5
|
+
export type LabelColor =
|
|
6
|
+
| "default"
|
|
7
|
+
| "primary"
|
|
8
|
+
| "secondary"
|
|
9
|
+
| "error"
|
|
10
|
+
| "warning"
|
|
11
|
+
| "success"
|
|
12
|
+
| "info";
|
|
13
|
+
|
|
14
|
+
export type LabelIcon = "none" | "left" | "right" | "only";
|
|
15
|
+
|
|
16
|
+
const colorConfig: Record<LabelColor, { bg: string; color: string }> = {
|
|
17
|
+
default: { bg: "#f7f7f7", color: "#666666" }, // --light/gray/1, --light/text/secondary
|
|
18
|
+
primary: { bg: "#f1f1f1", color: "#4c4c4c" }, // --light/primary/tint, --light/primary/main
|
|
19
|
+
secondary: { bg: "#eef1fc", color: "#2c4d9e" }, // --light/secondary/tint, --light/secondary/main
|
|
20
|
+
error: { bg: "#fdeaea", color: "#d32f2f" }, // --light/error/tint, --light/error/main
|
|
21
|
+
warning: { bg: "#fff3e0", color: "#ef6c00" }, // --light/warning/tint, --light/warning/main
|
|
22
|
+
success: { bg: "#eaf5ea", color: "#2e7d32" }, // --light/success/tint, --light/success/main
|
|
23
|
+
info: { bg: "#e1f5fe", color: "#0288d1" }, // --light/info/tint, --light/info/main
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
type LabelFilledProps = {
|
|
27
|
+
label?: string;
|
|
28
|
+
color?: LabelColor;
|
|
29
|
+
icon?: LabelIcon;
|
|
30
|
+
iconComponent?: ElementType;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export default function LabelFilled({
|
|
34
|
+
label = "Label Name",
|
|
35
|
+
color = "default",
|
|
36
|
+
icon = "none",
|
|
37
|
+
iconComponent: Icon = SellIcon,
|
|
38
|
+
}: LabelFilledProps) {
|
|
39
|
+
const { bg, color: textColor } = colorConfig[color];
|
|
40
|
+
const showText = icon !== "only";
|
|
41
|
+
const showIcon = icon !== "none";
|
|
42
|
+
const iconOnly = icon === "only";
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<Box
|
|
46
|
+
sx={{
|
|
47
|
+
display: "inline-flex",
|
|
48
|
+
alignItems: "center",
|
|
49
|
+
gap: showIcon && showText ? "5px" : 0,
|
|
50
|
+
px: "10px",
|
|
51
|
+
py: iconOnly ? "6px" : "3px",
|
|
52
|
+
borderRadius: "4px",
|
|
53
|
+
bgcolor: bg,
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
{/* Icon on the left (or icon-only) */}
|
|
57
|
+
{(icon === "left" || icon === "only") && (
|
|
58
|
+
<Icon sx={{ fontSize: 14, color: textColor, display: "block", flexShrink: 0 }} />
|
|
59
|
+
)}
|
|
60
|
+
|
|
61
|
+
{/* Label text */}
|
|
62
|
+
{showText && (
|
|
63
|
+
<Typography
|
|
64
|
+
sx={{
|
|
65
|
+
fontFamily: "Roboto, sans-serif",
|
|
66
|
+
fontWeight: 500,
|
|
67
|
+
fontSize: 12,
|
|
68
|
+
lineHeight: "20px",
|
|
69
|
+
letterSpacing: "0.14px",
|
|
70
|
+
color: textColor,
|
|
71
|
+
whiteSpace: "nowrap",
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
{label}
|
|
75
|
+
</Typography>
|
|
76
|
+
)}
|
|
77
|
+
|
|
78
|
+
{/* Icon on the right */}
|
|
79
|
+
{icon === "right" && (
|
|
80
|
+
<Icon sx={{ fontSize: 14, color: textColor, display: "block", flexShrink: 0 }} />
|
|
81
|
+
)}
|
|
82
|
+
</Box>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import SellIcon from "@mui/icons-material/Sell";
|
|
2
|
+
import { Box, Typography } from "@mui/material";
|
|
3
|
+
import type { ElementType } from "react";
|
|
4
|
+
import type { LabelColor, LabelIcon } from "./LabelFilled";
|
|
5
|
+
|
|
6
|
+
// Text/icon colors are identical to LabelFilled
|
|
7
|
+
const textColorConfig: Record<LabelColor, string> = {
|
|
8
|
+
default: "#666666", // --light/text/secondary
|
|
9
|
+
primary: "#4c4c4c", // --light/primary/main
|
|
10
|
+
secondary: "#2c4d9e", // --light/secondary/main
|
|
11
|
+
error: "#d32f2f", // --light/error/main
|
|
12
|
+
warning: "#ef6c00", // --light/warning/main
|
|
13
|
+
success: "#2e7d32", // --light/success/main
|
|
14
|
+
info: "#0288d1", // --light/info/main
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Border colors are lighter/distinct from text colors
|
|
18
|
+
const borderColorConfig: Record<LabelColor, string> = {
|
|
19
|
+
default: "#d9d9d9", // --light/primary/lighter
|
|
20
|
+
primary: "#808080", // --light/primary/light
|
|
21
|
+
secondary: "#6f8de3", // --light/secondary/light
|
|
22
|
+
error: "#ef5350", // --light/error/light
|
|
23
|
+
warning: "#ffd28c", // --light/warning/lighter
|
|
24
|
+
success: "#4caf50", // --light/success/light
|
|
25
|
+
info: "#03a9f4", // --light/info/light
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type LabelOutlinedProps = {
|
|
29
|
+
label?: string;
|
|
30
|
+
color?: LabelColor;
|
|
31
|
+
icon?: LabelIcon;
|
|
32
|
+
iconComponent?: ElementType;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default function LabelOutlined({
|
|
36
|
+
label = "Label Name",
|
|
37
|
+
color = "default",
|
|
38
|
+
icon = "none",
|
|
39
|
+
iconComponent: Icon = SellIcon,
|
|
40
|
+
}: LabelOutlinedProps) {
|
|
41
|
+
const textColor = textColorConfig[color];
|
|
42
|
+
const borderColor = borderColorConfig[color];
|
|
43
|
+
const showText = icon !== "only";
|
|
44
|
+
const showIcon = icon !== "none";
|
|
45
|
+
const iconOnly = icon === "only";
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Box
|
|
49
|
+
sx={{
|
|
50
|
+
display: "inline-flex",
|
|
51
|
+
alignItems: "center",
|
|
52
|
+
gap: showIcon && showText ? "5px" : 0,
|
|
53
|
+
px: "10px",
|
|
54
|
+
py: iconOnly ? "6px" : "3px",
|
|
55
|
+
borderRadius: "4px",
|
|
56
|
+
border: `1px solid ${borderColor}`,
|
|
57
|
+
bgcolor: "transparent",
|
|
58
|
+
}}
|
|
59
|
+
>
|
|
60
|
+
{(icon === "left" || icon === "only") && (
|
|
61
|
+
<Icon sx={{ fontSize: 14, color: textColor, display: "block", flexShrink: 0 }} />
|
|
62
|
+
)}
|
|
63
|
+
|
|
64
|
+
{showText && (
|
|
65
|
+
<Typography
|
|
66
|
+
sx={{
|
|
67
|
+
fontFamily: "Roboto, sans-serif",
|
|
68
|
+
fontWeight: 500,
|
|
69
|
+
fontSize: 12,
|
|
70
|
+
lineHeight: "20px",
|
|
71
|
+
letterSpacing: "0.14px",
|
|
72
|
+
color: textColor,
|
|
73
|
+
whiteSpace: "nowrap",
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
76
|
+
{label}
|
|
77
|
+
</Typography>
|
|
78
|
+
)}
|
|
79
|
+
|
|
80
|
+
{icon === "right" && (
|
|
81
|
+
<Icon sx={{ fontSize: 14, color: textColor, display: "block", flexShrink: 0 }} />
|
|
82
|
+
)}
|
|
83
|
+
</Box>
|
|
84
|
+
);
|
|
85
|
+
}
|