Skip to content

Commit e4e9bee

Browse files
feat: Updated the styles to better adapt the widget when user applies dark background colour (#1029)
2 parents 09f9d33 + 522afd1 commit e4e9bee

File tree

8 files changed

+843
-72
lines changed

8 files changed

+843
-72
lines changed

apps/widget/src/components/Common/Container/Container.tsx

Lines changed: 468 additions & 26 deletions
Large diffs are not rendered by default.

apps/widget/src/components/Common/Table/HandsonTable.styles.min.css

Lines changed: 227 additions & 37 deletions
Large diffs are not rendered by default.

apps/widget/src/components/Common/Table/Table.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const createErrorSvg = memoize(() => {
4949
errorSvg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
5050
errorSvg.setAttribute('viewBox', '-2 -2 24 24');
5151
errorSvg.setAttribute('width', '20');
52-
errorSvg.setAttribute('fill', 'currentColor');
52+
errorSvg.setAttribute('fill', 'var(--error-color)');
5353
const errorSvgPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
5454
errorSvgPath.setAttribute(
5555
'd',
@@ -76,9 +76,13 @@ Handsontable.renderers.registerRenderer(
7676
const hasWarnings = sourceData.warnings?.[name];
7777
const isUpdated = sourceData.updated?.[name];
7878

79+
// Reset classes first
7980
TD.className = 'custom-cell';
8081
TD.ariaLabel = '';
8182

83+
// Remove any inline background styles
84+
TD.style.backgroundColor = '';
85+
8286
let fieldValue = sourceData.record?.[name] ?? null;
8387

8488
if (typeof fieldValue === 'string' && fieldValue.length > name.length + 20) {
@@ -101,29 +105,30 @@ Handsontable.renderers.registerRenderer(
101105
if (fieldValue !== null) valueSpan.textContent = fieldValue;
102106
TD.appendChild(valueSpan);
103107

108+
// Apply CSS classes instead of inline styles
104109
if (isUpdated) {
110+
TD.classList.add('updated-cell');
105111
errorSvg.setAttribute('style', memoizedStyles.errorUpdated);
106112
if (hasError) {
113+
TD.classList.add('error-cell');
107114
TD.appendChild(errorSvg);
108115
}
109-
TD.style.backgroundColor = '#ffda5b';
110116
} else if (hasError) {
117+
TD.classList.add('error-cell');
111118
errorSvg.setAttribute('style', memoizedStyles.errorOnly);
112119
TD.appendChild(errorSvg);
113-
TD.style.backgroundColor = '#fdebeb';
114120
} else if (hasWarnings) {
121+
TD.classList.add('warning-cell');
115122
TD.ariaLabel = hasWarnings;
116123
TD.dataset.cooltipzDir = row < 5 ? 'bottom' : 'top';
117124
TD.dataset.cooltipzSize = 'fit';
118125
errorSvg.setAttribute('style', hasWarnings ? memoizedStyles.warningOnly : memoizedStyles.errorUpdated);
119126
TD.appendChild(errorSvg);
120-
TD.style.backgroundColor = '#ffda5b';
121127
}
122128

123129
return TD;
124130
}
125131
);
126-
127132
Handsontable.renderers.registerRenderer(
128133
'check',
129134
// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars

apps/widget/src/components/widget/Phases/Phase3/Phase3.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export function Phase3(props: IPhase3Props) {
128128
onClick={() => setShowDeleteConfirmModal(true)}
129129
>
130130
{texts.COMMON.DELETE}
131-
<Badge variant="light" ml="xs" color="red">
131+
<Badge variant="gradient" ml="xs" color="red">
132132
{numberFormatter(selectedRowsRef.current.size)}
133133
</Badge>
134134
</Button>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import { createStyles, MantineTheme } from '@mantine/core';
2+
3+
export const useStyles = createStyles((theme: MantineTheme) => ({
4+
modal: {
5+
backgroundColor: 'var(--background-color)',
6+
borderRadius: theme.radius.md,
7+
boxShadow: theme.shadows.md,
8+
padding: theme.spacing.xl,
9+
color: 'var(--text-color)',
10+
},
11+
12+
header: {
13+
marginBottom: '1rem',
14+
color: 'var(--text-color)',
15+
},
16+
17+
title: {
18+
color: 'var(--text-color)',
19+
fontWeight: 600,
20+
fontSize: theme.fontSizes.xl,
21+
},
22+
23+
label: {
24+
color: 'var(--label-color)',
25+
fontWeight: 500,
26+
fontSize: theme.fontSizes.lg,
27+
},
28+
29+
input: {
30+
color: 'var(--text-color)',
31+
backgroundColor: 'var(--background-color)',
32+
borderColor: 'var(--border-color)',
33+
34+
'&::placeholder': {
35+
color: 'var(--secondary-text-color)',
36+
},
37+
38+
'&:focus': {
39+
borderColor: 'var(--button-primary-background)',
40+
},
41+
},
42+
43+
select: {
44+
'& .mantine-Select-input': {
45+
color: 'var(--text-color)',
46+
backgroundColor: 'var(--background-color)',
47+
borderColor: 'var(--border-color)',
48+
},
49+
50+
'& .mantine-Select-label': {
51+
color: 'var(--label-color)',
52+
fontWeight: 500,
53+
fontSize: theme.fontSizes.lg,
54+
},
55+
56+
'& .mantine-Select-dropdown': {
57+
backgroundColor: 'var(--background-color)',
58+
borderColor: 'var(--border-color)',
59+
},
60+
61+
'& .mantine-Select-item': {
62+
backgroundColor: 'var(--background-color)',
63+
color: 'var(--text-color)',
64+
65+
'&:hover': {
66+
backgroundColor: 'var(--stepper-background)',
67+
},
68+
69+
'&[data-selected]': {
70+
backgroundColor: 'var(--button-primary-background)',
71+
color: 'var(--button-primary-color)',
72+
},
73+
},
74+
},
75+
76+
checkbox: {
77+
'& .mantine-Checkbox-input': {
78+
borderColor: 'var(--border-color)',
79+
backgroundColor: 'var(--background-color)',
80+
81+
'&:checked': {
82+
backgroundColor: 'var(--button-primary-background)',
83+
borderColor: 'var(--button-primary-background)',
84+
},
85+
},
86+
87+
'& .mantine-Checkbox-label': {
88+
color: 'var(--text-color)',
89+
fontWeight: 500,
90+
fontSize: theme.fontSizes.lg,
91+
},
92+
},
93+
94+
// Additional utility classes for consistent theming
95+
text: {
96+
color: 'var(--text-color)',
97+
},
98+
99+
secondaryText: {
100+
color: 'var(--secondary-text-color)',
101+
},
102+
103+
labelText: {
104+
color: 'var(--label-color)',
105+
},
106+
}));

apps/widget/src/components/widget/modals/FindReplace/FindReplaceModal.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { Button } from '@ui/Button';
1010
import { Select } from '@ui/Select';
1111
import { useAPIState } from '@store/api.context';
1212
import { useAppState } from '@store/app.context';
13+
import { useStyles } from './FindReplaceModal.styles';
1314

1415
interface IFindReplaceModalProps {
1516
opened: boolean;
@@ -22,6 +23,7 @@ interface IFindReplaceModalProps {
2223
}
2324

2425
export function FindReplaceModal(props: IFindReplaceModalProps) {
26+
const { classes } = useStyles();
2527
const { api } = useAPIState();
2628
const { uploadInfo } = useAppState();
2729
const [modifiedCount, setModifiedCount] = useState<number | undefined>();
@@ -60,11 +62,11 @@ export function FindReplaceModal(props: IFindReplaceModalProps) {
6062
<MantineModal
6163
centered
6264
size="lg"
63-
padding="xl"
6465
opened={opened}
6566
keepMounted={false}
6667
onClose={onCloseModal}
6768
title={texts.PHASE3.FIND_REPLACE}
69+
classNames={classes}
6870
>
6971
<FocusTrap active>
7072
<form onSubmit={handleSubmit((data) => replaceData(data))}>

apps/widget/src/design-system/MappingItem/MappingItem.style.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { createStyles, MantineTheme } from '@mantine/core';
2-
import { colors } from '../../config/colors.config';
32

43
const getRootStyles = (theme: MantineTheme): React.CSSProperties => ({
54
justifyContent: 'space-between',
@@ -28,7 +27,6 @@ const getSelectionRootStyles = (): React.CSSProperties => ({
2827

2928
const getHeadingStyles = (theme: MantineTheme) => ({
3029
padding: theme.spacing.xs,
31-
backgroundColor: colors.light,
3230
display: 'flex',
3331
alignItems: 'center',
3432
width: '50%',
@@ -53,6 +51,7 @@ export const getSelectStyles = (theme: MantineTheme, height: number): React.CSSP
5351
border: 'none',
5452
height: height,
5553
cursor: 'pointer',
54+
backgroundColor: 'var(--background-color)',
5655
});
5756

5857
export const getSelectRootStyles = (): React.CSSProperties => ({
@@ -66,6 +65,7 @@ export const getStatusTextStyles = (theme: MantineTheme): React.CSSProperties =>
6665
[`@media (max-width: ${theme.breakpoints.md}px)`]: {
6766
flexDirection: 'row-reverse',
6867
},
68+
color: 'var(--label-color)',
6969
});
7070

7171
export const getRequiredStyles = (): React.CSSProperties => ({

apps/widget/src/util/helpers/color.helpers.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,29 @@ export function generateShades(color: string, shadesCount = variables.defaultSha
5656
return shades.reverse();
5757
}
5858
}
59+
60+
// Helper function to determine if a color is dark
61+
export function isColorDark(color: string): boolean {
62+
// Remove # if present
63+
const hex = color.replace('#', '');
64+
65+
// Convert to RGB
66+
const red = parseInt(hex.substr(0, 2), 16);
67+
const green = parseInt(hex.substr(2, 2), 16);
68+
const blue = parseInt(hex.substr(4, 2), 16);
69+
70+
// Calculate luminance using the relative luminance formula
71+
const luminance = (0.299 * red + 0.587 * green + 0.114 * blue) / 255;
72+
73+
return luminance < 0.5;
74+
}
75+
76+
// Helper function to get contrasting text color
77+
export function getContrastingTextColor(backgroundColor: string): string {
78+
return isColorDark(backgroundColor) ? '#ffffff' : '#000000';
79+
}
80+
81+
// Helper function to get a lighter version of the text color for secondary text
82+
export function getSecondaryTextColor(backgroundColor: string): string {
83+
return isColorDark(backgroundColor) ? '#e0e0e0' : '#666666';
84+
}

0 commit comments

Comments
 (0)