mirror of
https://github.com/shoelace-style/webawesome.git
synced 2026-01-12 12:09:26 +00:00
[Details] Revamp CSS, simplify part names
First component to use the `display: contents` trick discussed in #207
This commit is contained in:
@@ -28,7 +28,7 @@ Use the `disabled` attribute to prevent the details from expanding.
|
||||
|
||||
### Customizing the Summary Icon
|
||||
|
||||
Use the `expand-icon` and `collapse-icon` slots to change the expand and collapse icons, respectively. To disable the animation, override the `rotate` property on the `summary-icon` part as shown below.
|
||||
Use the `expand-icon` and `collapse-icon` slots to change the expand and collapse icons, respectively. To disable the animation, override the `rotate` property on the `icon` part as shown below.
|
||||
|
||||
```html {.example}
|
||||
<wa-details summary="Toggle Me" class="custom-icons">
|
||||
@@ -40,8 +40,8 @@ Use the `expand-icon` and `collapse-icon` slots to change the expand and collaps
|
||||
</wa-details>
|
||||
|
||||
<style>
|
||||
wa-details.custom-icons::part(summary-icon) {
|
||||
/* Disable the expand/collapse animation */
|
||||
/* Disable the expand/collapse animation */
|
||||
wa-details.custom-icons::part(icon) {
|
||||
rotate: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,68 +1,65 @@
|
||||
:host {
|
||||
--background-color: var(--wa-color-surface-default);
|
||||
--border-color: var(--wa-color-surface-border);
|
||||
--border-radius: var(--wa-panel-border-radius);
|
||||
--border-style: var(--wa-panel-border-style);
|
||||
--border-width: var(--wa-panel-border-width);
|
||||
background-color: var(--wa-color-surface-default);
|
||||
border: var(--wa-panel-border-width) var(--wa-color-surface-border) var(--wa-panel-border-style);
|
||||
border-radius: var(--wa-panel-border-radius);
|
||||
|
||||
--icon-color: var(--wa-color-text-quiet);
|
||||
--spacing: var(--wa-space-m);
|
||||
--show-duration: 200ms;
|
||||
--hide-duration: 200ms;
|
||||
|
||||
display: block;
|
||||
display: contents !important;
|
||||
}
|
||||
|
||||
.details {
|
||||
background-color: var(--background-color);
|
||||
border-color: var(--border-color);
|
||||
border-radius: var(--border-radius);
|
||||
border-style: var(--border-style);
|
||||
border-width: var(--border-width);
|
||||
details {
|
||||
all: inherit;
|
||||
display: block;
|
||||
overflow-anchor: none;
|
||||
}
|
||||
|
||||
.details--disabled {
|
||||
:host([disabled]) details {
|
||||
opacity: 0.5;
|
||||
|
||||
summary {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
summary:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.details__header {
|
||||
summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: var(--spacing);
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
cursor: pointer;
|
||||
|
||||
&::marker,
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(1px + var(--wa-focus-ring-offset));
|
||||
}
|
||||
|
||||
[part~='summary'] {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.details__header::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.details__header:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.details__header:focus-visible {
|
||||
outline: var(--wa-focus-ring);
|
||||
outline-offset: calc(1px + var(--wa-focus-ring-offset));
|
||||
}
|
||||
|
||||
.details--disabled .details__header {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.details--disabled .details__header:focus-visible {
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.details__summary {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.details__summary-icon {
|
||||
[part~='icon'] {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -70,25 +67,25 @@
|
||||
transition: rotate var(--wa-transition-normal) var(--wa-transition-easing);
|
||||
}
|
||||
|
||||
.details--open .details__summary-icon {
|
||||
:host([open]) [part~='icon'] {
|
||||
rotate: 90deg;
|
||||
}
|
||||
|
||||
.details--open.details--rtl .details__summary-icon {
|
||||
:host([open]:dir(rtl)) [part~='icon'] {
|
||||
rotate: -90deg;
|
||||
}
|
||||
|
||||
.details--open slot[name='expand-icon'],
|
||||
.details:not(.details--open) slot[name='collapse-icon'] {
|
||||
:host([open]) slot[name='expand-icon'],
|
||||
:host(:not([open])) slot[name='collapse-icon'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Overflows get clipped during the closing animation if we don't wait until the close is gone. */
|
||||
:not(.details--open) .details__body {
|
||||
:host(:not([open])) .body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.details__content {
|
||||
.content {
|
||||
display: block;
|
||||
padding: var(--spacing);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { html } from 'lit';
|
||||
import { customElement, property, query } from 'lit/decorators.js';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { WaAfterHideEvent } from '../../events/after-hide.js';
|
||||
import { WaAfterShowEvent } from '../../events/after-show.js';
|
||||
import { WaHideEvent } from '../../events/hide.js';
|
||||
@@ -31,17 +30,13 @@ import styles from './details.css';
|
||||
* @event wa-hide - Emitted when the details closes.
|
||||
* @event wa-after-hide - Emitted after the details closes and all animations are complete.
|
||||
*
|
||||
* @csspart base - The component's base wrapper.
|
||||
* @csspart base - The inner `<details>` element used to render the component.
|
||||
* Styles you apply to the component are automatically applied to this part, so you usually don't need to deal with it unless you need to set the `display` property.
|
||||
* @csspart header - The header that wraps both the summary and the expand/collapse icon.
|
||||
* @csspart summary - The container that wraps the summary.
|
||||
* @csspart summary-icon - The container that wraps the expand/collapse icons.
|
||||
* @csspart icon - The container that wraps the expand/collapse icons.
|
||||
* @csspart content - The details content.
|
||||
*
|
||||
* @cssproperty --background-color - The details' background color.
|
||||
* @cssproperty --border-color - The details' border color.
|
||||
* @cssproperty --border-radius - The radius for the details' corners. Expects a single value.
|
||||
* @cssproperty --border-style - The style of the details' borders.
|
||||
* @cssproperty --border-width - The width of the details' borders. Expects a single value.
|
||||
* @cssproperty --icon-color - The color of the details' icon.
|
||||
* @cssproperty --spacing - The amount of space around and between the details' content. Expects a single value.
|
||||
* @cssproperty [--show-duration=200ms] - The show duration to use when applying built-in animation classes.
|
||||
@@ -54,10 +49,10 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
private detailsObserver: MutationObserver;
|
||||
private readonly localize = new LocalizeController(this);
|
||||
|
||||
@query('.details') details: HTMLDetailsElement;
|
||||
@query('.details__header') header: HTMLElement;
|
||||
@query('.details__body') body: HTMLElement;
|
||||
@query('.details__expand-icon-slot') expandIconSlot: HTMLSlotElement;
|
||||
@query('details') details: HTMLDetailsElement;
|
||||
@query('summary') header: HTMLElement;
|
||||
@query('.body') body: HTMLElement;
|
||||
@query('.expand-icon-slot') expandIconSlot: HTMLSlotElement;
|
||||
|
||||
/**
|
||||
* Indicates whether or not the details is open. You can toggle this attribute to show and hide the details, or you
|
||||
@@ -211,19 +206,9 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
const isRtl = !this.hasUpdated ? this.dir === 'rtl' : this.localize.dir() === 'rtl';
|
||||
|
||||
return html`
|
||||
<details
|
||||
part="base"
|
||||
class=${classMap({
|
||||
details: true,
|
||||
'details--open': this.open,
|
||||
'details--disabled': this.disabled,
|
||||
'details--rtl': isRtl,
|
||||
})}
|
||||
>
|
||||
<details part="base">
|
||||
<summary
|
||||
part="header"
|
||||
id="header"
|
||||
class="details__header"
|
||||
role="button"
|
||||
aria-expanded=${this.open ? 'true' : 'false'}
|
||||
aria-controls="content"
|
||||
@@ -232,9 +217,9 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
@click=${this.handleSummaryClick}
|
||||
@keydown=${this.handleSummaryKeyDown}
|
||||
>
|
||||
<slot name="summary" part="summary" class="details__summary">${this.summary}</slot>
|
||||
<slot name="summary" part="summary">${this.summary}</slot>
|
||||
|
||||
<span part="summary-icon" class="details__summary-icon">
|
||||
<span part="icon">
|
||||
<slot name="expand-icon">
|
||||
<wa-icon
|
||||
library="system"
|
||||
@@ -254,8 +239,8 @@ export default class WaDetails extends WebAwesomeElement {
|
||||
</span>
|
||||
</summary>
|
||||
|
||||
<div class="details__body" role="region" aria-labelledby="header">
|
||||
<slot part="content" id="content" class="details__content"></slot>
|
||||
<div class="body" role="region" aria-labelledby="header">
|
||||
<slot part="content" id="content" class="content"></slot>
|
||||
</div>
|
||||
</details>
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user