-
Notifications
You must be signed in to change notification settings - Fork 63
Conversation
Note, the current aria live region implementation is incorrect 😄 but will be revised soon. Edit: It doesn't exist anymore, and is unnecessary for this component. |
* @param {import('@nuxtjs/composition-api').SetupContext} context | ||
*/ | ||
setup() { | ||
const defaultWindow = typeof window !== 'undefined' ? window : undefined |
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.
The default window is being used in several places now to ensure that composables work correctly with SSR. Is there a way to extract this code somehow?
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 was thinking it could be the default value in the hook, at least. Not sure if it'll work, I'll test
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 don't think you can use a default value as it'll try to evaluate window
even when it's undefined and throw an error.
Co-authored-by: Olga Bulat <obulat@gmail.com>
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.
The Logo loader component is awesome!
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.
Looks amazing! You can see the attention to details, really nice ✨
Co-authored-by: Krystle Salazar <krystle.salazar@automattic.com>
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.
Nice! The CSS animations are magic to me 🤩 Just a couple documentation things but otherwise looks great!
With respect to the "pulsing" reduced motion version... I have decent vision and I can barely tell anything is happening. In fact, it might as well not even pulse if it's that subtle.
* @param {import('@nuxtjs/composition-api').SetupContext} context | ||
*/ | ||
setup() { | ||
const defaultWindow = typeof window !== 'undefined' ? window : undefined |
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 don't think you can use a default value as it'll try to evaluate window
even when it's undefined and throw an error.
watch(target, (value, oldValue) => { | ||
oldValue?.removeEventListener(event, handler) | ||
value?.addEventListener(event, handler) | ||
}) |
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.
Would it be better to use onInvalidate
to remove the event listener?
watch(target, (value, oldValue) => { | |
oldValue?.removeEventListener(event, handler) | |
value?.addEventListener(event, handler) | |
}) | |
watch(target, (value, _, onInvalidate) => { | |
value?.addEventListener(event, handler) | |
onInvalidate(() => value?.removeEventListener(event, handler)) | |
}) |
I'm not 100% sure there is a difference, I'll do some fiddling to test this out, but i think the watcher may never run on component dismount to remove the old listener but invalidate will run.
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 do like your take on it! 😄
onBeforeUnmount(() => { | ||
unref(target)?.removeEventListener(event, handler) | ||
}) |
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.
Oh wait, I see, I guess onInvalidate
isn't necessary because the clean up happens in one place here?
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
It looks awesome. Great work. I agree with @sarayourfriend as the fading effect is not very noticeable. And I would add that it might be unnecessary. The idea of motion reduction is great, but in this case, the animation is very subtle and lives in a context where the skeleton interface fading is more proper for showing the loading instance. |
@panchovm that's a great point about the skeleton loaders. I think I will go with no animation then! |
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
@sarayourfriend Let's follow up on the event listener code testing—it'd be nice to adopt that in more places in the future too. |
Fixes
Fixes #371 by @zackkrida
Description
Adds a new
VLogoLoader
component and some supporting composables:prefers-reduced-motion
The loader itself is an
aria-hidden
, visual enhancement to the site. It does not have any inherent accessibility qualities, nor is it focusable. Originally I thought this component should be an ARIA Live Region1 but after some research that will be a role better served by our actual search grid, which can announce it's own loading status, the # of newly added results after the user hits the 'load more' button, and so on. I'll make a new ticket soon to spec out those improvements.Testing Instructions
This component can be tested with
npm run storybook
and viewing theVLogoLoader
story. There are a few things you can do:status
prop from "loading" to "idle" with the handlesprefers-reduced-motion
in your browser while in the "loading" status, observe the change in animation to a more subtle, non-moving effect. This is currently a gentle pulse from full to partial opacity. @panchovm might have a better idea for a subtle animation that doesn't add movement, but still visually conveys to the user that loading is occurring. Prefers reduced motion !== wants no motion. Here's a quick video on how to test for prefers reduced motion:CleanShot.2021-12-02.at.19.26.37-converted.mp4
Follow-up questions
Please suggest any test cases I should add. I admittedly don't love unit testing of front-end components and am always looking for improvements there.
The component is extremely small in terms of pixel values in the mockups (cc @panchovm), with the logo being 20px tall with 14px of padding surrounding. This has been increased to 32px tall with 16px of padding in my component. Otherwise the Openverse logo is barely legible, even on my 5k monitor.
The mobile menu includes the logotext "Openverse", I think that can simply exist next to this loader but perhaps be wrapped in the same
<NuxtLink />
component.Checklist
Update index.md
).main
) or a parent feature branch.Developer Certificate of Origin
Developer Certificate of Origin
Footnotes
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions ↩