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.
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ export { default as LabelFilled } from "./LabelFilled";
2
+ export { default as LabelOutlined } from "./LabelOutlined";
3
+ export type { LabelColor, LabelIcon } from "./LabelFilled";