-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(back-to-top): pf-back-to-top element (#2589)
* feat(back-to-top): add back-to-top * fix(back-to-top): improve accessibility * fix(back-to-top): add href implementation, update demos * docs(back-to-top): improve demos * fix(back-to-top): inline-flex * docs(back-to-top): fix fragment anchors * fix(back-to-top): add button part to link * docs(back-to-top): use main target for all examples * docs(back-to-top): use main target for overview * test(back-to-top): add basic tests * fix(back-to-top): rename part to trigger to avoid confusion with button * docs(back-to-top): update cssprop documentation * docs(back-to-top): correct slot descriptions * chore(back-to-top): add changeset * chore: update typescript version * chore: pat typescript on the head * style(back-to-top): small refactors * perf(back-to-top): prevent memory leak * docs(back-to-top): add readme * docs(back-to-top): update readme * docs(back-to-top): move css link to top of demos * fix(back-to-top): remove type assertion * fix(back-to-top): memeber ordering * fix(back-to-top): rename classes variable * fix(back-to-top): update var * test(back-to-top): improve test ordering * fix(back-to-top): move eventlistener bindings to reactive callback * fix(back-to-top): wait for updatecomplete to reattach listener * fix(back-to-top): reorganizing code with suggestions from review * refactor(back-to-top): refactor element and tests * fix(back-to-top): add label ifDefined back accidental removal * docs(back-to-top): fix inline doc demos * fix(back-to-top): re-add vertical alignment for pf-icon * docs(back-to-top): update scrollable selector inline demos * docs(back-to-top): fix inline scroll selector demos * docs(back-to-top): update jsdoc * chore: remove errant changeset * chore: readd changeset misread review comment * docs: fix elements/readme, was incorrectly edited * test(back-to-top): fix describe async nesting * docs(back-to-top): remove content guidelines copy * refactor(back-to-top): label attribute * docs(back-to-top): clarify scrollable selector and distance usage * test(back-to-top): add tests for label attribute * test(back-to-top): test for keyboard accessibility * test(back-to-top): use snapshot to check that it doesnt exist in a11y tree * test(back-to-top): add async to a11y axe tests --------- Co-authored-by: Benny Powers <web@bennypowers.com>
- Loading branch information
1 parent
c71bbe5
commit 22d7536
Showing
22 changed files
with
1,001 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
"@patternfly/elements": minor | ||
--- | ||
|
||
✨ Added `<pf-back-to-top>` | ||
|
||
```html | ||
<pf-back-to-top href="#top" scrollable-selector="main">Back to Top</pf-back-to-top> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
"@patternfly/pfe-tools": patch | ||
--- | ||
Update typescript version |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
# PatternFly Elements | ||
|
||
See [PatternFly Elements Docs](https://patternflyelements.org) for more | ||
See [PatternFly Elements Docs](https://patternflyelements.org) for more | ||
information. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Back to top | ||
|
||
The **back to top** component is a shortcut that allows users to quickly navigate to the top of a lengthy content page. | ||
|
||
|
||
## Installation | ||
Load `<pf-back-to-top>` via CDN: | ||
|
||
```html | ||
<script src="https://jspm.dev/@patternfly/elements/pf-back-to-top/pf-back-to-top.js"></script> | ||
|
||
|
||
Or, if you are using [NPM](https://npm.im), install it | ||
|
||
```bash | ||
npm install @patternfly/elements | ||
``` | ||
|
||
Then once installed, import it to your application: | ||
|
||
```js | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
``` | ||
|
||
## Usage | ||
|
||
```html | ||
<pf-back-to-top href="#top">Back to Top</pf-back-to-top> | ||
|
||
``` | ||
|
||
[docs]: https://patternflyelements.org/components/back-to-top |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<div class="outer-container padded" id="top"> | ||
<h2>Always visible</h2> | ||
<a href="#focusable-element-top" id="top">Focusable element (top)</a> | ||
</div> | ||
|
||
<pf-back-to-top always-visible href="#top">Back to top</pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<div class="outer-container" id="top"> | ||
<div class="scroll-indicator padded"> | ||
<h2>Button No Text</h2> | ||
<p><a href="#focusable-element-top">Focusable element (top)</a></p> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 400px (default). | ||
</div> | ||
</div> | ||
<a href="#focusable-element-bottom">Focusable element (bottom)</a> | ||
|
||
<pf-back-to-top scrollable-selector="main"></pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
document.querySelector('pf-back-to-top').addEventListener('click', function() { | ||
// scroll to some element | ||
const target = document.querySelector('#top'); | ||
target.scrollIntoView(); | ||
target.focus(); | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<pf-banner variant="info" id="top"> | ||
<pf-icon icon="info-circle" slot="icon"></pf-icon> | ||
<strong>Accessibility Warning</strong> Using the Button/JS variant, implementation must apply click event and focus to the element that is scrolled to. | ||
</pf-banner> | ||
<div class="outer-container"> | ||
<div class="scroll-indicator padded"> | ||
<h2>Button</h2> | ||
<p><a href="#focusable-element-top">Focusable element (top)</a></p> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 400px (default). | ||
</div> | ||
</div> | ||
<a href="#focusable-element-bottom">Focusable element (bottom)</a> | ||
|
||
<pf-back-to-top scrollable-selector="main">Back to top</pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
import '@patternfly/elements/pf-banner/pf-banner.js'; | ||
document.querySelector('pf-back-to-top').addEventListener('click', function() { | ||
// scroll to some element | ||
const target = document.querySelector('#top'); | ||
target.scrollIntoView(); | ||
target.focus(); | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
:root { | ||
--_scroll-distance: 400px; | ||
} | ||
|
||
main { | ||
scroll-behavior: smooth; | ||
} | ||
|
||
.scroll-distance { | ||
--_scroll-distance: 200px; | ||
} | ||
|
||
.outer-container { | ||
height: calc(100vh - var(--pf-demo-header-height) + var(--_scroll-distance)); | ||
} | ||
|
||
.padded { | ||
padding: var(--pf-global--spacer--md, 1rem); | ||
} | ||
|
||
.scroll-indicator { | ||
height: var(--_scroll-distance); | ||
background-color: var(--pf-global--palette--cyan-50, #f2f9f9) !important; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<div class="outer-container" id="top"> | ||
<div class="scroll-indicator padded"> | ||
<h2>Default</h2> | ||
<p><a href="#focusable-element-top">Focusable element (top)</a></p> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 400px (default). | ||
</div> | ||
</div> | ||
<a href="#focusable-element-bottom">Focusable element (bottom)</a> | ||
|
||
<pf-back-to-top scrollable-selector="main" href="#top" label="Top"></pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<div class="outer-container" id="top"> | ||
<div class="scroll-indicator padded"> | ||
<h2>No Text</h2> | ||
<p><a href="#focusable-element-top">Focusable element (top)</a></p> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 400px (default). | ||
</div> | ||
</div> | ||
<a href="#focusable-element-bottom">Focusable element (bottom)</a> | ||
|
||
<pf-back-to-top scrollable-selector="main" href="top"></pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<div class="outer-container" id="top"> | ||
<div class="scroll-indicator padded"> | ||
<h2>Default</h2> | ||
<p><a href="#focusable-element-top">Focusable element (top)</a></p> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 400px (default). | ||
</div> | ||
</div> | ||
<a href="#focusable-element-bottom">Focusable element (bottom)</a> | ||
|
||
<pf-back-to-top scrollable-selector="main" href="#top">Back to top</pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<link rel="stylesheet" href="demo.css"> | ||
|
||
<div class="outer-container scroll-distance" id="top"> | ||
<div class="scroll-indicator padded"> | ||
<h2>Default</h2> | ||
<p><a href="#focusable-element-top" id="top">Focusable element (top)</a></p> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 200px (default). | ||
</div> | ||
</div> | ||
<a href="#focusable-element-bottom">Focusable element (bottom)</a> | ||
|
||
<pf-back-to-top href="#top" scrollable-selector="main" scroll-distance="200">Back to top</pf-back-to-top> | ||
|
||
<script type="module"> | ||
import '@patternfly/elements/pf-back-to-top/pf-back-to-top.js'; | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
<style> | ||
:not(.override) > .example-preview pf-back-to-top { | ||
position: sticky !important; | ||
left: 100%; | ||
bottom: 0; | ||
} | ||
|
||
:not(.override) > .example-preview pf-back-to-top::part(trigger) { | ||
display: inline-block !important; | ||
} | ||
|
||
.override > .example-preview :is(#scrollable-selector-example, #scroll-distance-example) { | ||
position: relative; | ||
height: 200px; | ||
overflow-y: scroll; | ||
} | ||
|
||
.override > .example-preview :is(#scrollable-selector-example, #scroll-distance-example) pf-back-to-top { | ||
position: sticky !important; | ||
left: 100%; | ||
bottom: 0; | ||
} | ||
|
||
.overflow { | ||
height: 573px; | ||
position: relative; | ||
} | ||
|
||
.scroll-indicator { | ||
padding: var(--pf-global--spacer--md, 1rem); | ||
background-color: var(--pf-global--palette--cyan-50, #f2f9f9) !important; | ||
} | ||
|
||
#scrollable-selector-example .scroll-indicator { | ||
height: 400px; | ||
} | ||
|
||
#scroll-distance-example .scroll-indicator { | ||
height: 100px; | ||
} | ||
|
||
</style> | ||
|
||
{% renderOverview %} | ||
Back to top button is designed to only be used once per page. | ||
<pf-back-to-top href="#main">Back to top</pf-back-to-top> | ||
{% endrenderOverview %} | ||
|
||
{% band header="Usage" %} | ||
|
||
### Default | ||
{% htmlexample %}<pf-back-to-top href="#main">Back to top</pf-back-to-top>{% endhtmlexample %} | ||
|
||
### Label attribute | ||
{% htmlexample %}<pf-back-to-top href="#main" label="Return to top"></pf-back-to-top>{% endhtmlexample %} | ||
|
||
### No text or label attribute | ||
`[aria-label]` attribute defaults to text 'Back to top' | ||
{% htmlexample %} | ||
|
||
<pf-back-to-top href="#main"></pf-back-to-top> | ||
{% endhtmlexample %} | ||
|
||
<div class="override"> | ||
|
||
### Scrollable Selector | ||
|
||
See [scrollable-selector](#attributes) in Attributes section below for more information. | ||
|
||
{% htmlexample %} | ||
<div id="scrollable-selector-example"> | ||
<div class="overflow" tabindex="0"> | ||
<div class="scroll-indicator"> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 400px (default). | ||
</div> | ||
</div> | ||
<pf-back-to-top href="#main" scrollable-selector="#scrollable-selector-example">Back to top</pf-back-to-top> | ||
</div> | ||
{% endhtmlexample %} | ||
|
||
### Scroll Distance | ||
|
||
See [scroll-distance](#attributes) in Attributes section below for more information. | ||
|
||
{% htmlexample %} | ||
<div id="scroll-distance-example"> | ||
<div class="overflow" tabindex="0"> | ||
<div class="scroll-indicator"> | ||
<pf-icon icon="arrow-down"></pf-icon> Scroll down to end of cyan box, 100px. | ||
</div> | ||
</div> | ||
<pf-back-to-top href="#main" scroll-distance="100" scrollable-selector="#scroll-distance-example">Back to top</pf-back-to-top> | ||
</div> | ||
{% endhtmlexample %} | ||
|
||
</div> | ||
|
||
{% endband %} | ||
|
||
{% renderSlots %}{% endrenderSlots %} | ||
|
||
{% renderAttributes %}{% endrenderAttributes %} | ||
|
||
{% renderMethods %}{% endrenderMethods %} | ||
|
||
{% renderEvents %}{% endrenderEvents %} | ||
|
||
{% renderCssCustomProperties %}{% endrenderCssCustomProperties %} | ||
|
||
{% renderCssParts %}{% endrenderCssParts %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
:host { | ||
display: inline-block; | ||
position: absolute; | ||
right: var(--pf-c-back-to-top--Right, var(--pf-global--spacer--2xl, 3rem)); | ||
bottom: var(--pf-c-back-to-top--Bottom, var(--pf-global--spacer--lg, 1.5rem)); | ||
} | ||
|
||
[part="trigger"] { | ||
box-shadow: var(--pf-c-back-to-top--c-button--BoxShadow, var(--pf-global--BoxShadow--lg-bottom, 0 0.75rem 0.75rem -0.5rem rgba(3, 3, 3, 0.18))); | ||
|
||
--pf-c-button--FontSize: var(--pf-c-back-to-top--c-button--FontSize, var(--pf-global--FontSize--xs, 0.75rem)); | ||
--pf-c-button--BorderRadius: var(--pf-c-back-to-top--c-button--BorderRadius, var(--pf-global--BorderRadius--lg, 30em)); | ||
--pf-c-button--PaddingTop: var(--pf-c-back-to-top--c-button--PaddingTop, var(--pf-global--spacer--xs, 0.25rem)); | ||
--pf-c-button--PaddingRight: var(--pf-c-back-to-top--c-button--PaddingRight, var(--pf-global--spacer--sm, 0.5rem)); | ||
--pf-c-button--PaddingBottom: var(--pf-c-back-to-top--c-button--PaddingBottom, var(--pf-global--spacer--xs, 0.25rem)); | ||
--pf-c-button--PaddingLeft: var(--pf-c-back-to-top--c-button--PaddingLeft, var(--pf-global--spacer--sm, 0.5rem)); | ||
} | ||
|
||
a { | ||
display: inline-flex; | ||
align-items: center; | ||
justify-content: center; | ||
color: var(--pf-c-button--m-primary--Color, var(--pf-global--Color--light-100, #fff)); | ||
background-color: var(--pf-c-button--m-primary--BackgroundColor, var(--pf-global--primary-color--100, #06c)); | ||
text-decoration: none; | ||
font-size: var(--pf-c-button--FontSize); | ||
padding: var(--pf-c-button--PaddingTop) var(--pf-c-button--PaddingRight) var(--pf-c-button--PaddingBottom) var(--pf-c-button--PaddingLeft); | ||
border-radius: var(--pf-c-button--BorderRadius); | ||
gap: var(--pf-c-button__icon--m-end--MarginLeft, var(--pf-global--spacer--xs, 0.25rem)); | ||
} | ||
|
||
[part="trigger"][hidden] { | ||
display: none; | ||
} | ||
|
||
pf-icon { | ||
/* override icon size as default sm variant is incorrect */ | ||
--pf-icon--size: var(--pf-c-button--FontSize); | ||
vertical-align: -0.125rem; | ||
} | ||
|
||
span { | ||
display: inline-flex; | ||
align-items: center; | ||
justify-content: center; | ||
gap: var(--pf-c-button__icon--m-end--MarginLeft, var(--pf-global--spacer--xs, 0.25rem)); | ||
} | ||
|
||
@media (min-width: 768px) { | ||
:host { | ||
--pf-c-back-to-top--Bottom: var(--pf-c-back-to-top--md--Bottom, var(--pf-global--spacer--2xl, 3rem)); | ||
} | ||
} |
Oops, something went wrong.