Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Conversation

@sarayourfriend
Copy link
Contributor

@sarayourfriend sarayourfriend commented Sep 14, 2021

Fixes

Related to #149 by @zackkrida

Description

Adds a new DownloadButton component based on the DropdownButton component.

Technical details

Adds the filesize dependency which is a function for displaying filesizes with their units appropriatly. It's pretty small: https://bundlephobia.com/package/filesize

Tests

Most of the behavior of this component is already tested in the DropdownButton component's tests. The behavior around the localStorage would be worth testing though, so I'll add some unit tests for that (assuming JSDOM supports it)

To test this locally run npm run storybook and navigate to /?path=/story/components-downloadbutton--default to test the component manually. It should even let you download the files 🙂

Screenshots

Captura de Tela 2021-09-14 às 09 03 12

Checklist

  • My pull request has a descriptive title (not a vague title like Update index.md).
  • My pull request targets the default branch of the repository (main or master).
  • My commit messages follow best practices.
  • My code follows the established code style of the repository.
  • I added or updated tests for the changes I made (if applicable).
  • I added or updated documentation (if applicable).
  • I tried running the project locally and verified that there are no visible errors.

Developer Certificate of Origin

Developer Certificate of Origin
Developer Certificate of Origin Version 1.1 Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 1 Letterman Drive Suite D4700 San Francisco, CA, 94129 Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. 
@zackkrida
Copy link
Member

This is looking great 🤩
One item of interest, there's a small localStorage wrapper in https://github.com/WordPress/openverse-frontend/blob/main/src/utils/local.js you can use, with local.get(key) and local.set(key, value) methods. This exists to include a simple window check in SSR scenarios.

@sarayourfriend
Copy link
Contributor Author

Awesome, thanks for the heads up @zackkrida!

axios.head.mockReset()
})

// TODO(@sarayourfriend) convert this to testing-library once it's possible to get the `vm` from the wrapper
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is blocked by this PR testing-library/vue-testing-library#250

@sarayourfriend sarayourfriend marked this pull request as ready for review September 15, 2021 17:40
@sarayourfriend sarayourfriend requested a review from a team as a code owner September 15, 2021 17:40
@sarayourfriend sarayourfriend added 🕹 aspect: interface Concerns end-users' experience with the software 🌟 goal: addition Addition of new feature labels Sep 15, 2021
@zackkrida zackkrida mentioned this pull request Sep 16, 2021
15 tasks
name: 'DownloadButton',
components: { DropdownButton },
props: {
formats: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very thorough validation!

: '',
]"
type="button"
v-bind="itemA11yProps"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we change the aria-label from dropdown to something like 'Select the download file format'?

@obulat
Copy link
Contributor

obulat commented Sep 21, 2021

The button works and looks amazing! I have a couple of questions about functionality.
When you open a dropdown and select the filetype, shouldn't the dropdown close after selection? That was my expectation.
When using keyboard to navigate, do you click on ShiftTab to go back from the dropdown to download button?

const response = await axios.head(format.download_url)
return [format.extension_name, response.headers['content-length']]
} catch (e) {
return [format.extension_name, undefined]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor point but I love seeing undefined in use 😄

@sarayourfriend
Copy link
Contributor Author

sarayourfriend commented Sep 21, 2021

When you open a dropdown and select the filetype, shouldn't the dropdown close after selection?

It should be doing that, if it's not it's a bug 😅

When using keyboard to navigate, do you click on ShiftTab to go back from the dropdown to download button?

Yup! I think that matches the behavior on the WAI-ARIA examples but I'll double check.

Update: I double checked against this example: https://www.w3.org/TR/wai-aria-practices-1.2/examples/menu-button/menu-button-actions-active-descendant.html

And it looks like we're matching the behavior. The only thing that is different is that the dropdown doesn't cycle through to the end if you arrow up/down at the end or beginning of the list. That should be a trivial fix.

Copy link
Member

@zackkrida zackkrida left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm seeing a few issues on this otherwise excellent work:

  • See inline code suggestion for the filesize font weight
  • The disjointed underline looks particularly bad, I think it'd be best just to remove the hover underline.
    CleanShot 2021-09-23 at 11 48 33@2x
  • I think there's still an issue with events firing multiple times, perhaps due to some event bubbling. Keyboard controls work flawlessly but clicks seem unpredictable. This video isn't the most helpful but should show some instances where 2,3, or even 5 clicks are necessary to reveal the dropdown.
CleanShot.2021-09-23.at.11.45.50.mp4
  • The dropdown does not close after selecting an item, again I think because of an event double fire

This is super close to merge 🤩

<span class="ml-4 selected-format">
{{ selectedFormat.extension_name }}
</span>
<span class="ml-1 font-thin">{{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<span class="ml-1 font-thin">{{
<span class="ml-1 font-normal">{{

The normal weight has enough contrast with the bold and is much more legible, I think. It also appears to be what is used in Figma.

@sarayourfriend
Copy link
Contributor Author

I think there's still an issue with events firing multiple times, perhaps due to some event bubbling. Keyboard controls work flawlessly but clicks seem unpredictable. This video isn't the most helpful but should show some instances where 2,3, or even 5 clicks are necessary to reveal the dropdown.

For some reason I'm not able to reproduce this... or the bug where clicking doesn't cause the dropdown to open 🤔 I'll keep digging and see if I can identify the problem though.

@sarayourfriend
Copy link
Contributor Author

So I've just done some experimenting and discovered something interesting... I wonder if it's at the root cause of what's going on here. When you @click bind an event in Vue on a button, it will also trigger the click when you hit space or enter... So if you combine @click with @keydown it'll fire BOTH events at the same time! You can see this happening here in this codesandbox:

https://codesandbox.io/s/reverent-lucy-j7kf3?file=/src/App.vue

I have absolutely no idea how to circumvent this... I suppose we could just not use the button element and use a div with some appropriate aria attributes applied... but is that the right solution? Or is there a different vue-y way to do this?

@zackkrida
Copy link
Member

zackkrida commented Sep 23, 2021

CleanShot 2021-09-23 at 13 28 20@2x

Also, small Safari bug where the button needs .appearance-none

@zackkrida
Copy link
Member

@sarayourfriend perhaps we just remove the keydown events? Is that all we need?

@sarayourfriend
Copy link
Contributor Author

perhaps we just remove the keydown events? Is that all we need?

We can do that for the dropdown button I think... but for the format buttons I don't think it's possible because we need to respond to specific keys (tab, arrows, page down/up, end/home, etc) as well as the click event... I wonder if there's a way of telling the click event to only fire if it's a true click, given we're handling the keydown event ourselves 🤔

@sarayourfriend
Copy link
Contributor Author

Apparently you can use https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail on the MouseEvent to tell whether it was triggered by a click or a keypress 🤔

@sarayourfriend
Copy link
Contributor Author

sarayourfriend commented Sep 23, 2021

Hmmm, actually we can't do that because we are depending on the @click behavior to handle when the dropdown item is actually selected... onItemKeydown only handles navigational keys, not selection (which makes sense because the DropdownButton shouldn't know anything outside of the a11y interactions for each item...)

Which also means that isn't the issue... the click and keydown events can fire at the same time and they shouldn't interact with each other in this case cause they're doing entirely different things.

@sarayourfriend
Copy link
Contributor Author

Additionally, I'm just noticing that because the link for the download button looks like a button, it doesn't actually behave like a button (Space doesn't trigger the download, in fact it scrolls the screen) so I wonder if there's something we need to do there to handle that situation?

@zackkrida
Copy link
Member

Additionally, I'm just noticing that because the link for the download button looks like a button, it doesn't actually behave like a button (Space doesn't trigger the download, in fact it scrolls the screen) so I wonder if there's something we need to do there to handle that situation?

@sarayourfriend I think it's okay for it to behave like a link and look like a button.

@sarayourfriend
Copy link
Contributor Author

I think I figured out the issue with clicking the dropdown button. The click only triggers if you click the button and not the icon 🤯

@zackkrida
Copy link
Member

@sarayourfriend pointer-events: none on the icon then should do it!

@sarayourfriend
Copy link
Contributor Author

Thanks @zackkrida !

@sarayourfriend
Copy link
Contributor Author

The dropdown does not close after selecting an item, again I think because of an event double fire

I still can't figure this out... or reproduce it 😞

Copy link
Member

@zackkrida zackkrida left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This now looks and works perfectly 🥳. The only bit of feedback I have is that I'd like to figure out how to show the focus ring on dropdown items only when the user is using the keyboard. If someone is using the mouse with the dropdown, it's confusing to see two interaction states: the gray background of the selected item and the pink ring defaulted to the first item.

@zackkrida zackkrida merged commit 52d25bc into main Sep 28, 2021
@zackkrida zackkrida deleted the add/download-button branch September 28, 2021 13:33
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

🕹 aspect: interface Concerns end-users' experience with the software 🌟 goal: addition Addition of new feature

4 participants