Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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
11 changes: 11 additions & 0 deletions 1st-gen/packages/illustrated-message/src/IllustratedMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ export class IllustratedMessage extends SpectrumElement {
return [headingStyles, bodyStyles, messageStyles];
}

protected override firstUpdated(): void {
if (window.__swc?.DEBUG) {
window.__swc.warn(
this,
`<${this.localName}> has been deprecated and will be removed from the project in an upcoming version. Learn more about Spectrum 2 (https://s2.spectrum.adobe.com/) as an alternative.`,
'https://s2.spectrum.adobe.com/',
{ level: 'deprecation' }
);
}
}

@property()
public heading = '';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,54 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import { expect, fixture, html } from '@open-wc/testing';
import { elementUpdated, expect, fixture, html } from '@open-wc/testing';
import { stub } from 'sinon';

import '@spectrum-web-components/illustrated-message/sp-illustrated-message.js';

import { IllustratedMessage } from '../';

describe('Illustrated Message', () => {
describe('dev mode', () => {
let consoleWarnStub!: ReturnType<typeof stub>;
before(() => {
window.__swc.verbose = true;
consoleWarnStub = stub(console, 'warn');
});
afterEach(() => {
consoleWarnStub.resetHistory();
});
after(() => {
window.__swc.verbose = false;
consoleWarnStub.restore();
});
it('warns of deprecation', async () => {
const el = document.createElement('sp-illustrated-message');
document.body.append(el);

await elementUpdated(el);

expect(consoleWarnStub.called).to.be.true;
const spyCall = consoleWarnStub.getCall(0);
expect(
spyCall.args[0].includes('deprecated'),
'confirm deprecation message'
).to.be.true;
expect(
spyCall.args[spyCall.args.length - 1],
'confirm `data` shape'
).to.deep.equal({
data: {
localName: 'sp-illustrated-message',
type: 'api',
level: 'deprecation',
},
});

el.remove();
});
});

it('loads', async () => {
const el = await fixture<IllustratedMessage>(html`
<sp-illustrated-message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ import { property } from 'lit/decorators.js';
import { SpectrumElement } from '@spectrum-web-components/core/element/index.js';

import {
ILLUSTRATED_MESSAGE_VALID_HEADING_LEVELS,
ILLUSTRATED_MESSAGE_VALID_ORIENTATIONS,
ILLUSTRATED_MESSAGE_VALID_SIZES,
type IllustratedMessageHeadingLevel,
type IllustratedMessageOrientation,
type IllustratedMessageSize,
} from './IllustratedMessage.types.js';
Expand All @@ -30,8 +28,10 @@ import {
*
* @slot - Decorative or informative SVG illustration. Decorative SVGs should include
* `aria-hidden="true"`; informative SVGs should include `role="img"` and `aria-label`.
* @slot heading - Heading text. Must be a single `<span>` element — the shadow DOM owns the
* heading tag and level. Consumers who previously slotted an `<h2>` must switch to `<span>`.
* @slot heading - The heading element. Must be an `<h2>`–`<h6>` element. The consumer owns
* the heading tag and level.
* @todo SWC-1943 Add slot constraints once the CEM slot constraints work is complete:
* `{required} {allowedChildren: h2, h3, h4, h5, h6} {maxChildren: 1}`
* @slot description - Description text. Links must be real `<a>` elements or link components
* with visible names.
*/
Expand All @@ -40,12 +40,6 @@ export abstract class IllustratedMessageBase extends SpectrumElement {
// API TO OVERRIDE
// ─────────────────────────

/**
* @internal
*/
static readonly VALID_HEADING_LEVELS: readonly IllustratedMessageHeadingLevel[] =
ILLUSTRATED_MESSAGE_VALID_HEADING_LEVELS;

/**
* @internal
*/
Expand All @@ -62,12 +56,6 @@ export abstract class IllustratedMessageBase extends SpectrumElement {
// SHARED API
// ──────────────────

/**
* The heading level of the illustrated message title. Accepts 2–6.
*/
@property({ type: Number, reflect: true, attribute: 'heading-level' })
public headingLevel: IllustratedMessageHeadingLevel = 2;

/**
* The size of the illustrated message.
*/
Expand All @@ -84,15 +72,6 @@ export abstract class IllustratedMessageBase extends SpectrumElement {
// IMPLEMENTATION
// ──────────────────────

/**
* Returns a valid heading level clamped to 2–6.
*
* @internal
*/
protected getHeadingLevel(): number {
return Math.max(2, Math.min(6, this.headingLevel));
}

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

if (
changedProperties.has('headingLevel') &&
(this.headingLevel < 2 || this.headingLevel > 6)
) {
window.__swc.warn(
this,
`<${this.localName}> received an invalid "heading-level" value of "${this.headingLevel}". Valid values are 2–6. The value has been clamped to ${this.getHeadingLevel()}.`,
'https://opensource.adobe.com/spectrum-web-components/components/illustrated-message/',
{ issues: [`heading-level="${this.headingLevel}"`] }
);
}

const headingSlot = this.shadowRoot?.querySelector<HTMLSlotElement>(
'slot[name="heading"]'
);
const assigned = headingSlot?.assignedElements() ?? [];
if (assigned.length > 0 && assigned[0].tagName.toLowerCase() !== 'span') {
window.__swc.warn(
this,
`<${this.localName}> expects the "heading" slot to contain a single <span> element. The shadow DOM owns the heading tag. Received: <${assigned[0].tagName.toLowerCase()}>.`,
'https://opensource.adobe.com/spectrum-web-components/components/illustrated-message/',
{ issues: [`heading slot: <${assigned[0].tagName.toLowerCase()}>`] }
);
if (headingSlot) {
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 @@ -12,10 +12,6 @@

import type { ElementSize } from '@spectrum-web-components/core/mixins/index.js';

export const ILLUSTRATED_MESSAGE_VALID_HEADING_LEVELS = [
2, 3, 4, 5, 6,
] as const satisfies readonly number[];

export const ILLUSTRATED_MESSAGE_VALID_SIZES = [
's',
'm',
Expand All @@ -27,9 +23,6 @@ export const ILLUSTRATED_MESSAGE_VALID_ORIENTATIONS = [
'horizontal',
] as const satisfies readonly string[];

export type IllustratedMessageHeadingLevel =
(typeof ILLUSTRATED_MESSAGE_VALID_HEADING_LEVELS)[number];

export type IllustratedMessageSize =
(typeof ILLUSTRATED_MESSAGE_VALID_SIZES)[number];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ import styles from './illustrated-message.css';

/**
* @element swc-illustrated-message
* @status preview
* @status unsupported
* @since 0.0.1
*
* @example
* <swc-illustrated-message>
* <svg slot="" aria-hidden="true" viewBox="0 0 200 160"><!-- illustration --></svg>
* <span slot="heading">Create your first asset.</span>
* <h2 slot="heading">Create your first asset.</h2>
* <span slot="description">Get started by uploading or importing some assets.</span>
* </swc-illustrated-message>
*
* @example
* <swc-illustrated-message heading-level="3">
* <swc-illustrated-message>
* <svg slot="" aria-hidden="true" viewBox="0 0 200 160"><!-- illustration --></svg>
* <span slot="heading">No results found.</span>
* <h3 slot="heading">No results found.</h3>
* <span slot="description">Try adjusting your search or filters.</span>
* </swc-illustrated-message>
*/
Expand All @@ -45,35 +45,13 @@ export class IllustratedMessage extends IllustratedMessageBase {
}

protected override render(): TemplateResult {
const level = this.getHeadingLevel();
const headingClass = 'swc-IllustratedMessage-heading';
const heading = html`<slot name="heading"></slot>`;

return html`
<div class="swc-IllustratedMessage">
<div class="swc-IllustratedMessage-illustration">
<slot></slot>
</div>
<div class="swc-IllustratedMessage-content">
${level === 2
? html`
<h2 class=${headingClass}>${heading}</h2>
`
: level === 3
? html`
<h3 class=${headingClass}>${heading}</h3>
`
: level === 4
? html`
<h4 class=${headingClass}>${heading}</h4>
`
: level === 5
? html`
<h5 class=${headingClass}>${heading}</h5>
`
: html`
<h6 class=${headingClass}>${heading}</h6>
`}
<slot name="heading"></slot>
<div class="swc-IllustratedMessage-description">
<slot name="description"></slot>
</div>
Expand Down
Loading
Loading