Implement collapsible and linkable panels

Co-authored-by: LB Johnston <mail@lb.ee>
pull/8948/head
Thibaud Colas 2022-07-25 15:15:31 +01:00
rodzic af9b16e93d
commit 3d96e7fbe7
34 zmienionych plików z 324 dodań i 113 usunięć

Wyświetl plik

@ -217,3 +217,8 @@
}
}
}
// For pages with the slim header, make sure the header is accounted for when scrolling to an anchor.
.page-slim-header {
scroll-padding-top: calc(theme('spacing.slim-header') + 1rem);
}

Wyświetl plik

@ -0,0 +1,77 @@
.w-panel {
margin-bottom: theme('spacing.10');
}
.w-panel__header {
display: flex;
align-items: center;
gap: theme('spacing.2');
margin-bottom: theme('spacing.5');
margin-left: calc(-1 * 2 * (theme('spacing.6') + theme('spacing.2')));
}
.w-panel__heading {
@apply w-h3;
display: inline-block;
margin: 0;
}
.w-panel__heading--label {
@apply w-label-1;
}
.w-panel__anchor,
.w-panel__toggle {
display: inline-grid;
justify-content: center;
align-content: center;
color: theme('colors.primary.DEFAULT');
padding: 0;
width: theme('spacing.6');
height: theme('spacing.6');
}
.w-panel__anchor {
visibility: hidden;
.w-panel__header:hover &,
.w-panel__header:focus-within & {
visibility: visible;
}
}
.w-panel__toggle {
appearance: none;
background: transparent;
}
.w-panel__icon {
width: theme('spacing.5');
height: theme('spacing.5');
[aria-expanded='false'] & {
transform: rotate(-90deg);
}
&.icon-link {
width: theme('spacing.[3.5]');
height: theme('spacing.[3.5]');
}
}
.w-panel__icon--custom {
// Only display the default icon when closed.
[aria-expanded='false'] & {
display: none;
}
// Hide the default icon when expanded.
[aria-expanded='true'] & + .w-panel__icon {
display: none;
}
}
// TODO Forms
.w-panel--row .w-panel__content {
@apply w-grid lg:w-grid-flow-col lg:w-grid-cols-3;
}

Wyświetl plik

@ -0,0 +1,28 @@
.w-field {
position: relative;
}
.w-field__errors {
@apply w-label-2;
color: theme('colors.critical.200');
margin-bottom: theme('spacing.[2.5]');
}
.w-field__errors-icon {
width: 1em;
height: 1em;
position: relative;
top: 0.125em;
margin-inline-end: 0.375em;
}
.w-field__label {
@apply w-label-3;
display: block;
margin-bottom: theme('spacing.3');
}
// Only add space in-between fields when there is more than one.
.w-field__wrapper + .w-field__wrapper {
margin-top: theme('spacing.5');
}

Wyświetl plik

@ -120,7 +120,9 @@ These are classes for components.
@import 'components/forms/file';
@import 'components/forms/switch';
@import 'components/forms/title';
@import 'components/forms/field-panel';
@import 'components/tabs';
@import 'components/panel';
@import 'components/dialog';
@import 'components/dropdown';
@import 'components/dropdown.legacy';

Wyświetl plik

@ -56,6 +56,12 @@ audio:not([controls]) {
display: none !important;
}
// See https://github.com/necolas/normalize.css/pull/879.
[hidden='until-found'] {
/* stylelint-disable-next-line declaration-no-important */
display: revert !important;
}
/* ==========================================================================
Base
========================================================================== */

Wyświetl plik

@ -93,7 +93,7 @@
display: none; // Nav toggle is for mobile only
&--mobile {
@apply w-bg-primary w-top-0 w-left-0 w-h-[50px] w-w-[50px] w-rounded-none hover:w-bg-primary-200;
@apply w-bg-primary w-top-0 w-left-0 w-h-slim-header w-w-slim-header w-rounded-none hover:w-bg-primary-200;
display: grid;
}

Wyświetl plik

@ -1,44 +0,0 @@
import $ from 'jquery';
function initCollapsibleBlocks() {
// eslint-disable-next-line func-names
$('.object.collapsible').each(function () {
const $target = $(this);
const $content = $target.find('.object-layout');
const onAnimationComplete = () =>
$content
.get(0)
.dispatchEvent(
new CustomEvent('commentAnchorVisibilityChange', { bubbles: true }),
);
if (
$target.hasClass('collapsed') &&
$target.find('.error-message').length === 0
) {
$content.hide({
complete: onAnimationComplete,
});
}
$target.find('> .title-wrapper').on('click', () => {
if (!$target.hasClass('collapsed')) {
$target.addClass('collapsed');
$content.hide({
duration: 'slow',
complete: onAnimationComplete,
});
} else {
$target.removeClass('collapsed');
$content.show({
duration: 'slow',
complete: onAnimationComplete,
});
}
});
});
}
window.initCollapsibleBlocks = initCollapsibleBlocks;
$(() => {
initCollapsibleBlocks();
});

Wyświetl plik

@ -345,7 +345,7 @@ window.comments = (() => {
commentCounter.className =
'-w-mr-3 w-py-0.5 w-px-[0.325rem] w-translate-y-[-8px] w-translate-x-[-4px] w-text-[0.5625rem] w-font-bold w-bg-secondary-100 w-text-white w-border w-border-white w-rounded-[1rem]';
commentToggle.className =
'w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary';
'w-h-slim-header w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary';
commentToggle.appendChild(commentCounter);
const updateCommentCount = () => {

Wyświetl plik

@ -6,6 +6,10 @@ import { initTabs } from '../../includes/tabs';
import { dialog } from '../../includes/dialog';
import initCollapsibleBreadcrumbs from '../../includes/breadcrumbs';
import initSidePanel from '../../includes/sidePanel';
import {
initAnchoredPanels,
initCollapsiblePanels,
} from '../../includes/panels';
if (process.env.NODE_ENV === 'development') {
// Run react-axe in development only, so it does not affect performance
@ -33,4 +37,13 @@ document.addEventListener('DOMContentLoaded', () => {
dialog();
initCollapsibleBreadcrumbs();
initSidePanel();
initCollapsiblePanels();
});
/**
* Prefer the documents DOMContentLoaded if possible.
* window `load` only fires once the pages resources are loaded.
*/
window.addEventListener('load', () => {
initAnchoredPanels();
});

Wyświetl plik

@ -0,0 +1,68 @@
/**
* Make panels collapsible, and collapse panels already marked as `collapsed`.
*/
export function initCollapsiblePanels() {
const toggles = document.querySelectorAll<HTMLButtonElement>(
'[data-panel-toggle]',
);
toggles.forEach((toggle) => {
const panel = toggle.closest<HTMLElement>('[data-panel]');
const content = document.querySelector<HTMLDivElement>(
`#${toggle.getAttribute('aria-controls')}`,
);
if (!content || !panel) {
return;
}
const onAnimationComplete = () => {
content.dispatchEvent(
new CustomEvent('commentAnchorVisibilityChange', { bubbles: true }),
);
};
const hasCollapsed = panel.classList.contains('collapsed');
const hasError = content.querySelector('[aria-invalid="true"]');
// Collapse panels marked as `collapsed`, unless they contain invalid fields.
if (hasCollapsed && !hasError) {
// Use experimental `until-found` value.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
content.hidden = 'until-found';
toggle.setAttribute('aria-expanded', 'false');
onAnimationComplete();
}
toggle.addEventListener('click', () => {
const wasExpanded = toggle.getAttribute('aria-expanded') === 'true';
const isExpanded = !wasExpanded;
// Use experimental `until-found` value, so users can search inside the panels.
// Browsers without support for `until-found` will ignore the value.
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
content.hidden = !isExpanded ? 'until-found' : '';
onAnimationComplete();
toggle.setAttribute('aria-expanded', `${isExpanded}`);
});
// Set the toggle back to expanded upon reveal.
content.addEventListener('beforematch', () => {
toggle.setAttribute('aria-expanded', 'true');
});
});
}
/**
* Smooth scroll onto any active panel.
* Needs to run after the whole page is loaded so the browser can resolve any
* JS-driven :target.
*/
export function initAnchoredPanels() {
const anchorTarget = document.querySelector('[data-panel]:target');
if (anchorTarget) {
anchorTarget.scrollIntoView({ behavior: 'smooth' });
}
}

Wyświetl plik

@ -278,7 +278,12 @@ class Tabs {
selectTabByURLHash() {
if (window.location.hash) {
const cleanedHash = window.location.hash.replace(/[^\w\-#]/g, '');
const tab = this.getTabElementByHref(cleanedHash);
// Support linking straight to a tab, or to an element within a tab.
const tabID = document
.querySelector(cleanedHash)
?.closest('[role="tabpanel"]')
?.getAttribute('aria-labelledby');
const tab = document.getElementById(tabID);
if (tab) {
this.selectTab(tab);
} else {

Wyświetl plik

@ -83,7 +83,10 @@ module.exports = {
...boxShadow,
none: 'none',
},
spacing,
spacing: {
...spacing,
'slim-header': '50px',
},
extend: {
outlineOffset: {
inside: '-3px',

Wyświetl plik

@ -33,7 +33,6 @@ module.exports = function exports(env, argv) {
'admin': [
'chooser-modal',
'chooser-widget',
'collapsible',
'comments',
'core',
'date-time-chooser',

Wyświetl plik

@ -96,7 +96,7 @@ To add extra information to a block within one of the above Wagtail templates, u
{% block content %}
{{ block.super }}
<div class="object">
<div>
<img src="{% get_media_prefix %}{{ instance.image }}"/>
</div>
{% endblock %}

Wyświetl plik

@ -90,8 +90,7 @@ This is a powerful but complex feature which will take some space to cover, so w
#### Collapsing InlinePanels to save space
Note that you can use `classname="collapsible collapsed"` to load the panel collapsed under its heading in order to save space in the Wagtail admin.
See {ref}`collapsible` for more details on `collapsible` usage.
Note that you can use `classname="collapsed"` to load the panel collapsed under its heading in order to save space in the Wagtail admin.
### FieldRowPanel
@ -240,11 +239,6 @@ See {ref}`collapsible` for more details on `collapsible` usage.
By adding CSS classes to your panel definitions or adding extra parameters to your field definitions, you can control much of how your fields will display in the Wagtail page editing interface. Wagtail's page editing interface takes much of its behaviour from Django's admin, so you may find many options for customisation covered there.
(See [Django model field reference](django:ref/models/fields)).
### Full-Width Input
Use `classname="full"` to make a field (input element) stretch the full width of the Wagtail page editor. This will not work if the field is encapsulated in a
[`MultiFieldPanel`](wagtail.admin.panels.MultiFieldPanel), which places its child fields into a formset.
### Titles
Use `classname="title"` to make Page's built-in title field stand out with more vertical padding.
@ -253,12 +247,11 @@ Use `classname="title"` to make Page's built-in title field stand out with more
### Collapsible
By default, panels are expanded and not collapsible.
Use `classname="collapsible"` to enable the collapse control.
Use `classname="collapsible collapsed"` will load the editor page with the panel collapsed under its heading.
```{versionchanged} 4.0
All panels are now collapsible by default.
```
You must define a `heading` when using `collapsible` with `MultiFieldPanel`.
You must define a `heading` or `label` when using `collapsible` with `InlinePanel`.
Using `classname="collapsed"` will load the editor page with the panel collapsed under its heading.
```python
content_panels = [
@ -269,7 +262,7 @@ You must define a `heading` or `label` when using `collapsible` with `InlinePane
FieldPanel('publisher'),
],
heading="Collection of Book Fields",
classname="collapsible collapsed"
classname="collapsed"
),
]
```

Wyświetl plik

@ -0,0 +1 @@
<svg id="icon-caret-down" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"/></svg>

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 221 B

Wyświetl plik

@ -16,7 +16,6 @@
window.unicodeSlugsEnabled = {% if unicode_slugs_enabled %}true{% else %}false{% endif %};
</script>
<script src="{% versioned_static 'wagtailadmin/js/collapsible.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/comments.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/vendor/rangy-core.js' %}"></script>
<script src="{% versioned_static 'wagtailadmin/js/vendor/mousetrap.min.js' %}"></script>

Wyświetl plik

@ -3,7 +3,7 @@
{% load i18n %}
{% block titletag %}{% blocktrans trimmed with page_type=content_type.model_class.get_verbose_name %}New {{ page_type }}{% endblocktrans %}{% endblock %}
{% block bodyclass %}page-editor create model-{{ content_type.model }}{% endblock %}
{% block bodyclass %}page-slim-header{% endblock %}
{% block content %}
<div id="comments"></div>

Wyświetl plik

@ -3,7 +3,7 @@
{% load i18n %}
{% load l10n %}
{% block titletag %}{% blocktrans trimmed with title=page.get_admin_display_title page_type=content_type.model_class.get_verbose_name %}Editing {{ page_type }}: {{ title }}{% endblocktrans %}{% endblock %}
{% block bodyclass %}page-editor {% if page.live %}page-is-live{% endif %} model-{{ content_type.model }} {% if page_locked %}page-locked{% endif %}{% endblock %}
{% block bodyclass %}page-slim-header {% if page.live %}page-is-live{% endif %} {% if page_locked %}page-locked{% endif %}{% endblock %}
{% block content %}
<div id="comments"></div>

Wyświetl plik

@ -1,7 +1,7 @@
{% extends "wagtailadmin/base.html" %}
{% load wagtailadmin_tags i18n %}
{% block titletag %}{% blocktrans trimmed with title=parent_page.get_admin_display_title %}Exploring {{ title }}{% endblocktrans %}{% endblock %}
{% block bodyclass %}page-explorer {% if ordering == 'ord' %}reordering{% endif %}{% endblock %}
{% block bodyclass %}page-explorer page-slim-header {% if ordering == 'ord' %}reordering{% endif %}{% endblock %}
{% block content %}
{% page_permissions parent_page as parent_page_perms %}

Wyświetl plik

@ -16,7 +16,7 @@
{% page_header_buttons parent_page page_perms=page_perms %}
{% endblock %}
{% block actions %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-slim-header w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% if not parent_page.is_root %}
{% include "wagtailadmin/shared/side_panel_toggles.html" %}
{# Page history #}

Wyświetl plik

@ -1,12 +1,15 @@
{% load wagtailadmin_tags i18n %}
<div id="{{ self.prefix }}-field" class="w-field {% if field.errors %}w-field--error{% endif %}" data-contentpath="{{ field.name }}">
<div class="w-field w-field--{{ field|fieldtype }} w-field--{{ field|widgettype }} {% if field.errors %}w-field--error{% endif %}" data-contentpath="{{ field.name }}" id="{{ self.prefix }}-field">
{% if errors %}
<p id="{{ error_message_id }}" class="w-error"><svg width="16" height="16"><use href="#icon-cross"></use></svg>{% for error in errors %}{{ error }} {% endfor %}</p>
<p class="w-field__errors" id="{{ error_message_id }}">
{% icon name="warning" class_name="w-field__errors-icon" %}
{% for error in errors %}{{ error }} {% endfor %}
</p>
{% endif %}
{{ rendered_field }}
{% if help_text %}
<p id="{{ help_text_id }}" class="w-help-text">{{ help_text }}</p>
<div id="{{ help_text_id }}" class="help">{{ help_text }}</div>
{% endif %}
{% if show_add_comment_button %}

Wyświetl plik

@ -1,6 +1,10 @@
{% load wagtailadmin_tags %}
{% for child in self.visible_children %}
<label {% if child.id_for_label %}for="{{ child.id_for_label }}"{% endif %} class="w-field__label">{{ child.heading }}{% if child.is_required %}<span class="w-error" aria-hidden="true">*</span>{% endif %}</label>
<div class="w-field__wrapper">
{% if child.heading %}
<label {% if child.id_for_label %}for="{{ child.id_for_label }}"{% endif %} class="w-field__label">{{ child.heading }}{% if child.is_required %}<span class="w-required-mark">*</span>{% endif %}</label>
{% endif %}
{% component child %}
{% component child %}
</div>
{% endfor %}

Wyświetl plik

@ -1,33 +1,7 @@
{% load wagtailadmin_tags %}
{% for child, identifier in self.visible_children_with_identifiers %}
<section
id="{{ self.prefix }}-childsection-{{ identifier }}"
aria-labelledby="{{ self.prefix }}-childheading-{{ identifier }}"
class="w-panel"
>
<div class="w-panel__header">
<a href="#{{ self.prefix }}-childsection-{{ identifier }}" aria-label="Link to {{ child.heading }}">#</a>
<button
type="button"
class="w-panel__toggle"
aria-label="Toggle {{ child.heading }}"
aria-controls="{{ self.prefix }}-childcontent-{{ identifier }}"
aria-expanded="true"
>
<svg width="16" height="16"><use href="#icon-pilcrow"></use></svg>
</button>
<h2 id="{{ self.prefix }}-childheading-{{ identifier }}" class="w-panel__heading">
{% if child.id_for_label %}
<label for="{{ child.id_for_label }}">{{ child.heading }}{% if child.is_required %}<span class="w-error" aria-hidden="true">*</span>{% endif %}</label>
{% else %}
{{ child.heading }}{% if child.is_required %}<span class="w-error" aria-hidden="true">*</span>{% endif %}
{% endif %}
</h2>
</div>
<div id="{{ self.prefix }}-childcontent-{{ identifier }}" class="w-panel__content">
{% component child %}
</div>
</section>
{% panel id_prefix=self.prefix id=identifier class_name=child.classes|join:' ' heading=child.heading heading_size="label" icon=child.icon id_for_label=child.id_for_label is_required=child.is_required %}
{% component child %}
{% endpanel %}
{% endfor %}

Wyświetl plik

@ -13,14 +13,14 @@
<button
type="button"
data-toggle-breadcrumbs
class="w-flex w-items-center w-justify-center w-box-border w-ml-0 w-p-4 w-w-[50px] w-h-full w-bg-transparent w-text-grey-400 w-transition hover:w-scale-110 hover:w-text-primary w-outline-offset-inside"
class="w-flex w-items-center w-justify-center w-box-border w-ml-0 w-p-4 w-w-slim-header w-h-full w-bg-transparent w-text-grey-400 w-transition hover:w-scale-110 hover:w-text-primary w-outline-offset-inside"
aria-label="{% trans 'Toggle breadcrumbs' %}"
aria-expanded="false"
>
{% icon name="breadcrumb-expand" class_name="w-w-4 w-h-4" %}
</button>
{% endif %}
<div class="w-relative w-h-[50px] w-mr-4 w-top-0 w-z-20 w-flex w-items-center w-flex-row w-flex-1 sm:w-flex-none w-transition w-duration-300">
<div class="w-relative w-h-slim-header w-mr-4 w-top-0 w-z-20 w-flex w-items-center w-flex-row w-flex-1 sm:w-flex-none w-transition w-duration-300">
<nav class="w-flex w-items-center w-flex-row w-h-full"
aria-label="{% trans 'Breadcrumb' %}">
<ol class="w-flex w-flex-row w-justify-start w-items-center w-h-full w-pl-0 w-my-0 w-gap-2 sm:w-gap-0 sm:w-space-x-2">

Wyświetl plik

@ -11,7 +11,7 @@
{% endblock %}
{% block actions %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-slim-header w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% include "wagtailadmin/shared/side_panel_toggles.html" %}
{% endwith %}
{% endblock %}

Wyświetl plik

@ -15,7 +15,7 @@
{% endblock %}
{% block actions %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-slim-header w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% include "wagtailadmin/shared/side_panel_toggles.html" %}
{# Page history #}

Wyświetl plik

@ -1,9 +1,10 @@
{% load wagtailadmin_tags i18n %}
{# Sticky header – make sure any view using this also sets the `page-slim-header` class on its body. #}
{# Z index 99 to ensure header is always above #}
<header class="w-flex w-flex-col sm:w-flex-row w-items-center w-justify-between w-bg-grey-50 w-border-b w-border-grey-100 w-px-0 w-py-0 w-mb-0 w-relative w-top-0 w-z-header sm:w-sticky w-min-h-[50px]">
<header class="w-flex w-flex-col sm:w-flex-row w-items-center w-justify-between w-bg-grey-50 w-border-b w-border-grey-100 w-px-0 w-py-0 w-mb-0 w-relative w-top-0 w-z-header sm:w-sticky w-min-h-slim-header">
{# Padding left on mobile to give space for navigation toggle, #}
<div class="w-pl-[50px] w-min-h-[50px] sm:w-pl-0 sm:w-pr-2 w-w-full w-flex-1 w-overflow-x-auto w-box-border">
<div class="w-pl-slim-header w-min-h-slim-header sm:w-pl-0 sm:w-pr-2 w-w-full w-flex-1 w-overflow-x-auto w-box-border">
<div class="w-flex w-flex-1 w-items-center w-overflow-hidden">
{% block header_content %}
{% endblock %}

Wyświetl plik

@ -0,0 +1,66 @@
{% load wagtailadmin_tags i18n %}
{% comment %}
Variables this template accepts:
id_prefix - A prefix for all id attributes.
classes - List of CSS classes to use for the panel.
class_name - String of CSS classes to use for the panel.
id - Unique to the page.
heading - The text of the panels heading.
heading_size - The size of the heading.
icon - Displayed alongside the heading.
id_for_label - id of an associated field.
is_required - If the panel contains a required field.
children - Where to insert the panels contents.
{% endcomment %}
{% fragment as prefix %}{% if id_prefix %}{{ id_prefix }}-{% endif %}{{ id }}{% endfragment %}
{% fragment as panel_id %}{{ prefix }}-section{% endfragment %}
{% fragment as heading_id %}{{ prefix }}-heading{% endfragment %}
{% fragment as content_id %}{{ prefix }}-content{% endfragment %}
<section
class="w-panel {{ classes|join:' ' }}{{ class_name }}"
id="{{ panel_id }}"
aria-labelledby="{{ heading_id }}"
data-panel
>
{# If a panel has no heading, we dont want any of the associated UI. #}
{% if heading %}
<div class="w-panel__header">
<a
class="w-panel__anchor"
href="#{{ panel_id }}"
aria-label="{% trans 'Anchor section' %}"
aria-describedby="{{ heading_id }}"
>
{% icon name="link" class_name="w-panel__icon" %}
</a>
<button
class="w-panel__toggle"
type="button"
aria-label="{% trans 'Toggle section' %}"
aria-describedby="{{ heading_id }}"
data-panel-toggle
aria-controls="{{ content_id }}"
aria-expanded="true"
>
{# If there is a custom icon, we display it when the panel is expanded. #}
{% if icon %}
{% icon name=icon class_name="w-panel__icon w-panel__icon--custom" %}
{% endif %}
{% icon name="caret-down" class_name="w-panel__icon" %}
</button>
<h2 class="w-panel__heading {% if heading_size == "label" %}w-panel__heading--label{% endif %}" id="{{ heading_id }}">
{% if id_for_label %}
<label for="{{ id_for_label }}">{{ heading }}{% if is_required %}<span class="w-required-mark">*</span>{% endif %}</label>
{% else %}
{{ heading }}{% if is_required %}<span class="w-required-mark">*</span>{% endif %}
{% endif %}
</h2>
</div>
{% endif %}
<div id="{{ content_id }}" class="w-panel__content">
{{ children }}
</div>
</section>

Wyświetl plik

@ -514,7 +514,7 @@ def page_header_buttons(context, page, page_perms):
"w-flex",
"w-justify-center",
"w-items-center",
"w-h-[50px]",
"w-h-slim-header",
],
"button_classes": [
"w-p-0",
@ -1019,6 +1019,13 @@ class HelpBlockNode(BlockInclusionNode):
register.tag("help_block", HelpBlockNode.handle)
class PanelNode(BlockInclusionNode):
template = "wagtailadmin/shared/panel.html"
register.tag("panel", PanelNode.handle)
# Button used to open dialogs
@register.inclusion_tag("wagtailadmin/shared/dialog/dialog_toggle.html")
def dialog_toggle(dialog_id, class_name="", text=None):

Wyświetl plik

@ -1006,6 +1006,7 @@ def register_icons(icons):
"bin.svg",
"bold.svg",
"breadcrumb-expand.svg",
"caret-down.svg",
"chain-broken.svg",
"check.svg",
"chevron-down.svg",

Wyświetl plik

@ -10,14 +10,14 @@
<button
type="button"
data-toggle-breadcrumbs
class="w-flex w-items-center w-justify-center w-box-border w-ml-0 w-p-4 w-w-[50px] w-h-full w-bg-transparent w-text-grey-400 w-transition hover:w-scale-110 hover:w-text-primary w-outline-offset-inside"
class="w-flex w-items-center w-justify-center w-box-border w-ml-0 w-p-4 w-w-slim-header w-h-full w-bg-transparent w-text-grey-400 w-transition hover:w-scale-110 hover:w-text-primary w-outline-offset-inside"
aria-label="{% trans 'Toggle breadcrumbs' %}"
aria-expanded="false"
>
{% icon name="breadcrumb-expand" class_name="w-w-4 w-h-4" %}
</button>
<div class="w-relative w-h-[50px] w-mr-4 w-top-0 w-z-20 w-flex w-items-center w-flex-row w-flex-1 sm:w-flex-none w-transition w-duration-300">
<div class="w-relative w-h-slim-header w-mr-4 w-top-0 w-z-20 w-flex w-items-center w-flex-row w-flex-1 sm:w-flex-none w-transition w-duration-300">
<nav class="w-flex w-items-center w-flex-row w-h-full"
aria-label="{% trans 'Breadcrumb' %}">
<ol class="w-flex w-flex-row w-justify-start w-items-center w-h-full w-pl-0 w-my-0 w-gap-2 sm:w-gap-0 sm:w-space-x-2">

Wyświetl plik

@ -22,7 +22,7 @@
{% endblock %}
{% block actions %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-slim-header w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% include "wagtailadmin/shared/side_panel_toggles.html" %}
{% endwith %}
{% endblock %}

Wyświetl plik

@ -19,7 +19,7 @@
{% endblock %}
{% block actions %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-[50px] w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% with nav_icon_classes='w-w-4 w-h-4' nav_icon_button_classes='w-h-slim-header w-bg-transparent w-box-border w-py-3 w-px-3 w-flex w-justify-center w-items-center w-outline-offset-inside w-text-grey-400 w-transition hover:w-transform hover:w-scale-110 hover:w-text-primary focus:w-text-primary' %}
{% include "wagtailadmin/shared/side_panel_toggles.html" %}
{# Object history #}