Skip to content
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

fix(material/sidenav): end position sidenav tab order not matching visual order #18101

Merged

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Jan 4, 2020

We project all sidenavs before the content in the DOM since we can't know ahead of time what their position will be. This is problematic when the drawer is in the end position, because the visual order of the content no longer matches the tab order. These changes fix the issue by moving the sidenav after the content manually when it's set to end and then moving it back if it's set to start again.

A couple of notes:

  1. We could technically do this with content projection, but it would only work when the position value is static (e.g. position="end"). I did it this way so we can cover the case where it's data bound.
  2. Currently the focus trap anchors are set around the sidenav, but that's problematic when we're moving the element around since the anchors will be left at their old positions. To avoid adding extra logic for moving the anchors, I've moved the focus trap to be inside the sidenav. Here's what the DOM looks like at the moment:
<container>
  <anchor/>
  <sidenav>Content</sidenav>
  <anchor/>
</container>

And this is what I've changed it to:

<container>
  <sidenav>
    <anchor/>
    Content
    <anchor/>
  </sidenav>
</container>

Fixes #15247.

@crisbeto crisbeto added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: patch This PR is targeted for the next patch release labels Jan 4, 2020
@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jan 4, 2020
@crisbeto crisbeto added the Accessibility This issue is related to accessibility (a11y) label Jan 4, 2020

if (newPosition === 'end') {
if (!this._anchor) {
this._anchor = this._document.createComment('mat-drawer-anchor');
Copy link
Contributor

Choose a reason for hiding this comment

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

neat trick

@mmalerba mmalerba added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Jan 6, 2020
@nehaabrol87
Copy link

Watching this.

@nehaabrol87
Copy link

@crisbeto a quick question: What version will this be available in?
Will it be available in 8 or 9 (future)

@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 2f1e180 to 4591a06 Compare January 19, 2020 12:27
@nehaabrol87
Copy link

@crisbeto When will this be merged?

@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 4591a06 to 44a210d Compare July 4, 2020 16:31
@mmalerba mmalerba removed the lgtm label Jul 31, 2020
@crisbeto crisbeto changed the title fix(sidenav): end position sidenav tab order not matching visual order fix(material/sidenav): end position sidenav tab order not matching visual order Oct 15, 2020
@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 44a210d to 7620342 Compare October 15, 2020 19:44
@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 7620342 to e708fa9 Compare November 26, 2020 17:44
@nandyne
Copy link

nandyne commented Mar 4, 2021

@crisbeto any updates here??

@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from e708fa9 to 3cddd0a Compare May 6, 2021 20:10
@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 3cddd0a to 5e161c6 Compare August 16, 2021 20:54
@crisbeto crisbeto requested a review from a team as a code owner August 16, 2021 20:54
@devversion devversion removed the request for review from a team August 18, 2021 12:54
@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 5e161c6 to 98f62e9 Compare December 9, 2021 07:27
@andrewseguin andrewseguin added needs rebase and removed cla: yes PR author has agreed to Google's Contributor License Agreement labels Dec 28, 2021
…sual order

We project all sidenavs before the content in the DOM since we can't know ahead of time what their
position will be. This is problematic when the drawer is in the end position, because the visual
order of the content no longer matches the tab order. These changes fix the issue by moving the
sidenav after the content manually when it's set to `end` and then moving it back if it's set to
`start` again.

A couple of notes:
1. We could technically do this with content projection, but it would only work when the `position`
value is static (e.g. `position="end"`). I did it this way so we can cover the case where it's
data bound.
2. Currently the focus trap anchors are set around the sidenav, but that's problematic when we're
moving the element around since the anchors will be left at their old positions. To avoid adding
extra logic for moving the anchors, I've moved the focus trap to be inside the sidenav. Here's
what the DOM looks like at the moment:

```html
<container>
  <anchor/>
  <sidenav>Content</sidenav>
  <anchor/>
</container>
```

And this is what I've changed it to:
```html
<container>
  <sidenav>
    <anchor/>
    Content
    <anchor/>
  </sidenav>
</container
```

Fixes angular#15247.
@crisbeto crisbeto force-pushed the 15247/sidenav-end-dom-position branch from 98f62e9 to eae6680 Compare January 14, 2022 17:38
@andrewseguin andrewseguin merged commit c489f37 into angular:master Jan 18, 2022
andrewseguin pushed a commit that referenced this pull request Jan 18, 2022
…sual order (#18101)

We project all sidenavs before the content in the DOM since we can't know ahead of time what their
position will be. This is problematic when the drawer is in the end position, because the visual
order of the content no longer matches the tab order. These changes fix the issue by moving the
sidenav after the content manually when it's set to `end` and then moving it back if it's set to
`start` again.

A couple of notes:
1. We could technically do this with content projection, but it would only work when the `position`
value is static (e.g. `position="end"`). I did it this way so we can cover the case where it's
data bound.
2. Currently the focus trap anchors are set around the sidenav, but that's problematic when we're
moving the element around since the anchors will be left at their old positions. To avoid adding
extra logic for moving the anchors, I've moved the focus trap to be inside the sidenav. Here's
what the DOM looks like at the moment:

```html
<container>
  <anchor/>
  <sidenav>Content</sidenav>
  <anchor/>
</container>
```

And this is what I've changed it to:
```html
<container>
  <sidenav>
    <anchor/>
    Content
    <anchor/>
  </sidenav>
</container
```

Fixes #15247.

(cherry picked from commit c489f37)
@@ -448,13 +463,20 @@ export class MatDrawer implements AfterContentInit, AfterContentChecked, OnDestr

/** Whether focus is currently within the drawer. */
private _isFocusWithinDrawer(): boolean {
const activeEl = this._doc?.activeElement;
const activeEl = this._doc.activeElement;
Copy link
Contributor

Choose a reason for hiding this comment

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

@crisbeto Is this change save? _doc still has the @optional decorator and could in theory be 'null'. At other code locations checks are still present.

crapStone pushed a commit to Calciumdibromid/CaBr2 that referenced this pull request Feb 7, 2022
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@angular/cdk](https://github.com/angular/components) | dependencies | minor | [`13.1.2` -> `13.2.1`](https://renovatebot.com/diffs/npm/@angular%2fcdk/13.1.2/13.2.1) |
| [@angular/material](https://github.com/angular/components) | dependencies | minor | [`13.1.2` -> `13.2.1`](https://renovatebot.com/diffs/npm/@angular%2fmaterial/13.1.2/13.2.1) |

---

### Release Notes

<details>
<summary>angular/components</summary>

### [`v13.2.1`](https://github.com/angular/components/blob/HEAD/CHANGELOG.md#&#8203;1321-vinyl-viola-2022-02-02)

[Compare Source](angular/components@13.2.0...13.2.1)

##### cdk

| Commit | Type | Description |
| -- | -- | -- |
| [70d1634e70](angular/components@70d1634) | fix | **a11y:** allow for multiple browser-generated description containers ([#&#8203;23507](angular/components#23507)) |

##### material

| Commit | Type | Description |
| -- | -- | -- |
| [d8ddfb04ca](angular/components@d8ddfb0) | fix | **datepicker:** content overflowing when large custom header is provided ([#&#8203;24255](angular/components#24255)) |
| [d7fe423a3e](angular/components@d7fe423) | fix | **menu:** adjust overlay size when amount of items changes ([#&#8203;21457](angular/components#21457)) |
| [974d330dc8](angular/components@974d330) | fix | **slider:** Ticks updated wrongly if the max property 0 ([#&#8203;24218](angular/components#24218)) |
| [a634505190](angular/components@a634505) | fix | **tabs:** use buttons for paginator ([#&#8203;14640](angular/components#14640)) |

##### cdk-experimental

| Commit | Type | Description |
| -- | -- | -- |
| [7aff50a6d8](angular/components@7aff50a) | fix | **menu:** keep context menus open when mouse is released ([#&#8203;24308](angular/components#24308)) |

##### material-experimental

| Commit | Type | Description |
| -- | -- | -- |
| [c02c43a2b9](angular/components@c02c43a) | fix | **mdc-button:** align outline color with spec ([#&#8203;24249](angular/components#24249)) |
| [5d7d6ea107](angular/components@5d7d6ea) | perf | **mdc-list:** reduce bundle size ([#&#8203;24291](angular/components#24291)) |

##### multiple

| Commit | Type | Description |
| -- | -- | -- |
| [b32d8d1624](angular/components@b32d8d1) | perf | Remove IE 11 cruft from table, column-resize, and popover-edit. ([#&#8203;23900](angular/components#23900)) |

#### Special Thanks

Dmytro Mezhenskyi, Joey Perrott, Karl Seamon, Kristiyan Kostadinov, Miles Malerba, Paul Gschwendtner, Zach Arend and ram

<!-- CHANGELOG SPLIT MARKER -->

### [`v13.2.0`](https://github.com/angular/components/blob/HEAD/CHANGELOG.md#&#8203;1320-terracotta-tiramisu-2022-01-26)

[Compare Source](angular/components@13.1.3...13.2.0)

##### material

| Commit | Type | Description |
| -- | -- | -- |
| [b9a3908fcf](angular/components@b9a3908) | feat | **tabs:** add API to update the pagination ([#&#8203;23288](angular/components#23288)) |
| [f10d245cca](angular/components@f10d245) | feat | **tabs:** label & body classes ([#&#8203;23691](angular/components#23691)) |
| [ea78a473a1](angular/components@ea78a47) | feat | **tabs:** Refactor MatTabNav to follow the ARIA tabs pattern ([#&#8203;24062](angular/components#24062)) |
| [337634f899](angular/components@337634f) | fix | **chips:** don't stop propagation on all click events ([#&#8203;19763](angular/components#19763)) |
| [2b6739742b](angular/components@2b67397) | fix | **datepicker:** change calendar cells to buttons ([#&#8203;24171](angular/components#24171)) |
| [c55524a8eb](angular/components@c55524a) | fix | **list:** add isDisabled to all list item harnesses ([#&#8203;24212](angular/components#24212)) |
| [fa7cd154d0](angular/components@fa7cd15) | fix | **list:** fix duplicate focus with chromevox on action-list items ([#&#8203;23361](angular/components#23361)) |
| [0477022d2c](angular/components@0477022) | fix | **slide-toggle:** remove divs nested inside label ([#&#8203;21224](angular/components#21224)) |

##### google-maps

| Commit | Type | Description |
| -- | -- | -- |
| [e6359cdc67](angular/components@e6359cd) | feat | allow for info window focus behavior to be customized ([#&#8203;23831](angular/components#23831)) |

##### material-experimental

| Commit | Type | Description |
| -- | -- | -- |
| [c5482c945f](angular/components@c5482c9) | feat | **mdc-chips:** switch to evolution API ([#&#8203;23931](angular/components#23931)) |
| [723b77ad1f](angular/components@723b77a) | feat | **mdc-core:** add missing color, density, typography mixins ([#&#8203;24063](angular/components#24063)) |
| [407682012d](angular/components@4076820) | feat | **mdc-form-field:** Add option for dynamic su… ([#&#8203;24241](angular/components#24241)) |
| [871a500fb8](angular/components@871a500) | feat | **mdc-list:** rework API to support secondary text with wrapping |
| [b0f38b7a64](angular/components@b0f38b7) | fix | **mdc-button:** remove unwanted native button styles ([#&#8203;24186](angular/components#24186)) |
| [c9ab38bcae](angular/components@c9ab38b) | fix | **mdc-chips:** fix changed after checked error when restoring focus to input ([#&#8203;24243](angular/components#24243)) |
| [68a29ff1dd](angular/components@68a29ff) | fix | **mdc-core:** make mat-option typography easier to override ([#&#8203;24247](angular/components#24247)) |
| [b79406fee8](angular/components@b79406f) | fix | **mdc-form-field:** Properly handle when defaults setting is 'dynamic' and the subscriptSizing input is not present. ([#&#8203;24263](angular/components#24263)) |
| [38affc3d43](angular/components@38affc3) | fix | **mdc-list:** ensure selection change event fires properly ([#&#8203;24174](angular/components#24174)) |
| [c199aa2544](angular/components@c199aa2) | fix | **mdc-list:** incorrect active/hover color for selected items |
| [1ce3e5e905](angular/components@1ce3e5e) | perf | **mdc-checkbox:** reduce bundle size ([#&#8203;24256](angular/components#24256)) |
| [152c60ba12](angular/components@152c60b) | perf | **mdc-radio:** reduce bundle size ([#&#8203;24267](angular/components#24267)) |
| [02c8f2aa02](angular/components@02c8f2a) | perf | **mdc-tabs:** reduce bundle size ([#&#8203;24262](angular/components#24262)) |

##### expansion-panel

| Commit | Type | Description |
| -- | -- | -- |
| [4ec34b5400](angular/components@4ec34b5) | fix | title text not centered with taller description ([#&#8203;12161](angular/components#12161)) |

#### Special Thanks

Amy Sorto, Andrew Seguin, Karl Seamon, Kristiyan Kostadinov, Miles Malerba, Paul Gschwendtner, Ruslan Lekhman, Wagner Maciel, Zach Arend, Zack Elliott, coopermeitz and renovate\[bot]

<!-- CHANGELOG SPLIT MARKER -->

### [`v13.1.3`](https://github.com/angular/components/blob/HEAD/CHANGELOG.md#&#8203;1313-plastic-koala-2022-01-19)

[Compare Source](angular/components@13.1.2...13.1.3)

##### cdk

| Commit | Type | Description |
| -- | -- | -- |
| [109d5a150f](angular/components@109d5a1) | fix | **a11y:** not detecting fake mousedown on firefox ([#&#8203;23493](angular/components#23493)) |
| [c48742eb4e](angular/components@c48742e) | fix | **table:** revert breaking change of CdkTable constructor ([#&#8203;24202](angular/components#24202)) |

##### material

| Commit | Type | Description |
| -- | -- | -- |
| [70e0170b95](angular/components@70e0170) | fix | **autocomplete:** don't handle enter events with modifier keys ([#&#8203;14717](angular/components#14717)) |
| [eae436fdab](angular/components@eae436f) | fix | **autocomplete:** optionSelections not emitting when the list of options changes ([#&#8203;14813](angular/components#14813)) |
| [402c07b3c7](angular/components@402c07b) | fix | **autocomplete** restore focus after emitting option selected event ([#&#8203;18707](angular/components#18707)) |
| [761f9f25a8](angular/components@761f9f2) | fix | **card:** handle picture element as mat-card-image ([#&#8203;23678](angular/components#23678)) |
| [3565cfac59](angular/components@3565cfa) | fix | **core:** make MatOption generic ([#&#8203;20242](angular/components#20242)) |
| [f0272cf5eb](angular/components@f0272cf) | fix | **core:** throw error if hue does not exist ([#&#8203;23612](angular/components#23612)) |
| [304afaef1d](angular/components@304afae) | fix | **datepicker:** add focus indication to calendar selected date in high contrast mode ([#&#8203;22889](angular/components#22889)) |
| [805eee8d07](angular/components@805eee8) | fix | **form-field:** outline gap not recalculated when switching to empty label ([#&#8203;23949](angular/components#23949)) |
| [feac08f138](angular/components@feac08f) | fix | **input:** inconsistently reading name from input with ngModel ([#&#8203;19233](angular/components#19233)) |
| [439ad2c59d](angular/components@439ad2c) | fix | **list:** fix up disabled list item styles ([#&#8203;18881](angular/components#18881)) |
| [4182717c57](angular/components@4182717) | fix | **menu:** not interrupting keyboard events to other overlays ([#&#8203;23310](angular/components#23310)) |
| [a4f655856e](angular/components@a4f6558) | fix | **paginator:** allow readonly options ([#&#8203;24054](angular/components#24054)) |
| [966b2c52b7](angular/components@966b2c5) | fix | **progress-bar:** unable to change value through property setter ([#&#8203;19025](angular/components#19025)) |
| [462cb6d713](angular/components@462cb6d) | fix | **progress-spinner:** animation not working on some zoom levels in Safari ([#&#8203;23674](angular/components#23674)) |
| [94d466235a](angular/components@94d4662) | fix | **select** component value not in sync with control value on init ([#&#8203;18443](angular/components#18443)) |
| [ce9d8caa1f](angular/components@ce9d8ca) | fix | **sidenav:** end position sidenav tab order not matching visual order ([#&#8203;18101](angular/components#18101)) |
| [cb0a2ad940](angular/components@cb0a2ad) | fix | **sidenav** implicit content element being registered twice with scroll dispatcher ([#&#8203;13973](angular/components#13973)) |
| [7be61b6357](angular/components@7be61b6) | fix | **slider:** avoid error on some touchstart events ([#&#8203;23823](angular/components#23823)) |
| [81528bc6a1](angular/components@81528bc) | fix | **slider:** first keypress ignored if out-of-bounds value is assigned ([#&#8203;23827](angular/components#23827)) |
| [64dd8ed8b5](angular/components@64dd8ed) | fix | **slider:** incorrectly inheriting color when nested inside component with theme ([#&#8203;21334](angular/components#21334)) |
| [99e77829cc](angular/components@99e7782) | fix | **snack-bar:** handle long single-line content ([#&#8203;24135](angular/components#24135)) |
| [ad21ee20ae](angular/components@ad21ee2) | fix | **table** not clearing some internal references on destroy ([#&#8203;16051](angular/components#16051)) |
| [9752b1d18f](angular/components@9752b1d) | fix | **table:** better handling of invalid data ([#&#8203;18953](angular/components#18953)) |
| [e01e579a49](angular/components@e01e579) | fix | **tooltip:** not closing if escape is pressed while trigger isn't focused ([#&#8203;14434](angular/components#14434)) |
| [4972dc5585](angular/components@4972dc5) | perf | **button:** do not run change detection when the anchor is clicked ([#&#8203;23992](angular/components#23992)) |

##### material-experimental

| Commit | Type | Description |
| -- | -- | -- |
| [fe39b55f93](angular/components@fe39b55) | fix | **mdc-checkbox:** emitting fallback values for density CSS variables ([#&#8203;24184](angular/components#24184)) |
| [0ab3dce58a](angular/components@0ab3dce) | fix | **mdc-snack-bar:** avoid hard reference to base components and align API ([#&#8203;21425](angular/components#21425)) |

#### Special Thanks

Andrew Seguin, Artur Androsovych, Jeri Peier, Joey Perrott, Kristiyan Kostadinov, Paul Gschwendtner and Ruslan Lekhman

<!-- CHANGELOG SPLIT MARKER -->

</details>

---

### Configuration

📅 **Schedule**: At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).

Co-authored-by: cabr2-bot <cabr2.help@gmail.com>
Reviewed-on: https://codeberg.org/Calciumdibromid/CaBr2/pulls/1149
Reviewed-by: crapStone <crapstone@noreply.codeberg.org>
Co-authored-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
Co-committed-by: Calciumdibromid Bot <cabr2_bot@noreply.codeberg.org>
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 24, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility This issue is related to accessibility (a11y) action: merge The PR is ready for merge by the caretaker P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent target: patch This PR is targeted for the next patch release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

MatSidenav with position="end" is in the wrong tab order
9 participants