Skip to content

💄 Fix light/dark themes for admin #616

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 49 additions & 5 deletions src/objects/scss/admin/_admin_theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,15 @@ Generic admin styling overrides.

DO NOT PUT ANY TARGET APP-SPECIFIC RULES HERE.
*/
@use './themes/dark' as dark-theme;
@use './themes/light' as light-theme;

@import "./vars";

@include light-theme.styles;
@include dark-theme.styles;


// override django CSS variables
// see admin/static/admin/css/base.css for a reference
:root {
Expand Down Expand Up @@ -131,22 +138,59 @@ div.breadcrumbs {
font-weight: bold !important;
}

@mixin icon-override($iconUrl) {
background: none;
// display: inline-flex;
// align-items: center;
// padding-left: 0;
color: var(--body-fg);
position: relative;

// need to use pseudo element, otherwise the text in the same element is not visible
// because of the mask clipping
&:before {
display: block;
content: '';
position: absolute;
left: 0;
top: 0;
width: 14px;
height: 14px;
margin-right: 2px;
background: var(--body-fg) !important;
color: var(--body-fg);
mask-image: url($iconUrl);
mask-repeat: no-repeat;
mask-size: 14px 14px;
mask-position: 0px 0px;
}
}

/* Icons */
.addlink {
background: url("../img/admin/plus-square-regular.svg") 0 0/14px 14px no-repeat;
@include icon-override('../img/admin/plus-square-regular.svg');
}

.object-tools a.addlink {
&:before {
display: none;
}
}

.changelink,
.inlinechangelink {
background: url("../img/admin/edit-regular.svg") 0 0/14px 14px no-repeat;
@include icon-override('../img/admin/edit-regular.svg');
}
.deletelink {
background: url("../img/admin/trash-alt-regular.svg") 0 0/14px 14px no-repeat;
background: url('../img/admin/trash-alt-regular.svg') 0 0/14px 14px no-repeat;
}
.datetimeshortcuts .clock-icon {
background: url("../img/admin/clock-regular.svg") 0 0/14px 14px no-repeat !important;
@include icon-override('../img/admin/clock-regular.svg');
background: none !important;
}
.datetimeshortcuts .date-icon {
background: url("../img/admin/calendar-alt-regular.svg") 0 0/14px 14px no-repeat !important;
@include icon-override('../img/admin/calendar-alt-regular.svg');
background: none !important;
}

/**
Expand Down
5 changes: 4 additions & 1 deletion src/objects/scss/admin/_app_overrides.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ $djai-border-width: 8px;
width: 100%;

/* Added to attach to body/breadcrumbs */
border-bottom: $djai-border-width solid $color_secondary;
border-bottom: var(--oz-djai-border-bottom-width) solid var(--oz-djai-border-bottom-color);

& &__drop {
min-width: 250px !important;
Expand Down Expand Up @@ -70,6 +70,9 @@ $djai-border-width: 8px;
}
}
}
@at-root body.login #header {
padding-bottom: 15px !important;
}
}

// TODO: check environment banner
Expand Down
36 changes: 18 additions & 18 deletions src/objects/scss/admin/_vars.scss
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
/* Colors */
$color-primary: #04a5bb;
$color-primary-dark: #017092;
$color-primary-light: #c3eaef;
$color_primary: #04a5bb;
$color_primary_dark: #017092;
$color_primary_light: #c3eaef;

$color-secondary: #f3f3f3;
$color-secondary-dark: #ddd;
$color-secondary-light: #fff;
$color_secondary: #f3f3f3;
$color_secondary_dark: #ddd;
$color_secondary_light: #fff;

$color-link: #017092;
$color-link-hover: #051f31;
$color_link: #017092;
$color_link_hover: #051f31;

$color-darkest: #000;
$color-dark: #333;
$color-lightest: #fff;
$color_darkest: #000;
$color_dark: #333;
$color_lightest: #fff;

$color-error: #ba2121; // default django admin color
$color_error: #ba2121; // default django admin color

$color-tooltip-background: #fffeaa;
$color-tooltip-border: #f7f071;
$color-tooltip-text: #000;
$color_tooltip_background: #fffeaa;
$color_tooltip_border: #f7f071;
$color_tooltip_text: #000;

/* Dimensions */
$input-field-size: 20em; // django-original: 20em;
$input_field_size: 20em; // django-original: 20em;

/* Responsive breakpoints used int the Django admin */
$breakpoint-tablet: 768px;
$breakpoint-laptop: 1025px;
$breakpoint_tablet: 768px;
$breakpoint_laptop: 1025px;
89 changes: 89 additions & 0 deletions src/objects/scss/admin/themes/_dark.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: EUPL-1.2 */
/* Copyright (C) 2025 Dimpact */
/**
* Dark theme implementation.
*
* Use this as:
*
* @use './themes/dark' as dark-theme;
*
* @include dark-theme.styles;
*/

/**
* Define the CSS properties overriding default admin theme.
*/
@mixin variables {
--primary: #037383 !important;
--secondary: #037383 !important;

--breadcrumbs-fg: #2fc0ec;
--breadcrumbs-link-hover: #888;
--breadcrumbs-bg: #333;

--link-fg: #04a5bb;
--link-hover-color: #b2cddf;

--hairline-color: #686868;

--button-hover-bg: #04a5bb;
--default-button-bg: #04a5bb;
--default-button-hover-bg: #888;
}

@mixin djai-variables {

// use a more specific selector so that the dark theme overrides the default,
// less specific selector.
.djai-dropdown-menu {
--djai-tab-bg--hover: #04a5bb;
--djai-tab-fg--active: #fff;
--djai-dropdown-bg--hover: #04a5bb;

--oz-djai-border-bottom-color: #333;
}
}

@mixin bootstrap {

.btn,
.btn:hover {
color: var(--body-fg);
}

pre {
color: var(--body-fg);
}
}


/**
* Aggregate the bits and pieces to define the dark theme style rules.
*/
@mixin styles {

// Include the relevant variables
@media (prefers-color-scheme: dark) {

// This either gets overridden by the more specific light theme selector, or applies
// in auto mode through the media query.
:root {
@include variables;
}

// only apply based on browser preferences if the theme is not explicitly set to
// light or dark
html[data-theme='auto'] {
@include variables;
@include djai-variables;
@include bootstrap;
}
}

// explicit dark-mode -> apply all relevant styles
html[data-theme='dark'] {
@include variables;
@include djai-variables;
@include bootstrap;
}
}
84 changes: 84 additions & 0 deletions src/objects/scss/admin/themes/_light.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: EUPL-1.2 */
/* Copyright (C) 2025 Dimpact */
/**
* Light/default theme implementation.
*
* Use this as:
*
* @use './themes/light' as light-theme;
*
* @include light-theme.styles;
*/

/**
* Define the CSS properties overriding default admin theme.
*
* @todo - check if the !important's are still needed?
*
* See `admin/static/admin/css/base.css` for a reference of available variables.
*/
@mixin variables {
--primary: #04a5bb !important;
--accent: #f3f3f3;
--secondary: #04a5bb !important;
--primary-fg: #fff;

--header-color: #fff;

--breadcrumbs-fg: #04a5bb;
--breadcrumbs-link-fg: var(--body-fg);
--breadcrumbs-link-hover: #000; // not in the core django vars
--breadcrumbs-bg: #f3f3f3;

--link-fg: #017092;
--link-hover-color: #051f31;
--link-selected-fg: #5b80b2;

// #748 client requested increased contrast for form-row borders
// here we override a django admin style
--hairline-color: #e5e5e5;

// --button-bg: var(--primary);
--button-fg: #fff;
--button-hover-bg: #017092;
--default-button-bg: #017092;
--default-button-hover-bg: #000;
--close-button-bg: #888;
--close-button-hover-bg: #333;

--object-tools-bg: #888;
--object-tools-hover-bg: #333;
}

@mixin djai-variables {
--djai-tab-bg: var(--primary); // no fallback to default admin vars
--djai-tab-bg--active: var(--breadcrumbs-bg);
--djai-tab-bg--hover: #017092;
--djai-tab-fg--active: var(--secondary);
--djai-dropdown-bg--active: #017092;
--djai-dropdown-bg--hover: #017092;

// custom properties
--oz-djai-border-bottom-width: 8px;
--oz-djai-border-bottom-color: #f3f3f3;
}

/**
* Aggregate the bits and pieces to define the light theme style rules.
*
* The light theme styles are not guarded by a media query to make sure they're the
* default that is applied.
*/
@mixin styles {

html[data-theme='light'],
:root {
@include variables;
}

// generic selector to be more specific than the library itself, but less specific
// than the dark theme styles
body {
@include djai-variables;
}
}
6 changes: 6 additions & 0 deletions src/objects/templates/admin/base_site.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

{% block branding %}
<h1 id="site-name"><a href="{% url 'admin:index' %}">{{ settings.PROJECT_NAME }} {% trans 'Administration' %}</a></h1>

{% if user.is_anonymous %}
{% include "admin/color_theme_toggle.html" %}
{% endif %}
{% endblock %}

{% block welcome-msg %}
Expand All @@ -35,6 +39,8 @@ <h1 id="site-name"><a href="{% url 'admin:index' %}">{{ settings.PROJECT_NAME }}
{% csrf_token %}
<button type="submit">{% trans 'Log out' %}</button>
</form>

{% include "admin/color_theme_toggle.html" %}
{% endblock %}

{% block nav-global %}{% endblock %}
Expand Down