Implement support for branding_logo sidebar customisation in slim sidebar

pull/7568/head
Thibaud Colas 2022-01-13 15:02:46 +00:00
rodzic 036fd3a4ac
commit 1341b3c9c9
10 zmienionych plików z 68 dodań i 152 usunięć

Wyświetl plik

@ -112,7 +112,6 @@
@import 'SidebarPanel';
@import 'menu/MenuItem';
@import 'menu/SubMenuItem';
@import 'modules/CustomBranding';
@import 'modules/MainMenu';
@import 'modules/Search';
@import 'modules/WagtailBranding';

Wyświetl plik

@ -10,7 +10,6 @@ import { SubMenuItemDefinition } from './menu/SubMenuItem';
import { initFocusOutline } from '../../utils/focus';
import '../../../../wagtail/admin/static/wagtailadmin/css/sidebar.css';
import { CustomBrandingModuleDefinition } from './modules/CustomBranding';
export default { title: 'Sidebar/Sidebar', parameters: { layout: 'fullscreen' } };
@ -261,14 +260,6 @@ export function standard() {
]);
}
export function withCustomBranding() {
return renderSidebarStory([
new CustomBrandingModuleDefinition('/admin/', '<p>Custom branding (todo)</p>'),
searchModule(),
bogStandardMenuModule(),
]);
}
export function withNestedSubmenu() {
const menuModule = bogStandardMenuModule();

Wyświetl plik

@ -1,19 +0,0 @@
.sidebar-custom-branding {
display: block;
align-items: center;
color: #aaa;
-webkit-font-smoothing: auto;
position: relative;
margin: 2em auto;
text-align: center;
padding: 10px 0;
transition: padding $menu-transition-duration ease;
&:hover {
color: $color-white;
}
@at-root .sidebar--slim #{&} {
padding: 40px 0;
}
}

Wyświetl plik

@ -1,67 +0,0 @@
/* eslint-disable react/prop-types */
import * as React from 'react';
import { ModuleDefinition } from '../Sidebar';
interface CustomBrandingProps {
homeUrl: string;
html: string;
strings;
currentPath: string;
navigate(url: string): void;
}
const CustomBranding: React.FunctionComponent<CustomBrandingProps> = ({
homeUrl,
html,
strings,
currentPath,
navigate,
}) => {
const onClick = (e: React.MouseEvent) => {
// Do not capture click events with modifier keys or non-main buttons.
if (
e.ctrlKey ||
e.shiftKey ||
e.metaKey ||
(e.button && e.button !== 0)
) {
return;
}
e.preventDefault();
navigate(homeUrl);
};
return (
<a
className="sidebar-custom-branding"
href={homeUrl}
onClick={onClick}
aria-label={strings.DASHBOARD}
aria-current={currentPath === homeUrl ? 'page' : undefined}
dangerouslySetInnerHTML={{ __html: html }}
/>
);
};
export class CustomBrandingModuleDefinition implements ModuleDefinition {
homeUrl: string;
html: string;
constructor(homeUrl: string, html: string) {
this.homeUrl = homeUrl;
this.html = html;
}
render({ strings, currentPath, navigate, key }) {
return (<CustomBranding
key={key}
homeUrl={this.homeUrl}
html={this.html}
strings={strings}
currentPath={currentPath}
navigate={navigate}
/>);
}
}

Wyświetl plik

@ -122,3 +122,23 @@
}
}
}
.sidebar-custom-branding {
display: block;
align-items: center;
color: #aaa;
-webkit-font-smoothing: auto;
position: relative;
margin: 2em auto;
text-align: center;
padding: 10px 0;
transition: padding $menu-transition-duration ease;
&:hover {
color: $color-white;
}
@at-root .sidebar--slim #{&} {
padding: 40px 0;
}
}

Wyświetl plik

@ -26,13 +26,14 @@ const WagtailBranding: React.FunctionComponent<WagtailBrandingProps> = ({
currentPath,
navigate,
}) => {
// Tail wagging
// If the pointer changes direction 8 or more times without leaving, wag the tail!
const lastMouseX = React.useRef(0);
const lastDir = React.useRef<'r' | 'l'>('r');
const dirChangeCount = React.useRef(0);
const [isWagging, setIsWagging] = React.useState(false);
const brandingLogo = React.useMemo(
() =>
document.querySelector<HTMLTemplateElement>(
'[data-wagtail-sidebar-branding-logo]'
),
[]
);
const hasCustomBranding = brandingLogo && brandingLogo.innerHTML !== '';
const onClick = (e: React.MouseEvent) => {
// Do not capture click events with modifier keys or non-main buttons.
@ -49,6 +50,27 @@ const WagtailBranding: React.FunctionComponent<WagtailBrandingProps> = ({
navigate(homeUrl);
};
// Render differently if custom branding is provided.
// This will only ever render once, so rendering before hooks is ok.
if (hasCustomBranding) {
return (
<a
className="sidebar-custom-branding"
href={homeUrl}
aria-label={strings.DASHBOARD}
aria-current={currentPath === homeUrl ? 'page' : undefined}
dangerouslySetInnerHTML={{ __html: brandingLogo ? brandingLogo.innerHTML : '' }}
/>
);
}
// Tail wagging
// If the pointer changes direction 8 or more times without leaving, wag the tail!
const lastMouseX = React.useRef(0);
const lastDir = React.useRef<'r' | 'l'>('r');
const dirChangeCount = React.useRef(0);
const [isWagging, setIsWagging] = React.useState(false);
const onMouseMove = (e: React.MouseEvent) => {
const mouseX = e.pageX;
const dir: 'r' | 'l' = (mouseX > lastMouseX.current) ? 'r' : 'l';

Wyświetl plik

@ -3,7 +3,6 @@ import { LinkMenuItemDefinition } from '../../components/Sidebar/menu/LinkMenuIt
import { SubMenuItemDefinition } from '../../components/Sidebar/menu/SubMenuItem';
import { PageExplorerMenuItemDefinition } from '../../components/Sidebar/menu/PageExplorerMenuItem';
import { CustomBrandingModuleDefinition } from '../../components/Sidebar/modules/CustomBranding';
import { WagtailBrandingModuleDefinition } from '../../components/Sidebar/modules/WagtailBranding';
import { SearchModuleDefinition } from '../../components/Sidebar/modules/Search';
import { MainMenuModuleDefinition } from '../../components/Sidebar/modules/MainMenu';
@ -13,7 +12,6 @@ window.telepath.register('wagtail.sidebar.SubMenuItem', SubMenuItemDefinition);
window.telepath.register('wagtail.sidebar.PageExplorerMenuItem', PageExplorerMenuItemDefinition);
window.telepath.register('wagtail.sidebar.WagtailBrandingModule', WagtailBrandingModuleDefinition);
window.telepath.register('wagtail.sidebar.CustomBrandingModule', CustomBrandingModuleDefinition);
window.telepath.register('wagtail.sidebar.SearchModule', SearchModuleDefinition);
window.telepath.register('wagtail.sidebar.MainMenuModule', MainMenuModuleDefinition);

Wyświetl plik

@ -3,21 +3,20 @@
{% block furniture %}
{% slim_sidebar_enabled as slim_sidebar_enabled %}
<template data-wagtail-sidebar-branding-logo>{% block branding_logo %}{% endblock %}</template>
{% if slim_sidebar_enabled %}
<aside id="wagtail-sidebar" data-wagtail-sidebar data-props="{% menu_props %}"></aside>
{% else %}
<aside id="wagtail-sidebar" class="nav-wrapper" data-nav-primary>
<div class="inner">
<a href="{% url 'wagtailadmin_home' %}" class="logo" aria-label="{% trans 'Dashboard' %}">
{% block branding_logo %}
{# Mobile-only logo: #}
<div class="wagtail-logo-container__mobile u-hidden@sm">
<img class="wagtail-logo wagtail-logo__full" src="{% versioned_static 'wagtailadmin/images/wagtail-logo.svg' %}" alt="" width="80" />
</div>
{# Mobile-only logo: #}
<div class="wagtail-logo-container__mobile u-hidden@sm">
<img class="wagtail-logo wagtail-logo__full" src="{% versioned_static 'wagtailadmin/images/wagtail-logo.svg' %}" alt="" width="80" />
</div>
{# Desktop logo (animated): #}
{% include "wagtailadmin/shared/animated_logo.html" %}
{% endblock %}
{# Desktop logo (animated): #}
{% include "wagtailadmin/shared/animated_logo.html" %}
<span class="u-hidden@sm">{% trans "Dashboard" %}</span>
</a>
@ -26,6 +25,16 @@
</div>
<div class="explorer__wrapper" data-explorer-menu></div>
</aside>
{# Backwards-compatibility for branding_logo customisations in legacy sidebar. #}
{# TODO Remove in Wagtail 2.17 #}
<script>
const branding_logo = document.querySelector('[data-wagtail-sidebar-branding-logo]');
const legacySidebar = document.querySelector('[data-nav-primary]');
if (branding_logo && branding_logo.innerHTML && legacySidebar) {
const link = legacySidebar.querySelector('a');
link.innerHTML = `${branding_logo.innerHTML}<span class="u-hidden@sm">{% trans "Dashboard" %}</span>`;
}
</script>
{% endif %}
<main class="content-wrapper" role="main" id="main">

Wyświetl plik

@ -5,8 +5,8 @@ from django.urls import reverse
from wagtail.admin.search import SearchArea
from wagtail.admin.ui.sidebar import (
CustomBrandingModule, LinkMenuItem, MainMenuModule, PageExplorerMenuItem, SearchModule,
SubMenuItem, WagtailBrandingModule)
LinkMenuItem, MainMenuModule, PageExplorerMenuItem, SearchModule, SubMenuItem,
WagtailBrandingModule)
from wagtail.core.telepath import JSContext
from wagtail.tests.utils import WagtailTestUtils
@ -150,30 +150,6 @@ class TestAdaptWagtailBrandingModule(TestCase):
})
class TestAdaptCustomBrandingModule(TestCase):
def test_adapt(self):
packed = JSContext().pack(CustomBrandingModule('<h1>My custom branding</h1>'))
self.assertEqual(packed, {
'_type': 'wagtail.sidebar.CustomBrandingModule',
'_args': [
'<h1>My custom branding</h1>',
False
]
})
def test_collapsible(self):
packed = JSContext().pack(CustomBrandingModule('<h1>My custom branding</h1>', collapsible=True))
self.assertEqual(packed, {
'_type': 'wagtail.sidebar.CustomBrandingModule',
'_args': [
'<h1>My custom branding</h1>',
True
]
})
class TestAdaptSearchModule(TestCase):
def test_adapt(self):
packed = JSContext().pack(SearchModule(SearchArea("Search", '/search/')))

Wyświetl plik

@ -123,19 +123,6 @@ class WagtailBrandingModule:
]
@adapter('wagtail.sidebar.CustomBrandingModule', base=BaseSidebarAdapter)
class CustomBrandingModule:
def __init__(self, html, collapsible=False):
self.html = html
self.collapsible = collapsible
def js_args(self):
return [
self.html,
self.collapsible,
]
@adapter('wagtail.sidebar.SearchModule', base=BaseSidebarAdapter)
class SearchModule:
def __init__(self, search_area):