Skip to content

Commit

Permalink
feat: typed events (#1981)
Browse files Browse the repository at this point in the history
* feat: typed events

adds typings to events
Changes the package use to generate the custom-elements.json file used to build React components
and tell Storybook about the web-components definitions
mgt- prefix from story component names to correct the connection to the data in custom-elements.json
set code pane content on agenda
disable ArgsTable on docs pages by default
show ArgsTable on base agenda stories

BREAKING CHANGE: moves agenda eventClick event from a property of e.detail to be the value of e.detail
BREAKING CHANGE: all events for mgt-task now emit a CustomEvent<ITask>
  • Loading branch information
gavinbarron authored Feb 6, 2023
1 parent 42c7be8 commit bbd5da4
Show file tree
Hide file tree
Showing 61 changed files with 468 additions and 413 deletions.
29 changes: 25 additions & 4 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,30 @@
/* global window */

import { addParameters, setCustomElements } from '@storybook/web-components';

import '../node_modules/@webcomponents/webcomponentsjs/webcomponents-bundle.js';
import customElements from '../custom-elements.json';
import { versionInfo } from './versionInfo';
import { noArgsDocsPage } from './story-elements/noArgsDocsPage.js';

const setCustomElementsManifestWithOptions = (customElements, options) => {
let { privateFields = true } = options;
if (!privateFields) {
customElements?.modules?.forEach(module => {
module?.declarations?.forEach(declaration => {
Object.keys(declaration).forEach(key => {
if (Array.isArray(declaration[key])) {
declaration[key] = declaration[key].filter(
member => !member.privacy?.includes('private') && !member.privacy?.includes('protected')
);
}
});
});
});
}
return setCustomElements(customElements);
};

setCustomElements(customElements);
setCustomElementsManifestWithOptions(customElements, { privateFields: false });

addParameters({
previewTabs: {
Expand All @@ -22,8 +41,10 @@ addParameters({
},
docs: {
iframeHeight: '400px',
inlineStories: false
}
inlineStories: false,
page: noArgsDocsPage
},
version: versionInfo
});

const req = require.context('../stories', true, /\.(js|mdx)$/);
Expand Down
14 changes: 14 additions & 0 deletions .storybook/story-elements/defaultDocsPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';

import { Title, Subtitle, Description, Primary, ArgsTable, Stories, PRIMARY_STORY } from '@storybook/addon-docs';

export const defaultDocsPage = () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<ArgsTable story={PRIMARY_STORY} />
<Stories />
</>
);
13 changes: 13 additions & 0 deletions .storybook/story-elements/noArgsDocsPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';

import { Title, Subtitle, Description, Primary, ArgsTable, Stories, PRIMARY_STORY } from '@storybook/addon-docs';

export const noArgsDocsPage = () => (
<>
<Title />
<Subtitle />
<Description />
<Primary />
<Stories />
</>
);
File renamed without changes.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
]
},
"scripts": {
"analyze": "custom-elements-manifest analyze --litelement --globs \"./packages/*/src/**/*.ts\"",
"build": "npm run prettier:check && npm run clean && lerna run build --scope @microsoft/*",
"build:compile": "npm run prettier:check && npm run clean && lerna run build:compile --scope @microsoft/*",
"build:mgt": "cd ./packages/mgt && npm run build",
Expand Down Expand Up @@ -51,7 +52,7 @@
"prettier:check": "npm run prettier:base -- --check \"packages/**/*.{ts,tsx}\"",
"prettier:write": "npm run prettier:base -- --write \"packages/**/*.{ts,tsx}\"",
"storybook": "start-storybook -p 6006 -s assets",
"storybook:dev": "npm run build:compile && wca analyze packages --format json --outFile custom-elements.json",
"storybook:dev": "npm run build:compile && npm run analyze",
"storybook:watch": "npm-run-all --parallel watch storybook:bundle:watch storybook",
"storybook:bundle": "rollup -c ./.storybook/rollup.config.js",
"storybook:bundle:watch": "rollup -c ./.storybook/rollup.config.js --watch",
Expand All @@ -74,6 +75,7 @@
"@babel/preset-env": "^7.12.7",
"@babel/preset-react": "^7.12.7",
"@babel/preset-typescript": "^7.12.7",
"@custom-elements-manifest/analyzer": "^0.6.6",
"@octokit/rest": "^18.5.3",
"@open-wc/testing-helpers": "^2.1.4",
"@storybook/addon-a11y": "^6.4.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { MgtPeople } from '../mgt-people/mgt-people';
* @class MgtAgenda
* @extends {MgtTemplatedComponent}
*
* @fires eventClick - Fired when user click an event
* @fires {CustomEvent<MicrosoftGraph.Event>} eventClick - Fired when user click an event
*
* @cssprop --event-box-shadow - {String} Event box shadow color and size
* @cssprop --event-margin - {String} Event margin
Expand Down Expand Up @@ -538,7 +538,7 @@ export class MgtAgenda extends MgtTemplatedComponent {
}

private eventClicked(event: MicrosoftGraph.Event) {
this.fireCustomEvent('eventClick', { event });
this.fireCustomEvent('eventClick', event);
}

private getEventTimeString(event: MicrosoftGraph.Event) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ registerFluentComponents(fluentProgressRing, fluentDesignSystemProvider);

/**
* The File List component displays a list of multiple folders and files by
* using the file/folder name, an icon, and other properties specicified by the developer.
* using the file/folder name, an icon, and other properties specified by the developer.
* This component uses the mgt-file component.
*
* @export
* @class MgtFileList
* @extends {MgtTemplatedComponent}
*
* @fires itemClick - Fired when user click a file. Returns the file (DriveItem) details.
* @fires {CustomEvent<MicrosoftGraph.DriveItem>} itemClick - Fired when user click a file. Returns the file (DriveItem) details.
* @cssprop --file-upload-border- {String} File upload border top style
* @cssprop --file-upload-background-color - {Color} File upload background color with opacity style
* @cssprop --file-upload-button-float - {string} Upload button float position
Expand Down Expand Up @@ -712,7 +712,7 @@ export class MgtFileList extends MgtTemplatedComponent {
*/
private onFileListKeyDown(event: KeyboardEvent): void {
const fileList = this.renderRoot.querySelector('.file-list');
let focusedItem;
let focusedItem: Element;

if (!fileList || !fileList.children.length) {
return;
Expand All @@ -736,7 +736,7 @@ export class MgtFileList extends MgtTemplatedComponent {
if (event.code === 'Enter' || event.code === 'Space') {
focusedItem = fileList.children[this._focusedItemIndex];

const file = focusedItem.children[0] as any;
const file = focusedItem.children[0] as MgtFile;
event.preventDefault();
this.fireCustomEvent('itemClick', file.fileDetails);

Expand Down
12 changes: 11 additions & 1 deletion packages/mgt-components/src/components/mgt-get/mgt-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,20 @@ const getResponseInvalidationTime = (currentInvalidationPeriod: number): number
const getIsResponseCacheEnabled = (): boolean =>
CacheService.config.response.isEnabled && CacheService.config.isEnabled;

/**
* Holder type emitted with the dataChange event
*/
export type DataChangedDetail = {
// tslint:disable: completed-docs
response?: any;
error?: any;
// tslint:enable: completed-docs
};

/**
* Custom element for making Microsoft Graph get queries
*
* @fires dataChange - Fired when data changes
* @fires {CustomEvent<DataChangedDetail>} dataChange - Fired when data changes
*
* @export
* @class mgt-get
Expand Down
10 changes: 5 additions & 5 deletions packages/mgt-components/src/components/mgt-login/mgt-login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ type PersonViewConfig = {
* @class MgtLogin
* @extends {MgtBaseComponent}
*
* @fires loginInitiated - Fired when login is initiated by the user
* @fires loginCompleted - Fired when login completes
* @fires loginFailed - Fired when login fails
* @fires logoutInitiated - Fired when logout is initiated by the user
* @fires logoutCompleted - Fired when logout completed
* @fires {CustomEvent<undefined>} loginInitiated - Fired when login is initiated by the user
* @fires {CustomEvent<undefined>} loginCompleted - Fired when login completes
* @fires {CustomEvent<undefined>} loginFailed - Fired when login fails
* @fires {CustomEvent<undefined>} logoutInitiated - Fired when logout is initiated by the user
* @fires {CustomEvent<undefined>} logoutCompleted - Fired when logout completed
*
* @template signed-in-button-content (dataContext: {personDetails, personImage})
* @template signed-out-button-content (dataContext: null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ interface IFocusable {
* @class MgtPicker
* @extends {MgtTemplatedComponent}
*
* @fires selectionChanged - Fired when selection changes
* @fires {CustomEvent<IDynamicPerson[]>} selectionChanged - Fired when set of selected people changes
*
* @cssprop --color - {Color} Default font color
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type HoverStatesActions = 'email' | 'chat' | 'video' | 'call';
* @class MgtPersonCard
* @extends {MgtTemplatedComponent}
*
* @fires expanded - Fired when expanded details section is opened
* @fires {CustomEvent<null>} expanded - Fired when expanded details section is opened
*
* @cssprop --person-card-display-name-font-size - {Length} Font size of display name title
* @cssprop --person-card-display-name-line-height - {Length} Line height of display name
Expand Down Expand Up @@ -784,26 +784,26 @@ export class MgtPersonCard extends MgtTemplatedComponent {
});

return html`
<fluent-tabs
orientation="horizontal"
activeindicator
@wheel=${(e: WheelEvent) => this.handleSectionScroll(e)}
<fluent-tabs
orientation="horizontal"
activeindicator
@wheel=${(e: WheelEvent) => this.handleSectionScroll(e)}
>
<fluent-tab
class="${overviewClasses}"
slot="tab"
@keyup="${() => this.updateCurrentSection(null)}"
@click=${() => this.updateCurrentSection(null)}
>
<fluent-tab
class="${overviewClasses}"
slot="tab"
@keyup="${() => this.updateCurrentSection(null)}"
@click=${() => this.updateCurrentSection(null)}
>
<div>${getSvg(SvgIcon.Overview)}</div>
</fluent-tab>
${additionalSectionTemplates}
<fluent-tab-panel slot="tabpanel" >
<div class="overview-panel">${!this._currentSection ? this.renderOverviewSection() : null}</div>
</fluent-tab-panel>
${additionalPanelTemplates}
</fluent-tabs>
`;
<div>${getSvg(SvgIcon.Overview)}</div>
</fluent-tab>
${additionalSectionTemplates}
<fluent-tab-panel slot="tabpanel" >
<div class="overview-panel">${!this._currentSection ? this.renderOverviewSection() : null}</div>
</fluent-tab-panel>
${additionalPanelTemplates}
</fluent-tabs>
`;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ const defaultPersonProperties = [
* @class MgtPerson
* @extends {MgtTemplatedComponent}
*
* @fires line1clicked - Fired when line1 is clicked
* @fires line2clicked - Fired when line2 is clicked
* @fires line3clicked - Fired when line3 is clicked
* @fires line4clicked - Fired when line4 is clicked
* @fires {CustomEvent<IDynamicPerson>} line1clicked - Fired when line1 is clicked
* @fires {CustomEvent<IDynamicPerson>} line2clicked - Fired when line2 is clicked
* @fires {CustomEvent<IDynamicPerson>} line3clicked - Fired when line3 is clicked
* @fires {CustomEvent<IDynamicPerson>} line4clicked - Fired when line4 is clicked
*
* @cssprop --avatar-size - {Length} Avatar size
* @cssprop --avatar-border - {String} Avatar border
Expand Down
18 changes: 10 additions & 8 deletions packages/mgt-components/src/components/mgt-tasks/mgt-tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ const plannerAssignment = {
* @class MgtTasks
* @extends {MgtBaseComponent}
*
* @fires taskAdded - Fires when a new task has been created.
* @fires taskChanged - Fires when task metadata has been changed, such as marking completed.
* @fires taskClick - Fires when the user clicks or taps on a task.
* @fires taskRemoved - Fires when an existing task has been deleted.
* @fires {CustomEvent<ITask>} taskAdded - Fires when a new task has been created.
* @fires {CustomEvent<ITask>} taskChanged - Fires when task metadata has been changed, such as marking completed.
* @fires {CustomEvent<ITask>} taskClick - Fires when the user clicks or taps on a task.
* @fires {CustomEvent<ITask>} taskRemoved - Fires when an existing task has been deleted.
*
* @cssprop --tasks-header-padding - {String} Tasks header padding
* @cssprop --tasks-header-margin - {String} Tasks header margin
Expand Down Expand Up @@ -224,7 +224,7 @@ export class MgtTasks extends MgtTemplatedComponent {
*
* @memberof MgtTasks
*/
public get isNewTaskVisible() {
public get isNewTaskVisible(): boolean {
return this._isNewTaskVisible;
}

Expand Down Expand Up @@ -650,8 +650,8 @@ export class MgtTasks extends MgtTemplatedComponent {
} as ITask;

this._newTaskBeingAdded = true;
const task = await ts.addTask(newTask);
this.fireCustomEvent('taskAdded', task);
newTask._raw = await ts.addTask(newTask);
this.fireCustomEvent('taskAdded', newTask);

await this.requestStateUpdate();
this._newTaskBeingAdded = false;
Expand Down Expand Up @@ -1334,7 +1334,7 @@ export class MgtTasks extends MgtTemplatedComponent {

private handleTaskClick(task: ITask) {
if (task) {
this.fireCustomEvent('taskClick', { task: task._raw });
this.fireCustomEvent('taskClick', task);
}
}

Expand Down Expand Up @@ -1478,3 +1478,5 @@ export class MgtTasks extends MgtTemplatedComponent {
return null;
}
}

export { ITask };
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {
} from './mgt-tasks.graph.todo';

/**
* Itask
* ITask
*
* @export
* @interface ITask
Expand Down Expand Up @@ -611,7 +611,7 @@ export class TodoTaskSource extends TaskSourceBase implements ITaskSource {
* @returns {Promise<any>}
* @memberof TodoTaskSource
*/
public async addTask(newTask: ITask): Promise<any> {
public async addTask(newTask: ITask): Promise<OutlookTask> {
const task = {
parentFolderId: newTask.immediateParentId,
subject: newTask.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export interface MgtTeamsChannelPickerConfig {
* @class MgtTeamsChannelPicker
* @extends {MgtTemplatedComponent}
*
* @fires selectionChanged - Fired when the selection changes
* @fires {CustomEvent<SelectedChannel | null>} selectionChanged - Fired when the selection changes
*
* @cssprop --color - {font} Default font color
*
Expand Down Expand Up @@ -199,7 +199,7 @@ export class MgtTeamsChannelPicker extends MgtTemplatedComponent {
* @type {SelectedChannel}
* @memberof MgtTeamsChannelPicker
*/
public get selectedItem(): SelectedChannel {
public get selectedItem(): SelectedChannel | null {
if (this._selectedItemState) {
return { channel: this._selectedItemState.item, team: this._selectedItemState.parent.item };
} else {
Expand Down Expand Up @@ -896,7 +896,7 @@ export class MgtTeamsChannelPicker extends MgtTemplatedComponent {
private selectChannel(item: ChannelPickerItemState) {
if (this._selectedItemState !== item) {
this._selectedItemState = item;
this.fireCustomEvent('selectionChanged', item ? [this.selectedItem] : []);
this.fireCustomEvent('selectionChanged', this.selectedItem);
}

const input = this._input;
Expand Down
3 changes: 1 addition & 2 deletions packages/mgt-components/src/components/mgt-todo/mgt-todo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ import {
import { styles } from './mgt-todo-css';
import { strings } from './strings';

/*
/**
* Filter function
*/
// tslint:disable-next-line: completed-docs
export type TodoFilter = (task: TodoTask) => boolean;

/**
Expand Down
Loading

0 comments on commit bbd5da4

Please sign in to comment.