Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,6 @@ export abstract class IllustratedMessageBase extends SpectrumElement {
// IMPLEMENTATION
// ──────────────────────

protected override firstUpdated(changedProperties: PropertyValues): void {
super.firstUpdated(changedProperties);
const headingSlot = this.shadowRoot?.querySelector<HTMLSlotElement>(
'slot[name="heading"]'
);
if (headingSlot) {
headingSlot.addEventListener('slotchange', () =>
this.warnInvalidHeadingSlot(headingSlot)
);
this.warnInvalidHeadingSlot(headingSlot);
}
}

protected override updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (window.__swc?.DEBUG) {
Expand Down Expand Up @@ -114,18 +101,26 @@ export abstract class IllustratedMessageBase extends SpectrumElement {
}
}

private warnInvalidHeadingSlot(headingSlot: HTMLSlotElement): void {
if (!window.__swc?.DEBUG) {
return;
}
for (const el of headingSlot.assignedElements()) {
if (!['H2', 'H3', 'H4', 'H5', 'H6'].includes(el.tagName)) {
window.__swc?.warn(
this,
`<${this.localName}> heading slot received a <${el.tagName.toLowerCase()}> element. Only <h2>–<h6> elements are allowed in the heading slot.`,
'https://opensource.adobe.com/spectrum-web-components/components/illustrated-message/',
{ issues: [`heading slot: <${el.tagName.toLowerCase()}>`] }
);
/**
* Validates that the heading slot only contains `<h2>`–`<h6>` elements.
* Rendering subclasses must wire this to the heading slot's `slotchange`
* event (e.g. `<slot name="heading" @slotchange=${this.handleHeadingSlotChange}>`)
* for the validation warning to fire.
*
* @internal
*/
protected handleHeadingSlotChange(event: Event): void {
if (window.__swc?.DEBUG) {
const headingSlot = event.target as HTMLSlotElement;
for (const el of headingSlot.assignedElements()) {
if (!['H2', 'H3', 'H4', 'H5', 'H6'].includes(el.tagName)) {
window.__swc.warn(
this,
`<${this.localName}> heading slot received a <${el.tagName.toLowerCase()}> element. Only <h2>–<h6> elements are allowed in the heading slot.`,
'https://opensource.adobe.com/spectrum-web-components/components/illustrated-message/',
{ issues: [`heading slot: <${el.tagName.toLowerCase()}>`] }
);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class IllustratedMessage extends IllustratedMessageBase {
<slot></slot>
</div>
<div class="swc-IllustratedMessage-content">
<slot name="heading"></slot>
<slot name="heading" @slotchange=${this.handleHeadingSlotChange}></slot>
<div class="swc-IllustratedMessage-description">
<slot name="description"></slot>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
* governing permissions and limitations under the License.
*/

/* @todo SWC-1838 — replace with full S2 token-based styles */

:host {
display: block;
}
Expand All @@ -21,61 +19,133 @@
}

.swc-IllustratedMessage {
--_swc-illustrated-message-illustration-to-content: var(--swc-illustrated-message-illustration-to-content, token("spacing-200"));

display: flex;
flex-direction: column;
gap: var(--_swc-illustrated-message-illustration-to-content);
align-items: center;
text-align: center;
max-inline-size: var(--swc-illustrated-message-max-inline-size, token("illustrated-message-vertical-maximum-width"));
margin-inline: auto;
}

.swc-IllustratedMessage-illustration {
--_swc-illustrated-message-illustration-size: var(--swc-illustrated-message-illustration-size, 96px);

display: flex;
align-items: center;
flex-shrink: 0;
justify-content: center;
inline-size: var(--swc-illustrated-message-illustration-inline-size, var(--_swc-illustrated-message-illustration-size));
block-size: var(--swc-illustrated-message-illustration-block-size, var(--_swc-illustrated-message-illustration-size));
color: var(--swc-illustrated-message-illustration-color, token("neutral-content-color-default"));
}

.swc-IllustratedMessage-content {
display: flex;
flex-direction: column;
align-items: center;
gap: token("spacing-75");
text-align: center;
}

.swc-IllustratedMessage-description {
font-size: var(--swc-illustrated-message-description-font-size, token("illustrated-message-medium-body-font-size"));
font-weight: token("regular-font-weight");
line-height: var(--swc-illustrated-message-description-line-height, token("body-line-height"));
color: token("body-color");
}

/* @todo SWC-1838 — heading typography (size, weight, line-height, color) */
/* ── Size: small ─────────────────────────────────────────────────────────── */

/*
* Reset native heading styles (font-size, font-weight, margin) so component tokens can take over.
* The :not([class]) guard leaves intentionally-classed headings untouched.
*/
::slotted(h2:not([class])),
::slotted(h3:not([class])),
::slotted(h4:not([class])),
::slotted(h5:not([class])),
::slotted(h6:not([class])) {
margin: 0;
font: inherit;
:host([size="s"]) {
--swc-illustrated-message-illustration-size: 96px;
--swc-illustrated-message-illustration-to-content: token("spacing-200");
--swc-illustrated-message-heading-font-size: token("illustrated-message-small-title-font-size");
--swc-illustrated-message-description-font-size: token("illustrated-message-small-body-font-size");
}

/* @todo SWC-1838 — description typography (size, weight, line-height, color) */
/* ── Size: large ─────────────────────────────────────────────────────────── */

/* ── Size ───────────────────────────────────────────────────────────────── */
:host([size="l"]) {
--swc-illustrated-message-illustration-size: 160px;
--swc-illustrated-message-illustration-to-content: token("spacing-100");
--swc-illustrated-message-heading-font-size: token("illustrated-message-large-title-font-size");
--swc-illustrated-message-description-font-size: token("illustrated-message-large-body-font-size");
}

/* ── CJK language support ────────────────────────────────────────────────── */

/* @todo SWC-1838 — replace with full S2 token-based size values */
:host(:lang(ja)),
:host(:lang(ko)),
:host(:lang(zh)) {
--swc-illustrated-message-heading-font-size: token("illustrated-message-medium-cjk-title-font-size");
--swc-illustrated-message-heading-line-height: token("cjk-line-height-100");
--swc-illustrated-message-description-line-height: token("cjk-line-height-200");
}

:host([size="s"]) .swc-IllustratedMessage-illustration {
/* @todo SWC-1838 */
:host([size="s"]:lang(ja)),
:host([size="s"]:lang(ko)),
:host([size="s"]:lang(zh)) {
--swc-illustrated-message-heading-font-size: token("illustrated-message-small-cjk-title-font-size");
}

:host([size="l"]) .swc-IllustratedMessage-illustration {
/* @todo SWC-1838 */
:host([size="l"]:lang(ja)),
:host([size="l"]:lang(ko)),
:host([size="l"]:lang(zh)) {
--swc-illustrated-message-heading-font-size: token("illustrated-message-large-cjk-title-font-size");
}

/* ── Orientation ─────────────────────────────────────────────────────────── */
/* ── Orientation: horizontal ─────────────────────────────────────────────── */

/* @todo SWC-1838 — replace with full S2 token-based orientation values */
:host([orientation="horizontal"]) {
--swc-illustrated-message-max-inline-size: token("illustrated-message-horizontal-maximum-width");
}

:host([orientation="horizontal"]) .swc-IllustratedMessage {
/* @todo SWC-1838 */
flex-direction: row;
align-items: center;
}

:host([orientation="horizontal"]) .swc-IllustratedMessage-content {
/* @todo SWC-1838 */
align-items: flex-start;
text-align: start;
}

/* ── Slotted content ─────────────────────────────────────────────────────── */

/*
* Heading styles live on the slot element itself. Slotted elements inherit
* from their assigned slot per the spec, so these properties flow into the
* heading without needing ::slotted() for each individual property.
*/
slot[name="heading"] {
font-size: var(--swc-illustrated-message-heading-font-size, token("illustrated-message-medium-title-font-size"));
font-style: token("title-sans-serif-font-style");
font-weight: token("title-sans-serif-font-weight");
line-height: var(--swc-illustrated-message-heading-line-height, token("title-line-height"));
color: token("heading-color");
}

/*
* Direct slotted headings to inherit from the slot element.
* The :not([class]) guard leaves intentionally-classed headings untouched.
* !important is required to win over any light DOM styles targeting
* the slotted heading (e.g. global h2 resets from the host document).
*/
::slotted([slot="heading"]:not([class])) {
margin: 0 !important;
font: inherit !important;
/* stylelint-disable-next-line scale-unlimited/declaration-strict-value */
color: inherit !important;
}

/*
* Ensure slotted SVG illustrations fill the illustration container
* and use the component illustration color via currentcolor.
*/
::slotted(svg) {
display: block;
inline-size: 100%;
block-size: 100%;
fill: currentcolor;
stroke: currentcolor;
}
Loading
Loading