@cerebruminc/cerebellum 17.3.2 → 17.3.3
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/CHANGELOG.md +10 -0
- package/package.json +1 -1
- package/src/components/Button/Button.tsx +9 -1
- package/src/components/Button/ButtonComponentStyles.tsx +72 -5
- package/src/components/Button/helpers.ts +2 -2
- package/src/components/Button/types.ts +2 -0
- package/src/components/ToggleButtons/ToggleButtons.test.tsx +1 -1
- package/src/mantine/mantineTheme.ts +15 -15
- package/src/sharedTypes/types.ts +1 -0
- package/src/theme.ts +6 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# react-component-lib-boilerplate
|
|
2
2
|
|
|
3
|
+
## [17.3.3](https://github.com/cerebruminc/cerebellum/compare/v17.3.2...v17.3.3) (2026-06-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **button:** add secondaryText color property and hover text transitions ([22f165d](https://github.com/cerebruminc/cerebellum/commit/22f165d001263d93dccf583036c9ff4f07b37c83))
|
|
9
|
+
* **button:** sync Mantine theme button colors with accessible values ([b18f1eb](https://github.com/cerebruminc/cerebellum/commit/b18f1eb12f18eba7011d7b14c12fd110afe0083f))
|
|
10
|
+
* **button:** update color families for WCAG AA compliance ([75f6b2f](https://github.com/cerebruminc/cerebellum/commit/75f6b2fc044c50c536710339ae9472780f5924d8))
|
|
11
|
+
* **toggle-button:** update test to work with new colors ([e60fe71](https://github.com/cerebruminc/cerebellum/commit/e60fe71f0ce2ba94e2937c2200b38eb13a81523d))
|
|
12
|
+
|
|
3
13
|
## [17.3.2](https://github.com/cerebruminc/cerebellum/compare/v17.3.1...v17.3.2) (2026-06-15)
|
|
4
14
|
|
|
5
15
|
|
package/package.json
CHANGED
|
@@ -89,7 +89,13 @@ export const Button: FC<ButtonType> = (props: ButtonType) => {
|
|
|
89
89
|
const arrowGap = directionalButtonGap || theme.button?.directionalButtonGap;
|
|
90
90
|
const confirmedCaretGap = caretGap || theme.button?.caretGap;
|
|
91
91
|
const confirmedIconGap = iconGap ?? (boxed || textButton ? 10 : boxedOutline ? 13 : Icon ? 20 : arrowGap || 70);
|
|
92
|
-
const iconColor = disabled
|
|
92
|
+
const iconColor = disabled
|
|
93
|
+
? disabledTextColor || theme.button?.disabledTextColor
|
|
94
|
+
: primary && !white
|
|
95
|
+
? colorGroup.text
|
|
96
|
+
: secondary || boxed
|
|
97
|
+
? colorGroup.secondaryText || colorGroup.main
|
|
98
|
+
: colorGroup.main;
|
|
93
99
|
const loadingStyleFormat =
|
|
94
100
|
loadingConfiguration || getLoadingConfiguration({ primary, outline, boxedOutline, secondary, textButton, boxed, colorGroup });
|
|
95
101
|
const loadingOffsetParams = { iconSize, autoIconSize, iconGap, confirmedIconGap, Icon, backButton, caret, nextButton };
|
|
@@ -182,7 +188,9 @@ export const Button: FC<ButtonType> = (props: ButtonType) => {
|
|
|
182
188
|
$disabled={disabled}
|
|
183
189
|
$disabledTextColor={disabledTextColor}
|
|
184
190
|
$letterSpacing={letterSpacing}
|
|
191
|
+
$outline={outline}
|
|
185
192
|
$primary={!(!primary || white)}
|
|
193
|
+
$secondary={secondary}
|
|
186
194
|
$textButton={textButton}
|
|
187
195
|
$textFontSize={textFontSize}
|
|
188
196
|
data-sentry-unmask
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { colors } from "../../const/colors";
|
|
2
|
-
import { styled } from "styled-components";
|
|
2
|
+
import { styled, type DefaultTheme } from "styled-components";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
ButtonElementProps,
|
|
@@ -11,6 +11,64 @@ import {
|
|
|
11
11
|
UnderlineProps,
|
|
12
12
|
} from "./types";
|
|
13
13
|
|
|
14
|
+
type BaseTextColorProps = Pick<TextProps, "$primary" | "$secondary" | "$boxed" | "$colorGroup" | "$disabled" | "$disabledTextColor"> & {
|
|
15
|
+
theme: DefaultTheme;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type HoverTextColorProps = Pick<
|
|
19
|
+
TextProps,
|
|
20
|
+
"$primary" | "$secondary" | "$boxed" | "$outline" | "$boxedOutline" | "$textButton" | "$colorGroup" | "$disabled" | "$disabledTextColor"
|
|
21
|
+
> & {
|
|
22
|
+
theme: DefaultTheme;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const getBaseTextColor = ({ $primary, $secondary, $boxed, $colorGroup, $disabled, $disabledTextColor, theme }: BaseTextColorProps) => {
|
|
26
|
+
if ($disabled) {
|
|
27
|
+
return $disabledTextColor || theme.button?.disabledTextColor;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if ($primary) {
|
|
31
|
+
return $colorGroup.text;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ($secondary || $boxed) {
|
|
35
|
+
return $colorGroup.secondaryText || $colorGroup.main;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return $colorGroup.main;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const getHoverTextColor = ({
|
|
42
|
+
$primary,
|
|
43
|
+
$secondary,
|
|
44
|
+
$boxed,
|
|
45
|
+
$outline,
|
|
46
|
+
$boxedOutline,
|
|
47
|
+
$textButton,
|
|
48
|
+
$colorGroup,
|
|
49
|
+
$disabled,
|
|
50
|
+
$disabledTextColor,
|
|
51
|
+
theme,
|
|
52
|
+
}: HoverTextColorProps) => {
|
|
53
|
+
if ($disabled) {
|
|
54
|
+
return $disabledTextColor || theme.button?.disabledTextColor;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if ($primary) {
|
|
58
|
+
return $colorGroup.text;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if ($outline || $boxedOutline) {
|
|
62
|
+
return $colorGroup.hover;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if ($textButton || $secondary || $boxed) {
|
|
66
|
+
return $colorGroup.secondaryText || $colorGroup.main;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return $colorGroup.main;
|
|
70
|
+
};
|
|
71
|
+
|
|
14
72
|
export const ButtonElement = styled.button<ButtonElementProps>`
|
|
15
73
|
align-items: center;
|
|
16
74
|
line-height: ${({ $lineHeight }) => ($lineHeight ? $lineHeight : 1.15)};
|
|
@@ -40,7 +98,11 @@ export const ButtonElement = styled.button<ButtonElementProps>`
|
|
|
40
98
|
}};
|
|
41
99
|
border: 1px solid
|
|
42
100
|
${({ $boxedOutline, disabled, $disabledTextColor, $outline, $colorGroup, $textButton, theme }) =>
|
|
43
|
-
$boxedOutline || $outline
|
|
101
|
+
$boxedOutline || $outline
|
|
102
|
+
? (disabled ? $disabledTextColor || theme.button?.disabledTextColor : $colorGroup.main)
|
|
103
|
+
: $textButton
|
|
104
|
+
? "transparent"
|
|
105
|
+
: theme.button?.outlineColor || "transparent"};
|
|
44
106
|
border-radius: ${({ $borderRadius, $boxed, $boxedOutline, $textButton }) =>
|
|
45
107
|
$borderRadius ?? ($boxedOutline ? 7 : $boxed || $textButton ? 8 : 30)}px;
|
|
46
108
|
box-shadow: ${({ $colorGroup, disabled, $primary, $shadow }) =>
|
|
@@ -88,6 +150,8 @@ export const ButtonElement = styled.button<ButtonElementProps>`
|
|
|
88
150
|
? $colorGroup.medium
|
|
89
151
|
: $colorGroup.hover;
|
|
90
152
|
}};
|
|
153
|
+
${({ $boxedOutline, $outline, $colorGroup, disabled }) =>
|
|
154
|
+
($boxedOutline || $outline) && !disabled ? `border-color: ${$colorGroup.hover};` : ""}
|
|
91
155
|
}
|
|
92
156
|
&:after {
|
|
93
157
|
content: "";
|
|
@@ -142,15 +206,18 @@ export const NextIconBox = styled(IconBox)`
|
|
|
142
206
|
margin-right: 0;
|
|
143
207
|
`;
|
|
144
208
|
export const Text = styled.span<TextProps>`
|
|
145
|
-
color: ${
|
|
146
|
-
$disabled ? $disabledTextColor || theme.button?.disabledTextColor : $primary ? $colorGroup.text : $colorGroup.main};
|
|
209
|
+
color: ${getBaseTextColor};
|
|
147
210
|
font-size: ${(props) => props.$textFontSize || props.theme.button?.textFontSize}px;
|
|
148
211
|
font-weight: ${({ $boxed, $boxedOutline, $textButton }) => ($boxed || $boxedOutline || $textButton ? 500 : 600)};
|
|
149
|
-
letter-spacing: ${({ $boxed, $boxedOutline, $letterSpacing, $textButton: textButton }) => ($letterSpacing ? $letterSpacing :
|
|
212
|
+
letter-spacing: ${({ $boxed, $boxedOutline, $letterSpacing, $textButton: textButton }) => ($letterSpacing ? $letterSpacing : $boxed || $boxedOutline || textButton ? "0.36px" : "0.07em")};
|
|
150
213
|
position: relative;
|
|
214
|
+
transition: color 150ms ease-out;
|
|
151
215
|
vertical-align: middle;
|
|
152
216
|
white-space: nowrap;
|
|
153
217
|
z-index: 1;
|
|
218
|
+
${ButtonElement}:hover & {
|
|
219
|
+
color: ${getHoverTextColor};
|
|
220
|
+
}
|
|
154
221
|
`;
|
|
155
222
|
export const TextButtonBackground = styled.span<TextBackgroundProps>`
|
|
156
223
|
bottom: 0;
|
|
@@ -69,7 +69,7 @@ export const getLoadingConfiguration = ({
|
|
|
69
69
|
if (primary) {
|
|
70
70
|
return PrimaryButtonLoadingConfiguration(colorGroup?.text);
|
|
71
71
|
} else if (secondary) {
|
|
72
|
-
return SecondaryButtonLoadingConfiguration(colorGroup?.main);
|
|
72
|
+
return SecondaryButtonLoadingConfiguration(colorGroup?.secondaryText || colorGroup?.main);
|
|
73
73
|
} else if (outline) {
|
|
74
74
|
return OutlineButtonLoadingConfiguration(colorGroup?.main);
|
|
75
75
|
} else if (boxedOutline) {
|
|
@@ -77,7 +77,7 @@ export const getLoadingConfiguration = ({
|
|
|
77
77
|
} else if (textButton) {
|
|
78
78
|
return TextButtonLoadingConfiguration(colorGroup?.main);
|
|
79
79
|
} else if (boxed) {
|
|
80
|
-
return BoxedButtonLoadingConfiguration(colorGroup?.main);
|
|
80
|
+
return BoxedButtonLoadingConfiguration(colorGroup?.secondaryText || colorGroup?.main);
|
|
81
81
|
} else {
|
|
82
82
|
return {};
|
|
83
83
|
}
|
|
@@ -164,7 +164,9 @@ export interface TextProps {
|
|
|
164
164
|
$disabled?: boolean;
|
|
165
165
|
$disabledTextColor?: string;
|
|
166
166
|
$letterSpacing?: string;
|
|
167
|
+
$outline?: boolean;
|
|
167
168
|
$primary: boolean;
|
|
169
|
+
$secondary?: boolean;
|
|
168
170
|
$textButton?: boolean;
|
|
169
171
|
$textFontSize?: number;
|
|
170
172
|
}
|
|
@@ -139,7 +139,7 @@ describe("ToggleButtons", () => {
|
|
|
139
139
|
const iconBox = screen.getByTestId(`${buttonText} icon`);
|
|
140
140
|
const path = iconBox.querySelector("path");
|
|
141
141
|
// Default: active icon fill = colorGroup.hover = BLUE_100
|
|
142
|
-
expect(path?.getAttribute("fill")).toBe("#
|
|
142
|
+
expect(path?.getAttribute("fill")).toBe("#4965c8");
|
|
143
143
|
});
|
|
144
144
|
|
|
145
145
|
test("active icon uses colorGroup.light fill when invertActive is true", () => {
|
|
@@ -82,13 +82,13 @@ const blue: MantineColorsTuple = [
|
|
|
82
82
|
"#E5EBFC", // BLUE_5 - 0
|
|
83
83
|
"#D7E1FF", // BLUE_10 - 1
|
|
84
84
|
"#ADBDFE", // BLUE_25 - 2
|
|
85
|
-
"#
|
|
86
|
-
"#
|
|
87
|
-
"#
|
|
88
|
-
"#
|
|
89
|
-
"#
|
|
90
|
-
"#
|
|
91
|
-
"#
|
|
85
|
+
"#7A97FA", // BLUE_45 - 3
|
|
86
|
+
"#6988f4", // BLUE_70 - 4
|
|
87
|
+
"#5d7cf0", // BLUE_80 - 5
|
|
88
|
+
"#4F6CEA", // BLUE_100 - 6 (main)
|
|
89
|
+
"#4965c8", // BLUE_120 - 7 (hover)
|
|
90
|
+
"#4158aa", // BLUE_130 - 8 (secondaryText)
|
|
91
|
+
"#394B91", // BLUE_150 - 9
|
|
92
92
|
];
|
|
93
93
|
|
|
94
94
|
// High-contrast binary palette — mirrors styled-components highContrastColorFamily (BLACK/WHITE only)
|
|
@@ -288,15 +288,15 @@ export const createCustomMantineTheme = (optionsOrBrandColor?: CreateCustomManti
|
|
|
288
288
|
? highContrastRed
|
|
289
289
|
: [
|
|
290
290
|
"#FFDDE5", // RED_5 - 0
|
|
291
|
-
"#
|
|
291
|
+
"#FFD5DD", // RED_10 - 1
|
|
292
292
|
"#FFBBC4", // RED_25 - 2
|
|
293
|
-
"#
|
|
294
|
-
"#
|
|
295
|
-
"#
|
|
296
|
-
"#
|
|
297
|
-
"#
|
|
298
|
-
"#
|
|
299
|
-
"#
|
|
293
|
+
"#FF8F9C", // RED_50 - 3
|
|
294
|
+
"#FF677E", // RED_70 - 4
|
|
295
|
+
"#FF3161", // RED_100 - 5
|
|
296
|
+
"#D72F53", // RED_120 - 6 (main)
|
|
297
|
+
"#C42D4C", // RED_130 - 7 (hover)
|
|
298
|
+
"#B02B45", // RED_140 - 8 (secondaryText)
|
|
299
|
+
"#9E293E", // RED_150 - 9
|
|
300
300
|
],
|
|
301
301
|
peach: highContrast
|
|
302
302
|
? highContrastGray
|
package/src/sharedTypes/types.ts
CHANGED
package/src/theme.ts
CHANGED
|
@@ -775,9 +775,10 @@ export const cerebellumTheme: DefaultTheme = {
|
|
|
775
775
|
medium: colors.BLUE_10,
|
|
776
776
|
mediumDark: colors.BLUE_25,
|
|
777
777
|
dark: colors.BLUE_45,
|
|
778
|
-
main: colors.
|
|
779
|
-
hover: colors.
|
|
778
|
+
main: colors.BLUE_100,
|
|
779
|
+
hover: colors.BLUE_120,
|
|
780
780
|
text: colors.WHITE,
|
|
781
|
+
secondaryText: colors.BLUE_130,
|
|
781
782
|
},
|
|
782
783
|
COOL_GREY: {
|
|
783
784
|
light: colors.COOL_GREY_4,
|
|
@@ -811,9 +812,10 @@ export const cerebellumTheme: DefaultTheme = {
|
|
|
811
812
|
medium: colors.RED_10,
|
|
812
813
|
mediumDark: colors.RED_25,
|
|
813
814
|
dark: colors.RED_65,
|
|
814
|
-
main: colors.
|
|
815
|
-
hover: colors.
|
|
815
|
+
main: colors.RED_120,
|
|
816
|
+
hover: colors.RED_130,
|
|
816
817
|
text: colors.WHITE,
|
|
818
|
+
secondaryText: colors.RED_140,
|
|
817
819
|
},
|
|
818
820
|
},
|
|
819
821
|
colorPicker: {
|