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
Re-implement chooser modals with new design #9246
base: main
Are you sure you want to change the base?
Conversation
Manage this branch in SquashTest this branch here: https://stevedyafeaturea11y-choosers-2jmh3.squash.io |
What is the impact of these changes for third party packages? |
Initially I wasn't keen on having a
|
@gasman I've made quite a few updates since we last chatted about these changes and I do have some good news 🙂 After tinkering with the |
self.body.html(response.html); | ||
self.container.modal('show'); | ||
self.container.show(); | ||
self.body.innerHTML = response.html; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I recall correctly, jquery's html(...)
function has the hidden feature of executing any <script>
tags in the HTML content, which innerHTML
doesn't do. If that is the case, we should check whether any of our modals are relying on inline <script>
s (I suspect they are...) and ensure we reinstate that behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah jQuery does do that. It’s not too hard to replicate with vanilla JS but I think we could just stick to jQuery’s .html
for the time being (and add a comment that this is for good reason).
import {initTabs} from './tabs'; | ||
import {initTooltips} from './initTooltips'; | ||
import initChooserCreationForm from './initChooserCreationForm'; | ||
import initChooserFilters from "./chooserFilters"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be neater to make initChooserCreationForm
and initChooserFilters
into methods on ChooserModalOnloadHandlerFactory
, so that subclasses of ChooserModalOnloadHandlerFactory
can customise them where appropriate?
(ah, now I see that initChooserCreationForm
is called on page load too. Does that imply that "chooser creation forms" exist outside of chooser modals?)
Looks like that would also avoid having to expose ajaxify-chooser-links
as a custom event, which I'm not entirely keen on - 'ajaxifying' feels like too much of an internal implementation detail of choosers to be appropriate to expose to external code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing this 😃 Thats a great idea. It definitely would be a lot neater to have them inside of the ChooserModalOnloadHandlerFactory
Chooser creation forms/toggling don't exist outside of the choosers so we definitely wouldn't need them on page load then either yep.
I agree on removing the ajaxify-chooser-links
event because we won't need it then either. I'll add this to my TODO list
@@ -290,9 +303,11 @@ class ChooserModalOnloadHandlerFactory { | |||
} | |||
|
|||
onLoadReshowCreationFormStep(modal, jsonData) { | |||
$(this.creationFormTabSelector, modal.body).replaceWith( | |||
$(this.creationFormTabSelector, modal.body).html( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
html()
sets the inner content of the creationFormTabSelector
element, while replaceWith
replaces it. Given that the data-chooser-creation-form-wrapper
element that creationFormTabSelector
refers to is the top-level element of creation_form.html - and will thus appear in the htmlFragment - won't this change mean that we end up with two nested data-chooser-creation-form-wrapper
elements?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm yes there is a chance for duplicated nested elements if a creation_form is returned for sure. I may have to revisit this then.
I had originally made this change to avoid having to re-add the same classes / data attributes to all the potential nested templates. For example confirm_duplicate_upload.html
when using replaceWith()
will also need to have these attributes/classes for styling/events.
class="w-chooser-creation-form"
data-chooser-creation-form-wrapper
I will also have to re-update event listeners when the element is replaced if we went with replaceWIth() (not a problem)
I would be interested in knowing all the possible templates that onLoadReshowCreationFormStep
could potentially send back.
@zerolab Sorry for the delayed reply. This is a good idea! I did try to keep as much similar as I could but i'm sure some notes on the upgrade path will still be needed because of the vast amount of changes. I've put this as a TODO on this PR now. Thanks! |
@@ -330,6 +330,16 @@ | |||
} | |||
} | |||
|
|||
// For buttons we want to look like inline links | |||
&.plain { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add these to the pattern library and styleguide template?
Note: We actually recently removed something similar unbutton
as it was not used, not sure if we should revisit this class that was already present in the code instead of adding a new name?
Alternatively, should we name this to be a bit clearer - .as-link
or w-button--as-link
(for longer term adoption of BEM classes). Or does this get close enough if we add .link
to the button?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to me like something that might not need to live in this file as a generic button style to start with, since (at least currently) it’s very specific to choosers?
<header class="w-chooser-header"> | ||
<div class="w-chooser-header__wrapper"> | ||
<div class="w-chooser-header__search-field"> | ||
<form class="search-form search-form" action="{% url "wagtailadmin_choose_page_search" %}?page_type={{ page_type_string }}" method="get" novalidate role="search"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gotta remove this duplicated class oops
@@ -330,6 +330,16 @@ | |||
} | |||
} | |||
|
|||
// For buttons we want to look like inline links | |||
&.plain { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to me like something that might not need to live in this file as a generic button style to start with, since (at least currently) it’s very specific to choosers?
} | ||
} | ||
|
||
.w-chooser-listing { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably use its own file.
|
||
} | ||
|
||
.w-chooser { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this could be worth its own file.
self.body.html(response.html); | ||
self.container.modal('show'); | ||
self.container.show(); | ||
self.body.innerHTML = response.html; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah jQuery does do that. It’s not too hard to replicate with vanilla JS but I think we could just stick to jQuery’s .html
for the time being (and add a comment that this is for good reason).
client/src/includes/dialog.js
Outdated
}; | ||
|
||
const template = ` | ||
<div aria-hidden="true" id="${id}" aria-labelledby="title-${id}" class="w-dialog ${isChooser && 'w-dialog--chooser'}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would need a comment to explain why we have this HTML in JS.
{% for tag in popular_tags %} | ||
<option value="{{ tag.name }}">{{ tag.name }}</option> | ||
{% endfor %} | ||
</select> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤟
<div class="w-dialog__message w-dialog__message--warning"> | ||
{% icon name='warning' class_name="w-dialog__message-icon" %} | ||
<div class="w-dialog__message-header"> | ||
<p class="w-dialog__message-description "> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<p class="w-dialog__message-description "> | |
<p class="w-dialog__message-description"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
font-size: 3rem; | ||
.icon { | ||
width: 100%; | ||
max-height: theme('spacing.9'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn’t we have to keep all styles here as-is for tables listing?
} | ||
|
||
.w-chooser__body[aria-hidden="true"] { | ||
transform: translateX(-100%); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this work in RTL mode?
Will there be any plans to revisit the JS approach in the context of Stimulus adoption? I've kind of kept that out of scope for the Outreachy project for now but have a few ideas about chooser implementations that would leverage Stimulus. Let me know if it's worth a POC or some notes |
25127c8
to
873a0ff
Compare
@lb- we’re planning to revisit the JS but haven’t discussed further how exactly to go about that. |
I'm not sure where this request lands in the 30-odd issues listed above - quite a few places possibly - but there are two things I'd find really useful in redeveloped choosers:
Also I think worth considering for the chooser dialogs:
|
@stevedya @thibaudcolas - what's the status of this work? Is this something that still aligns with the frontend / UI strategy? A lot has changed since this PR was opened so not sure on the best way forward. Multiple parts of the JS impacted here has changed with Stimulus adoption, formalising support for RTL layouts, larger reworking of choosers that have since happened, and an extensive amount of rework of base listings & generic chooser viewsets. Is there a way we can split out some parts of the goals here into smaller issues that can be picked up by a wider range of contributors? Maybe there's parts that make sense as part of further inline script removal / Stimulus migration of choosers also. I have a call lined up with @thibaudcolas and @laymonage for a fortnight's time, maybe this is a good discussion item if we get this happening. @dkirkham you probably already know but there are lots of improvements to the way generic choosers can be build with Chooser Viewsets since this PR was raised. https://docs.wagtail.org/en/stable/reference/viewsets.html#chooserviewset However, other items are still outstanding from what I can see. |
Thanks @dkirkham - I must not have read your comments correctly then. Anyway, yes I think think an issue or two-ish to clearly lay out the enhancements you'd like to see would be helpful. Doesn't mean it will be built but it can help guide future directions, external packages or APIs even if not solved directly as requested. It's also a good way to have a discussion with others that may want to see similar features outside of a PR. Thanks. |
This draft PR is for converting the current chooser functionality to use the new accessible choosers.
Still left TODO as part of this work:
initChooserCreationForm
andinitChooserFilters
into methods on ChooserModalOnloadHandlerFactoryMaybe:
In Progress Screenshots
Image chooser
Image chooser with duplicated image
#Image chooser with open filters
Snippet chooser with search
Image chooser update form
Page chooser
Choose image format for Draftail images