Skip to content

Commit bcc7711

Browse files
committed
fix: dark/light mode compatibility for entire admin UI
- Replace hardcoded white backgrounds with props.theme.colors.neutral0 - Replace hardcoded hex borders with rgba values for theme flexibility - Convert static theme color refs to props.theme for ThemeProvider support - Fix hardcoded text colors with CSS variable fallbacks - Affects 16 files: HomePageModern, CreateEditModal, ViewsWidget, ViewsListPopover, CustomSelect, QueryBuilder, FilterModals, LicenseGuard, UpgradePage, License, UpgradePrompt and more
1 parent a271ce1 commit bcc7711

18 files changed

Lines changed: 729 additions & 130 deletions

admin/src/components/AdvancedFilterButton.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Filter, Cross } from '@strapi/icons';
44
import { useNavigate, useLocation } from 'react-router-dom';
55
import { useFetchClient } from '@strapi/strapi/admin';
66
import styled from 'styled-components';
7-
import SimpleAdvancedFilterModal from './SimpleAdvancedFilterModal';
7+
import StrapiStyleFilterModal from './StrapiStyleFilterModal';
88

99
// ================ STYLED COMPONENTS ================
1010
const FilterButtonGroup = styled.div`
@@ -22,19 +22,19 @@ const FilterButton = styled.button<{ $isActive?: boolean }>`
2222
padding: 0 14px;
2323
font-size: 13px;
2424
font-weight: 500;
25-
border: 1px solid ${props => props.$isActive ? '#4945FF' : '#dcdce4'};
25+
border: 1px solid ${props => props.$isActive ? '#4945FF' : 'rgba(128, 128, 128, 0.25)'};
2626
border-radius: 4px;
2727
background: ${props => props.$isActive
2828
? '#EEF0FF'
29-
: '#ffffff'};
29+
: props.theme.colors.neutral0};
3030
color: ${props => props.$isActive ? '#4945FF' : '#32324d'};
3131
cursor: pointer;
3232
transition: all 0.15s ease;
3333
white-space: nowrap;
3434
3535
&:hover {
3636
background: ${props => props.$isActive ? '#E0E7FF' : '#f6f6f9'};
37-
border-color: ${props => props.$isActive ? '#4945FF' : '#c0c0cf'};
37+
border-color: ${props => props.$isActive ? '#4945FF' : 'rgba(128, 128, 128, 0.3)'};
3838
}
3939
4040
&:active {
@@ -55,7 +55,7 @@ const ClearButton = styled.button`
5555
width: 36px;
5656
height: 36px;
5757
padding: 0;
58-
border: 1px solid #fecaca;
58+
border: 1px solid rgba(239, 68, 68, 0.3);
5959
border-radius: 4px;
6060
background: #fef2f2;
6161
color: #dc2626;
@@ -64,7 +64,7 @@ const ClearButton = styled.button`
6464
6565
&:hover {
6666
background: #fee2e2;
67-
border-color: #fca5a5;
67+
border-color: rgba(239, 68, 68, 0.4);
6868
}
6969
7070
&:active {
@@ -304,7 +304,7 @@ const AdvancedFilterButton: React.FC = () => {
304304
)}
305305

306306
{showModal && (
307-
<SimpleAdvancedFilterModal
307+
<StrapiStyleFilterModal
308308
onClose={() => setShowModal(false)}
309309
onApply={handleApplyFilters}
310310
availableFields={availableFields}

admin/src/components/AdvancedFilterModal.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const ModalOverlay = styled.div`
2525
`;
2626

2727
const ModalContent = styled(Box)`
28-
background: white;
28+
background: ${(p) => p.theme.colors.neutral0};
2929
border-radius: 8px;
3030
max-height: 90vh;
3131
overflow: auto;
@@ -35,17 +35,17 @@ const ModalContent = styled(Box)`
3535

3636
const FilterRow = styled(Flex)`
3737
padding: 12px;
38-
background: #f7f8fa;
38+
background: ${(p) => p.theme.colors.neutral100};
3939
border-radius: 4px;
4040
margin-bottom: 8px;
4141
`;
4242

4343
const StyledSelect = styled.select`
4444
width: 100%;
4545
padding: 8px 12px;
46-
border: 1px solid #dcdce4;
46+
border: 1px solid rgba(128, 128, 128, 0.25);
4747
border-radius: 4px;
48-
background: white;
48+
background: ${(p) => p.theme.colors.neutral0};
4949
font-size: 14px;
5050
font-family: inherit;
5151
cursor: pointer;
@@ -56,7 +56,7 @@ const StyledSelect = styled.select`
5656
}
5757
5858
&:disabled {
59-
background: #f7f8fa;
59+
background: ${(p) => p.theme.colors.neutral100};
6060
cursor: not-allowed;
6161
}
6262
`;
@@ -365,13 +365,13 @@ const AdvancedFilterModal: React.FC<AdvancedFilterModalProps> = ({
365365
? 'linear-gradient(135deg, #DBEAFE 0%, #BFDBFE 100%)'
366366
: field.enabled
367367
? 'linear-gradient(135deg, #D1FAE5 0%, #A7F3D0 100%)'
368-
: 'white',
368+
: 'transparent',
369369
borderRadius: '10px',
370370
border: field.deep
371371
? '2px solid #3B82F6'
372372
: field.enabled
373373
? '2px solid #10B981'
374-
: '2px solid #E5E7EB',
374+
: '2px solid rgba(128, 128, 128, 0.2)',
375375
cursor: 'pointer',
376376
transition: 'all 0.2s ease',
377377
textAlign: 'center',

admin/src/components/CreateEditModal.tsx

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ const Overlay = styled.div`
151151
`;
152152

153153
const ModalContainer = styled.div`
154-
background: ${theme.colors.neutral[0]};
154+
background: ${(p) => p.theme.colors.neutral0};
155155
border-radius: 16px;
156156
max-height: 90vh;
157157
overflow: hidden;
@@ -217,19 +217,19 @@ const ModalBody = styled.div`
217217

218218
const ModalFooter = styled.div`
219219
padding: 16px 28px;
220-
background: ${theme.colors.neutral[100]};
221-
border-top: 1px solid ${theme.colors.neutral[200]};
220+
background: ${(p) => p.theme.colors.neutral100};
221+
border-top: 1px solid rgba(128, 128, 128, 0.25);
222222
display: flex;
223223
justify-content: flex-end;
224224
gap: 12px;
225225
`;
226226

227227
const Section = styled.div<{ $collapsed?: boolean }>`
228228
margin-bottom: 20px;
229-
border: 1px solid ${theme.colors.neutral[200]};
229+
border: 1px solid rgba(128, 128, 128, 0.25);
230230
border-radius: 12px;
231231
overflow: hidden;
232-
background: ${theme.colors.neutral[0]};
232+
background: ${(p) => p.theme.colors.neutral0};
233233
transition: all 0.2s ease;
234234
235235
&:hover {
@@ -240,7 +240,7 @@ const Section = styled.div<{ $collapsed?: boolean }>`
240240
const SectionHeader = styled.button<{ $hasIcon?: boolean }>`
241241
width: 100%;
242242
padding: 14px 16px;
243-
background: ${theme.colors.neutral[100]};
243+
background: ${(p) => p.theme.colors.neutral100};
244244
border: none;
245245
cursor: pointer;
246246
display: flex;
@@ -249,7 +249,7 @@ const SectionHeader = styled.button<{ $hasIcon?: boolean }>`
249249
transition: all 0.15s ease;
250250
251251
&:hover {
252-
background: ${theme.colors.neutral[200]};
252+
background: ${(p) => p.theme.colors.neutral200};
253253
}
254254
`;
255255

@@ -259,7 +259,7 @@ const SectionTitle = styled.div`
259259
gap: 10px;
260260
font-weight: 600;
261261
font-size: 0.875rem;
262-
color: ${theme.colors.neutral[800]};
262+
color: ${(p) => p.theme.colors.neutral800};
263263
264264
svg {
265265
width: 18px;
@@ -283,7 +283,7 @@ const ChevronIcon = styled.div<{ $collapsed?: boolean }>`
283283
svg {
284284
width: 18px;
285285
height: 18px;
286-
color: ${theme.colors.neutral[600]};
286+
color: ${(p) => p.theme.colors.neutral600};
287287
}
288288
`;
289289

@@ -292,7 +292,7 @@ const IconPicker = styled.div`
292292
grid-template-columns: repeat(8, 1fr);
293293
gap: 8px;
294294
padding: 12px;
295-
background: ${theme.colors.neutral[100]};
295+
background: ${(p) => p.theme.colors.neutral100};
296296
border-radius: 8px;
297297
max-height: 180px;
298298
overflow-y: auto;
@@ -317,15 +317,15 @@ const IconButton = styled.button<{ $isSelected?: boolean }>`
317317
justify-content: center;
318318
padding: 10px;
319319
border: 2px solid ${props => props.$isSelected ? theme.colors.primary[500] : 'transparent'};
320-
background: ${props => props.$isSelected ? theme.colors.primary[100] : theme.colors.neutral[0]};
320+
background: ${props => props.$isSelected ? theme.colors.primary[100] : props.theme.colors.neutral0};
321321
border-radius: 8px;
322322
cursor: pointer;
323323
transition: all 0.15s ease;
324324
325325
svg {
326326
width: 20px;
327327
height: 20px;
328-
color: ${props => props.$isSelected ? theme.colors.primary[500] : theme.colors.neutral[600]};
328+
color: ${props => props.$isSelected ? theme.colors.primary[500] : props.theme.colors.neutral600};
329329
}
330330
331331
&:hover {
@@ -353,7 +353,7 @@ const SelectedIconCircle = styled.div`
353353
width: 52px;
354354
height: 52px;
355355
border-radius: 12px;
356-
background: ${theme.colors.neutral[0]};
356+
background: ${(p) => p.theme.colors.neutral0};
357357
border: 2px solid ${theme.colors.primary[500]};
358358
display: flex;
359359
align-items: center;
@@ -372,7 +372,7 @@ const PublicToggleContainer = styled.div`
372372
align-items: center;
373373
justify-content: space-between;
374374
padding: 14px 16px;
375-
background: ${theme.colors.neutral[100]};
375+
background: ${(p) => p.theme.colors.neutral100};
376376
border-radius: 10px;
377377
margin-bottom: 16px;
378378
`;
@@ -432,9 +432,9 @@ const SwitchSlider = styled.span<{ $checked?: boolean }>`
432432
const SelectionList = styled.div<{ $disabled?: boolean }>`
433433
max-height: 140px;
434434
overflow-y: auto;
435-
border: 1px solid ${theme.colors.neutral[200]};
435+
border: 1px solid rgba(128, 128, 128, 0.25);
436436
border-radius: 8px;
437-
background: ${props => props.$disabled ? theme.colors.neutral[100] : theme.colors.neutral[0]};
437+
background: ${props => props.$disabled ? props.theme.colors.neutral100 : props.theme.colors.neutral0};
438438
opacity: ${props => props.$disabled ? 0.6 : 1};
439439
pointer-events: ${props => props.$disabled ? 'none' : 'auto'};
440440
@@ -458,7 +458,7 @@ const SelectionItem = styled.label<{ $selected?: boolean }>`
458458
gap: 12px;
459459
padding: 10px 14px;
460460
cursor: pointer;
461-
border-bottom: 1px solid ${theme.colors.neutral[200]};
461+
border-bottom: 1px solid rgba(128, 128, 128, 0.25);
462462
background: ${props => props.$selected ? theme.colors.primary[100] : 'transparent'};
463463
transition: all 0.15s ease;
464464
@@ -467,15 +467,15 @@ const SelectionItem = styled.label<{ $selected?: boolean }>`
467467
}
468468
469469
&:hover {
470-
background: ${props => props.$selected ? theme.colors.primary[100] : theme.colors.neutral[100]};
470+
background: ${props => props.$selected ? theme.colors.primary[100] : props.theme.colors.neutral100};
471471
}
472472
`;
473473

474474
const CustomCheckbox = styled.div<{ $checked?: boolean }>`
475475
width: 20px;
476476
height: 20px;
477477
border-radius: 4px;
478-
border: 2px solid ${props => props.$checked ? theme.colors.primary[500] : theme.colors.neutral[400]};
478+
border: 2px solid ${props => props.$checked ? theme.colors.primary[500] : props.theme.colors.neutral400};
479479
background: ${props => props.$checked ? theme.colors.primary[500] : 'transparent'};
480480
display: flex;
481481
align-items: center;
@@ -493,7 +493,7 @@ const CustomCheckbox = styled.div<{ $checked?: boolean }>`
493493

494494
const ItemLabel = styled.span<{ $selected?: boolean }>`
495495
font-size: 0.875rem;
496-
color: ${props => props.$selected ? theme.colors.primary[600] : theme.colors.neutral[800]};
496+
color: ${props => props.$selected ? theme.colors.primary[600] : props.theme.colors.neutral800};
497497
font-weight: ${props => props.$selected ? 600 : 400};
498498
`;
499499

@@ -518,13 +518,13 @@ const Label = styled.label`
518518
display: block;
519519
font-size: 0.875rem;
520520
font-weight: 600;
521-
color: ${theme.colors.neutral[800]};
521+
color: ${(p) => p.theme.colors.neutral800};
522522
margin-bottom: 8px;
523523
`;
524524

525525
const HintText = styled.p`
526526
font-size: 0.75rem;
527-
color: ${theme.colors.neutral[600]};
527+
color: ${(p) => p.theme.colors.neutral600};
528528
margin-top: 6px;
529529
display: flex;
530530
align-items: center;
@@ -539,12 +539,12 @@ const HintText = styled.p`
539539

540540
const PathDisplay = styled.div`
541541
padding: 12px 14px;
542-
background: ${theme.colors.neutral[100]};
543-
border: 1px solid ${theme.colors.neutral[200]};
542+
background: ${(p) => p.theme.colors.neutral100};
543+
border: 1px solid rgba(128, 128, 128, 0.25);
544544
border-radius: 8px;
545545
font-family: 'Monaco', 'Menlo', monospace;
546546
font-size: 0.8rem;
547-
color: ${theme.colors.neutral[600]};
547+
color: ${(p) => p.theme.colors.neutral600};
548548
word-break: break-all;
549549
`;
550550

@@ -565,7 +565,7 @@ const ErrorBox = styled.div`
565565
const SectionLabel = styled.div`
566566
font-size: 0.75rem;
567567
font-weight: 600;
568-
color: ${theme.colors.neutral[600]};
568+
color: ${(p) => p.theme.colors.neutral600};
569569
text-transform: uppercase;
570570
letter-spacing: 0.5px;
571571
margin-bottom: 8px;
@@ -579,7 +579,7 @@ const SectionLabel = styled.div`
579579
const StyledTextInput = styled(TextInput)`
580580
input {
581581
border-radius: 8px;
582-
border: 1px solid ${theme.colors.neutral[200]};
582+
border: 1px solid rgba(128, 128, 128, 0.25);
583583
584584
&:focus {
585585
border-color: ${theme.colors.primary[500]};
@@ -591,7 +591,7 @@ const StyledTextInput = styled(TextInput)`
591591
const StyledTextarea = styled(Textarea)`
592592
textarea {
593593
border-radius: 8px;
594-
border: 1px solid ${theme.colors.neutral[200]};
594+
border: 1px solid rgba(128, 128, 128, 0.25);
595595
min-height: 80px;
596596
597597
&:focus {
@@ -844,7 +844,7 @@ const CreateEditModal: React.FC<CreateEditModalProps> = ({
844844
<SelectedIcon />
845845
</SelectedIconCircle>
846846
<div style={{ display: 'flex', flexDirection: 'column', gap: '2px' }}>
847-
<Typography variant="pi" fontWeight="semiBold" style={{ color: theme.colors.neutral[800], display: 'block' }}>
847+
<Typography variant="pi" fontWeight="semiBold" style={{ color: 'var(--colors-neutral800, #32324D)', display: 'block' }}>
848848
{BOOKMARK_ICONS.find(i => i.id === icon)?.label || 'Bookmark'}
849849
</Typography>
850850
<Typography variant="pi" textColor="neutral600" style={{ fontSize: '0.75rem', display: 'block' }}>
@@ -893,10 +893,10 @@ const CreateEditModal: React.FC<CreateEditModalProps> = ({
893893
<PublicToggleInfo>
894894
<GlobeAltIcon />
895895
<div style={{ display: 'flex', flexDirection: 'column', gap: '2px' }}>
896-
<Typography variant="pi" fontWeight="semiBold" style={{ color: theme.colors.neutral[800], display: 'block' }}>
896+
<Typography variant="pi" fontWeight="semiBold" style={{ color: 'var(--colors-neutral800, #32324D)', display: 'block' }}>
897897
Public Bookmark
898898
</Typography>
899-
<Typography variant="pi" style={{ fontSize: '0.75rem', color: theme.colors.neutral[600], display: 'block' }}>
899+
<Typography variant="pi" style={{ fontSize: '0.75rem', color: 'var(--colors-neutral600, #666687)', display: 'block' }}>
900900
All admin users can see this
901901
</Typography>
902902
</div>
@@ -1003,7 +1003,7 @@ const CreateEditModal: React.FC<CreateEditModalProps> = ({
10031003
<FormField>
10041004
<Label>
10051005
{formatMessage({ id: `${pluginId}.form.description`, defaultMessage: 'Description' })}
1006-
<span style={{ fontWeight: 400, color: theme.colors.neutral[600] }}> (Optional)</span>
1006+
<span style={{ fontWeight: 400, color: 'var(--colors-neutral600, #666687)' }}> (Optional)</span>
10071007
</Label>
10081008
<StyledTextarea
10091009
placeholder={formatMessage({ id: `${pluginId}.form.descriptionPlaceholder`, defaultMessage: 'Add a description...' })}

admin/src/components/CreateViewModal.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const IconPicker = styled.div`
2323
grid-template-columns: repeat(8, 1fr);
2424
gap: 8px;
2525
padding: 12px;
26-
background: #f6f6f9;
26+
background: ${(p) => p.theme.colors.neutral100};
2727
border-radius: 6px;
2828
max-height: 200px;
2929
overflow-y: auto;
@@ -35,8 +35,8 @@ const IconButton = styled.button<{ $isSelected?: boolean }>`
3535
align-items: center;
3636
justify-content: center;
3737
padding: 10px;
38-
border: 2px solid ${props => props.$isSelected ? '#4945FF' : '#dcdce4'};
39-
background: ${props => props.$isSelected ? '#EEF0FF' : '#ffffff'};
38+
border: 2px solid ${props => props.$isSelected ? '#4945FF' : 'rgba(128, 128, 128, 0.25)'};
39+
background: ${props => props.$isSelected ? '#EEF0FF' : props.theme.colors.neutral0};
4040
border-radius: 6px;
4141
cursor: pointer;
4242
transition: all 0.15s ease;

0 commit comments

Comments
 (0)