kopia lustrzana https://github.com/wagtail/wagtail
Implement support for branding_logo sidebar customisation in slim sidebar
rodzic
036fd3a4ac
commit
1341b3c9c9
|
@ -112,7 +112,6 @@
|
|||
@import 'SidebarPanel';
|
||||
@import 'menu/MenuItem';
|
||||
@import 'menu/SubMenuItem';
|
||||
@import 'modules/CustomBranding';
|
||||
@import 'modules/MainMenu';
|
||||
@import 'modules/Search';
|
||||
@import 'modules/WagtailBranding';
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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}
|
||||
/>);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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/')))
|
||||
|
|
|
@ -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):
|
||||
|
|
Ładowanie…
Reference in New Issue