From 51a82d4019879355bfdb0cd464343b17f18a1a2a Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Thu, 7 Nov 2024 16:28:55 -0500 Subject: [PATCH 01/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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/10] 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); } } }