From 51a82d4019879355bfdb0cd464343b17f18a1a2a Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 7 Nov 2024 16:28:55 -0500 Subject: [PATCH 01/26] feat(disclosure): add `` --- .changeset/nasty-ravens-joke.md | 21 +++++++ docs/_data/repoStatus.ts | 12 ++++ elements/rh-disclosure/README.md | 22 +++++++ .../rh-disclosure/demo/color-context.html | 21 +++++++ .../rh-disclosure/demo/rh-disclosure.html | 18 ++++++ elements/rh-disclosure/docs/00-overview.md | 9 +++ elements/rh-disclosure/docs/10-style.md | 1 + elements/rh-disclosure/docs/20-guidelines.md | 1 + .../rh-disclosure/docs/40-accessibility.md | 1 + elements/rh-disclosure/docs/screenshot.png | Bin 0 -> 6220 bytes .../rh-disclosure/rh-disclosure-lightdom.css | 56 ++++++++++++++++++ elements/rh-disclosure/rh-disclosure.css | 3 + elements/rh-disclosure/rh-disclosure.ts | 25 ++++++++ .../rh-disclosure/test/rh-disclosure.e2e.ts | 25 ++++++++ .../rh-disclosure/test/rh-disclosure.spec.ts | 44 ++++++++++++++ 15 files changed, 259 insertions(+) create mode 100644 .changeset/nasty-ravens-joke.md create mode 100644 elements/rh-disclosure/README.md create mode 100644 elements/rh-disclosure/demo/color-context.html create mode 100644 elements/rh-disclosure/demo/rh-disclosure.html create mode 100644 elements/rh-disclosure/docs/00-overview.md create mode 100644 elements/rh-disclosure/docs/10-style.md create mode 100644 elements/rh-disclosure/docs/20-guidelines.md create mode 100644 elements/rh-disclosure/docs/40-accessibility.md create mode 100644 elements/rh-disclosure/docs/screenshot.png create mode 100644 elements/rh-disclosure/rh-disclosure-lightdom.css create mode 100644 elements/rh-disclosure/rh-disclosure.css create mode 100644 elements/rh-disclosure/rh-disclosure.ts create mode 100644 elements/rh-disclosure/test/rh-disclosure.e2e.ts create mode 100644 elements/rh-disclosure/test/rh-disclosure.spec.ts diff --git a/.changeset/nasty-ravens-joke.md b/.changeset/nasty-ravens-joke.md new file mode 100644 index 0000000000..c8c1dc4d27 --- /dev/null +++ b/.changeset/nasty-ravens-joke.md @@ -0,0 +1,21 @@ +--- +"@rhds/elements": minor +--- + +✨ Added `` + +A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible). + +```html + +
+ + + Collapsed panel title + +
+ Lorem ipsum dolor sit amet consectetur adipisicing, elit. +
+
+
+``` diff --git a/docs/_data/repoStatus.ts b/docs/_data/repoStatus.ts index 3e2813c1dc..358c4ca748 100644 --- a/docs/_data/repoStatus.ts +++ b/docs/_data/repoStatus.ts @@ -199,6 +199,18 @@ export default [ docs: 'ready', }, }, + { + tagName: 'rh-disclosure', + name: 'Disclosure', + type: 'element', + overallStatus: 'ready', + libraries: { + figma: 'ready', + rhds: 'ready', + shared: 'ready', + docs: 'ready', + }, + }, { tagName: 'rh-footer', name: 'Footer', diff --git a/elements/rh-disclosure/README.md b/elements/rh-disclosure/README.md new file mode 100644 index 0000000000..e582925f7a --- /dev/null +++ b/elements/rh-disclosure/README.md @@ -0,0 +1,22 @@ +# Disclosure + +A disclosure is a widget that enables content to be either +collapsed (hidden) or expanded (visible). + +## Usage + +Place the following markup on your page: + +```html + +
+ + + Collapsed panel title + +
+ Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? +
+
+
+``` diff --git a/elements/rh-disclosure/demo/color-context.html b/elements/rh-disclosure/demo/color-context.html new file mode 100644 index 0000000000..ee5d54f39b --- /dev/null +++ b/elements/rh-disclosure/demo/color-context.html @@ -0,0 +1,21 @@ + + +
+ + + Collapsed panel title + +
+ Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? +
+
+
+
+ + + + diff --git a/elements/rh-disclosure/demo/rh-disclosure.html b/elements/rh-disclosure/demo/rh-disclosure.html new file mode 100644 index 0000000000..4bfd596893 --- /dev/null +++ b/elements/rh-disclosure/demo/rh-disclosure.html @@ -0,0 +1,18 @@ + +
+ + + Collapsed panel title + +
+ Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? +
+
+
+ + + + diff --git a/elements/rh-disclosure/docs/00-overview.md b/elements/rh-disclosure/docs/00-overview.md new file mode 100644 index 0000000000..671def32ee --- /dev/null +++ b/elements/rh-disclosure/docs/00-overview.md @@ -0,0 +1,9 @@ +## When to use + +- When you want to have some content you want to expand and collapse +- When putting all of the content on the page might not be relevant to all users +or distract them from the main content on the page + +
+ An expanded disclosure element with a panel trigger and lorem ipsum for details content +
diff --git a/elements/rh-disclosure/docs/10-style.md b/elements/rh-disclosure/docs/10-style.md new file mode 100644 index 0000000000..a687d018ea --- /dev/null +++ b/elements/rh-disclosure/docs/10-style.md @@ -0,0 +1 @@ +## Style diff --git a/elements/rh-disclosure/docs/20-guidelines.md b/elements/rh-disclosure/docs/20-guidelines.md new file mode 100644 index 0000000000..5a11f092d4 --- /dev/null +++ b/elements/rh-disclosure/docs/20-guidelines.md @@ -0,0 +1 @@ +## Guidelines diff --git a/elements/rh-disclosure/docs/40-accessibility.md b/elements/rh-disclosure/docs/40-accessibility.md new file mode 100644 index 0000000000..f6593a1e87 --- /dev/null +++ b/elements/rh-disclosure/docs/40-accessibility.md @@ -0,0 +1 @@ +## Accessibility diff --git a/elements/rh-disclosure/docs/screenshot.png b/elements/rh-disclosure/docs/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..30b2459bab4d1a6d09ad3bb08a6d131ffdc435b6 GIT binary patch literal 6220 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 + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'rh-disclosure': RhDisclosure; + } +} diff --git a/elements/rh-disclosure/test/rh-disclosure.e2e.ts b/elements/rh-disclosure/test/rh-disclosure.e2e.ts new file mode 100644 index 0000000000..78d4d6d1d9 --- /dev/null +++ b/elements/rh-disclosure/test/rh-disclosure.e2e.ts @@ -0,0 +1,25 @@ +import { test } from '@playwright/test'; +import { PfeDemoPage } from '@patternfly/pfe-tools/test/playwright/PfeDemoPage.js'; +import { SSRPage } from '@patternfly/pfe-tools/test/playwright/SSRPage.js'; + +const tagName = 'rh-disclosure'; + +test.describe(tagName, () => { + test('snapshot', async ({ page }) => { + const componentPage = new PfeDemoPage(page, tagName); + await componentPage.navigate(); + await componentPage.snapshot(); + }); + + test('ssr', async ({ browser }) => { + const fixture = new SSRPage({ + tagName, + browser, + demoDir: new URL('../demo/', import.meta.url), + importSpecifiers: [ + `@patternfly/elements/${tagName}/${tagName}.js`, + ], + }); + await fixture.snapshots(); + }); +}); diff --git a/elements/rh-disclosure/test/rh-disclosure.spec.ts b/elements/rh-disclosure/test/rh-disclosure.spec.ts new file mode 100644 index 0000000000..058b6d7b4a --- /dev/null +++ b/elements/rh-disclosure/test/rh-disclosure.spec.ts @@ -0,0 +1,44 @@ +import { expect, html } from '@open-wc/testing'; +import { createFixture } from '@patternfly/pfe-tools/test/create-fixture.js'; +import { RhDisclosure } from '@rhds/elements/rh-disclosure/rh-disclosure.js'; + +describe('', function() { + describe('simply instantiating', function() { + let element: RhDisclosure; + it('imperatively instantiates', function() { + expect(document.createElement('rh-disclosure')).to.be.an.instanceof(RhDisclosure); + }); + + it('should upgrade', async function() { + element = await createFixture(html``); + const klass = customElements.get('rh-disclosure'); + expect(element) + .to.be.an.instanceOf(klass) + .and + .to.be.an.instanceOf(RhDisclosure); + }); + }); + + describe('when the element loads', function() { + let element: RhDisclosure; + beforeEach(async function() { + element = await createFixture(html` + +
+ + Summary title + +
+ Details content goes here. +
+
+
+ `); + await element.updateComplete; + }); + + it('should be accessible', async function() { + await expect(element).to.be.accessible(); + }); + }); +}); From 6f9598cfec33acd347a8d705f1e2d44575331fe9 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 8 Nov 2024 12:33:04 -0500 Subject: [PATCH 02/26] fix(disclosure): make borders show up when used without a context provider --- elements/rh-disclosure/rh-disclosure-lightdom.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css index e21039f968..075538d0bb 100644 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -1,6 +1,6 @@ rh-disclosure { & details { - border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle); + border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle, #c7c7c7); font-family: var(--rh-font-family-body-text); & .details-content { @@ -42,7 +42,7 @@ rh-disclosure { box-shadow: var(--rh-box-shadow-sm, 0 2px 4px 0 rgba(21, 21, 21, 0.2)); & summary { - border-inline-color: var(--rh-color-accent-brand); + border-inline-color: var(--rh-color-brand-red-on-light, #ee0000); & rh-icon[icon='caret-down'] { transform: rotate(-180deg); @@ -50,7 +50,7 @@ rh-disclosure { } & .details-content { - border-inline-color: var(--rh-color-accent-brand); + border-inline-color: var(--rh-color-brand-red-on-light, #ee0000); } } } From 0271e0fd915d01aae0a8dcd68cf1da646205f71b Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 8 Nov 2024 13:56:22 -0500 Subject: [PATCH 03/26] fix(disclosure): avoid 1px outer + inner border overlap inconsistencies --- .../rh-disclosure/rh-disclosure-lightdom.css | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css index 075538d0bb..538beda423 100644 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -4,7 +4,6 @@ rh-disclosure { font-family: var(--rh-font-family-body-text); & .details-content { - border-inline-start: var(--rh-border-width-lg, 3px) solid transparent; font-size: var(--rh-font-size-body-text-md, 1rem); line-height: var(--rh-line-height-body-text, 1.5); padding: var(--rh-space-xl, 24px); @@ -18,7 +17,6 @@ rh-disclosure { & summary { align-items: center; - border-inline-start: var(--rh-border-width-lg, 3px) solid transparent; cursor: pointer; display: flex; font-size: var(--rh-font-size-body-text-md, 1rem); @@ -40,17 +38,21 @@ rh-disclosure { details[open] { box-shadow: var(--rh-box-shadow-sm, 0 2px 4px 0 rgba(21, 21, 21, 0.2)); + position: relative; + + &:before { + content: ''; + border-inline-start: 3px solid var(--rh-color-brand-red-on-light, #ee0000); + position: absolute; + z-index: 1; + inset-inline-start: -1px; + inset-block: -1px; + } & summary { - border-inline-color: var(--rh-color-brand-red-on-light, #ee0000); - & rh-icon[icon='caret-down'] { transform: rotate(-180deg); } } - - & .details-content { - border-inline-color: var(--rh-color-brand-red-on-light, #ee0000); - } } } From 501ebccf8d7d4ab1e6907262e59458a80eebd5c5 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 8 Nov 2024 14:05:00 -0500 Subject: [PATCH 04/26] fix(disclosure): export RhDisclosure class, fix tests --- elements/rh-disclosure/rh-disclosure.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index cf2d632bcc..650fb38c1a 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -8,7 +8,7 @@ import styles from './rh-disclosure.css'; * @slot - Place the details, summary, and `.details-content` div here. */ @customElement('rh-disclosure') -class RhDisclosure extends LitElement { +export class RhDisclosure extends LitElement { static readonly styles = [styles]; render() { From 6e021d23acd7b748553c824e7b6307faed11a0db Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Fri, 8 Nov 2024 14:27:28 -0500 Subject: [PATCH 05/26] feat(disclosure): enable ESC to close --- .../rh-disclosure/demo/rh-disclosure.html | 2 +- elements/rh-disclosure/rh-disclosure.ts | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/elements/rh-disclosure/demo/rh-disclosure.html b/elements/rh-disclosure/demo/rh-disclosure.html index 4bfd596893..41f6dd37e8 100644 --- a/elements/rh-disclosure/demo/rh-disclosure.html +++ b/elements/rh-disclosure/demo/rh-disclosure.html @@ -5,7 +5,7 @@ Collapsed panel title
- Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? + Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?
diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 650fb38c1a..84d77b89f2 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -5,17 +5,41 @@ import styles from './rh-disclosure.css'; /** * @summary A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible). - * @slot - Place the details, summary, and `.details-content` div here. + * @slot - Place the `details`, `summary`, and `.details-content` elements in the default slot. */ @customElement('rh-disclosure') export class RhDisclosure extends LitElement { static readonly styles = [styles]; + #details!: HTMLDetailsElement; + #summary!: HTMLElement; + + connectedCallback() { + super.connectedCallback(); + this.#details = this.querySelector('details')!; + this.#summary = this.querySelector('details summary')!; + this.#details.addEventListener('keydown', this.#closeDetails.bind(this)); + } + + disconnectedCallback() { + this.#details.removeEventListener('keydown', this.#closeDetails.bind(this)); + } + render() { return html` `; } + + #closeDetails(event: KeyboardEvent): void { + if (this.#details.open === false) { + return; + } + if (event.code === 'Escape') { + this.#details.open = false; + this.#summary.focus(); + } + } } declare global { From a6cfa99bf613608e0245fdf6b0798b0e320afee2 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 11 Nov 2024 14:22:22 -0500 Subject: [PATCH 06/26] test(disclosure): ignore fallback value error --- elements/rh-disclosure/rh-disclosure-lightdom.css | 1 + 1 file changed, 1 insertion(+) diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css index 538beda423..464e49f039 100644 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -1,5 +1,6 @@ rh-disclosure { & details { + /* stylelint-disable-next-line rhds/token-values */ border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle, #c7c7c7); font-family: var(--rh-font-family-body-text); From bfea41e6ac50a152a5172227056b944e28428d84 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 11 Nov 2024 14:36:12 -0500 Subject: [PATCH 07/26] test(disclosure): fix `removeEventListener` error --- elements/rh-disclosure/rh-disclosure.ts | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 84d77b89f2..303f9b7207 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -11,18 +11,20 @@ import styles from './rh-disclosure.css'; export class RhDisclosure extends LitElement { static readonly styles = [styles]; - #details!: HTMLDetailsElement; - #summary!: HTMLElement; + #details?: HTMLDetailsElement; + #summary?: HTMLElement; - connectedCallback() { - super.connectedCallback(); + firstUpdated() { this.#details = this.querySelector('details')!; this.#summary = this.querySelector('details summary')!; - this.#details.addEventListener('keydown', this.#closeDetails.bind(this)); + this.#details?.addEventListener('keydown', this.#closeDetails.bind(this)); } disconnectedCallback() { - this.#details.removeEventListener('keydown', this.#closeDetails.bind(this)); + if (this.#details) { + this.#details.removeEventListener('keydown', this.#closeDetails.bind(this)); + } + super.disconnectedCallback(); } render() { @@ -32,12 +34,14 @@ export class RhDisclosure extends LitElement { } #closeDetails(event: KeyboardEvent): void { - if (this.#details.open === false) { + if (this.#details?.open === false) { return; } if (event.code === 'Escape') { - this.#details.open = false; - this.#summary.focus(); + if (this.#details) { + this.#details.open = false; + } + this.#summary?.focus(); } } } From 9d6b727810d522326a1878901e725983029298f3 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 13 Nov 2024 15:35:02 -0500 Subject: [PATCH 08/26] fix(disclosure): escape closes currently focused disclosure --- .../demo/nested-disclosures.html | 44 +++++++++++++++++++ elements/rh-disclosure/rh-disclosure.ts | 21 +++++---- 2 files changed, 56 insertions(+), 9 deletions(-) create mode 100644 elements/rh-disclosure/demo/nested-disclosures.html diff --git a/elements/rh-disclosure/demo/nested-disclosures.html b/elements/rh-disclosure/demo/nested-disclosures.html new file mode 100644 index 0000000000..ec28e5065b --- /dev/null +++ b/elements/rh-disclosure/demo/nested-disclosures.html @@ -0,0 +1,44 @@ + +
+ + + This is the top level disclosure + +
+

Be sure to test the ESC key + focus when nesting disclosures together. Lorem ipsum dolor fake link adipisicing, elit.

+ + +
+ + + Be sure to open this disclosure + +
+

You can hit escape to test focus and see which details element closes!

+ + +
+ + + Third nested disclosure + +
+

This is nesting! fake link 2 and more text.

+
+
+
+ +
+
+
+ +
+
+
+ + + + diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 303f9b7207..b57933b715 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -7,6 +7,7 @@ import styles from './rh-disclosure.css'; * @summary A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible). * @slot - Place the `details`, `summary`, and `.details-content` elements in the default slot. */ + @customElement('rh-disclosure') export class RhDisclosure extends LitElement { static readonly styles = [styles]; @@ -17,12 +18,12 @@ export class RhDisclosure extends LitElement { firstUpdated() { this.#details = this.querySelector('details')!; this.#summary = this.querySelector('details summary')!; - this.#details?.addEventListener('keydown', this.#closeDetails.bind(this)); + this.#details?.addEventListener('keydown', this.#handleKeyDown.bind(this)); } disconnectedCallback() { if (this.#details) { - this.#details.removeEventListener('keydown', this.#closeDetails.bind(this)); + this.#details.removeEventListener('keydown', this.#handleKeyDown.bind(this)); } super.disconnectedCallback(); } @@ -33,14 +34,16 @@ export class RhDisclosure extends LitElement { `; } - #closeDetails(event: KeyboardEvent): void { - if (this.#details?.open === false) { - return; - } + #handleKeyDown(event: KeyboardEvent): void { if (event.code === 'Escape') { - if (this.#details) { - this.#details.open = false; - } + event.stopPropagation(); + this.#closeDetails(); + } + } + + #closeDetails(): void { + if (this.#details?.open) { + this.#details.open = false; this.#summary?.focus(); } } From de409dee12b5488402cbf647f499ffb938776bcb Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 13 Nov 2024 15:36:07 -0500 Subject: [PATCH 09/26] feat(disclosure): add `!isServer` check for SSR --- elements/rh-disclosure/rh-disclosure.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index b57933b715..251942da95 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -1,4 +1,4 @@ -import { LitElement, html } from 'lit'; +import { LitElement, html, isServer } from 'lit'; import { customElement } from 'lit/decorators/custom-element.js'; import styles from './rh-disclosure.css'; @@ -18,11 +18,13 @@ export class RhDisclosure extends LitElement { firstUpdated() { this.#details = this.querySelector('details')!; this.#summary = this.querySelector('details summary')!; - this.#details?.addEventListener('keydown', this.#handleKeyDown.bind(this)); + if (!isServer) { + this.#details?.addEventListener('keydown', this.#handleKeyDown.bind(this)); + } } disconnectedCallback() { - if (this.#details) { + if (!isServer && this.#details) { this.#details.removeEventListener('keydown', this.#handleKeyDown.bind(this)); } super.disconnectedCallback(); From 5c8d706ba34f1aa9de1725fc633bf247ff180987 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 13 Nov 2024 16:12:08 -0500 Subject: [PATCH 10/26] fix(disclosure): proper nested rh-icon caret rotation on open/close --- elements/rh-disclosure/rh-disclosure-lightdom.css | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css index 464e49f039..7670fef0e3 100644 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -27,6 +27,8 @@ rh-disclosure { padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); & rh-icon[icon='caret-down'] { + inline-size: var(--rh-space-lg, 16px); + block-size: var(--rh-space-lg, 16px); transition: 0.2s; will-change: rotate; } @@ -50,10 +52,8 @@ rh-disclosure { inset-block: -1px; } - & summary { - & rh-icon[icon='caret-down'] { - transform: rotate(-180deg); - } + & > summary rh-icon[icon='caret-down'] { + transform: rotate(-180deg); } } } From f791d693e6a3baf0ab3c1bbc2ba82943cd3b6205 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 18 Nov 2024 13:52:52 -0500 Subject: [PATCH 11/26] fix(disclosure): correct gap spacing on `` --- elements/rh-disclosure/rh-disclosure-lightdom.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css index 7670fef0e3..73b8ab00dd 100644 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -22,7 +22,7 @@ rh-disclosure { display: flex; font-size: var(--rh-font-size-body-text-md, 1rem); font-weight: var(--rh-font-weight-body-text-medium, 500); - gap: var(--rh-length-sm, 6px); + gap: var(--rh-space-md, 8px); list-style: none; padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); From 4b53e2e5a5947e21017d55bad4fb774f25e06c68 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 18 Nov 2024 15:39:15 -0500 Subject: [PATCH 12/26] refactor(disclosure): move `details`/`summary` to shadowdom --- .changeset/nasty-ravens-joke.md | 13 ++-- elements/rh-disclosure/README.md | 13 ++-- .../rh-disclosure/demo/color-context.html | 16 ++--- .../demo/nested-disclosures.html | 54 +++++----------- .../rh-disclosure/demo/rh-disclosure.html | 16 ++--- .../rh-disclosure/rh-disclosure-lightdom.css | 59 ----------------- elements/rh-disclosure/rh-disclosure.css | 64 +++++++++++++++++++ elements/rh-disclosure/rh-disclosure.ts | 51 +++++++-------- .../rh-disclosure/test/rh-disclosure.spec.ts | 12 ++-- 9 files changed, 123 insertions(+), 175 deletions(-) delete mode 100644 elements/rh-disclosure/rh-disclosure-lightdom.css diff --git a/.changeset/nasty-ravens-joke.md b/.changeset/nasty-ravens-joke.md index c8c1dc4d27..c93101efba 100644 --- a/.changeset/nasty-ravens-joke.md +++ b/.changeset/nasty-ravens-joke.md @@ -8,14 +8,9 @@ A disclosure is a widget that enables content to be either collapsed (hidden) or ```html -
- - - Collapsed panel title - -
- Lorem ipsum dolor sit amet consectetur adipisicing, elit. -
-
+ + Collapsed panel title + +

Lorem ipsum dolor sit amet consectetur adipisicing, elit.

``` diff --git a/elements/rh-disclosure/README.md b/elements/rh-disclosure/README.md index e582925f7a..b5da93576e 100644 --- a/elements/rh-disclosure/README.md +++ b/elements/rh-disclosure/README.md @@ -9,14 +9,9 @@ Place the following markup on your page: ```html -
- - - Collapsed panel title - -
- Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? -
-
+ + Collapsed panel title + +

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.

``` diff --git a/elements/rh-disclosure/demo/color-context.html b/elements/rh-disclosure/demo/color-context.html index ee5d54f39b..8e59025b3d 100644 --- a/elements/rh-disclosure/demo/color-context.html +++ b/elements/rh-disclosure/demo/color-context.html @@ -1,21 +1,13 @@ -
- - - Collapsed panel title - -
- Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? -
-
+ + Collapsed panel title + +

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.

- - diff --git a/elements/rh-disclosure/demo/nested-disclosures.html b/elements/rh-disclosure/demo/nested-disclosures.html index ec28e5065b..b096565805 100644 --- a/elements/rh-disclosure/demo/nested-disclosures.html +++ b/elements/rh-disclosure/demo/nested-disclosures.html @@ -1,44 +1,22 @@ -
- - - This is the top level disclosure - -
-

Be sure to test the ESC key + focus when nesting disclosures together. Lorem ipsum dolor fake link adipisicing, elit.

- - -
- - - Be sure to open this disclosure - -
-

You can hit escape to test focus and see which details element closes!

- - -
- - - Third nested disclosure - -
-

This is nesting! fake link 2 and more text.

-
-
-
- -
-
-
- -
-
+ + This is the top level disclosure + +

Be sure to test the ESC key + focus when nesting disclosures together. Lorem ipsum dolor fake link adipisicing.

+ + + This is the second level disclosure + +

You can hit escape to test focus and see which details element closes!

+ + + Third nested disclosure + +

This is nesting! fake link 2 and more text.

+
+
- - diff --git a/elements/rh-disclosure/demo/rh-disclosure.html b/elements/rh-disclosure/demo/rh-disclosure.html index 41f6dd37e8..e8f5ac35e4 100644 --- a/elements/rh-disclosure/demo/rh-disclosure.html +++ b/elements/rh-disclosure/demo/rh-disclosure.html @@ -1,18 +1,10 @@ -
- - - Collapsed panel title - -
- Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum? -
-
+ + Collapsed panel title + +

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?

- - diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css deleted file mode 100644 index 73b8ab00dd..0000000000 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ /dev/null @@ -1,59 +0,0 @@ -rh-disclosure { - & details { - /* stylelint-disable-next-line rhds/token-values */ - border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle, #c7c7c7); - font-family: var(--rh-font-family-body-text); - - & .details-content { - font-size: var(--rh-font-size-body-text-md, 1rem); - line-height: var(--rh-line-height-body-text, 1.5); - padding: var(--rh-space-xl, 24px); - padding-block-start: var(--rh-space-lg, 16px); - - & :is(p, h2, h3, h4, h5, h6):first-of-type { - margin-block-start: 0; - } - } - } - - & summary { - align-items: center; - cursor: pointer; - display: flex; - font-size: var(--rh-font-size-body-text-md, 1rem); - font-weight: var(--rh-font-weight-body-text-medium, 500); - gap: var(--rh-space-md, 8px); - list-style: none; - padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); - - & rh-icon[icon='caret-down'] { - inline-size: var(--rh-space-lg, 16px); - block-size: var(--rh-space-lg, 16px); - transition: 0.2s; - will-change: rotate; - } - - &::-webkit-details-marker, - &::marker { - display: none; - } - } - - details[open] { - box-shadow: var(--rh-box-shadow-sm, 0 2px 4px 0 rgba(21, 21, 21, 0.2)); - position: relative; - - &:before { - content: ''; - border-inline-start: 3px solid var(--rh-color-brand-red-on-light, #ee0000); - position: absolute; - z-index: 1; - inset-inline-start: -1px; - inset-block: -1px; - } - - & > summary rh-icon[icon='caret-down'] { - transform: rotate(-180deg); - } - } -} diff --git a/elements/rh-disclosure/rh-disclosure.css b/elements/rh-disclosure/rh-disclosure.css index 5d4e87f30f..cea177f469 100644 --- a/elements/rh-disclosure/rh-disclosure.css +++ b/elements/rh-disclosure/rh-disclosure.css @@ -1,3 +1,67 @@ :host { display: block; } + +details { + /* stylelint-disable-next-line rhds/token-values */ + border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle, #c7c7c7); + font-family: var(--rh-font-family-body-text); +} + +summary { + align-items: center; + cursor: pointer; + display: flex; + font-size: var(--rh-font-size-body-text-md, 1rem); + font-weight: var(--rh-font-weight-body-text-medium, 500); + gap: var(--rh-space-md, 8px); + list-style: none; + padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); + + &::-webkit-details-marker, + &::marker { + display: none; + } + + & ::slotted([slot='summary-label']) { + font-family: var(--rh-font-family-body-text); + font-size: var(--rh-font-size-body-text-md, 1rem) !important; + font-weight: var(--rh-font-weight-body-text-medium, 500); + } +} + +#caret { + inline-size: var(--rh-space-lg, 16px); + block-size: var(--rh-space-lg, 16px); + transition: 0.2s; + will-change: rotate; +} + +#details-content { + font-size: var(--rh-font-size-body-text-md, 1rem); + line-height: var(--rh-line-height-body-text, 1.5); + padding: var(--rh-space-xl, 24px); + padding-block-start: var(--rh-space-lg, 16px); +} + +::slotted(:is(p, h1, h2, h3, h4, h5, h6):first-of-type) { + margin-block-start: 0; +} + +details[open] { + box-shadow: var(--rh-box-shadow-sm, 0 2px 4px 0 rgba(21, 21, 21, 0.2)); + position: relative; + + &:before { + content: ''; + border-inline-start: 3px solid var(--rh-color-brand-red-on-light, #ee0000); + position: absolute; + z-index: 1; + inset-inline-start: -1px; + inset-block: -1px; + } + + #caret { + transform: rotate(-180deg); + } +} diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 251942da95..4518357aa1 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -1,52 +1,47 @@ import { LitElement, html, isServer } from 'lit'; import { customElement } from 'lit/decorators/custom-element.js'; +import { query } from 'lit/decorators/query.js'; + +import '@rhds/elements/rh-icon/rh-icon.js'; import styles from './rh-disclosure.css'; /** * @summary A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible). - * @slot - Place the `details`, `summary`, and `.details-content` elements in the default slot. + * @slot - Place the content you want to disclose in the default slot. This content is hidden by default. + * @slot summary-label - The title of the disclosure + * @csspart caret - The caret icon in the shadow DOM */ @customElement('rh-disclosure') export class RhDisclosure extends LitElement { static readonly styles = [styles]; - #details?: HTMLDetailsElement; - #summary?: HTMLElement; - - firstUpdated() { - this.#details = this.querySelector('details')!; - this.#summary = this.querySelector('details summary')!; - if (!isServer) { - this.#details?.addEventListener('keydown', this.#handleKeyDown.bind(this)); - } - } - - disconnectedCallback() { - if (!isServer && this.#details) { - this.#details.removeEventListener('keydown', this.#handleKeyDown.bind(this)); - } - super.disconnectedCallback(); - } + @query('details') private detailsEl!: HTMLDetailsElement; + @query('summary') private summaryEl!: HTMLElement; render() { return html` - +
+ + + Panel Title + +
+ +
+
`; } - #handleKeyDown(event: KeyboardEvent): void { + #closeDetails(event: KeyboardEvent): void { + if (!this.detailsEl.hasAttribute('open')) { + return; + } if (event.code === 'Escape') { event.stopPropagation(); - this.#closeDetails(); - } - } - - #closeDetails(): void { - if (this.#details?.open) { - this.#details.open = false; - this.#summary?.focus(); + this.detailsEl.removeAttribute('open'); + this.summaryEl.focus(); } } } diff --git a/elements/rh-disclosure/test/rh-disclosure.spec.ts b/elements/rh-disclosure/test/rh-disclosure.spec.ts index 058b6d7b4a..0f406ca0a0 100644 --- a/elements/rh-disclosure/test/rh-disclosure.spec.ts +++ b/elements/rh-disclosure/test/rh-disclosure.spec.ts @@ -24,14 +24,10 @@ describe('', function() { beforeEach(async function() { element = await createFixture(html` -
- - Summary title - -
- Details content goes here. -
-
+ + Summary title + +

Details content goes here.

`); await element.updateComplete; From e5c35c84addeb3a0365a30ec7fd39ca055c3a98d Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 18 Nov 2024 15:39:34 -0500 Subject: [PATCH 13/26] feat(disclosure): add lightdom shim + example demo --- elements/rh-disclosure/demo/no-fouc.html | 25 +++++++++++++++++++ .../rh-disclosure-lightdom-shim.css | 8 ++++++ 2 files changed, 33 insertions(+) create mode 100644 elements/rh-disclosure/demo/no-fouc.html create mode 100644 elements/rh-disclosure/rh-disclosure-lightdom-shim.css diff --git a/elements/rh-disclosure/demo/no-fouc.html b/elements/rh-disclosure/demo/no-fouc.html new file mode 100644 index 0000000000..9c254539fb --- /dev/null +++ b/elements/rh-disclosure/demo/no-fouc.html @@ -0,0 +1,25 @@ + + + No flash of unstyled content + +

This demo includes a lightdom shim CSS file that hides all content that's not in a slot until this component's JavaScript loads.

+
    +
  • Pros: +
      +
    • No flash of unstyled content during page load
    • +
    • Less/no cumulative layout shift
    • +
    +
  • +
  • Cons: +
      +
    • If, for whatever reason, JavaScript fails to load, all content in the default slot will be hidden to end users.
    • +
    +
  • +
+
+ + + + diff --git a/elements/rh-disclosure/rh-disclosure-lightdom-shim.css b/elements/rh-disclosure/rh-disclosure-lightdom-shim.css new file mode 100644 index 0000000000..a2b92b5265 --- /dev/null +++ b/elements/rh-disclosure/rh-disclosure-lightdom-shim.css @@ -0,0 +1,8 @@ +/** + * WARNING: Using this stylesheet acknoledges this component requires JavaScript + * If you are OK with a FOUC, you do not need to link this file in your app + * 👇 Hides all content in the default slot +*/ +rh-disclosure:not(:defined) *:not([slot]) { + display: none; +} From f87b4803fcb551385c18afb47baefa56815e3245 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 19 Nov 2024 16:16:27 -0500 Subject: [PATCH 14/26] fix(disclosure): improve FOUC / CLS --- .../rh-disclosure/demo/color-context.html | 2 ++ .../demo/nested-disclosures.html | 2 ++ elements/rh-disclosure/demo/no-fouc.html | 1 + .../rh-disclosure/demo/rh-disclosure.html | 2 ++ .../rh-disclosure/rh-disclosure-lightdom.css | 14 +++++++++++ elements/rh-disclosure/rh-disclosure.css | 23 +++++++++++-------- 6 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 elements/rh-disclosure/rh-disclosure-lightdom.css diff --git a/elements/rh-disclosure/demo/color-context.html b/elements/rh-disclosure/demo/color-context.html index 8e59025b3d..7a4147db22 100644 --- a/elements/rh-disclosure/demo/color-context.html +++ b/elements/rh-disclosure/demo/color-context.html @@ -7,6 +7,8 @@
+ + diff --git a/elements/rh-disclosure/demo/no-fouc.html b/elements/rh-disclosure/demo/no-fouc.html index 9c254539fb..c36afb7289 100644 --- a/elements/rh-disclosure/demo/no-fouc.html +++ b/elements/rh-disclosure/demo/no-fouc.html @@ -18,6 +18,7 @@ + diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css new file mode 100644 index 0000000000..111f9cbcd3 --- /dev/null +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -0,0 +1,14 @@ +rh-disclosure { + /* stylelint-disable-next-line rhds/token-values */ + border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle, #c7c7c7); + display: block; + font-family: var(--rh-font-family-body-text); + padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); +} + +rh-disclosure > [slot='summary-label'] { + display: block; + font-size: var(--rh-font-size-body-text-md, 1rem); + font-weight: var(--rh-font-weight-body-text-medium, 500); + font-family: var(--rh-font-family-body-text); +} diff --git a/elements/rh-disclosure/rh-disclosure.css b/elements/rh-disclosure/rh-disclosure.css index cea177f469..5b6f6f22f0 100644 --- a/elements/rh-disclosure/rh-disclosure.css +++ b/elements/rh-disclosure/rh-disclosure.css @@ -2,12 +2,6 @@ display: block; } -details { - /* stylelint-disable-next-line rhds/token-values */ - border: var(--rh-border-width-sm, 1px) solid var(--rh-color-border-subtle, #c7c7c7); - font-family: var(--rh-font-family-body-text); -} - summary { align-items: center; cursor: pointer; @@ -16,13 +10,20 @@ summary { font-weight: var(--rh-font-weight-body-text-medium, 500); gap: var(--rh-space-md, 8px); list-style: none; - padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); + position: relative; &::-webkit-details-marker, &::marker { display: none; } + &:before { + content: ''; + inset-block: -16px; + inset-inline: -24px; + position: absolute; + } + & ::slotted([slot='summary-label']) { font-family: var(--rh-font-family-body-text); font-size: var(--rh-font-size-body-text-md, 1rem) !important; @@ -40,15 +41,15 @@ summary { #details-content { font-size: var(--rh-font-size-body-text-md, 1rem); line-height: var(--rh-line-height-body-text, 1.5); - padding: var(--rh-space-xl, 24px); - padding-block-start: var(--rh-space-lg, 16px); + padding-block: var(--rh-space-xl, 24px); + padding-block-end: var(--rh-space-md, 8px); } ::slotted(:is(p, h1, h2, h3, h4, h5, h6):first-of-type) { margin-block-start: 0; } -details[open] { +:host:has(details[open]) { box-shadow: var(--rh-box-shadow-sm, 0 2px 4px 0 rgba(21, 21, 21, 0.2)); position: relative; @@ -60,7 +61,9 @@ details[open] { inset-inline-start: -1px; inset-block: -1px; } +} +details[open] { #caret { transform: rotate(-180deg); } From 35e7146660e150d3da8e67baaaa4fffeddcb2704 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 19 Nov 2024 16:20:56 -0500 Subject: [PATCH 15/26] refactor(disclosure): `summary-label` slot becomes `summary` --- .changeset/nasty-ravens-joke.md | 2 +- elements/rh-disclosure/README.md | 2 +- elements/rh-disclosure/demo/color-context.html | 2 +- elements/rh-disclosure/demo/nested-disclosures.html | 6 +++--- elements/rh-disclosure/demo/no-fouc.html | 2 +- elements/rh-disclosure/demo/rh-disclosure.html | 2 +- elements/rh-disclosure/rh-disclosure-lightdom.css | 2 +- elements/rh-disclosure/rh-disclosure.css | 2 +- elements/rh-disclosure/rh-disclosure.ts | 4 ++-- elements/rh-disclosure/test/rh-disclosure.spec.ts | 2 +- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.changeset/nasty-ravens-joke.md b/.changeset/nasty-ravens-joke.md index c93101efba..9cf3df79c7 100644 --- a/.changeset/nasty-ravens-joke.md +++ b/.changeset/nasty-ravens-joke.md @@ -8,7 +8,7 @@ A disclosure is a widget that enables content to be either collapsed (hidden) or ```html - + Collapsed panel title

Lorem ipsum dolor sit amet consectetur adipisicing, elit.

diff --git a/elements/rh-disclosure/README.md b/elements/rh-disclosure/README.md index b5da93576e..6f6ce47944 100644 --- a/elements/rh-disclosure/README.md +++ b/elements/rh-disclosure/README.md @@ -9,7 +9,7 @@ Place the following markup on your page: ```html - + Collapsed panel title

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.

diff --git a/elements/rh-disclosure/demo/color-context.html b/elements/rh-disclosure/demo/color-context.html index 7a4147db22..d4e2eaa32b 100644 --- a/elements/rh-disclosure/demo/color-context.html +++ b/elements/rh-disclosure/demo/color-context.html @@ -1,6 +1,6 @@ - + Collapsed panel title

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.

diff --git a/elements/rh-disclosure/demo/nested-disclosures.html b/elements/rh-disclosure/demo/nested-disclosures.html index 669604d853..c99ba96853 100644 --- a/elements/rh-disclosure/demo/nested-disclosures.html +++ b/elements/rh-disclosure/demo/nested-disclosures.html @@ -1,15 +1,15 @@ - + This is the top level disclosure

Be sure to test the ESC key + focus when nesting disclosures together. Lorem ipsum dolor fake link adipisicing.

- + This is the second level disclosure

You can hit escape to test focus and see which details element closes!

- + Third nested disclosure

This is nesting! fake link 2 and more text.

diff --git a/elements/rh-disclosure/demo/no-fouc.html b/elements/rh-disclosure/demo/no-fouc.html index c36afb7289..332cc1d936 100644 --- a/elements/rh-disclosure/demo/no-fouc.html +++ b/elements/rh-disclosure/demo/no-fouc.html @@ -1,5 +1,5 @@ - + No flash of unstyled content

This demo includes a lightdom shim CSS file that hides all content that's not in a slot until this component's JavaScript loads.

diff --git a/elements/rh-disclosure/demo/rh-disclosure.html b/elements/rh-disclosure/demo/rh-disclosure.html index bb7a8f046c..507fa0d671 100644 --- a/elements/rh-disclosure/demo/rh-disclosure.html +++ b/elements/rh-disclosure/demo/rh-disclosure.html @@ -1,5 +1,5 @@ - + Collapsed panel title

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?

diff --git a/elements/rh-disclosure/rh-disclosure-lightdom.css b/elements/rh-disclosure/rh-disclosure-lightdom.css index 111f9cbcd3..54d2cf5753 100644 --- a/elements/rh-disclosure/rh-disclosure-lightdom.css +++ b/elements/rh-disclosure/rh-disclosure-lightdom.css @@ -6,7 +6,7 @@ rh-disclosure { padding: var(--rh-space-lg, 16px) var(--rh-space-xl, 24px); } -rh-disclosure > [slot='summary-label'] { +rh-disclosure > [slot='summary'] { display: block; font-size: var(--rh-font-size-body-text-md, 1rem); font-weight: var(--rh-font-weight-body-text-medium, 500); diff --git a/elements/rh-disclosure/rh-disclosure.css b/elements/rh-disclosure/rh-disclosure.css index 5b6f6f22f0..ce00b9235c 100644 --- a/elements/rh-disclosure/rh-disclosure.css +++ b/elements/rh-disclosure/rh-disclosure.css @@ -24,7 +24,7 @@ summary { position: absolute; } - & ::slotted([slot='summary-label']) { + & ::slotted([slot='summary']) { font-family: var(--rh-font-family-body-text); font-size: var(--rh-font-size-body-text-md, 1rem) !important; font-weight: var(--rh-font-weight-body-text-medium, 500); diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 4518357aa1..587b95a835 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -9,7 +9,7 @@ import styles from './rh-disclosure.css'; /** * @summary A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible). * @slot - Place the content you want to disclose in the default slot. This content is hidden by default. - * @slot summary-label - The title of the disclosure + * @slot summary - The title of the disclosure * @csspart caret - The caret icon in the shadow DOM */ @@ -25,7 +25,7 @@ export class RhDisclosure extends LitElement {
- Panel Title + Panel Title
diff --git a/elements/rh-disclosure/test/rh-disclosure.spec.ts b/elements/rh-disclosure/test/rh-disclosure.spec.ts index 0f406ca0a0..30db395447 100644 --- a/elements/rh-disclosure/test/rh-disclosure.spec.ts +++ b/elements/rh-disclosure/test/rh-disclosure.spec.ts @@ -24,7 +24,7 @@ describe('', function() { beforeEach(async function() { element = await createFixture(html` - + Summary title

Details content goes here.

From 0f58da857249c616dd6d310f93eb3057135723d2 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 19 Nov 2024 16:23:12 -0500 Subject: [PATCH 16/26] fix(disclosure): remove default content for `summary` slot --- elements/rh-disclosure/rh-disclosure.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 587b95a835..d51a2fa48c 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -25,7 +25,7 @@ export class RhDisclosure extends LitElement {
- Panel Title +
From b850ac50e8e539ea8c192a21ee86ceb5217bf31e Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 19 Nov 2024 16:36:56 -0500 Subject: [PATCH 17/26] fix(disclosure): expand `summary` focus outline --- elements/rh-disclosure/rh-disclosure.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/elements/rh-disclosure/rh-disclosure.css b/elements/rh-disclosure/rh-disclosure.css index ce00b9235c..59459b841c 100644 --- a/elements/rh-disclosure/rh-disclosure.css +++ b/elements/rh-disclosure/rh-disclosure.css @@ -24,6 +24,10 @@ summary { position: absolute; } + &:focus { + outline-offset: var(--rh-space-lg, 16px); + } + & ::slotted([slot='summary']) { font-family: var(--rh-font-family-body-text); font-size: var(--rh-font-size-body-text-md, 1rem) !important; From f196568c0ec2a7350f75af44ac9aef8e68d8d648 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 19 Nov 2024 17:18:00 -0500 Subject: [PATCH 18/26] fix(disclosure): let `render` handle elements/state --- elements/rh-disclosure/rh-disclosure.ts | 32 ++++++++++++++++++------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index d51a2fa48c..2693b8090b 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -1,5 +1,6 @@ -import { LitElement, html, isServer } from 'lit'; +import { LitElement, html } from 'lit'; import { customElement } from 'lit/decorators/custom-element.js'; +import { property } from 'lit/decorators/property.js'; import { query } from 'lit/decorators/query.js'; import '@rhds/elements/rh-icon/rh-icon.js'; @@ -12,17 +13,24 @@ import styles from './rh-disclosure.css'; * @slot summary - The title of the disclosure * @csspart caret - The caret icon in the shadow DOM */ - @customElement('rh-disclosure') export class RhDisclosure extends LitElement { static readonly styles = [styles]; + /** + * Sets the disclosure to be in its open state + */ + @property({ type: Boolean, reflect: true }) open = false; + @query('details') private detailsEl!: HTMLDetailsElement; @query('summary') private summaryEl!: HTMLElement; render() { return html` -
+
@@ -34,16 +42,22 @@ export class RhDisclosure extends LitElement { `; } - #closeDetails(event: KeyboardEvent): void { - if (!this.detailsEl.hasAttribute('open')) { - return; - } + #onToggle(): void { + this.open = this.detailsEl.open; + } + + #onKeydown(event: KeyboardEvent): void { if (event.code === 'Escape') { event.stopPropagation(); - this.detailsEl.removeAttribute('open'); - this.summaryEl.focus(); + this.#closeDetails(); } } + + #closeDetails(): void { + this.detailsEl.open = false; + this.open = false; + this.summaryEl.focus(); + } } declare global { From 452925e73bc0cc789b4a60e1c942a32643269eba Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 20 Nov 2024 11:55:31 -0500 Subject: [PATCH 19/26] feat(disclosure): add `summary` prop, convert demos to use it --- .../rh-disclosure/demo/color-context.html | 5 +--- .../demo/nested-disclosures.html | 15 +++-------- elements/rh-disclosure/demo/no-fouc.html | 5 +--- .../rh-disclosure/demo/rh-disclosure.html | 5 +--- .../rh-disclosure/demo/slotted-summary.html | 26 +++++++++++++++++++ elements/rh-disclosure/rh-disclosure.ts | 7 ++++- 6 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 elements/rh-disclosure/demo/slotted-summary.html diff --git a/elements/rh-disclosure/demo/color-context.html b/elements/rh-disclosure/demo/color-context.html index d4e2eaa32b..ebc0a9ed75 100644 --- a/elements/rh-disclosure/demo/color-context.html +++ b/elements/rh-disclosure/demo/color-context.html @@ -1,8 +1,5 @@ - - - Collapsed panel title - +

Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.

diff --git a/elements/rh-disclosure/demo/nested-disclosures.html b/elements/rh-disclosure/demo/nested-disclosures.html index c99ba96853..a57ea16349 100644 --- a/elements/rh-disclosure/demo/nested-disclosures.html +++ b/elements/rh-disclosure/demo/nested-disclosures.html @@ -1,17 +1,8 @@ - - - This is the top level disclosure - +

Be sure to test the ESC key + focus when nesting disclosures together. Lorem ipsum dolor fake link adipisicing.

- - - This is the second level disclosure - +

You can hit escape to test focus and see which details element closes!

- - - Third nested disclosure - +

This is nesting! fake link 2 and more text.

diff --git a/elements/rh-disclosure/demo/no-fouc.html b/elements/rh-disclosure/demo/no-fouc.html index 332cc1d936..513a403854 100644 --- a/elements/rh-disclosure/demo/no-fouc.html +++ b/elements/rh-disclosure/demo/no-fouc.html @@ -1,7 +1,4 @@ - - - No flash of unstyled content - +

This demo includes a lightdom shim CSS file that hides all content that's not in a slot until this component's JavaScript loads.

  • Pros: diff --git a/elements/rh-disclosure/demo/rh-disclosure.html b/elements/rh-disclosure/demo/rh-disclosure.html index 507fa0d671..a6627f7eee 100644 --- a/elements/rh-disclosure/demo/rh-disclosure.html +++ b/elements/rh-disclosure/demo/rh-disclosure.html @@ -1,7 +1,4 @@ - - - Collapsed panel title - +

    Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?

    diff --git a/elements/rh-disclosure/demo/slotted-summary.html b/elements/rh-disclosure/demo/slotted-summary.html new file mode 100644 index 0000000000..10b00d5885 --- /dev/null +++ b/elements/rh-disclosure/demo/slotted-summary.html @@ -0,0 +1,26 @@ + + + This is a slotted summary with extra markup + +

    Instead of using <rh-disclosure summary="Hello world">, users can slot content into a summary slot and include additional HTML if needed.

    +

    Also note that slotted summary content will render on the page if/when JavaScript fails to load.

    +
    + + + + + + diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 2693b8090b..5135f0314a 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -22,6 +22,11 @@ export class RhDisclosure extends LitElement { */ @property({ type: Boolean, reflect: true }) open = false; + /** + * Sets the disclosure title via an attribute + */ + @property({ reflect: true }) summary?: string; + @query('details') private detailsEl!: HTMLDetailsElement; @query('summary') private summaryEl!: HTMLElement; @@ -33,7 +38,7 @@ export class RhDisclosure extends LitElement { @toggle="${this.#onToggle}"> - + ${this.summary}
    From 5dee62ac7705055ac801731a66a9b841a15f2dce Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 20 Nov 2024 12:12:28 -0500 Subject: [PATCH 20/26] fix(disclosure): remove `display: flex;` from `` --- elements/rh-disclosure/rh-disclosure.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/elements/rh-disclosure/rh-disclosure.css b/elements/rh-disclosure/rh-disclosure.css index 59459b841c..0eba79fa32 100644 --- a/elements/rh-disclosure/rh-disclosure.css +++ b/elements/rh-disclosure/rh-disclosure.css @@ -3,12 +3,9 @@ } summary { - align-items: center; cursor: pointer; - display: flex; font-size: var(--rh-font-size-body-text-md, 1rem); font-weight: var(--rh-font-weight-body-text-medium, 500); - gap: var(--rh-space-md, 8px); list-style: none; position: relative; @@ -40,6 +37,9 @@ summary { block-size: var(--rh-space-lg, 16px); transition: 0.2s; will-change: rotate; + position: relative; + inset-block-start: 3px; + margin-inline-end: var(--rh-space-md, 8px); } #details-content { From dbe6e6d821f6048e83de408707280b1c38a662d8 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 20 Nov 2024 14:05:15 -0500 Subject: [PATCH 21/26] fix(disclosure): prevent ESC from closing disclosure on certain interactive elements --- .../demo/nested-disclosures.html | 35 +++++++++++++++++++ elements/rh-disclosure/rh-disclosure.ts | 13 +++++++ 2 files changed, 48 insertions(+) diff --git a/elements/rh-disclosure/demo/nested-disclosures.html b/elements/rh-disclosure/demo/nested-disclosures.html index a57ea16349..43f6395e5b 100644 --- a/elements/rh-disclosure/demo/nested-disclosures.html +++ b/elements/rh-disclosure/demo/nested-disclosures.html @@ -4,6 +4,41 @@

    You can hit escape to test focus and see which details element closes!

    This is nesting! fake link 2 and more text.

    +
    +
    + + +
    +
    + + +
    +
    +
    + Choose a shipping method: + +
    + +
    +
    +
    +
    +
    + Select your pizza toppings: + +
    + +
    +
    +
    +
    + +
    +
    +

    This is a sentence with a link.

    diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 5135f0314a..306ed32b0e 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -52,8 +52,21 @@ export class RhDisclosure extends LitElement { } #onKeydown(event: KeyboardEvent): void { + const preventEscElements = ` + input:not([type='hidden']):not([type='radio']):not([inert]):not([inert] *):not([tabindex^='-']):not(:disabled), + input[type='radio']:not([inert]):not([inert] *):not([tabindex^='-']):not(:disabled), + select:not([inert]):not([inert] *):not([tabindex^='-']):not(:disabled), + textarea:not([inert]):not([inert] *):not([tabindex^='-']):not(:disabled), + iframe:not([inert]):not([inert] *):not([tabindex^='-']), + audio[controls]:not([inert]):not([inert] *):not([tabindex^='-']), + video[controls]:not([inert]):not([inert] *):not([tabindex^='-']), + [contenteditable]:not([inert]):not([inert] *):not([tabindex^='-']) + `; if (event.code === 'Escape') { event.stopPropagation(); + if (document.activeElement?.matches(preventEscElements)) { + return; + } this.#closeDetails(); } } From b5cce6f0aae0d47461f6dcbe0af55df31748b7e1 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 20 Nov 2024 14:48:28 -0500 Subject: [PATCH 22/26] fix(disclosure): improve outline on focus --- elements/rh-disclosure/rh-disclosure.css | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/elements/rh-disclosure/rh-disclosure.css b/elements/rh-disclosure/rh-disclosure.css index 0eba79fa32..4cf2af0ff2 100644 --- a/elements/rh-disclosure/rh-disclosure.css +++ b/elements/rh-disclosure/rh-disclosure.css @@ -22,7 +22,14 @@ summary { } &:focus { - outline-offset: var(--rh-space-lg, 16px); + outline: 0; + } + + &:focus:before { + outline: var(--rh-border-width-md, 2px) solid; + /* stylelint-disable-next-line rhds/token-values */ + outline-color: var(--rh-color-interactive-primary-focus, #003366); + outline-offset: -2px; } & ::slotted([slot='summary']) { From fe71de010cbae25fc0896f82707c3d3c84847ed3 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 20 Nov 2024 15:10:40 -0500 Subject: [PATCH 23/26] fix(disclosure): move FOUC styles to lightdom-shim, remove FOUC demo --- .../rh-disclosure/demo/color-context.html | 2 +- .../demo/nested-disclosures.html | 2 +- elements/rh-disclosure/demo/no-fouc.html | 23 ------------------- .../rh-disclosure/demo/rh-disclosure.html | 2 +- .../rh-disclosure/demo/slotted-summary.html | 2 +- .../rh-disclosure-lightdom-shim.css | 20 ++++++++++------ .../rh-disclosure/rh-disclosure-lightdom.css | 14 ----------- 7 files changed, 17 insertions(+), 48 deletions(-) delete mode 100644 elements/rh-disclosure/demo/no-fouc.html delete mode 100644 elements/rh-disclosure/rh-disclosure-lightdom.css diff --git a/elements/rh-disclosure/demo/color-context.html b/elements/rh-disclosure/demo/color-context.html index ebc0a9ed75..b74615cd9a 100644 --- a/elements/rh-disclosure/demo/color-context.html +++ b/elements/rh-disclosure/demo/color-context.html @@ -4,7 +4,7 @@ - + diff --git a/elements/rh-disclosure/demo/rh-disclosure.html b/elements/rh-disclosure/demo/rh-disclosure.html index a6627f7eee..5137f8c20e 100644 --- a/elements/rh-disclosure/demo/rh-disclosure.html +++ b/elements/rh-disclosure/demo/rh-disclosure.html @@ -2,7 +2,7 @@

    Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?

    - + diff --git a/elements/rh-disclosure/rh-disclosure.ts b/elements/rh-disclosure/rh-disclosure.ts index 306ed32b0e..8f9dde551c 100644 --- a/elements/rh-disclosure/rh-disclosure.ts +++ b/elements/rh-disclosure/rh-disclosure.ts @@ -7,10 +7,17 @@ import '@rhds/elements/rh-icon/rh-icon.js'; import styles from './rh-disclosure.css'; +export class DisclosureToggleEvent extends Event { + constructor() { + super('toggle', { bubbles: true, cancelable: true }); + } +} + /** * @summary A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible). * @slot - Place the content you want to disclose in the default slot. This content is hidden by default. * @slot summary - The title of the disclosure + * @fires {DisclosureToggleEvent} toggle - Fires when a user opens or closes a disclosure. * @csspart caret - The caret icon in the shadow DOM */ @customElement('rh-disclosure') @@ -49,6 +56,8 @@ export class RhDisclosure extends LitElement { #onToggle(): void { this.open = this.detailsEl.open; + const event = new DisclosureToggleEvent(); + this.dispatchEvent(event); } #onKeydown(event: KeyboardEvent): void { @@ -67,11 +76,14 @@ export class RhDisclosure extends LitElement { if (document.activeElement?.matches(preventEscElements)) { return; } - this.#closeDetails(); + this.#closeDisclosure(); } } - #closeDetails(): void { + #closeDisclosure(): void { + if (!this.open) { + return; + } this.detailsEl.open = false; this.open = false; this.summaryEl.focus(); From 190120ee4e2c9cf6cb17f4cca17d0e3f1400e406 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Wed, 20 Nov 2024 16:28:10 -0500 Subject: [PATCH 25/26] fix(disclosure): prevent wrapping in slotted summary demo via demo styles --- elements/rh-disclosure/demo/slotted-summary.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/elements/rh-disclosure/demo/slotted-summary.html b/elements/rh-disclosure/demo/slotted-summary.html index 10d294c5e7..dbf8053bb2 100644 --- a/elements/rh-disclosure/demo/slotted-summary.html +++ b/elements/rh-disclosure/demo/slotted-summary.html @@ -15,7 +15,7 @@