Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(disclosure): add <rh-disclosure> #2043

Open
wants to merge 27 commits into
base: staging/cubone
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
51a82d4
feat(disclosure): add `<rh-disclosure>`
adamjohnson Nov 7, 2024
6f9598c
fix(disclosure): make borders show up when used without a context pro…
adamjohnson Nov 8, 2024
0271e0f
fix(disclosure): avoid 1px outer + inner border overlap inconsistencies
adamjohnson Nov 8, 2024
501ebcc
fix(disclosure): export RhDisclosure class, fix tests
adamjohnson Nov 8, 2024
6e021d2
feat(disclosure): enable ESC to close
adamjohnson Nov 8, 2024
a6cfa99
test(disclosure): ignore fallback value error
adamjohnson Nov 11, 2024
bfea41e
test(disclosure): fix `removeEventListener` error
adamjohnson Nov 11, 2024
9d6b727
fix(disclosure): escape closes currently focused disclosure
adamjohnson Nov 13, 2024
de409de
feat(disclosure): add `!isServer` check for SSR
adamjohnson Nov 13, 2024
5c8d706
fix(disclosure): proper nested rh-icon caret rotation on open/close
adamjohnson Nov 13, 2024
f791d69
fix(disclosure): correct gap spacing on `<summary>`
adamjohnson Nov 18, 2024
4b53e2e
refactor(disclosure): move `details`/`summary` to shadowdom
adamjohnson Nov 18, 2024
e5c35c8
feat(disclosure): add lightdom shim + example demo
adamjohnson Nov 18, 2024
f87b480
fix(disclosure): improve FOUC / CLS
adamjohnson Nov 19, 2024
35e7146
refactor(disclosure): `summary-label` slot becomes `summary`
adamjohnson Nov 19, 2024
0f58da8
fix(disclosure): remove default content for `summary` slot
adamjohnson Nov 19, 2024
b850ac5
fix(disclosure): expand `summary` focus outline
adamjohnson Nov 19, 2024
f196568
fix(disclosure): let `render` handle elements/state
adamjohnson Nov 19, 2024
4530f6a
Merge branch 'staging/cubone' into feat/rh-disclosure
bennypowers Nov 20, 2024
452925e
feat(disclosure): add `summary` prop, convert demos to use it
adamjohnson Nov 20, 2024
5dee62a
fix(disclosure): remove `display: flex;` from `<summay>`
adamjohnson Nov 20, 2024
dbe6e6d
fix(disclosure): prevent ESC from closing disclosure on certain inter…
adamjohnson Nov 20, 2024
b5cce6f
fix(disclosure): improve outline on focus
adamjohnson Nov 20, 2024
fe71de0
fix(disclosure): move FOUC styles to lightdom-shim, remove FOUC demo
adamjohnson Nov 20, 2024
dbe8f1f
feat(disclosure): add `toggle` event and events demo
adamjohnson Nov 20, 2024
190120e
fix(disclosure): prevent wrapping in slotted summary demo via demo st…
adamjohnson Nov 20, 2024
b1e0b00
fix(disclosure): use `composedPath()` for ESC functionality
adamjohnson Nov 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .changeset/nasty-ravens-joke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
"@rhds/elements": minor
---

✨ Added `<rh-disclosure>`

A disclosure is a widget that enables content to be either collapsed (hidden) or expanded (visible).

```html
<rh-disclosure>
<span slot="summary">
Collapsed panel title
</span>
<p>Lorem ipsum dolor sit amet consectetur adipisicing, elit.</p>
</rh-disclosure>
```
12 changes: 12 additions & 0 deletions docs/_data/repoStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
17 changes: 17 additions & 0 deletions elements/rh-disclosure/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# 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
<rh-disclosure>
<span slot="summary">
Collapsed panel title
</span>
<p>Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.</p>
</rh-disclosure>
```
12 changes: 12 additions & 0 deletions elements/rh-disclosure/demo/color-context.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<rh-context-demo>
<rh-disclosure summary="Collapsed panel title">
<p>Lorem ipsum dolor sit amet consectetur adipisicing, elit. Velit distinctio, nesciunt nobis sit.</p>
</rh-disclosure>
</rh-context-demo>

<link rel="stylesheet" href="../rh-disclosure-lightdom-shim.css">

<script type="module">
import '@rhds/elements/lib/elements/rh-context-demo/rh-context-demo.js';
import '@rhds/elements/rh-disclosure/rh-disclosure.js';
</script>
26 changes: 26 additions & 0 deletions elements/rh-disclosure/demo/events.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<form id="disclosure-events">
<rh-disclosure summary="Collapsed panel title">
<p>Lorem ipsum dolor <a href="#">sit amet consectetur</a> adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?</p>
</rh-disclosure>

<fieldset>
<legend>Events Fired</legend>
<output name="events">No events yet</output>
</fieldset>
</form>

<link rel="stylesheet" href="../rh-disclosure-lightdom-shim.css">

<script type="module">
import '@rhds/elements/rh-disclosure/rh-disclosure.js';

const disclosure = document.querySelector('rh-disclosure');
const form = document.getElementById('disclosure-events');
const events = [];
form.addEventListener('submit', e => e.preventDefault());
const onDisclosureEvent = event => {
events.push(event.type);
form.elements.events.value = events.join(', ');
};
disclosure.addEventListener('toggle', onDisclosureEvent);
</script>
50 changes: 50 additions & 0 deletions elements/rh-disclosure/demo/nested-disclosures.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<rh-disclosure summary="This is the top level disclosure">
<p>Be sure to test the ESC key + focus when nesting disclosures together. Lorem ipsum dolor <a href="#">fake link</a> adipisicing.</p>
<rh-disclosure summary="This is the second level disclosure">
<p>You can hit escape to test focus and see which details element closes!</p>
<rh-disclosure summary="Third nested disclosure">
<p>This is nesting! <a href="#">fake link 2</a> and more text.</p>
<form action="#" method="get" class="form-example">
<div class="form-example">
<label for="name">Enter your name: </label>
<input type="text" name="name" id="name" required />
</div>
<div class="form-example">
<label for="favcity">Which is your favorite city?</label>
<select id="favcity" name="select">
<option value="1">Amsterdam</option>
<option value="2">Buenos Aires</option>
</select>
</div>
<div class="form-example">
<fieldset>
<legend>Choose a shipping method:</legend>
<input id="overnight" type="radio" name="shipping" value="overnight">
<label for="overnight">Overnight</label><br>
<input id="twoday" type="radio" name="shipping" value="twoday">
<label for="twoday">Two day</label><br>
</fieldset>
</div>
<div class="form-example">
<fieldset>
<legend>Select your pizza toppings:</legend>
<input id="ham" type="checkbox" name="toppings" value="ham">
<label for="ham">Ham</label><br>
<input id="pepperoni" type="checkbox" name="toppings" value="pepperoni">
<label for="pepperoni">Pepperoni</label><br>
</fieldset>
</div>
<div class="form-example">
<input type="submit" value="Subscribe!" />
</div>
</form>
<p>This is a sentence with <a href="#">a link</a>.</p>
</rh-disclosure>
</rh-disclosure>
</rh-disclosure>

<link rel="stylesheet" href="../rh-disclosure-lightdom-shim.css">

<script type="module">
import '@rhds/elements/rh-disclosure/rh-disclosure.js';
</script>
9 changes: 9 additions & 0 deletions elements/rh-disclosure/demo/rh-disclosure.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<rh-disclosure summary="Collapsed panel title">
<p>Lorem ipsum dolor <a href="#">sit amet consectetur</a> adipisicing, elit. Velit distinctio, nesciunt nobis sit, a dolor, non numquam rerum recusandae, deserunt enim assumenda quidem. Id impedit necessitatibus obcaecati ratione reprehenderit laborum?</p>
</rh-disclosure>

<link rel="stylesheet" href="../rh-disclosure-lightdom-shim.css">

<script type="module">
import '@rhds/elements/rh-disclosure/rh-disclosure.js';
</script>
26 changes: 26 additions & 0 deletions elements/rh-disclosure/demo/slotted-summary.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<rh-disclosure>
<span slot="summary">
This is a slotted summary with extra markup <rh-icon set="ui" icon="like"></rh-icon>
</span>
<p>Instead of using <code>&lt;rh-disclosure summary="Hello world"&gt;</code>, users can slot content into a <code>summary</code> slot and include additional HTML if needed.</p>
<p>Also note that slotted <code>summary</code> content will render on the page if/when JavaScript fails to load.</p>
</rh-disclosure>

<link rel="stylesheet" href="../rh-disclosure-lightdom-shim.css">

<script type="module">
import '@rhds/elements/rh-disclosure/rh-disclosure.js';
import '@rhds/elements/rh-icon/rh-icon.js';
</script>

<style>
span[slot='summary'] {
display: inline-flex;
align-items: center;
gap: var(--rh-space-sm, 6px);
}

p {
margin-block-end: var(--rh-space-lg, 16px);
}
</style>
9 changes: 9 additions & 0 deletions elements/rh-disclosure/docs/00-overview.md
Original file line number Diff line number Diff line change
@@ -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

<div id="overview-image-description" class="visually-hidden">
An expanded disclosure element with a panel trigger and lorem ipsum for details content
</div>
1 change: 1 addition & 0 deletions elements/rh-disclosure/docs/10-style.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## Style
1 change: 1 addition & 0 deletions elements/rh-disclosure/docs/20-guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## Guidelines
1 change: 1 addition & 0 deletions elements/rh-disclosure/docs/40-accessibility.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
## Accessibility
Binary file added elements/rh-disclosure/docs/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions elements/rh-disclosure/rh-disclosure-lightdom-shim.css
Original file line number Diff line number Diff line change
@@ -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'] {
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);
}
81 changes: 81 additions & 0 deletions elements/rh-disclosure/rh-disclosure.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
:host {
display: block;
}

summary {
cursor: pointer;
font-size: var(--rh-font-size-body-text-md, 1rem);
font-weight: var(--rh-font-weight-body-text-medium, 500);
list-style: none;
position: relative;

&::-webkit-details-marker,
&::marker {
display: none;
}

&:before {
content: '';
inset-block: -16px;
inset-inline: -24px;
position: absolute;
}

&:focus {
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']) {
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;
position: relative;
inset-block-start: 3px;
margin-inline-end: var(--rh-space-md, 8px);
}

#details-content {
font-size: var(--rh-font-size-body-text-md, 1rem);
line-height: var(--rh-line-height-body-text, 1.5);
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;
}

:host:has(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;
}
}

details[open] {
#caret {
transform: rotate(-180deg);
}
}
Loading
Loading