diff --git a/.changeset/khaki-bananas-perform.md b/.changeset/khaki-bananas-perform.md new file mode 100644 index 0000000000..afdcb0fba5 --- /dev/null +++ b/.changeset/khaki-bananas-perform.md @@ -0,0 +1,9 @@ +--- +"@patternfly/elements": minor +--- + +✨ Added `` + +```html + Back to Top +``` \ No newline at end of file diff --git a/.changeset/pfe-tools-ts52.md b/.changeset/pfe-tools-ts52.md new file mode 100644 index 0000000000..bbb400777b --- /dev/null +++ b/.changeset/pfe-tools-ts52.md @@ -0,0 +1,4 @@ +--- +"@patternfly/pfe-tools": patch +--- +Update typescript version \ No newline at end of file diff --git a/elements/README.md b/elements/README.md index 78416895d2..fed8c9178d 100644 --- a/elements/README.md +++ b/elements/README.md @@ -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. diff --git a/elements/package.json b/elements/package.json index 7f5e86daa3..014d929f90 100644 --- a/elements/package.json +++ b/elements/package.json @@ -18,6 +18,7 @@ "./pf-accordion/pf-accordion.js": "./pf-accordion/pf-accordion.js", "./pf-avatar/BaseAvatar.js": "./pf-avatar/BaseAvatar.js", "./pf-avatar/pf-avatar.js": "./pf-avatar/pf-avatar.js", + "./pf-back-to-top/pf-back-to-top.js": "./pf-back-to-top/pf-back-to-top.js", "./pf-background-image/pf-background-image.js": "./pf-background-image/pf-background-image.js", "./pf-badge/BaseBadge.js": "./pf-badge/BaseBadge.js", "./pf-badge/pf-badge.js": "./pf-badge/pf-badge.js", diff --git a/elements/pf-back-to-top/README.md b/elements/pf-back-to-top/README.md new file mode 100644 index 0000000000..3a681e4fd7 --- /dev/null +++ b/elements/pf-back-to-top/README.md @@ -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 `` via CDN: + +```html + + + +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 +Back to Top + +``` + +[docs]: https://patternflyelements.org/components/back-to-top diff --git a/elements/pf-back-to-top/demo/always-visible.html b/elements/pf-back-to-top/demo/always-visible.html new file mode 100644 index 0000000000..427492d97f --- /dev/null +++ b/elements/pf-back-to-top/demo/always-visible.html @@ -0,0 +1,12 @@ + + +
+

Always visible

+ Focusable element (top) +
+ +Back to top + + diff --git a/elements/pf-back-to-top/demo/button-no-text.html b/elements/pf-back-to-top/demo/button-no-text.html new file mode 100644 index 0000000000..09728fc299 --- /dev/null +++ b/elements/pf-back-to-top/demo/button-no-text.html @@ -0,0 +1,22 @@ + + +
+
+

Button No Text

+

Focusable element (top)

+ Scroll down to end of cyan box, 400px (default). +
+
+Focusable element (bottom) + + + + diff --git a/elements/pf-back-to-top/demo/button.html b/elements/pf-back-to-top/demo/button.html new file mode 100644 index 0000000000..a05dd33e70 --- /dev/null +++ b/elements/pf-back-to-top/demo/button.html @@ -0,0 +1,27 @@ + + + + + Accessibility Warning Using the Button/JS variant, implementation must apply click event and focus to the element that is scrolled to. + +
+
+

Button

+

Focusable element (top)

+ Scroll down to end of cyan box, 400px (default). +
+
+Focusable element (bottom) + +Back to top + + diff --git a/elements/pf-back-to-top/demo/demo.css b/elements/pf-back-to-top/demo/demo.css new file mode 100644 index 0000000000..39ac723ffd --- /dev/null +++ b/elements/pf-back-to-top/demo/demo.css @@ -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; +} + diff --git a/elements/pf-back-to-top/demo/label.html b/elements/pf-back-to-top/demo/label.html new file mode 100644 index 0000000000..51db65dd2f --- /dev/null +++ b/elements/pf-back-to-top/demo/label.html @@ -0,0 +1,16 @@ + + +
+
+

Default

+

Focusable element (top)

+ Scroll down to end of cyan box, 400px (default). +
+
+Focusable element (bottom) + + + + diff --git a/elements/pf-back-to-top/demo/no-text.html b/elements/pf-back-to-top/demo/no-text.html new file mode 100644 index 0000000000..66e8d4bbfa --- /dev/null +++ b/elements/pf-back-to-top/demo/no-text.html @@ -0,0 +1,16 @@ + + +
+
+

No Text

+

Focusable element (top)

+ Scroll down to end of cyan box, 400px (default). +
+
+Focusable element (bottom) + + + + diff --git a/elements/pf-back-to-top/demo/pf-back-to-top.html b/elements/pf-back-to-top/demo/pf-back-to-top.html new file mode 100644 index 0000000000..f22fb4277d --- /dev/null +++ b/elements/pf-back-to-top/demo/pf-back-to-top.html @@ -0,0 +1,16 @@ + + +
+
+

Default

+

Focusable element (top)

+ Scroll down to end of cyan box, 400px (default). +
+
+Focusable element (bottom) + +Back to top + + diff --git a/elements/pf-back-to-top/demo/scroll-distance.html b/elements/pf-back-to-top/demo/scroll-distance.html new file mode 100644 index 0000000000..b7d97a6015 --- /dev/null +++ b/elements/pf-back-to-top/demo/scroll-distance.html @@ -0,0 +1,16 @@ + + +
+
+

Default

+

Focusable element (top)

+ Scroll down to end of cyan box, 200px (default). +
+
+Focusable element (bottom) + +Back to top + + diff --git a/elements/pf-back-to-top/docs/pf-back-to-top.md b/elements/pf-back-to-top/docs/pf-back-to-top.md new file mode 100644 index 0000000000..525c404334 --- /dev/null +++ b/elements/pf-back-to-top/docs/pf-back-to-top.md @@ -0,0 +1,110 @@ + + +{% renderOverview %} + Back to top button is designed to only be used once per page. + Back to top +{% endrenderOverview %} + +{% band header="Usage" %} + + ### Default + {% htmlexample %}Back to top{% endhtmlexample %} + + ### Label attribute + {% htmlexample %}{% endhtmlexample %} + + ### No text or label attribute + `[aria-label]` attribute defaults to text 'Back to top' + {% htmlexample %} + + + {% endhtmlexample %} + +
+ + ### Scrollable Selector + + See [scrollable-selector](#attributes) in Attributes section below for more information. + + {% htmlexample %} +
+
+
+ Scroll down to end of cyan box, 400px (default). +
+
+ Back to top +
+ {% endhtmlexample %} + + ### Scroll Distance + + See [scroll-distance](#attributes) in Attributes section below for more information. + + {% htmlexample %} +
+
+
+ Scroll down to end of cyan box, 100px. +
+
+ Back to top +
+ {% endhtmlexample %} + +
+ +{% endband %} + +{% renderSlots %}{% endrenderSlots %} + +{% renderAttributes %}{% endrenderAttributes %} + +{% renderMethods %}{% endrenderMethods %} + +{% renderEvents %}{% endrenderEvents %} + +{% renderCssCustomProperties %}{% endrenderCssCustomProperties %} + +{% renderCssParts %}{% endrenderCssParts %} diff --git a/elements/pf-back-to-top/pf-back-to-top.css b/elements/pf-back-to-top/pf-back-to-top.css new file mode 100644 index 0000000000..793e87e68a --- /dev/null +++ b/elements/pf-back-to-top/pf-back-to-top.css @@ -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)); + } +} diff --git a/elements/pf-back-to-top/pf-back-to-top.ts b/elements/pf-back-to-top/pf-back-to-top.ts new file mode 100644 index 0000000000..c594de18d1 --- /dev/null +++ b/elements/pf-back-to-top/pf-back-to-top.ts @@ -0,0 +1,202 @@ +import { LitElement, html, type PropertyValues } from 'lit'; +import { customElement } from 'lit/decorators/custom-element.js'; +import { property } from 'lit/decorators/property.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; + +import { Logger } from '@patternfly/pfe-core/controllers/logger.js'; + +import '@patternfly/elements/pf-button/pf-button.js'; +import '@patternfly/elements/pf-icon/pf-icon.js'; + +import styles from './pf-back-to-top.css'; + +/** + * The **back to top** component is a shortcut that allows users to quickly navigate to the top of a lengthy content page. + * @summary A shortcut that allows users to quickly navigate to the top of a lengthy content page. + * + * @csspart trigger - The `` or `` element + * + * @slot icon + * Contains the prefix icon to display before the link or button. + * @slot + * Text to display inside the link or button. + * + * @cssprop {} --pf-c-back-to-top--Right {@default `3rem``} + * @cssprop {} --pf-c-back-to-top--Bottom {@default `1.5rem``} + * @cssprop --pf-c-back-to-top--c-button--BoxShadow {@default `0 0.75rem 0.75rem -0.5rem rgba(3, 3, 3, 0.18)`} + * @cssprop {} --pf-c-button--FontSize {@default `0.75rem`} + * @cssprop {|} --pf-c-button--BorderRadius {@default `30em`} + * @cssprop {} --pf-c-button--PaddingTop {@default `0.25rem`} + * @cssprop {} --pf-c-button--PaddingRight {@default `0.5rem`} + * @cssprop {} --pf-c-button--PaddingBottom {@default `0.25rem`} + * @cssprop {} --pf-c-button--PaddingLeft {@default `0.5rem`} + * @cssprop {} --pf-c-button--m-primary--Color {@default `#fff`} + * @cssprop {} --pf-c-button--m-primary--BackgroundColor {@default `#06c`} + * @cssprop {} --pf-c-button__icon--m-end--MarginLeft {@default `0.25rem`} + * + */ +@customElement('pf-back-to-top') +export class PfBackToTop extends LitElement { + static readonly styles = [styles]; + + /** Shorthand for the `icon` slot, the value is icon name */ + @property({ reflect: true }) icon?: string; + + /** Icon set for the `icon` property */ + @property({ attribute: 'icon-set' }) iconSet?: string; + + /** Flag to always show back to top button, defaults to false. */ + @property({ reflect: true, type: Boolean, attribute: 'always-visible' }) alwaysVisible = false; + + /** Element selector to spy on for scrolling. Not passing a selector defaults to spying on window scroll events */ + @property({ reflect: true, attribute: 'scrollable-selector' }) scrollableSelector?: string; + + /** Distance from the top of the scrollable element to trigger the visibility of the back to top button */ + @property({ type: Number, attribute: 'scroll-distance' }) scrollDistance = 400; + + /** Accessible name for the back-to-top link, use when component does not have slotted text */ + @property() label?: string; + + /** Page fragment link to target element, must include hash ex: #top */ + @property({ reflect: true }) href?: string; + + #scrollSpy = false; + + #visible = false; + + #scrollElement?: Element | Window; + + #hasSlottedText = false; + + #logger = new Logger(this); + + get #rootNode(): Document | ShadowRoot { + const root = this.getRootNode(); + if (root instanceof Document || root instanceof ShadowRoot) { + return root; + } else { + return document; + } + } + + get #ariaLabel(): string | undefined { + if (this.#hasSlottedText) { + return undefined; + } + return this.label ?? 'Back to top'; + } + + override connectedCallback(): void { + super.connectedCallback(); + this.#addScrollListener(); + } + + override disconnectedCallback(): void { + super.disconnectedCallback(); + this.#removeScrollListener(); + } + + override willUpdate(changed: PropertyValues): void { + if (changed.has('scrollableSelector')) { + this.#addScrollListener(); + } + if (changed.has('alwaysVisible')) { + this.#toggleVisibility(); + } + } + + render() { + // ensure href has a hash + if (this.href && this.href.charAt(0) !== '#') { + this.href = `#${this.href}`; + this.#logger.warn(`missing hash in href fragment link`); + } + + if (this.href) { + return html` + + + + + + `; + } else { + return html` + + + + + + + + `; + } + } + + #onSlotchange(event: Event) { + const slot = event.currentTarget as HTMLSlotElement; + const nodes = slot.assignedNodes(); + this.#hasSlottedText = nodes.length > 0 ? true : false; + this.requestUpdate(); + } + + #removeScrollListener() { + this.#scrollElement?.removeEventListener('scroll', this.#toggleVisibility); + } + + #addScrollListener() { + this.#removeScrollListener(); + + if (this.scrollableSelector?.trim() === '') { + this.#logger.error(`scrollable-selector attribute cannot be empty`); + return; + } + + this.#scrollSpy = !!this.scrollableSelector; + if (this.#scrollSpy && this.scrollableSelector) { + const scrollableElement = this.#rootNode.querySelector(this.scrollableSelector); + if (!scrollableElement) { + this.#logger.error(`unable to find element with selector ${this.scrollableSelector}`); + return; + } + this.#scrollElement = scrollableElement; + } else { + this.#scrollElement = window; + } + + this.#scrollElement.addEventListener('scroll', this.#toggleVisibility, { passive: true }); + this.#toggleVisibility(); + } + + #toggleVisibility = () => { + if (this.alwaysVisible) { + this.#visible = true; + this.requestUpdate(); + return; + } + const previousVisibility = this.#visible; + if (this.#scrollElement) { + const scrolled = + (this.#scrollElement instanceof Window) ? + this.#scrollElement.scrollY + : this.#scrollElement.scrollTop; + this.#visible = (scrolled > this.scrollDistance); + if (previousVisibility !== this.#visible) { + this.requestUpdate(); + } + } + }; +} + +declare global { + interface HTMLElementTagNameMap { + 'pf-back-to-top': PfBackToTop; + } +} diff --git a/elements/pf-back-to-top/test/pf-back-to-top.e2e.ts b/elements/pf-back-to-top/test/pf-back-to-top.e2e.ts new file mode 100644 index 0000000000..708611d7a3 --- /dev/null +++ b/elements/pf-back-to-top/test/pf-back-to-top.e2e.ts @@ -0,0 +1,12 @@ +import { test } from '@playwright/test'; +import { PfeDemoPage } from '@patternfly/pfe-tools/test/playwright/PfeDemoPage.js'; + +const tagName = 'pf-back-to-top'; + +test.describe(tagName, () => { + test('snapshot', async ({ page }) => { + const componentPage = new PfeDemoPage(page, tagName); + await componentPage.navigate(); + await componentPage.snapshot(); + }); +}); diff --git a/elements/pf-back-to-top/test/pf-back-to-top.spec.ts b/elements/pf-back-to-top/test/pf-back-to-top.spec.ts new file mode 100644 index 0000000000..139200bb04 --- /dev/null +++ b/elements/pf-back-to-top/test/pf-back-to-top.spec.ts @@ -0,0 +1,313 @@ +import { expect, html, nextFrame } from '@open-wc/testing'; +import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js'; +import { setViewport, sendKeys } from '@web/test-runner-commands'; + +import { allUpdates } from '@patternfly/pfe-tools/test/utils.js'; + +import { PfBackToTop } from '../pf-back-to-top.js'; +import { type A11yTreeSnapshot, a11ySnapshot } from '@patternfly/pfe-tools/test/a11y-snapshot.js'; + +const takeProps = (props: string[]) => (obj: object) => + Object.fromEntries(Object.entries(obj).filter(([k]) => props.includes(k))); + +describe('', function() { + it('imperatively instantiates', function() { + expect(document.createElement('pf-back-to-top')).to.be.an.instanceof(PfBackToTop); + }); + + describe('simply instantiating', function() { + let element: PfBackToTop; + + beforeEach(async function() { + element = await createFixture(html``); + }); + + it('should upgrade', function() { + const klass = customElements.get('pf-back-to-top'); + expect(element) + .to.be.an.instanceOf(klass) + .and + .to.be.an.instanceOf(PfBackToTop); + }); + }); + + describe('when rendered in a viewport with a height smaller then content length', function() { + let element: PfBackToTop; + let snapshot: A11yTreeSnapshot; + + beforeEach(async function() { + await setViewport({ width: 320, height: 640 }); + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + const container = await createFixture(html` +
+
+ Back to top +
+ `); + element = container.querySelector('pf-back-to-top')!; + snapshot = await a11ySnapshot(); + + await allUpdates(element); + }); + + it('should be hidden on init', function() { + const { children } = snapshot; + expect(children).to.be.undefined; + }); + + it('should not be accessible', function() { + expect(snapshot.children).to.be.undefined; + }); + + describe('when scrolled 401px', function() { + beforeEach(async function() { + window.scrollTo({ top: 401, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should be visible', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'link', name: 'Back to top' }]); + }); + + it('should be accessible', async function() { + await expect(element).to.be.accessible; + }); + + describe('pressing the tab key', function() { + beforeEach(async function() { + await sendKeys({ press: 'Tab' }); + await allUpdates(element); + await nextFrame(); + }); + + it('should focus the component', function() { + expect(document.activeElement).to.equal(element); + }); + }); + }); + + describe('when the always visible property is true', function() { + beforeEach(async function() { + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + element.alwaysVisible = true; + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should be visible', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'link', name: 'Back to top' }]); + }); + + it('should be accessible', async function() { + await expect(element).to.be.accessible; + }); + + describe('pressing the tab key', function() { + beforeEach(async function() { + await sendKeys({ press: 'Tab' }); + await allUpdates(element); + await nextFrame(); + }); + it('should focus the component', function() { + expect(document.activeElement).to.equal(element); + }); + }); + }); + + describe('when the scroll distance is set to 1000', function() { + beforeEach(async function() { + element.scrollDistance = 1000; + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should be hidden', function() { + const { children } = snapshot; + expect(children).to.be.undefined; + }); + + describe('when scrolled 1001px', function() { + beforeEach(async function() { + window.scrollTo({ top: 1001, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should be visible', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'link', name: 'Back to top' }]); + }); + }); + }); + }); + + describe('when rendered in an element with an overflowed height', function() { + let element: PfBackToTop; + let snapshot: A11yTreeSnapshot; + + beforeEach(async function() { + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + const container = await createFixture(html` +
+
+ Back to top +
+ `); + element = container.querySelector('pf-back-to-top')!; + snapshot = await a11ySnapshot(); + + await allUpdates(element); + }); + + it('should be hidden on init', function() { + const { children } = snapshot; + expect(children).to.be.undefined; + }); + + describe('when scrolled 401px', function() { + beforeEach(async function() { + const scrollableElement = document.querySelector('#top')!; + scrollableElement.scrollTo({ top: 401, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should be visible', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'link', name: 'Back to top' }]); + }); + }); + }); + + describe('when no text is provided', function() { + let element: PfBackToTop; + let snapshot: A11yTreeSnapshot; + + describe('as a link', function() { + beforeEach(async function() { + await setViewport({ width: 320, height: 640 }); + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + const container = await createFixture(html` +
+
+ +
+ `); + element = container.querySelector('pf-back-to-top')!; + await allUpdates(element); + }); + + describe('when scrolled', function() { + beforeEach(async function() { + window.scrollTo({ top: 401, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should have a label of "Back to top"', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'link', name: 'Back to top' }]); + }); + }); + }); + + describe('as a button', function() { + beforeEach(async function() { + await setViewport({ width: 320, height: 640 }); + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + const container = await createFixture(html` +
+
+ +
+ `); + element = container.querySelector('pf-back-to-top')!; + await allUpdates(element); + }); + + describe('when scrolled', function() { + beforeEach(async function() { + window.scrollTo({ top: 401, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should have a label of "Back to top"', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'button', name: 'Back to top' }]); + }); + }); + }); + }); + + describe('when a label is provided', function() { + let element: PfBackToTop; + let snapshot: A11yTreeSnapshot; + + describe('as a link', function() { + beforeEach(async function() { + await setViewport({ width: 320, height: 640 }); + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + const container = await createFixture(html` +
+
+ +
+ `); + element = container.querySelector('pf-back-to-top')!; + await allUpdates(element); + }); + + describe('when scrolled', function() { + beforeEach(async function() { + window.scrollTo({ top: 401, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should have a label of "Return to top"', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'link', name: 'Return to top' }]); + }); + }); + }); + + describe('as a button', function() { + beforeEach(async function() { + await setViewport({ width: 320, height: 640 }); + window.scrollTo({ top: 0, behavior: 'instant' }); + await nextFrame(); + const container = await createFixture(html` +
+
+ +
+ `); + element = container.querySelector('pf-back-to-top')!; + await allUpdates(element); + }); + + describe('when scrolled', function() { + beforeEach(async function() { + window.scrollTo({ top: 401, behavior: 'instant' }); + await nextFrame(); + await allUpdates(element); + snapshot = await a11ySnapshot(); + }); + + it('should have a label of "Return to top"', function() { + expect(snapshot.children?.map(takeProps(['name', 'role']))).to.deep.equal([{ role: 'button', name: 'Return to top' }]); + }); + }); + }); + }); +}); + diff --git a/package-lock.json b/package-lock.json index 48f090cae0..9ec1858cde 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,10 +27,10 @@ "@octokit/core": "^4.2.0", "@patternfly/patternfly": "^4.224.2", "@rhds/elements": "^1.0.0", - "@types/koa__router": "^12.0.0", - "@types/numeral": "^2.0.2", - "@types/prismjs": "^1.26.0", - "@types/prompts": "^2.4.4", + "@types/koa__router": "^12.0.1", + "@types/numeral": "^2.0.3", + "@types/prismjs": "^1.26.1", + "@types/prompts": "^2.4.5", "commitlint": "^17.6.1", "execa": "^7.1.1", "fuse.js": "^6.6.2", @@ -3894,18 +3894,18 @@ "integrity": "sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==" }, "node_modules/@types/eslint": { - "version": "8.37.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", - "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "version": "8.44.3", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.3.tgz", + "integrity": "sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", + "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==" }, "node_modules/@types/express": { "version": "4.17.17", @@ -4013,9 +4013,9 @@ } }, "node_modules/@types/koa__router": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-12.0.0.tgz", - "integrity": "sha512-S6eHyZyoWCZLNHyy8j0sMW85cPrpByCbGGU2/BO4IzGiI87aHJ92lZh4E9xfsM9DcbCT469/OIqyC0sSJXSIBQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-12.0.1.tgz", + "integrity": "sha512-uqV+v6pCsfLZwK+Ar6XavKSZ6Cbsgw12bCEX9L0IKHj81LTWXcrayxJWkLtez5vOMQlq+ax+lZcuCyh9CgxYGw==", "dev": true, "dependencies": { "@types/koa": "*" @@ -4030,9 +4030,9 @@ } }, "node_modules/@types/koa-send": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.3.tgz", - "integrity": "sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.4.tgz", + "integrity": "sha512-+ttyO5T1T1cLRUtk9etg/4E7ZIplJJUANkuzYptCPysWX5LRfGHsv9YOCiB7+gkAuedjEgZrl4K02RWJ2gaJ6Q==", "dependencies": { "@types/koa": "*" } @@ -4091,15 +4091,15 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" }, "node_modules/@types/numeral": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/numeral/-/numeral-2.0.2.tgz", - "integrity": "sha512-A8F30k2gYJ/6e07spSCPpkuZu79LCnkPTvqmIWQzNGcrzwFKpVOydG41lNt5wZXjSI149qjyzC2L1+F2PD/NUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/numeral/-/numeral-2.0.3.tgz", + "integrity": "sha512-37VDYvFbx/I+Ve1kwcDUq5+qvgNl+uy9YUZhBMJ6YWHBtr2+d6CAgdn4R81NqBlZbTpvLxJOTUhwbki7+90+qQ==", "dev": true }, "node_modules/@types/nunjucks": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.2.tgz", - "integrity": "sha512-qarGBZOVxv1pF6BxQHwYHYYxim/TCm3aXF8BUt/kyF/+xi/DXMoj1Bhw3hXVBl2Yov+w47reDldm0iXXFZTotA==" + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-Ro2d3CROK+QNreS9MgFloCuRyHaLHyxkoiDax97uUWHQQwtKckH11ZvJfRVEuYGcTgJPY7JFwrjK3jRCTRLXwQ==" }, "node_modules/@types/parse5": { "version": "6.0.3", @@ -4107,15 +4107,15 @@ "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, "node_modules/@types/prismjs": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz", - "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==", + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.1.tgz", + "integrity": "sha512-Q7jDsRbzcNHIQje15CS/piKhu6lMLb9jwjxSfEIi4KcFKXW23GoJMkwQiJ8VObyfx+VmUaDcJxXaWN+cTCjVog==", "dev": true }, "node_modules/@types/prompts": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.4.tgz", - "integrity": "sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.5.tgz", + "integrity": "sha512-TvrzGMCwARi2qqXcD7VmvMvfMP3F7JRQpeEHECK0oufRNZInoBqzd8v/1zksKFE5XW8OOGto/5FsDT8lnpvGRA==", "dev": true, "dependencies": { "@types/node": "*", @@ -4169,9 +4169,9 @@ } }, "node_modules/@types/sinon": { - "version": "10.0.14", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.14.tgz", - "integrity": "sha512-mn72up6cjaMyMuaPaa/AwKf6WtsSRysQC7wxFkCm1XcOKXPM1z+5Y4H5wjIVBz4gdAkjvZxVVfjA6ba1nHr5WQ==", + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.17.tgz", + "integrity": "sha512-+6ILpcixQ0Ma3dHMTLv4rSycbDXkDljgKL+E0nI2RUxxhYTFyPSjt6RVMxh7jUshvyVcBvicb0Ktj+lAJcjgeA==", "dependencies": { "@types/sinonjs__fake-timers": "*" } @@ -4212,9 +4212,9 @@ } }, "node_modules/@types/uglifycss": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@types/uglifycss/-/uglifycss-0.0.7.tgz", - "integrity": "sha512-nBnwN8pNN4CPS/o7XgYRFHqSlj1zP/QEeI7wMe0nmcl39JF7+vsMqhBNJZD/ZldA/hUBrMUYSFm6bwWdZ5CFYQ==" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/uglifycss/-/uglifycss-0.0.8.tgz", + "integrity": "sha512-a5PSkAxKFTZ8IuYMNO25K6ho7vsgrig9s2upDa9NoHs55m6n6C9XEHfjE2j5FXfhsgeyIvtG6Q4WPE+ACk8lXQ==" }, "node_modules/@types/ws": { "version": "7.4.7", @@ -4225,9 +4225,9 @@ } }, "node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "version": "17.0.25", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.25.tgz", + "integrity": "sha512-gy7iPgwnzNvxgAEi2bXOHWCVOG6f7xsprVJH4MjlAWeBmJ7vh/Y1kwMtUrs64ztf24zVIRCpr3n/z6gm9QIkgg==", "dependencies": { "@types/yargs-parser": "*" } @@ -16792,9 +16792,9 @@ } }, "node_modules/ts-patch": { - "version": "3.0.0-beta3", - "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.0.0-beta3.tgz", - "integrity": "sha512-WAuauq0u3jPWJLJRVQi4tz01XQ1KHi05sPxUrzjGx4xUweoCzYtpLHaTlbcBVw0u7iptQQ8hPZNCS36C6Uu8vw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.0.2.tgz", + "integrity": "sha512-iTg8euqiNsNM1VDfOsVIsP0bM4kAVXU38n7TGQSkky7YQX/syh6sDPIRkvSS0HjT8ZOr0pq1h+5Le6jdB3hiJQ==", "dependencies": { "chalk": "^4.1.2", "global-prefix": "^3.0.0", @@ -16971,15 +16971,15 @@ } }, "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=12.20" + "node": ">=14.17" } }, "node_modules/typical": { @@ -17916,7 +17916,7 @@ "version": "2.0.1", "license": "MIT", "dependencies": { - "@types/eslint": "^8.37.0", + "@types/eslint": "^8.44.3", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", "eslint": "^8.35.0", @@ -18038,13 +18038,13 @@ "@playwright/test": "^1.32.3", "@rollup/plugin-replace": "^5.0.2", "@types/dedent": "^0.7.0", - "@types/estree": "^1.0.0", - "@types/koa-send": "^4.1.3", + "@types/estree": "^1.0.2", + "@types/koa-send": "^4.1.4", "@types/mocha": "10.0.1", - "@types/nunjucks": "^3.2.2", - "@types/sinon": "^10.0.13", - "@types/uglifycss": "^0.0.7", - "@types/yargs": "^17.0.24", + "@types/nunjucks": "^3.2.4", + "@types/sinon": "^10.0.17", + "@types/uglifycss": "^0.0.8", + "@types/yargs": "^17.0.25", "@web/dev-server": "^0.1.38", "@web/dev-server-esbuild": "^0.3.6", "@web/dev-server-import-maps": "^0.0.8", @@ -18083,8 +18083,8 @@ "sinon": "^15.0.3", "ts-lit-plugin": "^1.2.1", "ts-node": "^10.9.1", - "ts-patch": "3.0.0-beta3", - "typescript": "5.0.4", + "ts-patch": "3.0.2", + "typescript": "5.2.2", "urlpattern-polyfill": "^7.0.0", "web-dev-server-plugin-lit-css": "^2.0.5" }, @@ -20603,7 +20603,7 @@ "@patternfly/eslint-config-elements": { "version": "file:tools/eslint-config", "requires": { - "@types/eslint": "^8.37.0", + "@types/eslint": "^8.44.3", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", "eslint": "^8.35.0", @@ -20687,14 +20687,14 @@ "@playwright/test": "^1.32.3", "@rollup/plugin-replace": "^5.0.2", "@types/dedent": "^0.7.0", - "@types/estree": "^1.0.0", + "@types/estree": "^1.0.2", "@types/glob": "^8.1.0", - "@types/koa-send": "^4.1.3", + "@types/koa-send": "^4.1.4", "@types/mocha": "10.0.1", - "@types/nunjucks": "^3.2.2", - "@types/sinon": "^10.0.13", - "@types/uglifycss": "^0.0.7", - "@types/yargs": "^17.0.24", + "@types/nunjucks": "^3.2.4", + "@types/sinon": "^10.0.17", + "@types/uglifycss": "^0.0.8", + "@types/yargs": "^17.0.25", "@web/dev-server": "^0.1.38", "@web/dev-server-esbuild": "^0.3.6", "@web/dev-server-import-maps": "^0.0.8", @@ -20733,8 +20733,8 @@ "sinon": "^15.0.3", "ts-lit-plugin": "^1.2.1", "ts-node": "^10.9.1", - "ts-patch": "3.0.0-beta3", - "typescript": "5.0.4", + "ts-patch": "3.0.2", + "typescript": "5.2.2", "urlpattern-polyfill": "^7.0.0", "web-dev-server-plugin-lit-css": "^2.0.5" } @@ -21135,18 +21135,18 @@ "integrity": "sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==" }, "@types/eslint": { - "version": "8.37.0", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.37.0.tgz", - "integrity": "sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==", + "version": "8.44.3", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.44.3.tgz", + "integrity": "sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g==", "requires": { "@types/estree": "*", "@types/json-schema": "*" } }, "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.2.tgz", + "integrity": "sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA==" }, "@types/express": { "version": "4.17.17", @@ -21254,9 +21254,9 @@ } }, "@types/koa__router": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-12.0.0.tgz", - "integrity": "sha512-S6eHyZyoWCZLNHyy8j0sMW85cPrpByCbGGU2/BO4IzGiI87aHJ92lZh4E9xfsM9DcbCT469/OIqyC0sSJXSIBQ==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@types/koa__router/-/koa__router-12.0.1.tgz", + "integrity": "sha512-uqV+v6pCsfLZwK+Ar6XavKSZ6Cbsgw12bCEX9L0IKHj81LTWXcrayxJWkLtez5vOMQlq+ax+lZcuCyh9CgxYGw==", "dev": true, "requires": { "@types/koa": "*" @@ -21271,9 +21271,9 @@ } }, "@types/koa-send": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.3.tgz", - "integrity": "sha512-daaTqPZlgjIJycSTNjKpHYuKhXYP30atFc1pBcy6HHqB9+vcymDgYTguPdx9tO4HMOqNyz6bz/zqpxt5eLR+VA==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/koa-send/-/koa-send-4.1.4.tgz", + "integrity": "sha512-+ttyO5T1T1cLRUtk9etg/4E7ZIplJJUANkuzYptCPysWX5LRfGHsv9YOCiB7+gkAuedjEgZrl4K02RWJ2gaJ6Q==", "requires": { "@types/koa": "*" } @@ -21332,15 +21332,15 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==" }, "@types/numeral": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/numeral/-/numeral-2.0.2.tgz", - "integrity": "sha512-A8F30k2gYJ/6e07spSCPpkuZu79LCnkPTvqmIWQzNGcrzwFKpVOydG41lNt5wZXjSI149qjyzC2L1+F2PD/NUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/numeral/-/numeral-2.0.3.tgz", + "integrity": "sha512-37VDYvFbx/I+Ve1kwcDUq5+qvgNl+uy9YUZhBMJ6YWHBtr2+d6CAgdn4R81NqBlZbTpvLxJOTUhwbki7+90+qQ==", "dev": true }, "@types/nunjucks": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.2.tgz", - "integrity": "sha512-qarGBZOVxv1pF6BxQHwYHYYxim/TCm3aXF8BUt/kyF/+xi/DXMoj1Bhw3hXVBl2Yov+w47reDldm0iXXFZTotA==" + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@types/nunjucks/-/nunjucks-3.2.4.tgz", + "integrity": "sha512-Ro2d3CROK+QNreS9MgFloCuRyHaLHyxkoiDax97uUWHQQwtKckH11ZvJfRVEuYGcTgJPY7JFwrjK3jRCTRLXwQ==" }, "@types/parse5": { "version": "6.0.3", @@ -21348,15 +21348,15 @@ "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, "@types/prismjs": { - "version": "1.26.0", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.0.tgz", - "integrity": "sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==", + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.1.tgz", + "integrity": "sha512-Q7jDsRbzcNHIQje15CS/piKhu6lMLb9jwjxSfEIi4KcFKXW23GoJMkwQiJ8VObyfx+VmUaDcJxXaWN+cTCjVog==", "dev": true }, "@types/prompts": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.4.tgz", - "integrity": "sha512-p5N9uoTH76lLvSAaYSZtBCdEXzpOOufsRjnhjVSrZGXikVGHX9+cc9ERtHRV4hvBKHyZb1bg4K+56Bd2TqUn4A==", + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.5.tgz", + "integrity": "sha512-TvrzGMCwARi2qqXcD7VmvMvfMP3F7JRQpeEHECK0oufRNZInoBqzd8v/1zksKFE5XW8OOGto/5FsDT8lnpvGRA==", "dev": true, "requires": { "@types/node": "*", @@ -21409,9 +21409,9 @@ } }, "@types/sinon": { - "version": "10.0.14", - "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.14.tgz", - "integrity": "sha512-mn72up6cjaMyMuaPaa/AwKf6WtsSRysQC7wxFkCm1XcOKXPM1z+5Y4H5wjIVBz4gdAkjvZxVVfjA6ba1nHr5WQ==", + "version": "10.0.17", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-10.0.17.tgz", + "integrity": "sha512-+6ILpcixQ0Ma3dHMTLv4rSycbDXkDljgKL+E0nI2RUxxhYTFyPSjt6RVMxh7jUshvyVcBvicb0Ktj+lAJcjgeA==", "requires": { "@types/sinonjs__fake-timers": "*" } @@ -21451,9 +21451,9 @@ } }, "@types/uglifycss": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@types/uglifycss/-/uglifycss-0.0.7.tgz", - "integrity": "sha512-nBnwN8pNN4CPS/o7XgYRFHqSlj1zP/QEeI7wMe0nmcl39JF7+vsMqhBNJZD/ZldA/hUBrMUYSFm6bwWdZ5CFYQ==" + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/uglifycss/-/uglifycss-0.0.8.tgz", + "integrity": "sha512-a5PSkAxKFTZ8IuYMNO25K6ho7vsgrig9s2upDa9NoHs55m6n6C9XEHfjE2j5FXfhsgeyIvtG6Q4WPE+ACk8lXQ==" }, "@types/ws": { "version": "7.4.7", @@ -21464,9 +21464,9 @@ } }, "@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "version": "17.0.25", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.25.tgz", + "integrity": "sha512-gy7iPgwnzNvxgAEi2bXOHWCVOG6f7xsprVJH4MjlAWeBmJ7vh/Y1kwMtUrs64ztf24zVIRCpr3n/z6gm9QIkgg==", "requires": { "@types/yargs-parser": "*" } @@ -30927,9 +30927,9 @@ } }, "ts-patch": { - "version": "3.0.0-beta3", - "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.0.0-beta3.tgz", - "integrity": "sha512-WAuauq0u3jPWJLJRVQi4tz01XQ1KHi05sPxUrzjGx4xUweoCzYtpLHaTlbcBVw0u7iptQQ8hPZNCS36C6Uu8vw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/ts-patch/-/ts-patch-3.0.2.tgz", + "integrity": "sha512-iTg8euqiNsNM1VDfOsVIsP0bM4kAVXU38n7TGQSkky7YQX/syh6sDPIRkvSS0HjT8ZOr0pq1h+5Le6jdB3hiJQ==", "requires": { "chalk": "^4.1.2", "global-prefix": "^3.0.0", @@ -31057,9 +31057,9 @@ } }, "typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==" + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==" }, "typical": { "version": "4.0.0", diff --git a/package.json b/package.json index fcc645db32..bb7dec4b25 100644 --- a/package.json +++ b/package.json @@ -307,10 +307,10 @@ "@octokit/core": "^4.2.0", "@patternfly/patternfly": "^4.224.2", "@rhds/elements": "^1.0.0", - "@types/koa__router": "^12.0.0", - "@types/numeral": "^2.0.2", - "@types/prismjs": "^1.26.0", - "@types/prompts": "^2.4.4", + "@types/koa__router": "^12.0.1", + "@types/numeral": "^2.0.3", + "@types/prismjs": "^1.26.1", + "@types/prompts": "^2.4.5", "commitlint": "^17.6.1", "execa": "^7.1.1", "fuse.js": "^6.6.2", diff --git a/tools/eslint-config/package.json b/tools/eslint-config/package.json index e91d70786b..7e6de21352 100644 --- a/tools/eslint-config/package.json +++ b/tools/eslint-config/package.json @@ -21,7 +21,7 @@ "@patternfly/eslint-plugin-elements": "^1.1.0" }, "dependencies": { - "@types/eslint": "^8.37.0", + "@types/eslint": "^8.44.3", "@typescript-eslint/eslint-plugin": "^5.58.0", "@typescript-eslint/parser": "^5.58.0", "eslint": "^8.35.0", diff --git a/tools/pfe-tools/package.json b/tools/pfe-tools/package.json index 8ff7b10658..31f4795826 100644 --- a/tools/pfe-tools/package.json +++ b/tools/pfe-tools/package.json @@ -72,13 +72,13 @@ "@playwright/test": "^1.32.3", "@rollup/plugin-replace": "^5.0.2", "@types/dedent": "^0.7.0", - "@types/estree": "^1.0.0", - "@types/koa-send": "^4.1.3", + "@types/estree": "^1.0.2", + "@types/koa-send": "^4.1.4", "@types/mocha": "10.0.1", - "@types/nunjucks": "^3.2.2", - "@types/sinon": "^10.0.13", - "@types/uglifycss": "^0.0.7", - "@types/yargs": "^17.0.24", + "@types/nunjucks": "^3.2.4", + "@types/sinon": "^10.0.17", + "@types/uglifycss": "^0.0.8", + "@types/yargs": "^17.0.25", "@web/dev-server": "^0.1.38", "@web/dev-server-esbuild": "^0.3.6", "@web/dev-server-import-maps": "^0.0.8", @@ -117,8 +117,8 @@ "sinon": "^15.0.3", "ts-lit-plugin": "^1.2.1", "ts-node": "^10.9.1", - "ts-patch": "3.0.0-beta3", - "typescript": "5.0.4", + "ts-patch": "3.0.2", + "typescript": "5.2.2", "urlpattern-polyfill": "^7.0.0", "web-dev-server-plugin-lit-css": "^2.0.5" },