remove slot wrappers

This commit is contained in:
Cory LaViska
2022-12-02 17:03:59 -05:00
parent 31b05fedd3
commit 80a16ee42a
55 changed files with 229 additions and 283 deletions

View File

@@ -583,11 +583,11 @@ const App = () => (
### Customizing the Divider
You can target the `divider` part to apply CSS properties to the divider. To add a handle, slot an icon or another element into the `handle` slot. When customizing the divider, make sure to think about focus styles for keyboard users.
You can target the `divider` part to apply CSS properties to the divider. To add a custom handle, slot an icon into the `divider` slot. When customizing the divider, make sure to think about focus styles for keyboard users.
```html preview
<sl-split-panel style="--divider-width: 20px;">
<sl-icon slot="handle" name="grip-vertical"></sl-icon>
<sl-icon slot="divider" name="grip-vertical"></sl-icon>
<div
slot="start"
style="height: 200px; background: var(--sl-color-neutral-50); display: flex; align-items: center; justify-content: center;"
@@ -608,7 +608,7 @@ import { SlSplitPanel, SlIcon } from '@shoelace-style/shoelace/dist/react';
const App = () => (
<SlSplitPanel style={{ '--divider-width': '20px' }}>
<SlIcon slot="handle" name="grip-vertical" />
<SlIcon slot="divider" name="grip-vertical" />
<div
slot="start"
style={{
@@ -640,9 +640,9 @@ const App = () => (
Here's a more elaborate example that changes the divider's color and width and adds a styled handle.
```html preview
<div class="split-panel-handle">
<div class="split-panel-divider">
<sl-split-panel>
<sl-icon slot="handle" name="grip-vertical"></sl-icon>
<sl-icon slot="divider" name="grip-vertical"></sl-icon>
<div
slot="start"
style="height: 200px; background: var(--sl-color-neutral-50); display: flex; align-items: center; justify-content: center;"
@@ -659,15 +659,15 @@ Here's a more elaborate example that changes the divider's color and width and a
</div>
<style>
.split-panel-handle sl-split-panel {
.split-panel-divider sl-split-panel {
--divider-width: 2px;
}
.split-panel-handle sl-split-panel::part(divider) {
.split-panel-divider sl-split-panel::part(divider) {
background-color: var(--sl-color-pink-600);
}
.split-panel-handle sl-icon {
.split-panel-divider sl-icon {
position: absolute;
border-radius: var(--sl-border-radius-small);
background: var(--sl-color-pink-600);
@@ -675,11 +675,11 @@ Here's a more elaborate example that changes the divider's color and width and a
padding: 0.5rem 0.125rem;
}
.split-panel-handle sl-split-panel::part(divider):focus-visible {
.split-panel-divider sl-split-panel::part(divider):focus-visible {
background-color: var(--sl-color-primary-600);
}
.split-panel-handle sl-split-panel:focus-within sl-icon {
.split-panel-divider sl-split-panel:focus-within sl-icon {
background-color: var(--sl-color-primary-600);
color: var(--sl-color-neutral-0);
}
@@ -690,15 +690,15 @@ Here's a more elaborate example that changes the divider's color and width and a
import { SlSplitPanel, SlIcon } from '@shoelace-style/shoelace/dist/react';
const css = `
.split-panel-handle sl-split-panel {
.split-panel-divider sl-split-panel {
--divider-width: 2px;
}
.split-panel-handle sl-split-panel::part(divider) {
.split-panel-divider sl-split-panel::part(divider) {
background-color: var(--sl-color-pink-600);
}
.split-panel-handle sl-icon {
.split-panel-divider sl-icon {
position: absolute;
border-radius: var(--sl-border-radius-small);
background: var(--sl-color-pink-600);
@@ -706,11 +706,11 @@ const css = `
padding: .5rem .125rem;
}
.split-panel-handle sl-split-panel::part(divider):focus-visible {
.split-panel-divider sl-split-panel::part(divider):focus-visible {
background-color: var(--sl-color-primary-600);
}
.split-panel-handle sl-split-panel:focus-within sl-icon {
.split-panel-divider sl-split-panel:focus-within sl-icon {
background-color: var(--sl-color-primary-600);
color: var(--sl-color-neutral-0);
}
@@ -718,9 +718,9 @@ const css = `
const App = () => (
<>
<div className="split-panel-handle">
<div className="split-panel-divider">
<SlSplitPanel>
<SlIcon slot="handle" name="grip-vertical" />
<SlIcon slot="divider" name="grip-vertical" />
<div
slot="start"
style={{

View File

@@ -10,6 +10,8 @@ New versions of Shoelace are released as-needed and generally occur when a criti
## Next
- 🚨 BREAKING: removed the `handle-icon` part and slot from `<sl-image-comparer>` (use `handle` instead)
- 🚨 BREAKING: removed the `handle` slot from `<sl-split-panel>` (use the `divider` slot instead)
- Added `header-actions` slot to `<sl-dialog>` and `<sl-drawer>`
- Added the `expand-icon` and `collapse-icon` slots to `<sl-details>` and refactored the icon animation [#1046](https://github.com/shoelace-style/shoelace/discussions/1046)
- Fixed a bug in `<sl-tree-item>` where `sl-selection-change` was emitted when the selection didn't change [#1030](https://github.com/shoelace-style/shoelace/pull/1030)
@@ -22,6 +24,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti
- Improved IntelliSense in VS Code, courtesy of [Burton's amazing CEM Analyzer plugin](https://github.com/break-stuff/cem-plugin-vs-code-custom-data-generator)
- Improved accessibility of `<sl-alert>` so the alert is announced and the close button has a label
- Refactored all styles and animations to use `translate`, `rotate`, and `scale` instead of `transform`
- Removed slot wrappers from many components, allowing better control over user-applied styles
- Removed unused aria attributes from `<sl-skeleton>`
- Replaced the `x` icon in the system icon library with `x-lg` to improve icon consistency

View File

@@ -83,6 +83,7 @@ export default css`
.alert__message {
flex: 1 1 auto;
display: block;
padding: var(--sl-spacing-large);
overflow: hidden;
}

View File

@@ -197,13 +197,9 @@ export default class SlAlert extends ShoelaceElement {
aria-hidden=${this.open ? 'false' : 'true'}
@mousemove=${this.handleMouseMove}
>
<span part="icon" class="alert__icon">
<slot name="icon"></slot>
</span>
<slot name="icon" part="icon" class="alert__icon"></slot>
<span part="message" class="alert__message" aria-live="polite">
<slot></slot>
</span>
<slot part="message" class="alert__message" aria-live="polite"></slot>
${this.closable
? html`

View File

@@ -67,11 +67,9 @@ export default class SlAvatar extends ShoelaceElement {
${this.initials
? html` <div part="initials" class="avatar__initials">${this.initials}</div> `
: html`
<div part="icon" class="avatar__icon" aria-hidden="true">
<slot name="icon">
<sl-icon name="person-fill" library="system"></sl-icon>
</slot>
</div>
<slot name="icon" part="icon" class="avatar__icon" aria-hidden="true">
<sl-icon name="person-fill" library="system"></sl-icon>
</slot>
`}
${this.image && !this.hasError
? html`

View File

@@ -30,7 +30,7 @@ export default class SlBadge extends ShoelaceElement {
render() {
return html`
<span
<slot
part="base"
class=${classMap({
badge: true,
@@ -43,9 +43,7 @@ export default class SlBadge extends ShoelaceElement {
'badge--pulse': this.pulse
})}
role="status"
>
<slot></slot>
</span>
></slot>
`;
}
}

View File

@@ -55,9 +55,7 @@ export default class SlBreadcrumbItem extends ShoelaceElement {
'breadcrumb-item--has-suffix': this.hasSlotController.test('suffix')
})}
>
<span part="prefix" class="breadcrumb-item__prefix">
<slot name="prefix"></slot>
</span>
<slot name="prefix" part="prefix" class="breadcrumb-item__prefix"></slot>
${isLink
? html`
@@ -77,13 +75,9 @@ export default class SlBreadcrumbItem extends ShoelaceElement {
</button>
`}
<span part="suffix" class="breadcrumb-item__suffix">
<slot name="suffix"></slot>
</span>
<slot name="suffix" part="suffix" class="breadcrumb-item__suffix"></slot>
<span part="separator" class="breadcrumb-item__separator" aria-hidden="true">
<slot name="separator"></slot>
</span>
<slot name="separator" part="separator" class="breadcrumb-item__separator" aria-hidden="true"></slot>
</div>
`;
}

View File

@@ -63,9 +63,9 @@ export default class SlButtonGroup extends ShoelaceElement {
}
render() {
// eslint-disable-next-line lit-a11y/mouse-events-have-key-events -- focusout & focusin support bubbling whereas focus & blur do not which is necessary here
// eslint-disable-next-line lit-a11y/mouse-events-have-key-events
return html`
<div
<slot
part="base"
class="button-group"
role="${this.disableRole ? 'presentation' : 'group'}"
@@ -74,9 +74,8 @@ export default class SlButtonGroup extends ShoelaceElement {
@focusin=${this.handleFocus}
@mouseover=${this.handleMouseOver}
@mouseout=${this.handleMouseOut}
>
<slot @slotchange=${this.handleSlotChange} role="none"></slot>
</div>
@slotchange=${this.handleSlotChange}
></slot>
`;
}
}

View File

@@ -61,7 +61,11 @@ export default css`
pointer-events: none;
}
.button__label ::slotted(sl-icon) {
.button__label {
display: inline-block;
}
.button__label::slotted(sl-icon) {
vertical-align: -2px;
}
@@ -574,6 +578,8 @@ export default css`
z-index: 1;
}
/* Focus and checked are always on top */
:host(.sl-button-group__button--focus),
:host(.sl-button-group__button[checked]) {
z-index: 2;
}

View File

@@ -270,15 +270,9 @@ export default class SlButton extends ShoelaceElement implements ShoelaceFormCon
@focus=${this.handleFocus}
@click=${this.handleClick}
>
<span part="prefix" class="button__prefix">
<slot name="prefix"></slot>
</span>
<span part="label" class="button__label">
<slot></slot>
</span>
<span part="suffix" class="button__suffix">
<slot name="suffix"></slot>
</span>
<slot name="prefix" part="prefix" class="button__prefix"></slot>
<slot part="label" class="button__label"></slot>
<slot name="suffix" part="suffix" class="button__suffix"></slot>
${
this.caret ? html` <sl-icon part="caret" class="button__caret" library="system" name="caret"></sl-icon> ` : ''
}

View File

@@ -23,13 +23,14 @@ export default css`
}
.card__image {
display: flex;
border-top-left-radius: var(--border-radius);
border-top-right-radius: var(--border-radius);
margin: calc(-1 * var(--border-width));
overflow: hidden;
}
.card__image ::slotted(img) {
.card__image::slotted(img) {
display: block;
width: 100%;
}
@@ -39,6 +40,7 @@ export default css`
}
.card__header {
display: block;
border-bottom: solid var(--border-width) var(--border-color);
padding: calc(var(--padding) / 2) var(--padding);
}
@@ -53,10 +55,12 @@ export default css`
}
.card__body {
display: block;
padding: var(--padding);
}
.card--has-footer .card__footer {
display: block;
border-top: solid var(--border-width) var(--border-color);
padding: var(--padding);
}

View File

@@ -45,21 +45,10 @@ export default class SlCard extends ShoelaceElement {
'card--has-header': this.hasSlotController.test('header')
})}
>
<div part="image" class="card__image">
<slot name="image"></slot>
</div>
<div part="header" class="card__header">
<slot name="header"></slot>
</div>
<div part="body" class="card__body">
<slot></slot>
</div>
<div part="footer" class="card__footer">
<slot name="footer"></slot>
</div>
<slot name="image" part="image" class="card__image"></slot>
<slot name="header" part="header" class="card__header"></slot>
<slot part="body" class="card__body"></slot>
<slot name="footer" part="footer" class="card__footer"></slot>
</div>
`;
}

View File

@@ -89,6 +89,7 @@ export default css`
}
.checkbox__label {
display: inline-block;
color: var(--sl-input-label-color);
line-height: var(--sl-toggle-size);
margin-inline-start: 0.5em;

View File

@@ -171,9 +171,7 @@ export default class SlCheckbox extends ShoelaceElement implements ShoelaceFormC
: ''}
</span>
<span part="label" class="checkbox__label">
<slot></slot>
</span>
<slot part="label" class="checkbox__label"></slot>
</label>
`;
}

View File

@@ -77,6 +77,7 @@ export default css`
}
.details__content {
display: block;
padding: var(--sl-spacing-medium);
}
`;

View File

@@ -192,9 +192,7 @@ export default class SlDetails extends ShoelaceElement {
</header>
<div class="details__body">
<div part="content" id="content" class="details__content" role="region" aria-labelledby="header">
<slot></slot>
</div>
<slot part="content" id="content" class="details__content" role="region" aria-labelledby="header"></slot>
</div>
</div>
`;

View File

@@ -86,6 +86,7 @@ export default css`
.dialog__body {
flex: 1 1 auto;
display: block;
padding: var(--body-spacing);
overflow: auto;
-webkit-overflow-scrolling: touch;

View File

@@ -296,9 +296,7 @@ export default class SlDialog extends ShoelaceElement {
`
: ''}
<div part="body" class="dialog__body">
<slot></slot>
</div>
<slot part="body" class="dialog__body"></slot>
<footer part="footer" class="dialog__footer">
<slot name="footer"></slot>

View File

@@ -117,6 +117,7 @@ export default css`
.drawer__body {
flex: 1 1 auto;
display: block;
padding: var(--body-spacing);
overflow: auto;
-webkit-overflow-scrolling: touch;

View File

@@ -327,9 +327,7 @@ export default class SlDrawer extends ShoelaceElement {
`
: ''}
<div part="body" class="drawer__body">
<slot></slot>
</div>
<slot part="body" class="drawer__body"></slot>
<footer part="footer" class="drawer__footer">
<slot name="footer"></slot>

View File

@@ -42,6 +42,7 @@ export default css`
}
.dropdown--open .dropdown__panel {
display: block;
pointer-events: all;
}

View File

@@ -46,8 +46,8 @@ export default class SlDropdown extends ShoelaceElement {
static styles: CSSResultGroup = styles;
@query('.dropdown') popup: SlPopup;
@query('.dropdown__trigger') trigger: HTMLElement;
@query('.dropdown__panel') panel: HTMLElement;
@query('.dropdown__trigger') trigger: HTMLSlotElement;
@query('.dropdown__panel') panel: HTMLSlotElement;
private readonly localize = new LocalizeController(this);
@@ -126,16 +126,14 @@ export default class SlDropdown extends ShoelaceElement {
}
focusOnTrigger() {
const slot = this.trigger.querySelector('slot')!;
const trigger = slot.assignedElements({ flatten: true })[0] as HTMLElement | undefined;
const trigger = this.trigger.assignedElements({ flatten: true })[0] as HTMLElement | undefined;
if (typeof trigger?.focus === 'function') {
trigger.focus();
}
}
getMenu() {
const slot = this.panel.querySelector('slot')!;
return slot.assignedElements({ flatten: true }).find(el => el.tagName.toLowerCase() === 'sl-menu') as
return this.panel.assignedElements({ flatten: true }).find(el => el.tagName.toLowerCase() === 'sl-menu') as
| SlMenu
| undefined;
}
@@ -293,8 +291,7 @@ export default class SlDropdown extends ShoelaceElement {
// To determine this, we assume the first tabbable element in the trigger slot is the "accessible trigger."
//
updateAccessibleTrigger() {
const slot = this.trigger.querySelector('slot')!;
const assignedElements = slot.assignedElements({ flatten: true }) as HTMLElement[];
const assignedElements = this.trigger.assignedElements({ flatten: true }) as HTMLElement[];
const accessibleTrigger = assignedElements.find(el => getTabbableBoundary(el).start);
let target: HTMLElement;
@@ -415,25 +412,23 @@ export default class SlDropdown extends ShoelaceElement {
'dropdown--open': this.open
})}
>
<span
<slot
name="trigger"
slot="anchor"
part="trigger"
class="dropdown__trigger"
@click=${this.handleTriggerClick}
@keydown=${this.handleTriggerKeyDown}
@keyup=${this.handleTriggerKeyUp}
>
<slot name="trigger" @slotchange=${this.handleTriggerSlotChange}></slot>
</span>
@slotchange=${this.handleTriggerSlotChange}
></slot>
<div
<slot
part="panel"
class="dropdown__panel"
aria-hidden=${this.open ? 'false' : 'true'}
aria-labelledby="dropdown"
>
<slot></slot>
</div>
></slot>
</sl-popup>
`;
}

View File

@@ -20,13 +20,14 @@ export default css`
.image-comparer__before,
.image-comparer__after {
display: block;
pointer-events: none;
}
.image-comparer__before ::slotted(img),
.image-comparer__after ::slotted(img),
.image-comparer__before ::slotted(svg),
.image-comparer__after ::slotted(svg) {
.image-comparer__before::slotted(img),
.image-comparer__after::slotted(img),
.image-comparer__before::slotted(svg),
.image-comparer__after::slotted(svg) {
display: block;
max-width: 100% !important;
height: auto;

View File

@@ -12,7 +12,7 @@ describe('<sl-image-comparer>', () => {
`);
const afterPart = el.shadowRoot!.querySelector<HTMLElement>('[part~="after"]')!;
const iconContainer = el.shadowRoot!.querySelector<HTMLSlotElement>('slot[name="handle-icon"]')!;
const iconContainer = el.shadowRoot!.querySelector<HTMLSlotElement>('slot[name="handle"]')!;
const handle = el.shadowRoot!.querySelector<HTMLElement>('[part~="handle"]')!;
expect(el.position).to.equal(50);

View File

@@ -21,7 +21,7 @@ import type { CSSResultGroup } from 'lit';
*
* @slot before - The before image, an `<img>` or `<svg>` element.
* @slot after - The after image, an `<img>` or `<svg>` element.
* @slot handle-icon - The icon used inside the handle.
* @slot handle - The icon used inside the handle.
*
* @event sl-change - Emitted when the position changes.
*
@@ -30,7 +30,6 @@ import type { CSSResultGroup } from 'lit';
* @csspart after - The container that holds the "after" image.
* @csspart divider - The divider that separates the images.
* @csspart handle - The handle that the user drags to expose the after image.
* @csspart handle-icon - The handle icon's `<slot>`.
*
* @cssproperty --divider-width - The width of the dividing line.
* @cssproperty --handle-size - The size of the compare handle.
@@ -109,19 +108,16 @@ export default class SlImageComparer extends ShoelaceElement {
@keydown=${this.handleKeyDown}
>
<div class="image-comparer__image">
<div part="before" class="image-comparer__before">
<slot name="before"></slot>
</div>
<slot name="before" part="before" class="image-comparer__before"></slot>
<div
<slot
name="after"
part="after"
class="image-comparer__after"
style=${styleMap({
clipPath: isRtl ? `inset(0 0 0 ${100 - this.position}%)` : `inset(0 ${100 - this.position}% 0 0)`
})}
>
<slot name="after"></slot>
</div>
></slot>
</div>
<div
@@ -133,7 +129,8 @@ export default class SlImageComparer extends ShoelaceElement {
@mousedown=${this.handleDrag}
@touchstart=${this.handleDrag}
>
<div
<slot
name="handle"
part="handle"
class="image-comparer__handle"
role="scrollbar"
@@ -143,10 +140,8 @@ export default class SlImageComparer extends ShoelaceElement {
aria-controls="image-comparer"
tabindex="0"
>
<slot part="handle-icon" name="handle-icon">
<sl-icon library="system" name="grip-vertical"></sl-icon>
</slot>
</div>
<sl-icon library="system" name="grip-vertical"></sl-icon>
</slot>
</div>
</div>
`;

View File

@@ -147,8 +147,8 @@ export default css`
cursor: default;
}
.input__prefix ::slotted(sl-icon),
.input__suffix ::slotted(sl-icon) {
.input__prefix::slotted(sl-icon),
.input__suffix::slotted(sl-icon) {
color: var(--sl-input-icon-color);
}
@@ -172,11 +172,11 @@ export default css`
width: calc(1em + var(--sl-input-spacing-small) * 2);
}
.input--small .input__prefix ::slotted(*) {
.input--small .input__prefix::slotted(*) {
margin-inline-start: var(--sl-input-spacing-small);
}
.input--small .input__suffix ::slotted(*) {
.input--small .input__suffix::slotted(*) {
margin-inline-end: var(--sl-input-spacing-small);
}
@@ -196,11 +196,11 @@ export default css`
width: calc(1em + var(--sl-input-spacing-medium) * 2);
}
.input--medium .input__prefix ::slotted(*) {
.input--medium .input__prefix::slotted(*) {
margin-inline-start: var(--sl-input-spacing-medium);
}
.input--medium .input__suffix ::slotted(*) {
.input--medium .input__suffix::slotted(*) {
margin-inline-end: var(--sl-input-spacing-medium);
}
@@ -220,11 +220,11 @@ export default css`
width: calc(1em + var(--sl-input-spacing-large) * 2);
}
.input--large .input__prefix ::slotted(*) {
.input--large .input__prefix::slotted(*) {
margin-inline-start: var(--sl-input-spacing-large);
}
.input--large .input__suffix ::slotted(*) {
.input--large .input__suffix::slotted(*) {
margin-inline-end: var(--sl-input-spacing-large);
}

View File

@@ -422,9 +422,7 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
'input--is-firefox': isFirefox
})}
>
<span part="prefix" class="input__prefix">
<slot name="prefix"></slot>
</span>
<slot name="prefix" part="prefix" class="input__prefix"></slot>
<input
part="input"
id="input"
@@ -460,60 +458,64 @@ export default class SlInput extends ShoelaceElement implements ShoelaceFormCont
@blur=${this.handleBlur}
/>
${hasClearIcon
? html`
<button
part="clear-button"
class="input__clear"
type="button"
aria-label=${this.localize.term('clearEntry')}
@click=${this.handleClearClick}
tabindex="-1"
>
<slot name="clear-icon">
<sl-icon name="x-circle-fill" library="system"></sl-icon>
</slot>
</button>
`
: ''}
${this.passwordToggle && !this.disabled
? html`
<button
part="password-toggle-button"
class="input__password-toggle"
type="button"
aria-label=${this.localize.term(this.passwordVisible ? 'hidePassword' : 'showPassword')}
@click=${this.handlePasswordToggle}
tabindex="-1"
>
${this.passwordVisible
? html`
<slot name="show-password-icon">
<sl-icon name="eye-slash" library="system"></sl-icon>
</slot>
`
: html`
<slot name="hide-password-icon">
<sl-icon name="eye" library="system"></sl-icon>
</slot>
`}
</button>
`
: ''}
${
hasClearIcon
? html`
<button
part="clear-button"
class="input__clear"
type="button"
aria-label=${this.localize.term('clearEntry')}
@click=${this.handleClearClick}
tabindex="-1"
>
<slot name="clear-icon">
<sl-icon name="x-circle-fill" library="system"></sl-icon>
</slot>
</button>
`
: ''
}
${
this.passwordToggle && !this.disabled
? html`
<button
part="password-toggle-button"
class="input__password-toggle"
type="button"
aria-label=${this.localize.term(this.passwordVisible ? 'hidePassword' : 'showPassword')}
@click=${this.handlePasswordToggle}
tabindex="-1"
>
${this.passwordVisible
? html`
<slot name="show-password-icon">
<sl-icon name="eye-slash" library="system"></sl-icon>
</slot>
`
: html`
<slot name="hide-password-icon">
<sl-icon name="eye" library="system"></sl-icon>
</slot>
`}
</button>
`
: ''
}
<span part="suffix" class="input__suffix">
<slot name="suffix"></slot>
</span>
<slot name="suffix" part="suffix" class="input__suffix"></slot>
</div>
</div>
<div
<slot
name="help-text"
part="form-control-help-text"
id="help-text"
class="form-control__help-text"
aria-hidden=${hasHelpText ? 'false' : 'true'}
>
<slot name="help-text">${this.helpText}</slot>
${this.helpText}
</slot>
</div>
</div>
`;

View File

@@ -33,6 +33,7 @@ export default css`
.menu-item .menu-item__label {
flex: 1 1 auto;
display: inline-block;
}
.menu-item .menu-item__prefix {
@@ -41,7 +42,7 @@ export default css`
align-items: center;
}
.menu-item .menu-item__prefix ::slotted(*) {
.menu-item .menu-item__prefix::slotted(*) {
margin-inline-end: var(--sl-spacing-x-small);
}
@@ -51,7 +52,7 @@ export default css`
align-items: center;
}
.menu-item .menu-item__suffix ::slotted(*) {
.menu-item .menu-item__suffix::slotted(*) {
margin-inline-start: var(--sl-spacing-x-small);
}

View File

@@ -96,17 +96,11 @@ export default class SlMenuItem extends ShoelaceElement {
<sl-icon name="check" library="system" aria-hidden="true"></sl-icon>
</span>
<span part="prefix" class="menu-item__prefix">
<slot name="prefix"></slot>
</span>
<slot name="prefix" part="prefix" class="menu-item__prefix"></slot>
<span part="label" class="menu-item__label">
<slot @slotchange=${this.handleDefaultSlotChange}></slot>
</span>
<slot part="label" class="menu-item__label" @slotchange=${this.handleDefaultSlotChange}></slot>
<span part="suffix" class="menu-item__suffix">
<slot name="suffix"></slot>
</span>
<slot name="suffix" part="suffix" class="menu-item__suffix"></slot>
<span class="menu-item__chevron">
<sl-icon name="chevron-right" library="system" aria-hidden="true"></sl-icon>

View File

@@ -9,6 +9,7 @@ export default css`
}
.menu-label {
display: inline-block;
font-family: var(--sl-font-sans);
font-size: var(--sl-font-size-small);
font-weight: var(--sl-font-weight-semibold);

View File

@@ -19,11 +19,7 @@ export default class SlMenuLabel extends ShoelaceElement {
static styles: CSSResultGroup = styles;
render() {
return html`
<div part="base" class="menu-label">
<slot></slot>
</div>
`;
return html` <slot part="base" class="menu-label"></slot> `;
}
}

View File

@@ -56,13 +56,7 @@ export default class SlProgressBar extends ShoelaceElement {
aria-valuenow=${this.indeterminate ? 0 : this.value}
>
<div part="indicator" class="progress-bar__indicator" style=${styleMap({ width: `${this.value}%` })}>
${!this.indeterminate
? html`
<span part="label" class="progress-bar__label">
<slot></slot>
</span>
`
: ''}
${!this.indeterminate ? html` <slot part="label" class="progress-bar__label"></slot> ` : ''}
</div>
</div>
`;

View File

@@ -72,9 +72,7 @@ export default class SlProgressRing extends ShoelaceElement {
<circle class="progress-ring__indicator" style="stroke-dashoffset: ${this.indicatorOffset}"></circle>
</svg>
<span part="label" class="progress-ring__label">
<slot></slot>
</span>
<slot part="label" class="progress-ring__label"></slot>
</div>
`;
}

View File

@@ -4,10 +4,14 @@ import buttonStyles from '../button/button.styles';
export default css`
${buttonStyles}
label {
display: inline-block;
.button__prefix,
.button__suffix,
.button__label {
display: inline-flex;
position: relative;
align-items: center;
}
/* We use a hidden input so constraint validation errors work, since they don't appear to show when used with buttons.
We can't actually hide it, though, otherwise the messages will be suppressed by the browser. */
.hidden-input {

View File

@@ -122,15 +122,9 @@ export default class SlRadioButton extends ShoelaceElement {
@focus=${this.handleFocus}
@click=${this.handleClick}
>
<span part="prefix" class="button__prefix">
<slot name="prefix"></slot>
</span>
<span part="label" class="button__label">
<slot></slot>
</span>
<span part="suffix" class="button__suffix">
<slot name="suffix"></slot>
</span>
<slot name="prefix" part="prefix" class="button__prefix"></slot>
<slot part="label" class="button__label"></slot>
<slot name="suffix" part="suffix" class="button__suffix"></slot>
</button>
</div>
`;

View File

@@ -300,14 +300,15 @@ export default class SlRadioGroup extends ShoelaceElement implements ShoelaceFor
: defaultSlot}
</div>
<div
<slot
name="help-text"
part="form-control-help-text"
id="help-text"
class="form-control__help-text"
aria-hidden=${hasHelpText ? 'false' : 'true'}
>
<slot name="help-text">${this.helpText}</slot>
</div>
${this.helpText}
</slot>
</fieldset>
`;
/* eslint-enable lit-a11y/click-events-have-key-events */

View File

@@ -95,6 +95,7 @@ export default css`
}
.radio__label {
display: inline-block;
color: var(--sl-input-label-color);
line-height: var(--sl-toggle-size);
margin-inline-start: 0.5em;

View File

@@ -99,9 +99,7 @@ export default class SlRadio extends ShoelaceElement {
${this.checked ? html` <sl-icon part="checked-icon" library="system" name="radio"></sl-icon> ` : ''}
</span>
<span part="label" class="radio__label">
<slot></slot>
</span>
<slot part="label" class="radio__label"></slot>
</span>
`;
}

View File

@@ -310,14 +310,15 @@ export default class SlRange extends ShoelaceElement implements ShoelaceFormCont
</div>
</div>
<div
<slot
name="help-text"
part="form-control-help-text"
id="help-text"
class="form-control__help-text"
aria-hidden=${hasHelpText ? 'false' : 'true'}
>
<slot name="help-text">${this.helpText}</slot>
</div>
${this.helpText}
</slot>
</div>
`;
}

View File

@@ -196,7 +196,7 @@ export default css`
min-height: var(--sl-input-height-small);
}
.select--small .select__prefix ::slotted(*) {
.select--small .select__prefix::slotted(*) {
margin-inline-start: var(--sl-input-spacing-small);
}
@@ -208,7 +208,7 @@ export default css`
margin-inline-end: var(--sl-input-spacing-small);
}
.select--small .select__suffix ::slotted(*) {
.select--small .select__suffix::slotted(*) {
margin-inline-end: var(--sl-input-spacing-small);
}
@@ -239,7 +239,7 @@ export default css`
min-height: var(--sl-input-height-medium);
}
.select--medium .select__prefix ::slotted(*) {
.select--medium .select__prefix::slotted(*) {
margin-inline-start: var(--sl-input-spacing-medium);
}
@@ -251,7 +251,7 @@ export default css`
margin-inline-end: var(--sl-input-spacing-medium);
}
.select--medium .select__suffix ::slotted(*) {
.select--medium .select__suffix::slotted(*) {
margin-inline-end: var(--sl-input-spacing-medium);
}
@@ -282,7 +282,7 @@ export default css`
min-height: var(--sl-input-height-large);
}
.select--large .select__prefix ::slotted(*) {
.select--large .select__prefix::slotted(*) {
margin-inline-start: var(--sl-input-spacing-large);
}
@@ -294,7 +294,7 @@ export default css`
margin-inline-end: var(--sl-input-spacing-large);
}
.select--large .select__suffix ::slotted(*) {
.select--large .select__suffix::slotted(*) {
margin-inline-end: var(--sl-input-spacing-large);
}

View File

@@ -533,9 +533,7 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon
@focus=${this.handleFocus}
@keydown=${this.handleKeyDown}
>
<span part="prefix" class="select__prefix">
<slot name="prefix"></slot>
</span>
<slot name="prefix" part="prefix" class="select__prefix"></slot>
<div part="display-label" class="select__label">
${this.displayTags.length > 0
@@ -561,9 +559,7 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon
`
: ''}
<span part="suffix" class="select__suffix">
<slot name="suffix"></slot>
</span>
<slot name="suffix" part="suffix" class="select__suffix"></slot>
<span part="icon" class="select__icon" aria-hidden="true">
<sl-icon name="chevron-down" library="system"></sl-icon>
@@ -588,14 +584,15 @@ export default class SlSelect extends ShoelaceElement implements ShoelaceFormCon
</sl-dropdown>
</div>
<div
<slot
name="help-text"
part="form-control-help-text"
id="help-text"
class="form-control__help-text"
aria-hidden=${hasHelpText ? 'false' : 'true'}
>
<slot name="help-text">${this.helpText}</slot>
</div>
${this.helpText}
</slot>
</div>
`;
}

View File

@@ -24,7 +24,7 @@ import type { CSSResultGroup } from 'lit';
*
* @slot start - The start panel.
* @slot end - The end panel.
* @slot handle - An optional handle to render at the center of the divider.
* @slot divider - The divider. Useful for slotting in a custom icon that renders as a handle in the divider.
*
* @cssproperty [--divider-width=4px] - The width of the visible divider.
* @cssproperty [--divider-hit-area=12px] - The invisible region around the divider where dragging can occur. This is
@@ -249,11 +249,10 @@ export default class SlSplitPanel extends ShoelaceElement {
this.style[gridTemplateAlt] = '';
return html`
<div part="panel start" class="start">
<slot name="start"></slot>
</div>
<slot name="start" part="panel start" class="start"></slot>
<div
<slot
name="divider"
part="divider"
class="divider"
tabindex=${ifDefined(this.disabled ? undefined : '0')}
@@ -262,13 +261,9 @@ export default class SlSplitPanel extends ShoelaceElement {
@keydown=${this.handleKeyDown}
@mousedown=${this.handleDrag}
@touchstart=${this.handleDrag}
>
<slot name="handle"></slot>
</div>
></slot>
<div part="panel end" class="end">
<slot name="end"></slot>
</div>
<slot name="end" part="panel end" class="end"></slot>
`;
}
}

View File

@@ -123,6 +123,7 @@ export default css`
}
.switch__label {
display: inline-block;
line-height: var(--height);
margin-inline-start: 0.5em;
user-select: none;

View File

@@ -176,9 +176,7 @@ export default class SlSwitch extends ShoelaceElement implements ShoelaceFormCon
<span part="thumb" class="switch__thumb"></span>
</span>
<span part="label" class="switch__label">
<slot></slot>
</span>
<slot part="label" class="switch__label"></slot>
</label>
`;
}

View File

@@ -33,6 +33,7 @@ export default css`
}
.tab-group__body {
display: block;
overflow: auto;
}

View File

@@ -45,7 +45,7 @@ export default class SlTabGroup extends ShoelaceElement {
private readonly localize = new LocalizeController(this);
@query('.tab-group') tabGroup: HTMLElement;
@query('.tab-group__body') body: HTMLElement;
@query('.tab-group__body') body: HTMLSlotElement;
@query('.tab-group__nav') nav: HTMLElement;
@query('.tab-group__indicator') indicator: HTMLElement;
@@ -131,8 +131,7 @@ export default class SlTabGroup extends ShoelaceElement {
}
getAllPanels() {
const slot = this.body.querySelector('slot')!;
return [...slot.assignedElements()].filter(el => el.tagName.toLowerCase() === 'sl-tab-panel') as [SlTabPanel];
return [...this.body.assignedElements()].filter(el => el.tagName.toLowerCase() === 'sl-tab-panel') as [SlTabPanel];
}
getActiveTab() {
@@ -405,9 +404,7 @@ export default class SlTabGroup extends ShoelaceElement {
: ''}
</div>
<div part="body" class="tab-group__body">
<slot @slotchange=${this.syncTabsAndPanels}></slot>
</div>
<slot part="body" class="tab-group__body" @slotchange=${this.syncTabsAndPanels}></slot>
</div>
`;
}

View File

@@ -11,6 +11,7 @@ export default css`
}
.tab-panel {
display: block;
padding: var(--padding);
}

View File

@@ -45,15 +45,13 @@ export default class SlTabPanel extends ShoelaceElement {
render() {
return html`
<div
<slot
part="base"
class=${classMap({
'tab-panel': true,
'tab-panel--active': this.active
})}
>
<slot></slot>
</div>
></slot>
`;
}
}

View File

@@ -70,9 +70,7 @@ export default class SlTag extends ShoelaceElement {
'tag--removable': this.removable
})}
>
<span part="content" class="tag__content">
<slot></slot>
</span>
<slot part="content" class="tag__content"></slot>
${this.removable
? html`

View File

@@ -336,14 +336,15 @@ export default class SlTextarea extends ShoelaceElement implements ShoelaceFormC
</div>
</div>
<div
<slot
name="help-text"
part="form-control-help-text"
id="help-text"
class="form-control__help-text"
aria-hidden=${hasHelpText ? 'false' : 'true'}
>
<slot name="help-text">${this.helpText}</slot>
</div>
${this.helpText}
</slot>
</div>
`;
}

View File

@@ -39,6 +39,7 @@ export default css`
}
.tooltip__body {
display: block;
width: max-content;
max-width: var(--max-width);
border-radius: var(--sl-tooltip-border-radius);

View File

@@ -292,9 +292,16 @@ export default class SlTooltip extends ShoelaceElement {
>
<slot slot="anchor" aria-describedby="tooltip"></slot>
<div part="body" id="tooltip" class="tooltip__body" role="tooltip" aria-hidden=${this.open ? 'false' : 'true'}>
<slot name="content" aria-live=${this.open ? 'polite' : 'off'}> ${this.content} </slot>
</div>
<slot
name="content"
part="body"
id="tooltip"
class="tooltip__body"
role="tooltip"
aria-live=${this.open ? 'polite' : 'off'}
>
${this.content}
</slot>
</sl-popup>
`;
}

View File

@@ -125,6 +125,7 @@ export default css`
}
.tree-item__children {
display: block;
font-size: calc(1em + var(--indent-size, var(--sl-spacing-medium)));
}

View File

@@ -264,22 +264,20 @@ export default class SlTreeItem extends ShoelaceElement {
?checked="${live(this.selected)}"
?indeterminate="${this.indeterminate}"
>
<div class="tree-item__label" part="label">
<slot></slot>
</div>
<slot class="tree-item__label" part="label"></slot>
</sl-checkbox>
`,
() => html`
<div class="tree-item__label" part="label">
<slot></slot>
</div>
`
() => html` <slot class="tree-item__label" part="label"></slot> `
)}
</div>
<div class="tree-item__children" part="children" role="group">
<slot name="children" @slotchange="${this.handleChildrenSlotChange}"></slot>
</div>
<slot
name="children"
class="tree-item__children"
part="children"
role="group"
@slotchange="${this.handleChildrenSlotChange}"
></slot>
</div>
`;
}

View File

@@ -38,9 +38,6 @@ export default css`
.form-control--has-help-text .form-control__help-text {
display: block;
color: var(--sl-input-help-text-color);
}
.form-control--has-help-text .form-control__help-text ::slotted(*) {
margin-top: var(--sl-spacing-3x-small);
}