Skip to content

Commit

Permalink
feat: delivery dev mode messages in various packages
Browse files Browse the repository at this point in the history
  • Loading branch information
Westbrook committed Aug 4, 2022
1 parent 942f77b commit 62370a1
Show file tree
Hide file tree
Showing 21 changed files with 546 additions and 59 deletions.
12 changes: 12 additions & 0 deletions packages/badge/src/Badge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ export class Badge extends SizedMixin(ObserveSlotText(SpectrumElement, '')) {
public variant: BadgeVariant = 'informative';

protected override render(): TemplateResult {
if (window.__swc.DEBUG) {
if (!BADGE_VARIANTS.includes(this.variant)) {
window.__swc.warn(
this,
`<${this.localName}> element expect the "variant" attribute to be one of the following:`,
'https://opensource.adobe.com/spectrum-web-components/components/badge/#variants',
{
issues: [...BADGE_VARIANTS]
},
);
}
}
return html`
<slot name="icon" ?icon-only=${!this.slotHasContent}></slot>
<div id="label">
Expand Down
34 changes: 34 additions & 0 deletions packages/badge/test/badge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { elementUpdated, expect, fixture, html } from '@open-wc/testing';

import '@spectrum-web-components/badge/sp-badge.js';
import '@spectrum-web-components/icons-workflow/icons/sp-icon-checkmark-circle.js';
import { stub } from 'sinon';
import { Badge } from '../src/Badge.js';
import { testForLitDevWarnings } from '../../../test/testing-helpers.js';

Expand All @@ -32,6 +33,7 @@ describe('Badge', () => {
)
);
it('loads default badge accessibly', async () => {
const consoleWarnStub = stub(console, 'warn');
const el = await fixture<Badge>(
html`
<sp-badge>
Expand All @@ -46,5 +48,37 @@ describe('Badge', () => {
await elementUpdated(el);

await expect(el).to.be.accessible();
expect(consoleWarnStub.called).to.be.false;
consoleWarnStub.restore();
});
it('warns in Dev Mode when sent an incorrect `variant`', async () => {
const consoleWarnStub = stub(console, 'warn');
const el = await fixture<Badge>(
html`
<sp-badge variant="other">
<sp-icon-checkmark-circle
slot="icon"
></sp-icon-checkmark-circle>
Icon and label
</sp-badge>
`
);

await elementUpdated(el);

expect(consoleWarnStub.called).to.be.true;
const spyCall = consoleWarnStub.getCall(0);
expect(
spyCall.args.at(0).includes('"variant"'),
'confirm variant-centric message'
).to.be.true;
expect(spyCall.args.at(-1), 'confirm `data` shape').to.deep.equal({
data: {
localName: 'sp-badge',
type: 'api',
level: 'default',
},
});
consoleWarnStub.restore();
});
});
49 changes: 49 additions & 0 deletions packages/base/src/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,52 @@ export function SpectrumMixin<T extends Constructor<ReactiveElement>>(
}

export class SpectrumElement extends SpectrumMixin(LitElement) {}

if (window.__swc.DEBUG) {
window.__swc = {
...window.__swc,
issuedWarnings: new Set(),
warn: (element, message, url, { type = 'api', level = 'default', issues } = {}): void => {
const { localName = 'base' } = element || {};
const id = `${localName}:${type}:${level}` as BrandedSWCWarningID;
if (!window.__swc.verbose && window.__swc.issuedWarnings.has(id))
return;
window.__swc.issuedWarnings.add(id);
if (window.__swc.ignoreWarningLocalNames?.[localName]) return;
if (window.__swc.ignoreWarningTypes?.[type]) return;
if (window.__swc.ignoreWarningLevels?.[level]) return;
let listedIssues = '';
if (issues && issues.length) {
issues.unshift('');
listedIssues = issues.join('\n - ') + '\n';
}
const intro = level === 'deprecation' ? 'DEPRECATION NOTICE: ' : '';
const inspectElement = element
? '\nInspect this issue in the follow element:'
: '';
const displayURL = (element ? '\n\n' : '\n') + url + '\n';
const messages: unknown[] = [];
messages.push(
intro + message + '\n' + listedIssues + inspectElement
);
if (element) {
messages.push(element);
}
messages.push(displayURL, {
data: {
localName,
type,
level,
}
});
console.warn(...messages);
},
};

window.__swc.warn(
undefined,
'Spectrum Web Components is in dev mode. Not recommended for production!',
'https://opensource.adobe.com/spectrum-web-components/dev-mode/',
{ type: 'default' },
);
}
37 changes: 37 additions & 0 deletions packages/base/test/base-devmode.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { expect } from '@open-wc/testing';
import { stub } from 'sinon';

describe('Base', () => {
it('warns in Dev Mode when no attributes', async () => {
const consoleWarnStub = stub(console, 'warn');
const { SpectrumElement } = await import(
'@spectrum-web-components/base'
);
expect(SpectrumElement).to.not.be.undefined;

expect(consoleWarnStub.called).to.be.true;
const spyCall = consoleWarnStub.getCall(0);
expect(
spyCall.args.at(0).includes('dev mode'),
'confirm "dev mode"-centric message'
).to.be.true;
expect(spyCall.args.at(-1), 'confirm `data` shape').to.deep.equal({
data: {
localName: 'base',
type: 'default',
level: 'default',
},
});
consoleWarnStub.restore();
});
});
1 change: 1 addition & 0 deletions packages/card/sp-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/

import { Card } from './src/Card.js';

customElements.define('sp-card', Card);
Expand Down
4 changes: 2 additions & 2 deletions packages/menu/src/Menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import {
query,
} from '@spectrum-web-components/base/src/decorators.js';

import {
MenuItem,
import { MenuItem } from './MenuItem.js';
import type {
MenuItemAddedOrUpdatedEvent,
MenuItemRemovedEvent,
} from './MenuItem.js';
Expand Down
4 changes: 3 additions & 1 deletion packages/overlay/src/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const openOverlay = async (
content: HTMLElement,
options: OverlayOptions
): Promise<() => void> => {
const { Overlay } = await import('./overlay.js');
const { Overlay } = await import(
'@spectrum-web-components/overlay/src/overlay.js'
);
return Overlay.open(target, interaction, content, options);
};
21 changes: 13 additions & 8 deletions packages/picker/src/Picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,27 +278,21 @@ export class PickerBase extends SizedMixin(Focusable) {

private popoverFragment!: DocumentFragment;

private async generatePopover(deprecatedMenu: Menu | null): Promise<void> {
private async generatePopover(): Promise<void> {
if (!this.popoverFragment) {
this.popoverFragment = document.createDocumentFragment();
}
render(this.renderPopover, this.popoverFragment, { host: this });
this.popover = this.popoverFragment.children[0] as Popover;
this.optionsMenu = this.popover.children[1] as Menu;

if (deprecatedMenu) {
console.warn(
`Deprecation Notice: You no longer need to provide an sp-menu child to ${this.tagName.toLowerCase()}. Any styling or attributes on the sp-menu will be ignored.`
);
}
}

private async openMenu(): Promise<void> {
/* c8 ignore next 9 */
let reparentableChildren: Element[] = [];
const deprecatedMenu = this.querySelector(':scope > sp-menu') as Menu;

await this.generatePopover(deprecatedMenu);
await this.generatePopover();
if (deprecatedMenu) {
reparentableChildren = Array.from(deprecatedMenu.children);
} else {
Expand Down Expand Up @@ -457,6 +451,17 @@ export class PickerBase extends SizedMixin(Focusable) {
if (changes.has('value') && !changes.has('selectedItem')) {
this.updateMenuItems();
}
if (window.__swc.DEBUG) {
if (!this.hasUpdated && this.querySelector('sp-menu')) {
const { localName } = this;
window.__swc.warn(
this,
`You no longer need to provide an <sp-menu> child to ${localName}. Any styling or attributes on the <sp-menu> will be ignored.`,
'https://opensource.adobe.com/spectrum-web-components/components/picker/#sizes',
{ level: 'deprecation' },
);
}
}
super.update(changes);
}

Expand Down
99 changes: 70 additions & 29 deletions packages/picker/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ OF ANY KIND, either express or implied. See the License for the specific languag
governing permissions and limitations under the License.
*/

import type { Picker } from '..';
import type { Picker } from '@spectrum-web-components/picker';

import type { OverlayOpenCloseDetail } from '@spectrum-web-components/overlay';
import type { MenuItem } from '@spectrum-web-components/menu';
Expand All @@ -24,7 +24,7 @@ import {
waitUntil,
} from '@open-wc/testing';
import '@spectrum-web-components/shared/src/focus-visible.js';
import { spy } from 'sinon';
import { spy, stub } from 'sinon';
import {
arrowDownEvent,
arrowLeftEvent,
Expand Down Expand Up @@ -1047,38 +1047,79 @@ export function runPickerTests(): void {

return test.querySelector('sp-picker') as Picker;
};
beforeEach(async () => {
el = await pickerFixture();
await elementUpdated(el);
});
afterEach(async () => {
if (el.open) {
const closed = oneEvent(el, 'sp-closed');
el.open = false;
await closed;
}
describe('Dev mode', () => {
it('warns in Dev Mode of deprecated `<sp-menu>` usage', async () => {
const consoleWarnStub = stub(console, 'warn');
el = await pickerFixture();
await elementUpdated(el);

expect(consoleWarnStub.called).to.be.true;
const spyCall = consoleWarnStub.getCall(0);
expect(
spyCall.args.at(0).includes('<sp-menu>'),
'confirm <sp-menu>-centric message'
).to.be.true;
expect(
spyCall.args.at(-1),
'confirm `data` shape'
).to.deep.equal({
data: {
localName: 'sp-picker',
type: 'api',
level: 'deprecation',
},
});
consoleWarnStub.restore();
if (el.open) {
const closed = oneEvent(el, 'sp-closed');
el.open = false;
await closed;
}
});
});
it('selects with deprecated syntax', async () => {
const secondItem = el.querySelector(
'sp-menu-item:nth-of-type(2)'
) as MenuItem;
describe('Dev mode ignored', () => {
const { ignoreWarningLocalNames } = window.__swc;
before(() => {
window.__swc.ignoreWarningLocalNames = {
'sp-picker': true,
};
});
before(() => {
window.__swc.ignoreWarningLocalNames = ignoreWarningLocalNames;
});
beforeEach(async () => {
el = await pickerFixture();
await elementUpdated(el);
});
afterEach(async () => {
if (el.open) {
const closed = oneEvent(el, 'sp-closed');
el.open = false;
await closed;
}
});
it('selects with deprecated syntax', async () => {
const secondItem = el.querySelector(
'sp-menu-item:nth-of-type(2)'
) as MenuItem;

const opened = oneEvent(el, 'sp-opened');
el.button.click();
await opened;
await elementUpdated(el);
const opened = oneEvent(el, 'sp-opened');
el.button.click();
await opened;
await elementUpdated(el);

expect(el.open).to.be.true;
expect(el.selectedItem?.itemText).to.be.undefined;
expect(el.value).to.equal('');
expect(el.open).to.be.true;
expect(el.selectedItem?.itemText).to.be.undefined;
expect(el.value).to.equal('');

const closed = oneEvent(el, 'sp-closed');
secondItem.click();
await closed;
const closed = oneEvent(el, 'sp-closed');
secondItem.click();
await closed;

expect(el.open).to.be.false;
expect(el.selectedItem?.itemText).to.equal('Select Inverse');
expect(el.value).to.equal('option-2');
expect(el.open).to.be.false;
expect(el.selectedItem?.itemText).to.equal('Select Inverse');
expect(el.value).to.equal('option-2');
});
});
});
testForLitDevWarnings(async () => await pickerFixture());
Expand Down
22 changes: 22 additions & 0 deletions packages/progress-bar/src/ProgressBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,27 @@ export class ProgressBar extends SizedMixin(SpectrumElement) {
if (this.label && changes.has('label')) {
this.setAttribute('aria-label', this.label);
}

if (window.__swc.DEBUG) {
if (
!this.label &&
!this.getAttribute('aria-label') &&
!this.getAttribute('aria-labelledby')
) {
window.__swc.warn(
this,
'<sp-progress-bar> elements will not be accessible to screen readers without one of the following:',
'https://opensource.adobe.com/spectrum-web-components/components/progress-bar/#accessibility',
{
type: 'accessibility',
issues: [
'value supplied to the "label" attribute, which will be displayed visually as part of the element, or',
'value supplied to the "aria-label" attribute, which will only be provided to screen readers, or',
'an element ID reference supplied to the "aria-labelledby" attribute, which will be provided by screen readers and will need to be managed manually by the parent application.',
]
},
);
}
}
}
}
Loading

0 comments on commit 62370a1

Please sign in to comment.