From c41d7190f771513583deac46e5c57fdf17575d81 Mon Sep 17 00:00:00 2001 From: Gavin Barron Date: Tue, 24 Oct 2023 05:32:40 -0700 Subject: [PATCH] feat: enable live code inclusion for consuming applications (#2642) Packages are marked as side effect free or have the files that include side effects listed in package.json. This allows bundlers to discard code not in the direct dependency tree of an import. Adds functions for registering components Moved to generating a single file per react wrpper component and a barrel file Update tests to use registerComponent calls fixing render problem when given and surname are null on personType objects move mgt-components to module type es2020 for dynamic imports refactored to only lazy load the person-card code when opening the flyout update list of components registered by registerMgtComponents move sample app to use lazy + Suspense to chunk up component usage adding documentation for tree shaking support --- cem-plugins/mgt-tag-plugin.mjs | 37 ++ custom-elements-manifest.config.mjs | 5 + lerna.json | 8 +- package.json | 6 +- packages/mgt-components/README.md | 98 ++++- packages/mgt-components/package.json | 4 + .../src/components/components.ts | 4 + .../src/components/mgt-agenda/mgt-agenda.ts | 16 +- .../src/components/mgt-contact/mgt-contact.ts | 9 +- .../components/mgt-file-list/mgt-file-list.ts | 16 +- .../mgt-file-upload/mgt-file-upload.ts | 15 +- .../src/components/mgt-file/mgt-file.ts | 7 +- .../src/components/mgt-get/mgt-get.ts | 13 +- .../src/components/mgt-login/mgt-login.ts | 24 +- .../components/mgt-messages/mgt-messages.ts | 5 +- .../mgt-organization/mgt-organization.ts | 10 +- .../mgt-people-picker/mgt-people-picker.ts | 21 +- .../src/components/mgt-people/mgt-people.ts | 19 +- .../mgt-person-card/mgt-person-card.ts | 37 +- .../src/components/mgt-person-card/types.ts | 7 + .../components/mgt-person/mgt-person.tests.ts | 4 + .../src/components/mgt-person/mgt-person.ts | 46 ++- .../src/components/mgt-picker/mgt-picker.ts | 13 +- .../src/components/mgt-profile/mgt-profile.ts | 5 +- .../mgt-tasks-base/mgt-tasks-base.ts | 5 +- .../src/components/mgt-tasks/mgt-tasks.ts | 33 +- .../mgt-taxonomy-picker.ts | 15 +- .../mgt-teams-channel-picker.ts | 26 +- .../mgt-theme-toggle.tests.ts | 4 + .../mgt-theme-toggle/mgt-theme-toggle.ts | 9 +- .../src/components/mgt-todo/mgt-todo.ts | 13 +- .../preview/mgt-search-box/mgt-search-box.ts | 9 +- .../mgt-search-results/mgt-search-results.ts | 15 +- .../mgt-arrow-options/mgt-arrow-options.ts | 10 +- .../mgt-dot-options/mgt-dot-options.ts | 12 +- .../sub-components/mgt-flyout/mgt-flyout.ts | 6 +- .../mgt-spinner/mgt-spinner.tests.ts | 2 + .../sub-components/mgt-spinner/mgt-spinner.ts | 6 +- packages/mgt-components/src/exports.ts | 12 + packages/mgt-components/src/index.ts | 11 +- .../src/registerMgtComponents.ts | 43 ++ packages/mgt-components/tsconfig.json | 1 + packages/mgt-element/README.md | 3 +- packages/mgt-element/package.json | 1 + packages/mgt-element/src/Graph.ts | 2 +- packages/mgt-element/src/index.ts | 9 +- packages/mgt-element/src/mock/MockGraph.ts | 2 +- .../mgt-element/src/providers/IProvider.ts | 4 +- packages/mgt-element/src/utils/Batch.ts | 4 +- packages/mgt-element/src/utils/CacheItem.ts | 23 ++ packages/mgt-element/src/utils/CacheSchema.ts | 37 ++ .../mgt-element/src/utils/CacheService.ts | 57 +-- packages/mgt-element/src/utils/CacheStore.ts | 4 +- .../src/utils/GraphHelpers.tests.ts | 4 +- .../mgt-element/src/utils/GraphHelpers.ts | 67 ---- .../src/utils/SdkVersionMiddleware.ts | 2 +- .../mgt-element/src/utils/chainMiddleware.ts | 28 ++ packages/mgt-element/src/utils/dbListKey.ts | 15 + .../src/utils/{index.ts => delay.ts} | 0 packages/mgt-element/src/utils/prepScopes.ts | 30 ++ .../src/utils/registerComponent.ts | 12 + .../mgt-element/src/utils/validateBaseURL.ts | 27 ++ .../custom-elements-manifest.config.mjs | 3 + packages/mgt-react/package.json | 3 +- packages/mgt-react/scripts/generate.js | 39 +- packages/mgt-react/src/Mgt.ts | 3 +- packages/mgt-react/src/generated/agenda.ts | 26 ++ packages/mgt-react/src/generated/file-list.ts | 41 ++ packages/mgt-react/src/generated/file.ts | 36 ++ packages/mgt-react/src/generated/get.ts | 29 ++ packages/mgt-react/src/generated/login.ts | 27 ++ .../mgt-react/src/generated/people-picker.ts | 41 ++ packages/mgt-react/src/generated/people.ts | 30 ++ .../mgt-react/src/generated/person-card.ts | 30 ++ packages/mgt-react/src/generated/person.ts | 42 ++ packages/mgt-react/src/generated/picker.ts | 29 ++ packages/mgt-react/src/generated/react.ts | 368 +----------------- .../mgt-react/src/generated/search-box.ts | 20 + .../mgt-react/src/generated/search-results.ts | 35 ++ packages/mgt-react/src/generated/spinner.ts | 16 + packages/mgt-react/src/generated/tasks.ts | 35 ++ .../src/generated/taxonomy-picker.ts | 31 ++ .../src/generated/teams-channel-picker.ts | 21 + .../mgt-react/src/generated/theme-toggle.ts | 18 + packages/mgt-react/src/generated/todo.ts | 25 ++ packages/mgt-react/src/index.ts | 2 +- packages/mgt-spfx-utils/package.json | 1 + packages/mgt-spfx/package.json | 1 + packages/mgt/package.json | 1 + .../mgt-electron-provider/package.json | 1 + .../providers/mgt-mock-provider/README.md | 2 +- .../providers/mgt-mock-provider/package.json | 4 + .../providers/mgt-mock-provider/src/index.ts | 3 + .../src/mgt-mock-provider.ts | 8 +- .../providers/mgt-msal2-provider/README.md | 6 +- .../providers/mgt-msal2-provider/package.json | 4 + .../mgt-msal2-provider/src/exports.ts | 2 + .../providers/mgt-msal2-provider/src/index.ts | 6 +- .../src/mgt-msal2-provider.ts | 11 +- .../providers/mgt-proxy-provider/README.md | 2 +- .../providers/mgt-proxy-provider/package.json | 4 + .../mgt-proxy-provider/src/exports.ts | 2 + .../providers/mgt-proxy-provider/src/index.ts | 6 +- .../src/mgt-proxy-provider.ts | 9 +- .../mgt-sharepoint-provider/package.json | 1 + .../mgt-teamsfx-provider/package.json | 1 + samples/react-contoso/src/Layout.tsx | 13 +- samples/react-contoso/src/index.tsx | 2 +- .../react-contoso/src/pages/DashboardPage.tsx | 4 +- samples/react-contoso/src/pages/FilesPage.tsx | 4 +- samples/react-contoso/src/pages/HomePage.tsx | 4 +- .../react-contoso/src/pages/OutlookPage.tsx | 4 +- .../react-contoso/src/pages/SearchPage.tsx | 4 +- .../react-contoso/src/pages/TaxonomyPage.tsx | 4 +- .../react-contoso/src/services/Navigation.tsx | 49 ++- 115 files changed, 1409 insertions(+), 696 deletions(-) create mode 100644 cem-plugins/mgt-tag-plugin.mjs create mode 100644 custom-elements-manifest.config.mjs create mode 100644 packages/mgt-components/src/components/mgt-person-card/types.ts create mode 100644 packages/mgt-components/src/exports.ts create mode 100644 packages/mgt-components/src/registerMgtComponents.ts create mode 100644 packages/mgt-element/src/utils/CacheItem.ts create mode 100644 packages/mgt-element/src/utils/CacheSchema.ts delete mode 100644 packages/mgt-element/src/utils/GraphHelpers.ts create mode 100644 packages/mgt-element/src/utils/chainMiddleware.ts create mode 100644 packages/mgt-element/src/utils/dbListKey.ts rename packages/mgt-element/src/utils/{index.ts => delay.ts} (100%) create mode 100644 packages/mgt-element/src/utils/prepScopes.ts create mode 100644 packages/mgt-element/src/utils/registerComponent.ts create mode 100644 packages/mgt-element/src/utils/validateBaseURL.ts create mode 100644 packages/mgt-react/custom-elements-manifest.config.mjs create mode 100644 packages/mgt-react/src/generated/agenda.ts create mode 100644 packages/mgt-react/src/generated/file-list.ts create mode 100644 packages/mgt-react/src/generated/file.ts create mode 100644 packages/mgt-react/src/generated/get.ts create mode 100644 packages/mgt-react/src/generated/login.ts create mode 100644 packages/mgt-react/src/generated/people-picker.ts create mode 100644 packages/mgt-react/src/generated/people.ts create mode 100644 packages/mgt-react/src/generated/person-card.ts create mode 100644 packages/mgt-react/src/generated/person.ts create mode 100644 packages/mgt-react/src/generated/picker.ts create mode 100644 packages/mgt-react/src/generated/search-box.ts create mode 100644 packages/mgt-react/src/generated/search-results.ts create mode 100644 packages/mgt-react/src/generated/spinner.ts create mode 100644 packages/mgt-react/src/generated/tasks.ts create mode 100644 packages/mgt-react/src/generated/taxonomy-picker.ts create mode 100644 packages/mgt-react/src/generated/teams-channel-picker.ts create mode 100644 packages/mgt-react/src/generated/theme-toggle.ts create mode 100644 packages/mgt-react/src/generated/todo.ts create mode 100644 packages/providers/mgt-msal2-provider/src/exports.ts create mode 100644 packages/providers/mgt-proxy-provider/src/exports.ts diff --git a/cem-plugins/mgt-tag-plugin.mjs b/cem-plugins/mgt-tag-plugin.mjs new file mode 100644 index 0000000000..d4a1e93783 --- /dev/null +++ b/cem-plugins/mgt-tag-plugin.mjs @@ -0,0 +1,37 @@ +import { resolveModuleOrPackageSpecifier } from '@custom-elements-manifest/analyzer/src/utils/index.js'; +export default function mgtTagPlugin() { + function isCustomRegistration(node) { + // this would be better if we tested arg[0] for a string literal + return node?.expression?.getText() === 'registerComponent' && node.arguments.length >= 2; + } + // Write a custom plugin + return { + // Make sure to always give your plugins a name, this helps when debugging + name: 'mgt-tag-plugin', + // Runs for all modules in a project, before continuing to the analyzePhase + collectPhase({ ts, node, context }) {}, + // Runs for each module + analyzePhase({ ts: TS, node, moduleDoc, context }) { + if (isCustomRegistration(node)) { + //do things... + if (context.dev) console.log(node); + + var elementClass = node.arguments[1].text; + var elementTag = node.arguments[0].text; + const definitionDoc = { + kind: 'custom-element-definition', + name: elementTag, + declaration: { + name: elementClass, + ...resolveModuleOrPackageSpecifier(moduleDoc, context, elementClass) + } + }; + moduleDoc.exports = [...(moduleDoc.exports || []), definitionDoc]; + } + }, + // Runs for each module, after analyzing, all information about your module should now be available + moduleLinkPhase({ moduleDoc, context }) {}, + // Runs after modules have been parsed and after post-processing + packageLinkPhase({ customElementsManifest, context }) {} + }; +} diff --git a/custom-elements-manifest.config.mjs b/custom-elements-manifest.config.mjs new file mode 100644 index 0000000000..9f6adcc959 --- /dev/null +++ b/custom-elements-manifest.config.mjs @@ -0,0 +1,5 @@ +import mgtTagPlugin from './cem-plugins/mgt-tag-plugin.mjs'; + +export default { + plugins: [mgtTagPlugin()] +}; diff --git a/lerna.json b/lerna.json index c722dc78c8..bc81d95746 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,9 @@ { - "packages": ["packages/*", "packages/providers/*", "samples/react-contoso"], + "packages": [ + "packages/*", + "packages/providers/*", + "samples/*" + ], "npmClient": "yarn", "version": "independent" -} +} \ No newline at end of file diff --git a/package.json b/package.json index 9e3239ae33..a6d7ea41c6 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ }, "scripts": { "init": "yarn && yarn build", - "analyze": "custom-elements-manifest analyze --litelement --globs \"./packages/*/src/**/*.ts\"", - "build": "npm run prettier:check && npm run clean && lerna run --scope '@microsoft/*' build", + "analyze": "custom-elements-manifest analyze --globs \"./packages/*/src/**/*.ts\"", + "build": "npm run prettier:check && npm run clean && lerna run build --scope '@microsoft/*'", "build:dev": "npm run prettier:check && lerna run build --scope '@microsoft/*' --ignore '@microsoft/mgt' --ignore '@microsoft/mgt-spf*' --ignore '@microsoft/mgt-sharepoint-provider' --ignore '@microsoft/mgt-electron-provider' --ignore '@microsoft/mgt-teamsfx-provider' --ignore '@microsoft/mgt-proxy-provider'", - "build:compile": "npm run prettier:check && npm run clean && lerna run --scope @microsoft/* build:compile", + "build:compile": "npm run prettier:check && npm run clean && lerna run build:compile --scope '@microsoft/*'", "build:mgt": "cd ./packages/mgt && npm run build", "build:mgt-element": "cd ./packages/mgt-element && npm run build", "build:mgt-components": "cd ./packages/mgt-components && npm run build", diff --git a/packages/mgt-components/README.md b/packages/mgt-components/README.md index d6351695a9..2ec0e8f38e 100644 --- a/packages/mgt-components/README.md +++ b/packages/mgt-components/README.md @@ -48,7 +48,7 @@ The components can be used on their own, but they are at their best when they ar ```html + + + + +``` ## Disambiguation @@ -71,17 +113,27 @@ To mitigate this challenge we built the [`mgt-spfx`](https://github.com/microsof To allow developers to build web parts using the latest version of MGT and load them on pages along with web parts that use v2.x of MGT, we've added a new disambiguation feature to MGT. Using this feature developers can specify a unique string to add to the tag name of all MGT web components in their application. -### Usage in standard HTML and JavaScript + +### Usage in standard HTML and JavaScript with explicit component registration The earlier example can be updated to use the disambiguation feature as follows: ```html + + + + +``` + +> Note: the `import` of `mgt-components` must use a dynamic import to ensure that the disambiguation is applied before the components are imported and the automatic registration is performed. When developing SharePoint Framework web parts the pattern for using disambiguation is based on whether or not the MGT React wrapper library is being used. If you are using React then the helper utility in the [`mgt-spfx-utils`](https://github.com/microsoftgraph/microsoft-graph-toolkit/tree/main/packages/mgt-spfx-utils) package should be used. SharePoint Framework web part example usages are provided below. @@ -109,15 +186,20 @@ import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base'; import { Providers } from '@microsoft/mgt-element'; import { SharePointProvider } from '@microsoft/mgt-sharepoint-provider'; import { customElementHelper } from '@microsoft/mgt-element/dist/es6/components/customElementHelper'; +import { registerMgtLoginComponent } from '@microsoft/mgt-components'; export default class MgtWebPart extends BaseClientSideWebPart> { protected onInit(): Promise { customElementHelper.withDisambiguation('foo'); + + // register the component + registerMgtLoginComponent(); + if (!Providers.globalProvider) { Providers.globalProvider = new SharePointProvider(this.context); } - return import('@microsoft/mgt-components').then(() => super.onInit()); + return super.onInit(); } public render(): void { @@ -131,6 +213,8 @@ export default class MgtWebPart extends BaseClientSideWebPart { ```typescript // static import via a statement import { Provider } from '@microsoft/mgt-element'; -import { Msal2Provider } from '@microsoft/mgt-msal2-provider'; +import { Msal2Provider } from '@microsoft/mgt-msal2-provider/dist/es6/exports'; import '@microsoft/mgt-components'; Providers.globalProvider = new Msal2Provider({clientId: 'clientId'}); diff --git a/packages/mgt-components/package.json b/packages/mgt-components/package.json index cbe621fa98..4c12fefb69 100644 --- a/packages/mgt-components/package.json +++ b/packages/mgt-components/package.json @@ -35,6 +35,10 @@ "sass": "gulp sass --cwd .", "sass:watch": "gulp watchSass --cwd ." }, + "sideEffects": [ + "./dist/es6/index.js", + "./src/index.ts" + ], "dependencies": { "@fluentui/web-components": "^2.5.12", "@microsoft/mgt-element": "*", diff --git a/packages/mgt-components/src/components/components.ts b/packages/mgt-components/src/components/components.ts index cc425c3462..d4989026f6 100644 --- a/packages/mgt-components/src/components/components.ts +++ b/packages/mgt-components/src/components/components.ts @@ -25,6 +25,7 @@ import './mgt-messages/mgt-messages'; import './mgt-organization/mgt-organization'; import './mgt-profile/mgt-profile'; import './mgt-theme-toggle/mgt-theme-toggle'; +import './sub-components/mgt-spinner/mgt-spinner'; export * from './mgt-agenda/mgt-agenda'; export * from './mgt-file/mgt-file'; @@ -47,3 +48,6 @@ export * from './mgt-messages/mgt-messages'; export * from './mgt-organization/mgt-organization'; export * from './mgt-profile/mgt-profile'; export * from './mgt-theme-toggle/mgt-theme-toggle'; +export * from './sub-components/mgt-spinner/mgt-spinner'; +// include preview components here for ease of import into mgt-react +export * from './preview'; diff --git a/packages/mgt-components/src/components/mgt-agenda/mgt-agenda.ts b/packages/mgt-components/src/components/mgt-agenda/mgt-agenda.ts index 3cea862ae0..cdbd0f4a35 100644 --- a/packages/mgt-components/src/components/mgt-agenda/mgt-agenda.ts +++ b/packages/mgt-components/src/components/mgt-agenda/mgt-agenda.ts @@ -8,17 +8,17 @@ import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; import { html, TemplateResult } from 'lit'; import { property } from 'lit/decorators.js'; -import { Providers, ProviderState, MgtTemplatedComponent, mgtHtml, customElement } from '@microsoft/mgt-element'; +import { Providers, ProviderState, MgtTemplatedComponent, mgtHtml } from '@microsoft/mgt-element'; import '../../styles/style-helper'; import '../mgt-person/mgt-person'; import { styles } from './mgt-agenda-css'; import { getEventsPageIterator, getEventsQueryPageIterator } from './mgt-agenda.graph'; import { SvgIcon, getSvg } from '../../utils/SvgHelper'; -import { MgtPeople } from '../mgt-people/mgt-people'; +import { MgtPeople, registerMgtPeopleComponent } from '../mgt-people/mgt-people'; import { registerFluentComponents } from '../../utils/FluentComponents'; import { fluentCard } from '@fluentui/web-components'; import { classMap } from 'lit/directives/class-map.js'; -registerFluentComponents(fluentCard); +import { registerComponent } from '@microsoft/mgt-element'; /** * Web Component which represents events in a user or group calendar. @@ -45,7 +45,15 @@ registerFluentComponents(fluentCard); * @cssprop --event-location-color - {Color} Event location color * @cssprop --event-attendees-color - {Color} Event attendees color */ -@customElement('agenda') + +export const registerMgtAgendaComponent = () => { + registerFluentComponents(fluentCard); + // register dependent components + registerMgtPeopleComponent(); + // register self + registerComponent('agenda', MgtAgenda); +}; + export class MgtAgenda extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-contact/mgt-contact.ts b/packages/mgt-components/src/components/mgt-contact/mgt-contact.ts index d41980c668..8a845c45cc 100644 --- a/packages/mgt-components/src/components/mgt-contact/mgt-contact.ts +++ b/packages/mgt-components/src/components/mgt-contact/mgt-contact.ts @@ -7,7 +7,7 @@ import { User } from '@microsoft/microsoft-graph-types'; import { html, TemplateResult } from 'lit'; -import { TeamsHelper, customElement } from '@microsoft/mgt-element'; +import { TeamsHelper } from '@microsoft/mgt-element'; import { classMap } from 'lit/directives/class-map.js'; import { getEmailFromGraphEntity } from '../../graph/graph.people'; @@ -15,6 +15,7 @@ import { BasePersonCardSection } from '../BasePersonCardSection'; import { styles } from './mgt-contact-css'; import { getSvg, SvgIcon } from '../../utils/SvgHelper'; import { strings } from './strings'; +import { registerComponent } from '@microsoft/mgt-element'; /** * Represents a contact part and its metadata @@ -31,6 +32,10 @@ interface IContactPart { type Protocol = 'mailto:' | 'tel:'; +export const registerMgtContactComponent = () => { + registerComponent('contact', MgtContact); +}; + /** * The contact details subsection of the person card * @@ -38,8 +43,6 @@ type Protocol = 'mailto:' | 'tel:'; * @class MgtContact * @extends {MgtTemplatedComponent} */ -@customElement('contact') -// @customElement('mgt-contact') export class MgtContact extends BasePersonCardSection { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-file-list/mgt-file-list.ts b/packages/mgt-components/src/components/mgt-file-list/mgt-file-list.ts index 5a22e819a0..e03adb98e1 100644 --- a/packages/mgt-components/src/components/mgt-file-list/mgt-file-list.ts +++ b/packages/mgt-components/src/components/mgt-file-list/mgt-file-list.ts @@ -10,7 +10,6 @@ import { GraphPageIterator, Providers, ProviderState, - customElement, mgtHtml, MgtTemplatedComponent } from '@microsoft/mgt-element'; @@ -42,14 +41,21 @@ import { getSvg, SvgIcon } from '../../utils/SvgHelper'; import { OfficeGraphInsightString, ViewType } from '../../graph/types'; import { styles } from './mgt-file-list-css'; import { strings } from './strings'; -import { MgtFile } from '../mgt-file/mgt-file'; -import { MgtFileUploadConfig } from './mgt-file-upload/mgt-file-upload'; +import { MgtFile, registerMgtFileComponent } from '../mgt-file/mgt-file'; +import { MgtFileUploadConfig, registerMgtFileUploadComponent } from './mgt-file-upload/mgt-file-upload'; import { fluentProgressRing } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; import { CardSection } from '../BasePersonCardSection'; +import { registerComponent } from '@microsoft/mgt-element'; -registerFluentComponents(fluentProgressRing); +export const registerMgtFileListComponent = () => { + registerFluentComponents(fluentProgressRing); + + registerMgtFileComponent(); + registerMgtFileUploadComponent(); + registerComponent('file-list', MgtFileList); +}; /** * The File List component displays a list of multiple folders and files by @@ -77,8 +83,6 @@ registerFluentComponents(fluentProgressRing); * @cssprop --show-more-button-border-bottom-left-radius - {String} the "show more" button bottom left border radius. Default value is 8px; * @cssprop --progress-ring-size -{String} Progress ring height and width. Default value is 24px. */ - -@customElement('file-list') export class MgtFileList extends MgtTemplatedComponent implements CardSection { @state() private _isCompact = false; /** diff --git a/packages/mgt-components/src/components/mgt-file-list/mgt-file-upload/mgt-file-upload.ts b/packages/mgt-components/src/components/mgt-file-list/mgt-file-upload/mgt-file-upload.ts index 7109fd2c90..e6991b64d5 100644 --- a/packages/mgt-components/src/components/mgt-file-list/mgt-file-upload/mgt-file-upload.ts +++ b/packages/mgt-components/src/components/mgt-file-list/mgt-file-upload/mgt-file-upload.ts @@ -6,7 +6,7 @@ */ import { fluentButton, fluentCheckbox, fluentDialog, fluentProgress } from '@fluentui/web-components'; -import { customElement, IGraph, MgtBaseComponent, mgtHtml } from '@microsoft/mgt-element'; +import { IGraph, MgtBaseComponent, mgtHtml } from '@microsoft/mgt-element'; import { html, TemplateResult } from 'lit'; import { property } from 'lit/decorators.js'; import { DriveItem } from '@microsoft/microsoft-graph-types'; @@ -26,8 +26,8 @@ import { getSvg, SvgIcon } from '../../../utils/SvgHelper'; import { formatBytes } from '../../../utils/Utils'; import { styles } from './mgt-file-upload-css'; import { strings } from './strings'; - -registerFluentComponents(fluentProgress, fluentButton, fluentCheckbox, fluentDialog); +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtFileComponent } from '../../mgt-file/mgt-file'; /** * Simple union type for file system entry and directory entry types @@ -236,6 +236,13 @@ interface FileWithPath extends File { fullPath: string; } +export const registerMgtFileUploadComponent = () => { + registerFluentComponents(fluentProgress, fluentButton, fluentCheckbox, fluentDialog); + + registerMgtFileComponent(); + registerComponent('file-upload', MgtFileUpload); +}; + /** * A component to upload files to OneDrive or SharePoint Sites * @@ -264,8 +271,6 @@ interface FileWithPath extends File { * @cssprop --file-upload-dialog-height - {String} the height of the file upload dialog box. Default value is auto. * @cssprop --file-upload-dialog-padding - {String} the padding of the file upload dialog box. Default value is 24px; */ - -@customElement('file-upload') export class MgtFileUpload extends MgtBaseComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-file/mgt-file.ts b/packages/mgt-components/src/components/mgt-file/mgt-file.ts index 0e1b3b9981..2816844257 100644 --- a/packages/mgt-components/src/components/mgt-file/mgt-file.ts +++ b/packages/mgt-components/src/components/mgt-file/mgt-file.ts @@ -9,7 +9,7 @@ import { DriveItem } from '@microsoft/microsoft-graph-types'; import { html, TemplateResult } from 'lit'; import { property } from 'lit/decorators.js'; import { styles } from './mgt-file-css'; -import { MgtTemplatedComponent, Providers, ProviderState, customElement } from '@microsoft/mgt-element'; +import { MgtTemplatedComponent, Providers, ProviderState } from '@microsoft/mgt-element'; import { getDriveItemById, getDriveItemByPath, @@ -31,6 +31,9 @@ import { OfficeGraphInsightString, ViewType } from '../../graph/types'; import { getFileTypeIconUriByExtension } from '../../styles/fluent-icons'; import { getSvg, SvgIcon } from '../../utils/SvgHelper'; import { strings } from './strings'; +import { registerComponent } from '@microsoft/mgt-element'; + +export const registerMgtFileComponent = () => registerComponent('file', MgtFile); /** * The File component is used to represent an individual file/folder from OneDrive or SharePoint by displaying information such as the file/folder name, an icon indicating the file type, and other properties such as the author, last modified date, or other details selected by the developer. @@ -62,8 +65,6 @@ import { strings } from './strings'; * @cssprop --file-line3-color - {Color} the third line text color. * @cssprop --file-line3-text-transform - {String} the third line text text transform. Default value is 400. */ - -@customElement('file') export class MgtFile extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-get/mgt-get.ts b/packages/mgt-components/src/components/mgt-get/mgt-get.ts index 42afe93a2f..8678115f1d 100644 --- a/packages/mgt-components/src/components/mgt-get/mgt-get.ts +++ b/packages/mgt-components/src/components/mgt-get/mgt-get.ts @@ -15,8 +15,8 @@ import { prepScopes, Providers, ProviderState, - customElement, - CollectionResponse + CollectionResponse, + IGraph } from '@microsoft/mgt-element'; import { getPhotoForResource } from '../../graph/graph.photos'; @@ -24,6 +24,8 @@ import { getDocumentThumbnail } from '../../graph/graph.files'; import { schemas } from '../../graph/cacheStores'; import { CacheResponse } from '../CacheResponse'; import { Entity } from '@microsoft/microsoft-graph-types'; +import { GraphRequest } from '@microsoft/microsoft-graph-client'; +import { registerComponent } from '@microsoft/mgt-element'; /** * Simple holder type for an image @@ -81,6 +83,8 @@ export interface DataChangedDetail { error?: object; } +export const registerMgtGetComponent = () => registerComponent('get', MgtGet); + /** * Custom element for making Microsoft Graph get queries * @@ -90,7 +94,6 @@ export interface DataChangedDetail { * @class mgt-get * @extends {MgtTemplatedComponent} */ -@customElement('get') export class MgtGet extends MgtTemplatedComponent { /** * The resource to get @@ -357,8 +360,8 @@ export class MgtGet extends MgtTemplatedComponent { isDeltaLink = new URL(uri, 'https://graph.microsoft.com').pathname.endsWith('delta'); } - const graph = provider.graph.forComponent(this); - let request = graph.api(uri).version(this.version); + const graph: IGraph = provider.graph.forComponent(this); + let request: GraphRequest = graph.api(uri).version(this.version); if (this.scopes?.length) { request = request.middlewareOptions(prepScopes(...this.scopes)); diff --git a/packages/mgt-components/src/components/mgt-login/mgt-login.ts b/packages/mgt-components/src/components/mgt-login/mgt-login.ts index 1067d9acff..c16021076d 100644 --- a/packages/mgt-components/src/components/mgt-login/mgt-login.ts +++ b/packages/mgt-components/src/components/mgt-login/mgt-login.ts @@ -9,19 +9,12 @@ import { CSSResult, html, TemplateResult } from 'lit'; import { property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { ifDefined } from 'lit/directives/if-defined.js'; -import { - Providers, - ProviderState, - MgtTemplatedComponent, - IProviderAccount, - mgtHtml, - customElement -} from '@microsoft/mgt-element'; +import { Providers, ProviderState, MgtTemplatedComponent, IProviderAccount, mgtHtml } from '@microsoft/mgt-element'; import { AvatarSize, IDynamicPerson, ViewType } from '../../graph/types'; -import { MgtFlyout } from '../sub-components/mgt-flyout/mgt-flyout'; +import { MgtFlyout, registerMgtFlyoutComponent } from '../sub-components/mgt-flyout/mgt-flyout'; import { getUserWithPhoto } from '../../graph/graph.userWithPhoto'; -import { MgtPerson } from '../mgt-person/mgt-person'; +import { MgtPerson, registerMgtPersonComponent } from '../mgt-person/mgt-person'; import { PersonViewType } from '../mgt-person/mgt-person-types'; import { getSvg, SvgIcon } from '../../utils/SvgHelper'; @@ -33,7 +26,7 @@ import '../../styles/style-helper'; import { fluentListbox, fluentProgressRing, fluentButton, fluentCard } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; -registerFluentComponents(fluentListbox, fluentProgressRing, fluentButton, fluentCard); +import { registerComponent } from '@microsoft/mgt-element'; /** * loginViewType describes the enum strings that can be passed in to determine @@ -46,6 +39,14 @@ interface PersonViewConfig { avatarSize: AvatarSize; } +export const registerMgtLoginComponent = () => { + registerFluentComponents(fluentListbox, fluentProgressRing, fluentButton, fluentCard); + + registerMgtFlyoutComponent(); + registerMgtPersonComponent(); + registerComponent('login', MgtLogin); +}; + /** * Web component button and flyout control to facilitate Microsoft identity platform authentication * @@ -82,7 +83,6 @@ interface PersonViewConfig { * @cssprop --login-account-item-hover-bg-color - {Color} the background color of the account item on hover. * @cssprop --login-flyout-command-text-color - {Color} the color for the text of the flyout command button. */ -@customElement('login') export class MgtLogin extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-messages/mgt-messages.ts b/packages/mgt-components/src/components/mgt-messages/mgt-messages.ts index 8b40c0562e..733acd2d1d 100644 --- a/packages/mgt-components/src/components/mgt-messages/mgt-messages.ts +++ b/packages/mgt-components/src/components/mgt-messages/mgt-messages.ts @@ -13,7 +13,9 @@ import { getSvg, SvgIcon } from '../../utils/SvgHelper'; import { getRelativeDisplayDate } from '../../utils/Utils'; import { styles } from './mgt-messages-css'; import { strings } from './strings'; -import { customElement } from '@microsoft/mgt-element'; +import { registerComponent } from '@microsoft/mgt-element'; + +export const registerMgtMessagesComponent = () => registerComponent('messages', MgtMessages); /** * The email messages subsection of the person card @@ -22,7 +24,6 @@ import { customElement } from '@microsoft/mgt-element'; * @class MgtMessages * @extends {MgtTemplatedComponent} */ -@customElement('messages') export class MgtMessages extends BasePersonCardSection { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-organization/mgt-organization.ts b/packages/mgt-components/src/components/mgt-organization/mgt-organization.ts index 3514084b30..751ff8dec6 100644 --- a/packages/mgt-components/src/components/mgt-organization/mgt-organization.ts +++ b/packages/mgt-components/src/components/mgt-organization/mgt-organization.ts @@ -14,7 +14,14 @@ import { MgtPersonCardState, UserWithManager } from '../mgt-person-card/mgt-pers import { styles } from './mgt-organization-css'; import { strings } from './strings'; import { ViewType } from '../../graph/types'; -import { mgtHtml, customElement } from '@microsoft/mgt-element'; +import { mgtHtml } from '@microsoft/mgt-element'; +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtPersonComponent } from '../mgt-person/mgt-person'; + +export const registerMgtOrganizationComponent = () => { + registerMgtPersonComponent(); + registerComponent('organization', MgtOrganization); +}; /** * The member organization subsection of the person card @@ -23,7 +30,6 @@ import { mgtHtml, customElement } from '@microsoft/mgt-element'; * @class MgtOrganization * @extends {MgtTemplatedComponent} */ -@customElement('organization') export class MgtOrganization extends BasePersonCardSection { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-people-picker/mgt-people-picker.ts b/packages/mgt-components/src/components/mgt-people-picker/mgt-people-picker.ts index 9002b2f0fa..d585cff0b2 100644 --- a/packages/mgt-components/src/components/mgt-people-picker/mgt-people-picker.ts +++ b/packages/mgt-components/src/components/mgt-people-picker/mgt-people-picker.ts @@ -31,28 +31,36 @@ import { MgtTemplatedComponent, arraysAreEqual, IGraph, - mgtHtml, - customElement + mgtHtml } from '@microsoft/mgt-element'; import '../../styles/style-helper'; import '../sub-components/mgt-spinner/mgt-spinner'; import { debounce, isValidEmail } from '../../utils/Utils'; -import { MgtPerson, defaultPersonProperties } from '../mgt-person/mgt-person'; +import { MgtPerson, defaultPersonProperties, registerMgtPersonComponent } from '../mgt-person/mgt-person'; import { PersonCardInteraction } from '../PersonCardInteraction'; -import { MgtFlyout } from '../sub-components/mgt-flyout/mgt-flyout'; +import { MgtFlyout, registerMgtFlyoutComponent } from '../sub-components/mgt-flyout/mgt-flyout'; import { styles } from './mgt-people-picker-css'; import { SvgIcon, getSvg } from '../../utils/SvgHelper'; import { fluentTextField, fluentCard } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; import { strings } from './strings'; import { Person, User } from '@microsoft/microsoft-graph-types'; +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtSpinnerComponent } from '../sub-components/mgt-spinner/mgt-spinner'; import { isGraphError } from '../../graph/isGraphError'; -registerFluentComponents(fluentTextField, fluentCard); - export { GroupType } from '../../graph/graph.groups'; export { PersonType, UserType } from '../../graph/graph.people'; +export const registerMgtPeoplePickerComponent = () => { + registerFluentComponents(fluentTextField, fluentCard); + + registerMgtFlyoutComponent(); + registerMgtPersonComponent(); + registerMgtSpinnerComponent(); + registerComponent('people-picker', MgtPeoplePicker); +}; + /** * Web component used to search for people from the Microsoft Graph * @@ -81,7 +89,6 @@ export { PersonType, UserType } from '../../graph/graph.people'; * @cssprop --people-picker-search-icon-color - {Color} the search icon color * @cssprop --people-picker-remove-selected-close-icon-color - {Color} the remove selected person close icon color. */ -@customElement('people-picker') export class MgtPeoplePicker extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-people/mgt-people.ts b/packages/mgt-components/src/components/mgt-people/mgt-people.ts index 74bf23cb36..a47ec9720a 100644 --- a/packages/mgt-components/src/components/mgt-people/mgt-people.ts +++ b/packages/mgt-components/src/components/mgt-people/mgt-people.ts @@ -13,18 +13,12 @@ import { getPeople, getPeopleFromResource, PersonType } from '../../graph/graph. import { getUsersPresenceByPeople } from '../../graph/graph.presence'; import { findGroupMembers, getUsersForPeopleQueries, getUsersForUserIds } from '../../graph/graph.user'; import { IDynamicPerson } from '../../graph/types'; -import { - Providers, - ProviderState, - MgtTemplatedComponent, - arraysAreEqual, - mgtHtml, - customElement -} from '@microsoft/mgt-element'; +import { Providers, ProviderState, MgtTemplatedComponent, arraysAreEqual, mgtHtml } from '@microsoft/mgt-element'; import '../../styles/style-helper'; import { PersonCardInteraction } from './../PersonCardInteraction'; import { styles } from './mgt-people-css'; -import { MgtPerson } from '../mgt-person/mgt-person'; +import { MgtPerson, registerMgtPersonComponent } from '../mgt-person/mgt-person'; +import { registerComponent } from '@microsoft/mgt-element'; export { PersonCardInteraction } from './../PersonCardInteraction'; @@ -41,7 +35,12 @@ export { PersonCardInteraction } from './../PersonCardInteraction'; * @cssprop --people-overflow-font-size - {String} the text color of the overflow text. Default is 12px. * @cssprop --people-overflow-font-weight - {String} the font weight of the overflow text. Default is 400. */ -@customElement('people') + +export const registerMgtPeopleComponent = () => { + registerMgtPersonComponent(); + registerComponent('people', MgtPeople); +}; + export class MgtPeople extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-person-card/mgt-person-card.ts b/packages/mgt-components/src/components/mgt-person-card/mgt-person-card.ts index cc1a8c4f79..31c46ef6cc 100644 --- a/packages/mgt-components/src/components/mgt-person-card/mgt-person-card.ts +++ b/packages/mgt-components/src/components/mgt-person-card/mgt-person-card.ts @@ -14,7 +14,6 @@ import { ProviderState, TeamsHelper, mgtHtml, - customElement, customElementHelper } from '@microsoft/mgt-element'; import { IGraph } from '@microsoft/mgt-element'; @@ -27,13 +26,13 @@ import { getUserWithPhoto } from '../../graph/graph.userWithPhoto'; import { getSvg, SvgIcon } from '../../utils/SvgHelper'; import { getUserPresence } from '../../graph/graph.presence'; import { getPersonCardGraphData, createChat, sendMessage } from './mgt-person-card.graph'; -import { MgtPerson } from '../mgt-person/mgt-person'; +import { MgtPerson, registerMgtPersonComponent } from '../mgt-person/mgt-person'; import { styles } from './mgt-person-card-css'; -import { MgtContact } from '../mgt-contact/mgt-contact'; -import { MgtFileList } from '../mgt-file-list/mgt-file-list'; -import { MgtMessages } from '../mgt-messages/mgt-messages'; -import { MgtOrganization } from '../mgt-organization/mgt-organization'; -import { MgtProfile } from '../mgt-profile/mgt-profile'; +import { MgtContact, registerMgtContactComponent } from '../mgt-contact/mgt-contact'; +import { MgtFileList, registerMgtFileListComponent } from '../mgt-file-list/mgt-file-list'; +import { MgtMessages, registerMgtMessagesComponent } from '../mgt-messages/mgt-messages'; +import { MgtOrganization, registerMgtOrganizationComponent } from '../mgt-organization/mgt-organization'; +import { MgtProfile, registerMgtProfileComponent } from '../mgt-profile/mgt-profile'; import { MgtPersonCardConfig, MgtPersonCardState } from './mgt-person-card.types'; import { strings } from './strings'; import { isUser } from '../../graph/entityType'; @@ -52,8 +51,9 @@ import { } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; import { BasePersonCardSection, CardSection } from '../BasePersonCardSection'; - -registerFluentComponents(fluentCard, fluentTabs, fluentTab, fluentTabPanel, fluentButton, fluentTextField); +import { buildComponentName, registerComponent } from '@microsoft/mgt-element'; +import { registerMgtSpinnerComponent } from '../sub-components/mgt-spinner/mgt-spinner'; +import { IHistoryClearer, IExpandable } from './types'; interface MgtPersonCardStateHistory { state: MgtPersonCardState; @@ -61,6 +61,22 @@ interface MgtPersonCardStateHistory { personImage: string; } +export const registerMgtPersonCardComponent = () => { + registerFluentComponents(fluentCard, fluentTabs, fluentTab, fluentTabPanel, fluentButton, fluentTextField); + // register self first to avoid infinte loop due to circular ref between person and person card and organization + registerComponent('person-card', MgtPersonCard); + + registerMgtSpinnerComponent(); + // these components newed up rather than created declaratively + registerMgtContactComponent(); + registerMgtOrganizationComponent(); + registerMgtMessagesComponent(); + registerMgtFileListComponent(); + registerMgtProfileComponent(); + // only register person if not already registered + if (!customElements.get(buildComponentName('person'))) registerMgtPersonComponent(); +}; + /** * Web Component used to show detailed data for a person in the Microsoft Graph * @@ -99,8 +115,7 @@ interface MgtPersonCardStateHistory { * @cssprop --person-card-chat-input-hover-color - {Color} The chat input hover color * @cssprop --person-card-chat-input-focus-color - {Color} The chat input focus color */ -@customElement('person-card') -export class MgtPersonCard extends MgtTemplatedComponent { +export class MgtPersonCard extends MgtTemplatedComponent implements IHistoryClearer, IExpandable { /** * Array of styles to apply to the element. The styles should be defined * using the `css` tag function. diff --git a/packages/mgt-components/src/components/mgt-person-card/types.ts b/packages/mgt-components/src/components/mgt-person-card/types.ts new file mode 100644 index 0000000000..2d0ae5bc17 --- /dev/null +++ b/packages/mgt-components/src/components/mgt-person-card/types.ts @@ -0,0 +1,7 @@ +export interface IExpandable { + isExpanded: boolean; +} + +export interface IHistoryClearer { + clearHistory: () => void; +} diff --git a/packages/mgt-components/src/components/mgt-person/mgt-person.tests.ts b/packages/mgt-components/src/components/mgt-person/mgt-person.tests.ts index 9338354e9b..096089b227 100644 --- a/packages/mgt-components/src/components/mgt-person/mgt-person.tests.ts +++ b/packages/mgt-components/src/components/mgt-person/mgt-person.tests.ts @@ -4,6 +4,8 @@ * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ +// import the mock for media match first to ensure it's hoisted and available for our dependencies +import '../mgt-theme-toggle/mock-media-match'; import { screen } from 'testing-library__dom'; import { fixture } from '@open-wc/testing-helpers'; @@ -12,11 +14,13 @@ import fetchMock from 'jest-fetch-mock'; import { MockProvider, Providers } from '@microsoft/mgt-element'; import { userPhotoBatchResponse } from './__test_data/mock-responses'; import './mgt-person'; +import { registerMgtPersonComponent } from './mgt-person'; enableFetchMocks(); let person: Element; describe('mgt-person - tests', () => { beforeEach(() => { + registerMgtPersonComponent(); fetchMock.resetMocks(); fetchMock // Response for the setup of the MockGraph to call to the proxy service diff --git a/packages/mgt-components/src/components/mgt-person/mgt-person.ts b/packages/mgt-components/src/components/mgt-person/mgt-person.ts index 79ed7cf3aa..afd078b99f 100644 --- a/packages/mgt-components/src/components/mgt-person/mgt-person.ts +++ b/packages/mgt-components/src/components/mgt-person/mgt-person.ts @@ -5,14 +5,7 @@ * ------------------------------------------------------------------------------------------- */ -import { - MgtTemplatedComponent, - ProviderState, - Providers, - customElement, - customElementHelper, - mgtHtml -} from '@microsoft/mgt-element'; +import { MgtTemplatedComponent, ProviderState, Providers, customElementHelper, mgtHtml } from '@microsoft/mgt-element'; import { Presence } from '@microsoft/microsoft-graph-types'; import { html, TemplateResult, nothing } from 'lit'; import { property, state } from 'lit/decorators.js'; @@ -25,15 +18,16 @@ import { getUserWithPhoto } from '../../graph/graph.userWithPhoto'; import { AvatarSize, IDynamicPerson, ViewType } from '../../graph/types'; import '../../styles/style-helper'; import { SvgIcon, getSvg } from '../../utils/SvgHelper'; -import { MgtPersonCard } from '../mgt-person-card/mgt-person-card'; import '../sub-components/mgt-flyout/mgt-flyout'; -import { MgtFlyout } from '../sub-components/mgt-flyout/mgt-flyout'; +import { MgtFlyout, registerMgtFlyoutComponent } from '../sub-components/mgt-flyout/mgt-flyout'; import { PersonCardInteraction } from './../PersonCardInteraction'; import { styles } from './mgt-person-css'; import { MgtPersonConfig, PersonViewType, avatarType } from './mgt-person-types'; import { strings } from './strings'; import { isUser, isContact } from '../../graph/entityType'; import { ifDefined } from 'lit/directives/if-defined.js'; +import { buildComponentName, registerComponent } from '@microsoft/mgt-element'; +import { IExpandable, IHistoryClearer } from '../mgt-person-card/types'; export { PersonCardInteraction } from '../PersonCardInteraction'; @@ -56,6 +50,13 @@ export const defaultPersonProperties = [ 'userType' ]; +export const registerMgtPersonComponent = () => { + // register self first to avoid infinte loop due to circular ref between person and person card + registerComponent('person', MgtPerson); + + registerMgtFlyoutComponent(); +}; + /** * The person component is used to display a person or contact by using their photo, name, and/or email address. * @@ -106,7 +107,6 @@ export const defaultPersonProperties = [ * * @cssprop --person-details-wrapper-width - {Length} the minimum width of the details section. Default is 168px. */ -@customElement('person') export class MgtPerson extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined @@ -531,6 +531,7 @@ export class MgtPerson extends MgtTemplatedComponent { @state() private _fetchedPresence: Presence; @state() private _isInvalidImageSrc: boolean; @state() private _personCardShouldRender: boolean; + @state() private _hasLoadedPersonCard = false; private _personDetailsInternal: IDynamicPerson; private _personDetails: IDynamicPerson; @@ -1031,12 +1032,13 @@ export class MgtPerson extends MgtTemplatedComponent { image: string, presence: Presence ): TemplateResult { - const flyoutContent = this._personCardShouldRender - ? html` + const flyoutContent = + this._personCardShouldRender && this._hasLoadedPersonCard + ? html`
${this.renderFlyoutContent(personDetails, image, presence)}
` - : html``; + : html``; const slotClasses = classMap({ vertical: this.isVertical() @@ -1342,16 +1344,30 @@ export class MgtPerson extends MgtTemplatedComponent { flyout.close(); } const personCard = - this.querySelector('.mgt-person-card') || this.renderRoot.querySelector('.mgt-person-card'); + this.querySelector('.mgt-person-card') || + this.renderRoot.querySelector('.mgt-person-card'); if (personCard) { personCard.isExpanded = false; personCard.clearHistory(); } }; + private readonly loadPersonCardResources = async () => { + // if there could be a person-card then we should load those resources using a dynamic import + if (this.personCardInteraction !== PersonCardInteraction.none && !this._hasLoadedPersonCard) { + const { registerMgtPersonCardComponent } = await import('../mgt-person-card/mgt-person-card'); + + // only register person card if it hasn't been registered yet + if (!customElements.get(buildComponentName('person-card'))) registerMgtPersonCardComponent(); + + this._hasLoadedPersonCard = true; + } + }; + public showPersonCard = () => { if (!this._personCardShouldRender) { this._personCardShouldRender = true; + void this.loadPersonCardResources(); } const flyout = this.flyout; diff --git a/packages/mgt-components/src/components/mgt-picker/mgt-picker.ts b/packages/mgt-components/src/components/mgt-picker/mgt-picker.ts index 2071dfcb81..d1e4e531e4 100644 --- a/packages/mgt-components/src/components/mgt-picker/mgt-picker.ts +++ b/packages/mgt-components/src/components/mgt-picker/mgt-picker.ts @@ -8,16 +8,22 @@ import { html, TemplateResult } from 'lit'; import { property, state } from 'lit/decorators.js'; import { ifDefined } from 'lit/directives/if-defined.js'; -import { MgtTemplatedComponent, mgtHtml, customElement } from '@microsoft/mgt-element'; +import { MgtTemplatedComponent, mgtHtml } from '@microsoft/mgt-element'; import { strings } from './strings'; import { fluentCombobox, fluentOption } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; import '../../styles/style-helper'; import { Entity } from '@microsoft/microsoft-graph-types'; -import { DataChangedDetail } from '../mgt-get/mgt-get'; +import { DataChangedDetail, registerMgtGetComponent } from '../mgt-get/mgt-get'; import { styles } from './mgt-picker-css'; +import { registerComponent } from '@microsoft/mgt-element'; -registerFluentComponents(fluentCombobox, fluentOption); +export const registerMgtPickerComponent = () => { + registerFluentComponents(fluentCombobox, fluentOption); + + registerMgtGetComponent(); + registerComponent('picker', MgtPicker); +}; /** * Web component that allows a single entity pick from a generic endpoint from Graph. Uses mgt-get. @@ -30,7 +36,6 @@ registerFluentComponents(fluentCombobox, fluentOption); * @cssprop --picker-background-color - {Color} Picker component background color * @cssprop --picker-list-max-height - {String} max height for options list. Default value is 380px. */ -@customElement('picker') export class MgtPicker extends MgtTemplatedComponent { protected get strings() { return strings; diff --git a/packages/mgt-components/src/components/mgt-profile/mgt-profile.ts b/packages/mgt-components/src/components/mgt-profile/mgt-profile.ts index 3824fa8e8e..40cda2b6f3 100644 --- a/packages/mgt-components/src/components/mgt-profile/mgt-profile.ts +++ b/packages/mgt-components/src/components/mgt-profile/mgt-profile.ts @@ -17,7 +17,9 @@ import { BasePersonCardSection } from '../BasePersonCardSection'; import { getSvg, SvgIcon } from '../../utils/SvgHelper'; import { styles } from './mgt-profile-css'; import { strings } from './strings'; -import { customElement } from '@microsoft/mgt-element'; +import { registerComponent } from '@microsoft/mgt-element'; + +export const registerMgtProfileComponent = () => registerComponent('profile', MgtProfile); /** * The user profile subsection of the person card @@ -28,7 +30,6 @@ import { customElement } from '@microsoft/mgt-element'; * * @cssprop --token-overflow-color - {Color} Color of the text showing more undisplayed values i.e. +3 more */ -@customElement('profile') export class MgtProfile extends BasePersonCardSection { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-tasks-base/mgt-tasks-base.ts b/packages/mgt-components/src/components/mgt-tasks-base/mgt-tasks-base.ts index 6405282901..e2690a5dea 100644 --- a/packages/mgt-components/src/components/mgt-tasks-base/mgt-tasks-base.ts +++ b/packages/mgt-components/src/components/mgt-tasks-base/mgt-tasks-base.ts @@ -12,9 +12,6 @@ import { strings } from './strings'; import { registerFluentComponents } from '../../utils/FluentComponents'; import { fluentTextField, fluentButton, fluentCalendar } from '@fluentui/web-components'; import { TodoTask } from '@microsoft/microsoft-graph-types'; - -registerFluentComponents(fluentTextField, fluentButton, fluentCalendar); - /** * The foundation for creating task based components. * @@ -75,6 +72,8 @@ export abstract class MgtTasksBase extends MgtTemplatedComponent { constructor() { super(); + registerFluentComponents(fluentTextField, fluentButton, fluentCalendar); + this.clearState(); this._previousMediaQuery = this.mediaQuery; } diff --git a/packages/mgt-components/src/components/mgt-tasks/mgt-tasks.ts b/packages/mgt-components/src/components/mgt-tasks/mgt-tasks.ts index eb36314cff..b4ed549121 100644 --- a/packages/mgt-components/src/components/mgt-tasks/mgt-tasks.ts +++ b/packages/mgt-components/src/components/mgt-tasks/mgt-tasks.ts @@ -5,14 +5,7 @@ * ------------------------------------------------------------------------------------------- */ -import { - ComponentMediaQuery, - MgtTemplatedComponent, - ProviderState, - Providers, - customElement, - mgtHtml -} from '@microsoft/mgt-element'; +import { ComponentMediaQuery, MgtTemplatedComponent, ProviderState, Providers, mgtHtml } from '@microsoft/mgt-element'; import { Person, PlannerAssignments, PlannerTask, User } from '@microsoft/microsoft-graph-types'; import { Contact, OutlookTask, OutlookTaskFolder } from '@microsoft/microsoft-graph-types-beta'; import { HTMLTemplateResult, PropertyValueMap, TemplateResult, html } from 'lit'; @@ -22,12 +15,12 @@ import { repeat } from 'lit/directives/repeat.js'; import { ifDefined } from 'lit/directives/if-defined.js'; import { getMe } from '../../graph/graph.user'; import { getShortDateString } from '../../utils/Utils'; -import { MgtPeoplePicker } from '../mgt-people-picker/mgt-people-picker'; -import { MgtPeople } from '../mgt-people/mgt-people'; +import { MgtPeoplePicker, registerMgtPeoplePickerComponent } from '../mgt-people-picker/mgt-people-picker'; +import { MgtPeople, registerMgtPeopleComponent } from '../mgt-people/mgt-people'; import '../mgt-person/mgt-person'; import '../sub-components/mgt-arrow-options/mgt-arrow-options'; import '../sub-components/mgt-dot-options/mgt-dot-options'; -import { MgtFlyout } from '../sub-components/mgt-flyout/mgt-flyout'; +import { MgtFlyout, registerMgtFlyoutComponent } from '../sub-components/mgt-flyout/mgt-flyout'; import { PersonCardInteraction } from './../PersonCardInteraction'; import { styles } from './mgt-tasks-css'; import { strings } from './strings'; @@ -43,8 +36,9 @@ import { fluentCheckbox, fluentSkeleton } from '@fluentui/web-components'; - -registerFluentComponents(fluentSelect, fluentOption, fluentTextField, fluentButton, fluentCheckbox, fluentSkeleton); +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtDotOptionsComponent } from '../sub-components/mgt-dot-options/mgt-dot-options'; +import { registerMgtArrowOptionsComponent } from '../sub-components/mgt-arrow-options/mgt-arrow-options'; /** * Defines how a person card is shown when a user interacts with @@ -137,6 +131,17 @@ const plannerAssignment = { orderHint: ' !' }; +export const registerMgtTasksComponent = () => { + registerFluentComponents(fluentSelect, fluentOption, fluentTextField, fluentButton, fluentCheckbox, fluentSkeleton); + + registerMgtArrowOptionsComponent(); + registerMgtDotOptionsComponent(); + registerMgtFlyoutComponent(); + registerMgtPeopleComponent(); + registerMgtPeoplePickerComponent(); + registerComponent('tasks', MgtTasks); +}; + /** * Web component enables the user to view, add, remove, complete, or edit tasks. It works with tasks in Microsoft Planner or Microsoft To-Do. * @@ -231,8 +236,6 @@ const plannerAssignment = { * @cssprop --tasks-border-radius - {Length} the border radius of the area where the tasks are rendered. Default is none. * @cssprop --tasks-padding - {Length} the padding of the are where the tasks are rendered. Default is 12px. */ - -@customElement('tasks') export class MgtTasks extends MgtTemplatedComponent { /** * determines whether todo, or planner functionality for task component diff --git a/packages/mgt-components/src/components/mgt-taxonomy-picker/mgt-taxonomy-picker.ts b/packages/mgt-components/src/components/mgt-taxonomy-picker/mgt-taxonomy-picker.ts index 4293fdf2ea..6d34dd60a5 100644 --- a/packages/mgt-components/src/components/mgt-taxonomy-picker/mgt-taxonomy-picker.ts +++ b/packages/mgt-components/src/components/mgt-taxonomy-picker/mgt-taxonomy-picker.ts @@ -9,15 +9,23 @@ import type * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; import { Position } from '../../graph/types'; import { html, TemplateResult } from 'lit'; import { property, state } from 'lit/decorators.js'; -import { MgtTemplatedComponent, mgtHtml, customElement } from '@microsoft/mgt-element'; +import { MgtTemplatedComponent, mgtHtml } from '@microsoft/mgt-element'; import { strings } from './strings'; import { fluentCombobox, fluentOption } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; import '../../styles/style-helper'; import { styles } from './mgt-taxonomy-picker-css'; -import { DataChangedDetail } from '../mgt-get/mgt-get'; +import { DataChangedDetail, registerMgtGetComponent } from '../mgt-get/mgt-get'; +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtSpinnerComponent } from '../sub-components/mgt-spinner/mgt-spinner'; -registerFluentComponents(fluentCombobox, fluentOption); +export const registerMgtTaxonomyPickerComponent = () => { + registerFluentComponents(fluentCombobox, fluentOption); + + registerMgtSpinnerComponent(); + registerMgtGetComponent(); + registerComponent('taxonomy-picker', MgtTaxonomyPicker); +}; /** * Web component that can query the Microsoft Graph API for Taxonomy @@ -36,7 +44,6 @@ registerFluentComponents(fluentCombobox, fluentOption); * @cssprop --taxonomy-picker-placeholder-color - {Color} Text color for the placeholder in the picker * @cssprop --taxonomy-picker-placeholder-hover-color - {Color} Text color for the placeholder in the picker on hover */ -@customElement('taxonomy-picker') export class MgtTaxonomyPicker extends MgtTemplatedComponent { /** * The strings to be used for localizing the component. diff --git a/packages/mgt-components/src/components/mgt-teams-channel-picker/mgt-teams-channel-picker.ts b/packages/mgt-components/src/components/mgt-teams-channel-picker/mgt-teams-channel-picker.ts index f841e433cb..1342652a5a 100644 --- a/packages/mgt-components/src/components/mgt-teams-channel-picker/mgt-teams-channel-picker.ts +++ b/packages/mgt-components/src/components/mgt-teams-channel-picker/mgt-teams-channel-picker.ts @@ -14,7 +14,6 @@ import { ProviderState, MgtTemplatedComponent, BetaGraph, - customElement, mgtHtml, CollectionResponse } from '@microsoft/mgt-element'; @@ -35,15 +34,8 @@ import { fluentCard, fluentTextField } from '@fluentui/web-components'; - -registerFluentComponents( - fluentBreadcrumb, - fluentBreadcrumbItem, - fluentCard, - fluentTreeView, - fluentTreeItem, - fluentTextField -); +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtSpinnerComponent } from '../sub-components/mgt-spinner/mgt-spinner'; /** * Team with displayName @@ -143,6 +135,19 @@ interface ChannelPickerItemState { parent: ChannelPickerItemState; } +export const registerMgtTeamsChannelPickerComponent = () => { + registerFluentComponents( + fluentBreadcrumb, + fluentBreadcrumbItem, + fluentCard, + fluentTreeView, + fluentTreeItem, + fluentTextField + ); + registerMgtSpinnerComponent(); + registerComponent('teams-channel-picker', MgtTeamsChannelPicker); +}; + /** * Web component used to select channels from a User's Microsoft Teams profile * @@ -173,7 +178,6 @@ interface ChannelPickerItemState { * @cssprop --channel-picker-close-icon-color - {Color} the close icon color. * */ -@customElement('teams-channel-picker') export class MgtTeamsChannelPicker extends MgtTemplatedComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.tests.ts b/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.tests.ts index c2e798da8a..7a7df69be7 100644 --- a/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.tests.ts +++ b/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.tests.ts @@ -9,6 +9,7 @@ import './mock-media-match'; import { screen } from 'testing-library__dom'; import { fixture } from '@open-wc/testing-helpers'; import './mgt-theme-toggle'; +import { registerMgtThemeToggleComponent } from './mgt-theme-toggle'; class Deferred { promise: Promise; @@ -23,6 +24,9 @@ class Deferred { } describe('mgt-theme-toggle - tests', () => { + beforeEach(() => { + registerMgtThemeToggleComponent(); + }); it('should render', async () => { await fixture(''); const toggle = await screen.findByRole('switch'); diff --git a/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.ts b/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.ts index 5e6d0b1eb0..87e99a0c1d 100644 --- a/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.ts +++ b/packages/mgt-components/src/components/mgt-theme-toggle/mgt-theme-toggle.ts @@ -7,13 +7,17 @@ import { html, TemplateResult } from 'lit'; import { property } from 'lit/decorators.js'; -import { customElement, MgtBaseComponent } from '@microsoft/mgt-element'; +import { MgtBaseComponent } from '@microsoft/mgt-element'; import { fluentSwitch } from '@fluentui/web-components'; import { registerFluentComponents } from '../../utils/FluentComponents'; import { applyTheme } from '../../styles/theme-manager'; import { strings } from './strings'; +import { registerComponent } from '@microsoft/mgt-element'; -registerFluentComponents(fluentSwitch); +export const registerMgtThemeToggleComponent = () => { + registerFluentComponents(fluentSwitch); + registerComponent('theme-toggle', MgtThemeToggle); +}; /** * Toggle to switch between light and dark mode @@ -24,7 +28,6 @@ registerFluentComponents(fluentSwitch); * @class MgtDarkToggle * @extends {MgtBaseComponent} */ -@customElement('theme-toggle') export class MgtThemeToggle extends MgtBaseComponent { constructor() { super(); diff --git a/packages/mgt-components/src/components/mgt-todo/mgt-todo.ts b/packages/mgt-components/src/components/mgt-todo/mgt-todo.ts index fb6e92d7c9..a132e55043 100644 --- a/packages/mgt-components/src/components/mgt-todo/mgt-todo.ts +++ b/packages/mgt-components/src/components/mgt-todo/mgt-todo.ts @@ -9,7 +9,7 @@ import { html, nothing, TemplateResult } from 'lit'; import { state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { repeat } from 'lit/directives/repeat.js'; -import { IGraph, customElement, mgtHtml } from '@microsoft/mgt-element'; +import { IGraph, mgtHtml } from '@microsoft/mgt-element'; import { Providers, ProviderState } from '@microsoft/mgt-element'; import { getDateString } from '../../utils/Utils'; import { getSvg, SvgIcon } from '../../utils/SvgHelper'; @@ -33,14 +33,20 @@ import { isElementDark } from '../../utils/isDark'; import { ifDefined } from 'lit/directives/if-defined.js'; import { TodoTaskList, TodoTask, TaskStatus } from '@microsoft/microsoft-graph-types'; - -registerFluentComponents(fluentCheckbox, fluentRadioGroup, fluentButton); +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtPickerComponent } from '../mgt-picker/mgt-picker'; /** * Filter function */ export type TodoFilter = (task: TodoTask) => boolean; +export const registerMgtTodoComponent = () => { + registerFluentComponents(fluentCheckbox, fluentRadioGroup, fluentButton); + registerMgtPickerComponent(); + registerComponent('todo', MgtTodo); +}; + /** * component enables the user to view, add, remove, complete, or edit todo tasks. It works with tasks in Microsoft Planner or Microsoft To-Do. * @@ -58,7 +64,6 @@ export type TodoFilter = (task: TodoTask) => boolean; * @cssprop --task-border-completed - {Color} - Task border color when completed * @cssprop --task-radio-background-color - {Color} - Task radio background color */ -@customElement('todo') export class MgtTodo extends MgtTasksBase { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/preview/mgt-search-box/mgt-search-box.ts b/packages/mgt-components/src/components/preview/mgt-search-box/mgt-search-box.ts index 2ec351735a..b599d1853c 100644 --- a/packages/mgt-components/src/components/preview/mgt-search-box/mgt-search-box.ts +++ b/packages/mgt-components/src/components/preview/mgt-search-box/mgt-search-box.ts @@ -7,14 +7,18 @@ import { CSSResult, html, TemplateResult } from 'lit'; import { property } from 'lit/decorators.js'; -import { customElement, MgtBaseComponent } from '@microsoft/mgt-element'; +import { MgtBaseComponent } from '@microsoft/mgt-element'; import { fluentSearch } from '@fluentui/web-components'; import { registerFluentComponents } from '../../../utils/FluentComponents'; import { strings } from './strings'; import { styles } from './mgt-search-box-css'; import { debounce } from '../../../utils/Utils'; +import { registerComponent } from '@microsoft/mgt-element'; -registerFluentComponents(fluentSearch); +export const registerMgtSearchBoxComponent = () => { + registerFluentComponents(fluentSearch); + registerComponent('search-box', MgtSearchBox); +}; /** * **Preview component** Web component used to enter a search value to power search scenarios. @@ -25,7 +29,6 @@ registerFluentComponents(fluentSearch); * @class MgtSearchBox * @extends {MgtBaseComponent} */ -@customElement('search-box') export class MgtSearchBox extends MgtBaseComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/preview/mgt-search-results/mgt-search-results.ts b/packages/mgt-components/src/components/preview/mgt-search-results/mgt-search-results.ts index 5ca2e4e2c0..f5916bc393 100644 --- a/packages/mgt-components/src/components/preview/mgt-search-results/mgt-search-results.ts +++ b/packages/mgt-components/src/components/preview/mgt-search-results/mgt-search-results.ts @@ -15,7 +15,6 @@ import { prepScopes, Providers, ProviderState, - customElement, mgtHtml, BetaGraph, BatchResponse, @@ -52,8 +51,9 @@ import { getSvg, SvgIcon } from '../../../utils/SvgHelper'; import { fluentSkeleton, fluentButton, fluentTooltip, fluentDivider } from '@fluentui/web-components'; import { registerFluentComponents } from '../../../utils/FluentComponents'; import { CacheResponse } from '../../CacheResponse'; - -registerFluentComponents(fluentSkeleton, fluentButton, fluentTooltip, fluentDivider); +import { registerComponent } from '@microsoft/mgt-element'; +import { registerMgtFileComponent } from '../../mgt-file/mgt-file'; +import { registerMgtPersonComponent } from '../../mgt-person/mgt-person'; /** * Object representing a thumbnail @@ -118,6 +118,14 @@ type SearchResource = Partial< */ type SearchResponseCollection = CollectionResponse; +export const registerMgtSearchResultsComponent = () => { + registerFluentComponents(fluentSkeleton, fluentButton, fluentTooltip, fluentDivider); + + registerMgtFileComponent(); + registerMgtPersonComponent(); + registerComponent('search-results', MgtSearchResults); +}; + /** * **Preview component** Custom element for making Microsoft Graph get queries. * Component may change before general availability release. @@ -132,7 +140,6 @@ type SearchResponseCollection = CollectionResponse; * @class mgt-search-results * @extends {MgtTemplatedComponent} */ -@customElement('search-results') export class MgtSearchResults extends MgtTemplatedComponent { /** * Default page size is 10 diff --git a/packages/mgt-components/src/components/sub-components/mgt-arrow-options/mgt-arrow-options.ts b/packages/mgt-components/src/components/sub-components/mgt-arrow-options/mgt-arrow-options.ts index 59bd25ac0b..11ac743906 100644 --- a/packages/mgt-components/src/components/sub-components/mgt-arrow-options/mgt-arrow-options.ts +++ b/packages/mgt-components/src/components/sub-components/mgt-arrow-options/mgt-arrow-options.ts @@ -8,11 +8,11 @@ import { html } from 'lit'; import { property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; -import { MgtBaseComponent, customElement } from '@microsoft/mgt-element'; +import { MgtBaseComponent } from '@microsoft/mgt-element'; import { styles } from './mgt-arrow-options-css'; import { registerFluentComponents } from '../../../utils/FluentComponents'; import { fluentMenu, fluentMenuItem, fluentButton } from '@fluentui/web-components'; -registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton); +import { registerComponent } from '@microsoft/mgt-element'; /* Ok, the name here deserves a bit of explanation, @@ -22,6 +22,11 @@ registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton); - benotter */ +export const registerMgtArrowOptionsComponent = () => { + registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton); + registerComponent('arrow-options', MgtArrowOptions); +}; + /** * Custom Component used to handle an arrow rendering for TaskGroups utilized in the task component. * @@ -35,7 +40,6 @@ registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton); * @class MgtArrowOptions * @extends {MgtBaseComponent} */ -@customElement('arrow-options') export class MgtArrowOptions extends MgtBaseComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/sub-components/mgt-dot-options/mgt-dot-options.ts b/packages/mgt-components/src/components/sub-components/mgt-dot-options/mgt-dot-options.ts index 918b92b940..6ffa21a5cc 100644 --- a/packages/mgt-components/src/components/sub-components/mgt-dot-options/mgt-dot-options.ts +++ b/packages/mgt-components/src/components/sub-components/mgt-dot-options/mgt-dot-options.ts @@ -6,21 +6,25 @@ */ import { fluentMenu, fluentMenuItem, fluentButton } from '@fluentui/web-components'; -import { MgtBaseComponent, customElement } from '@microsoft/mgt-element'; +import { MgtBaseComponent } from '@microsoft/mgt-element'; import { html } from 'lit'; import { property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { strings } from './strings'; import { registerFluentComponents } from '../../../utils/FluentComponents'; import { styles } from './mgt-dot-options-css'; - -registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton); +import { registerComponent } from '@microsoft/mgt-element'; /** * Defines the event functions passed to the option item. */ type MenuOptionEventFunction = (e: Event) => void; +export const registerMgtDotOptionsComponent = () => { + registerFluentComponents(fluentMenu, fluentMenuItem, fluentButton); + registerComponent('dot-options', MgtDotOptions); +}; + /** * Custom Component used to handle an arrow rendering for TaskGroups utilized in the task component. * @@ -28,7 +32,7 @@ type MenuOptionEventFunction = (e: Event) => void; * @class MgtDotOptions * @extends {MgtBaseComponent} */ -@customElement('dot-options') + export class MgtDotOptions extends MgtBaseComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/sub-components/mgt-flyout/mgt-flyout.ts b/packages/mgt-components/src/components/sub-components/mgt-flyout/mgt-flyout.ts index 612a843366..1dc936e82a 100644 --- a/packages/mgt-components/src/components/sub-components/mgt-flyout/mgt-flyout.ts +++ b/packages/mgt-components/src/components/sub-components/mgt-flyout/mgt-flyout.ts @@ -10,7 +10,10 @@ import { property } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { getSegmentAwareWindow, isWindowSegmentAware, IWindowSegment } from '../../../utils/WindowSegmentHelpers'; import { styles } from './mgt-flyout-css'; -import { MgtBaseComponent, customElement } from '@microsoft/mgt-element/'; +import { MgtBaseComponent } from '@microsoft/mgt-element/'; +import { registerComponent } from '@microsoft/mgt-element'; + +export const registerMgtFlyoutComponent = () => registerComponent('flyout', MgtFlyout); /** * A component to create flyout anchored to an element @@ -19,7 +22,6 @@ import { MgtBaseComponent, customElement } from '@microsoft/mgt-element/'; * @class MgtFlyout * @extends {LitElement} */ -@customElement('flyout') export class MgtFlyout extends MgtBaseComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.tests.ts b/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.tests.ts index 7044b2b094..d8c0e15469 100644 --- a/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.tests.ts +++ b/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.tests.ts @@ -8,10 +8,12 @@ import { screen } from 'testing-library__dom'; import { fixture } from '@open-wc/testing-helpers'; import './mgt-spinner'; +import { registerMgtSpinnerComponent } from './mgt-spinner'; let spinner: Element; describe('mgt-spinner tests', () => { beforeEach(async () => { + registerMgtSpinnerComponent(); spinner = await fixture(''); }); diff --git a/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.ts b/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.ts index c35a3bf1e5..ca31c4d7be 100644 --- a/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.ts +++ b/packages/mgt-components/src/components/sub-components/mgt-spinner/mgt-spinner.ts @@ -6,8 +6,11 @@ */ import { html } from 'lit'; -import { MgtBaseComponent, customElement } from '@microsoft/mgt-element'; +import { MgtBaseComponent } from '@microsoft/mgt-element'; import { styles } from './mgt-spinner-css'; +import { registerComponent } from '@microsoft/mgt-element'; + +export const registerMgtSpinnerComponent = () => registerComponent('spinner', MgtSpinner); /** * Custom Component used to handle loading state in components. @@ -16,7 +19,6 @@ import { styles } from './mgt-spinner-css'; * @class MgtSpinner * @extends {MgtBaseComponent} */ -@customElement('spinner') export class MgtSpinner extends MgtBaseComponent { /** * Array of styles to apply to the element. The styles should be defined diff --git a/packages/mgt-components/src/exports.ts b/packages/mgt-components/src/exports.ts new file mode 100644 index 0000000000..573989c5d6 --- /dev/null +++ b/packages/mgt-components/src/exports.ts @@ -0,0 +1,12 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +export * from './components/components'; +export * from './components/preview'; +export * from './graph/types'; +export * from './styles/theme-manager'; +export * from './graph/entityType'; diff --git a/packages/mgt-components/src/index.ts b/packages/mgt-components/src/index.ts index 573989c5d6..eedaa7a348 100644 --- a/packages/mgt-components/src/index.ts +++ b/packages/mgt-components/src/index.ts @@ -4,9 +4,10 @@ * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ +import { registerMgtComponents } from './registerMgtComponents'; -export * from './components/components'; -export * from './components/preview'; -export * from './graph/types'; -export * from './styles/theme-manager'; -export * from './graph/entityType'; +export * from './exports'; + +// this side effect will register all components +// this is to prevent a breaking change as we enable tree shaking +registerMgtComponents(); diff --git a/packages/mgt-components/src/registerMgtComponents.ts b/packages/mgt-components/src/registerMgtComponents.ts new file mode 100644 index 0000000000..24d264cc4b --- /dev/null +++ b/packages/mgt-components/src/registerMgtComponents.ts @@ -0,0 +1,43 @@ +import { + registerMgtAgendaComponent, + registerMgtFileComponent, + registerMgtFileListComponent, + registerMgtGetComponent, + registerMgtLoginComponent, + registerMgtPeopleComponent, + registerMgtPeoplePickerComponent, + registerMgtPersonCardComponent, + registerMgtPersonComponent, + registerMgtPickerComponent, + registerMgtSearchBoxComponent, + registerMgtSearchResultsComponent, + registerMgtSpinnerComponent, + registerMgtTasksComponent, + registerMgtTaxonomyPickerComponent, + registerMgtTeamsChannelPickerComponent, + registerMgtThemeToggleComponent, + registerMgtTodoComponent +} from './components/components'; + +export const registerMgtComponents = () => { + // this should match the set of components listed for export in packages/mgt-react/scripts/generate.js + // all "internal" components should be registered from their parent components + registerMgtPersonComponent(); + registerMgtPersonCardComponent(); + registerMgtAgendaComponent(); + registerMgtGetComponent(); + registerMgtLoginComponent(); + registerMgtPeoplePickerComponent(); + registerMgtPeopleComponent(); + registerMgtTasksComponent(); + registerMgtTeamsChannelPickerComponent(); + registerMgtTodoComponent(); + registerMgtFileComponent(); + registerMgtFileListComponent(); + registerMgtPickerComponent(); + registerMgtTaxonomyPickerComponent(); + registerMgtThemeToggleComponent(); + registerMgtSearchBoxComponent(); + registerMgtSearchResultsComponent(); + registerMgtSpinnerComponent(); +}; diff --git a/packages/mgt-components/tsconfig.json b/packages/mgt-components/tsconfig.json index 135364a38f..4cfdff7ab8 100644 --- a/packages/mgt-components/tsconfig.json +++ b/packages/mgt-components/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.base.json", "compilerOptions": { + "module": "ES2020", "outDir": "dist/es6", "sourceRoot": "src", "rootDir": "src", diff --git a/packages/mgt-element/README.md b/packages/mgt-element/README.md index c90d9b643d..ddd5cdbf9a 100644 --- a/packages/mgt-element/README.md +++ b/packages/mgt-element/README.md @@ -24,7 +24,8 @@ This example illustrates how to instantiate a new provider (MsalProvider in this ```ts import {Providers} from '@microsoft/mgt-element'; - import {Msal2Provider} from '@microsoft/mgt-msal2-provider'; + // importing via the export path will exclude the custom element for from the final bundle + import {Msal2Provider} from '@microsoft/mgt-msal2-provider/dist/es6/exports'; // initialize the auth provider globally Providers.globalProvider = new Msal2Provider({clientId: 'clientId'}); diff --git a/packages/mgt-element/package.json b/packages/mgt-element/package.json index c72dd5bf34..ea878a09c2 100644 --- a/packages/mgt-element/package.json +++ b/packages/mgt-element/package.json @@ -30,6 +30,7 @@ "setVersion": "gulp setVersion --cwd .", "postpack": "cpx *.tgz ../../artifacts" }, + "sideEffects": false, "dependencies": { "@microsoft/microsoft-graph-client": "3.0.2", "idb": "6.0.0", diff --git a/packages/mgt-element/src/Graph.ts b/packages/mgt-element/src/Graph.ts index a94e06e555..b28410beb8 100644 --- a/packages/mgt-element/src/Graph.ts +++ b/packages/mgt-element/src/Graph.ts @@ -21,7 +21,7 @@ import { IGraph, MICROSOFT_GRAPH_DEFAULT_ENDPOINT } from './IGraph'; import { IProvider } from './providers/IProvider'; import { Batch } from './utils/Batch'; import { ComponentMiddlewareOptions } from './utils/ComponentMiddlewareOptions'; -import { chainMiddleware } from './utils/GraphHelpers'; +import { chainMiddleware } from './utils/chainMiddleware'; import { SdkVersionMiddleware } from './utils/SdkVersionMiddleware'; import { PACKAGE_VERSION } from './utils/version'; import { customElementHelper } from './components/customElementHelper'; diff --git a/packages/mgt-element/src/index.ts b/packages/mgt-element/src/index.ts index 196ffb39e2..2f89f7612b 100644 --- a/packages/mgt-element/src/index.ts +++ b/packages/mgt-element/src/index.ts @@ -19,11 +19,16 @@ export * from './providers/IProvider'; export * from './providers/Providers'; export * from './providers/SimpleProvider'; +export * from './utils/CacheItem'; +export * from './utils/CacheSchema'; export * from './utils/CacheService'; export * from './utils/CacheStore'; +export * from './utils/dbListKey'; export * from './utils/EventDispatcher'; export * from './utils/equals'; -export * from './utils/GraphHelpers'; +export * from './utils/chainMiddleware'; +export * from './utils/prepScopes'; +export * from './utils/validateBaseURL'; export * from './utils/TeamsHelper'; export * from './utils/TemplateContext'; export * from './utils/TemplateHelper'; @@ -31,6 +36,8 @@ export * from './utils/GraphPageIterator'; export * from './utils/LocalizationHelper'; export * from './utils/mgtHtml'; export * from './utils/CustomElement'; +export * from './utils/registerComponent'; + export { PACKAGE_VERSION } from './utils/version'; export * from './CollectionResponse'; diff --git a/packages/mgt-element/src/mock/MockGraph.ts b/packages/mgt-element/src/mock/MockGraph.ts index 5cfb1ed55c..971ab546f3 100644 --- a/packages/mgt-element/src/mock/MockGraph.ts +++ b/packages/mgt-element/src/mock/MockGraph.ts @@ -16,7 +16,7 @@ import { } from '@microsoft/microsoft-graph-client'; import { MgtBaseComponent } from '../components/baseComponent'; import { Graph } from '../Graph'; -import { chainMiddleware } from '../utils/GraphHelpers'; +import { chainMiddleware } from '../utils/chainMiddleware'; import { MockProvider } from './MockProvider'; import { MockMiddleware } from './MockMiddleware'; diff --git a/packages/mgt-element/src/providers/IProvider.ts b/packages/mgt-element/src/providers/IProvider.ts index 810207c7b0..275e78aec5 100644 --- a/packages/mgt-element/src/providers/IProvider.ts +++ b/packages/mgt-element/src/providers/IProvider.ts @@ -6,12 +6,12 @@ */ import { AuthenticationProvider, AuthenticationProviderOptions } from '@microsoft/microsoft-graph-client'; -import { validateBaseURL } from '../utils/GraphHelpers'; +import { validateBaseURL } from '../utils/validateBaseURL'; import { GraphEndpoint, IGraph, MICROSOFT_GRAPH_DEFAULT_ENDPOINT } from '../IGraph'; import { EventDispatcher, EventHandler } from '../utils/EventDispatcher'; /** - * Provider Type to be extended for implmenting new providers + * Provider Type to be extended for implementing new providers * * @export * @abstract diff --git a/packages/mgt-element/src/utils/Batch.ts b/packages/mgt-element/src/utils/Batch.ts index dbaf42a504..37f326b090 100644 --- a/packages/mgt-element/src/utils/Batch.ts +++ b/packages/mgt-element/src/utils/Batch.ts @@ -7,8 +7,8 @@ import { BatchResponse, BatchResponseBody, IBatch } from '../IBatch'; import { BatchRequestContent, MiddlewareOptions } from '@microsoft/microsoft-graph-client'; -import { delay } from '../utils'; -import { prepScopes } from './GraphHelpers'; +import { delay } from './delay'; +import { prepScopes } from './prepScopes'; import { IGraph } from '../IGraph'; import { BatchRequest } from './BatchRequest'; diff --git a/packages/mgt-element/src/utils/CacheItem.ts b/packages/mgt-element/src/utils/CacheItem.ts new file mode 100644 index 0000000000..e8afa93183 --- /dev/null +++ b/packages/mgt-element/src/utils/CacheItem.ts @@ -0,0 +1,23 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +/** + * item that is stored in cache + * + * @export + * @interface CacheItem + */ + +export interface CacheItem { + /** + * date and time that item was retrieved from api/stored in cache + * + * @type {number} + * @memberof CacheItem + */ + timeCached?: number; +} diff --git a/packages/mgt-element/src/utils/CacheSchema.ts b/packages/mgt-element/src/utils/CacheSchema.ts new file mode 100644 index 0000000000..83575f8a22 --- /dev/null +++ b/packages/mgt-element/src/utils/CacheSchema.ts @@ -0,0 +1,37 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +/** + * Represents organization for a cache + * + * @export + * @interface CacheSchema + */ + +export interface CacheSchema { + /** + * version number of cache, useful for upgrading + * + * @type {number} + * @memberof CacheSchema + */ + version: number; + /** + * name of the cache + * + * @type {string} + * @memberof CacheSchema + */ + name: string; + /** + * list of stores in the cache + * + * @type {{ [name: string]: CacheSchemaStore }} + * @memberof CacheSchema + */ + stores: Record; +} diff --git a/packages/mgt-element/src/utils/CacheService.ts b/packages/mgt-element/src/utils/CacheService.ts index cfd8a80b19..08d5761fa0 100644 --- a/packages/mgt-element/src/utils/CacheService.ts +++ b/packages/mgt-element/src/utils/CacheService.ts @@ -8,14 +8,9 @@ import { Providers } from '../providers/Providers'; import { ProviderState } from '../providers/IProvider'; import { CacheStore } from './CacheStore'; - -/** - * Localstorage key for storing names of cache databases - * - * @type {string} - * - */ -export const dbListKey = 'mgt-db-list'; +import { CacheSchema } from './CacheSchema'; +import { CacheItem } from './CacheItem'; +import { dbListKey } from './dbListKey'; /** * Holds the cache options for cache store @@ -268,49 +263,3 @@ export class CacheService { this.isInitialized = true; } } - -/** - * Represents organization for a cache - * - * @export - * @interface CacheSchema - */ -export interface CacheSchema { - /** - * version number of cache, useful for upgrading - * - * @type {number} - * @memberof CacheSchema - */ - version: number; - /** - * name of the cache - * - * @type {string} - * @memberof CacheSchema - */ - name: string; - /** - * list of stores in the cache - * - * @type {{ [name: string]: CacheSchemaStore }} - * @memberof CacheSchema - */ - stores: Record; -} - -/** - * item that is stored in cache - * - * @export - * @interface CacheItem - */ -export interface CacheItem { - /** - * date and time that item was retrieved from api/stored in cache - * - * @type {number} - * @memberof CacheItem - */ - timeCached?: number; -} diff --git a/packages/mgt-element/src/utils/CacheStore.ts b/packages/mgt-element/src/utils/CacheStore.ts index 4211417834..d3c7ddfd00 100644 --- a/packages/mgt-element/src/utils/CacheStore.ts +++ b/packages/mgt-element/src/utils/CacheStore.ts @@ -7,7 +7,9 @@ import { openDB } from 'idb'; import { Providers } from '../providers/Providers'; -import { CacheItem, CacheSchema, dbListKey } from './CacheService'; +import { dbListKey } from './dbListKey'; +import { CacheItem } from './CacheItem'; +import { CacheSchema } from './CacheSchema'; /** * Represents a store in the cache diff --git a/packages/mgt-element/src/utils/GraphHelpers.tests.ts b/packages/mgt-element/src/utils/GraphHelpers.tests.ts index 5501f7e206..419ad757bd 100644 --- a/packages/mgt-element/src/utils/GraphHelpers.tests.ts +++ b/packages/mgt-element/src/utils/GraphHelpers.tests.ts @@ -9,7 +9,9 @@ import { it } from '@jest/globals'; import { AuthenticationHandlerOptions, Middleware } from '@microsoft/microsoft-graph-client'; import { MockProvider } from '../mock/MockProvider'; import { Providers } from '../providers/Providers'; -import { chainMiddleware, prepScopes, validateBaseURL } from './GraphHelpers'; +import { chainMiddleware } from './chainMiddleware'; +import { prepScopes } from './prepScopes'; +import { validateBaseURL } from './validateBaseURL'; describe('GraphHelpers - prepScopes', () => { it('should return an empty array when incremental consent is disabled', () => { diff --git a/packages/mgt-element/src/utils/GraphHelpers.ts b/packages/mgt-element/src/utils/GraphHelpers.ts deleted file mode 100644 index d6349f3616..0000000000 --- a/packages/mgt-element/src/utils/GraphHelpers.ts +++ /dev/null @@ -1,67 +0,0 @@ -/** - * ------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. - * See License in the project root for license information. - * ------------------------------------------------------------------------------------------- - */ - -import { AuthenticationHandlerOptions, Middleware } from '@microsoft/microsoft-graph-client'; -import { GraphEndpoint, MICROSOFT_GRAPH_ENDPOINTS } from '../IGraph'; -import { Providers } from '../providers/Providers'; - -/** - * creates an AuthenticationHandlerOptions from scopes array that - * can be used in the Graph sdk middleware chain - * - * @export - * @param {...string[]} scopes - * @returns - */ -export const prepScopes = (...scopes: string[]) => { - const authProviderOptions = { - scopes - }; - - if (!Providers.globalProvider.isIncrementalConsentDisabled) { - return [new AuthenticationHandlerOptions(undefined, authProviderOptions)]; - } else { - return []; - } -}; - -/** - * Helper method to chain Middleware when instantiating new Client - * - * @param {...Middleware[]} middleware - * @returns {Middleware} - */ -export const chainMiddleware = (...middleware: Middleware[]): Middleware => { - const rootMiddleware = middleware[0]; - let current = rootMiddleware; - for (let i = 1; i < middleware.length; ++i) { - const next = middleware[i]; - if (current.setNext) { - current.setNext(next); - } - current = next; - } - return rootMiddleware; -}; - -/** - * Helper method to validate a base URL string - * - * @param url a URL string - * @returns GraphEndpoint - */ -export const validateBaseURL = (url: string): GraphEndpoint => { - try { - const urlObj = new URL(url); - const originAsEndpoint = urlObj.origin as GraphEndpoint; - if (MICROSOFT_GRAPH_ENDPOINTS.has(originAsEndpoint)) { - return originAsEndpoint; - } - } catch (error) { - return; - } -}; diff --git a/packages/mgt-element/src/utils/SdkVersionMiddleware.ts b/packages/mgt-element/src/utils/SdkVersionMiddleware.ts index c6604d7b41..7bdcd68333 100644 --- a/packages/mgt-element/src/utils/SdkVersionMiddleware.ts +++ b/packages/mgt-element/src/utils/SdkVersionMiddleware.ts @@ -11,7 +11,7 @@ import { setRequestHeader } from '@microsoft/microsoft-graph-client/lib/es/src/middleware/MiddlewareUtil'; import { ComponentMiddlewareOptions } from './ComponentMiddlewareOptions'; -import { validateBaseURL } from './GraphHelpers'; +import { validateBaseURL } from './validateBaseURL'; /** * Implements Middleware for the Graph sdk to inject diff --git a/packages/mgt-element/src/utils/chainMiddleware.ts b/packages/mgt-element/src/utils/chainMiddleware.ts new file mode 100644 index 0000000000..a0352929fe --- /dev/null +++ b/packages/mgt-element/src/utils/chainMiddleware.ts @@ -0,0 +1,28 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +import { Middleware } from '@microsoft/microsoft-graph-client'; + +/** + * Helper method to chain Middleware when instantiating new Client + * + * @param {...Middleware[]} middleware + * @returns {Middleware} + */ + +export const chainMiddleware = (...middleware: Middleware[]): Middleware => { + const rootMiddleware = middleware[0]; + let current = rootMiddleware; + for (let i = 1; i < middleware.length; ++i) { + const next = middleware[i]; + if (current.setNext) { + current.setNext(next); + } + current = next; + } + return rootMiddleware; +}; diff --git a/packages/mgt-element/src/utils/dbListKey.ts b/packages/mgt-element/src/utils/dbListKey.ts new file mode 100644 index 0000000000..5c04ffe17c --- /dev/null +++ b/packages/mgt-element/src/utils/dbListKey.ts @@ -0,0 +1,15 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +/** + * Localstorage key for storing names of cache databases + * + * @type {string} + * + */ + +export const dbListKey = 'mgt-db-list'; diff --git a/packages/mgt-element/src/utils/index.ts b/packages/mgt-element/src/utils/delay.ts similarity index 100% rename from packages/mgt-element/src/utils/index.ts rename to packages/mgt-element/src/utils/delay.ts diff --git a/packages/mgt-element/src/utils/prepScopes.ts b/packages/mgt-element/src/utils/prepScopes.ts new file mode 100644 index 0000000000..a01e896db1 --- /dev/null +++ b/packages/mgt-element/src/utils/prepScopes.ts @@ -0,0 +1,30 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +import { AuthenticationHandlerOptions } from '@microsoft/microsoft-graph-client'; +import { Providers } from '../providers/Providers'; + +/** + * creates an AuthenticationHandlerOptions from scopes array that + * can be used in the Graph sdk middleware chain + * + * @export + * @param {...string[]} scopes + * @returns + */ + +export const prepScopes = (...scopes: string[]) => { + const authProviderOptions = { + scopes + }; + + if (!Providers.globalProvider.isIncrementalConsentDisabled) { + return [new AuthenticationHandlerOptions(undefined, authProviderOptions)]; + } else { + return []; + } +}; diff --git a/packages/mgt-element/src/utils/registerComponent.ts b/packages/mgt-element/src/utils/registerComponent.ts new file mode 100644 index 0000000000..f0327a25ef --- /dev/null +++ b/packages/mgt-element/src/utils/registerComponent.ts @@ -0,0 +1,12 @@ +import { customElementHelper } from '../components/customElementHelper'; + +export const buildComponentName = (tagBase: string) => `${customElementHelper.prefix}-${tagBase}`; + +export const registerComponent = ( + tagBase: string, + constructor: CustomElementConstructor, + options?: ElementDefinitionOptions +) => { + const tagName = buildComponentName(tagBase); + if (!customElements.get(tagName)) customElements.define(tagName, constructor, options); +}; diff --git a/packages/mgt-element/src/utils/validateBaseURL.ts b/packages/mgt-element/src/utils/validateBaseURL.ts new file mode 100644 index 0000000000..9279ee869b --- /dev/null +++ b/packages/mgt-element/src/utils/validateBaseURL.ts @@ -0,0 +1,27 @@ +/** + * ------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. + * See License in the project root for license information. + * ------------------------------------------------------------------------------------------- + */ + +import { GraphEndpoint, MICROSOFT_GRAPH_ENDPOINTS } from '../IGraph'; + +/** + * Helper method to validate a base URL string + * + * @param url a URL string + * @returns GraphEndpoint + */ + +export const validateBaseURL = (url: string): GraphEndpoint => { + try { + const urlObj = new URL(url); + const originAsEndpoint = urlObj.origin as GraphEndpoint; + if (MICROSOFT_GRAPH_ENDPOINTS.has(originAsEndpoint)) { + return originAsEndpoint; + } + } catch (error) { + return; + } +}; diff --git a/packages/mgt-react/custom-elements-manifest.config.mjs b/packages/mgt-react/custom-elements-manifest.config.mjs new file mode 100644 index 0000000000..ffa8748d08 --- /dev/null +++ b/packages/mgt-react/custom-elements-manifest.config.mjs @@ -0,0 +1,3 @@ +import config from '../../custom-elements-manifest.config.mjs'; + +export default config; diff --git a/packages/mgt-react/package.json b/packages/mgt-react/package.json index 690e9cf372..0330c70b5c 100644 --- a/packages/mgt-react/package.json +++ b/packages/mgt-react/package.json @@ -30,9 +30,10 @@ "compile:watch": "tsc -w", "build:watch": "npm run compile:watch", "postpack": "cpx *.tgz ../../artifacts", - "analyze": "custom-elements-manifest analyze --litelement --globs \"../*/src/**/*.ts\" --outdir temp", + "analyze": "custom-elements-manifest analyze --globs \"../*/src/**/*.ts\" --outdir temp", "generate": "npm run analyze && node ./scripts/generate.js" }, + "sideEffects": false, "dependencies": { "@microsoft/mgt-components": "*", "@microsoft/mgt-element": "*", diff --git a/packages/mgt-react/scripts/generate.js b/packages/mgt-react/scripts/generate.js index 710b95b04f..c11473c534 100644 --- a/packages/mgt-react/scripts/generate.js +++ b/packages/mgt-react/scripts/generate.js @@ -24,7 +24,7 @@ const gaTags = new Set([ 'search-results', 'spinner' ]); -const outputFileName = 'react'; +const barrelFileName = 'react'; const generateTags = (tags, fileName) => { const mgtComponentImports = new Set(); @@ -73,6 +73,14 @@ const generateTags = (tags, fileName) => { } }; + const registrationFunctions = new Set(); + + const generateRegisterFunctionName = type => `register${type}Component`; + + const addComponentRegistrationImport = type => { + registrationFunctions.add(generateRegisterFunctionName(type)); + }; + for (const tag of customTags.sort((a, b) => (a.tagName > b.tagName ? 1 : -1))) { const className = tag.tagName .split('-') @@ -81,10 +89,13 @@ const generateTags = (tags, fileName) => { wrappers.push({ tag: tag.tagName, + componentClass: tag.name, propsType: className + 'Props', className: className }); + addComponentRegistrationImport(tag.name); + const props = {}; for (let i = 0; i < tag.members.length; ++i) { @@ -142,13 +153,23 @@ const generateTags = (tags, fileName) => { } for (const wrapper of wrappers) { - output += `\nexport const ${wrapper.className} = wrapMgt<${wrapper.propsType}>('${wrapper.tag}');\n`; + output += `\nexport const ${wrapper.className} = wrapMgt<${wrapper.propsType}>('${ + wrapper.tag + }', ${generateRegisterFunctionName(wrapper.componentClass)});\n`; } + const componentTypeImports = Array.from(mgtComponentImports).join(','); + const initialLine = componentTypeImports + ? `import { ${componentTypeImports} } from '@microsoft/mgt-components/dist/es6/exports'; +` + : ''; output = `/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { ${Array.from(mgtComponentImports).join(',')} } from '@microsoft/mgt-components'; +${initialLine}import { ${Array.from(registrationFunctions).join( + ',' + )} } from '@microsoft/mgt-components/dist/es6/components/components'; import { ${Array.from(mgtElementImports).join(',')} } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; // eslint-disable-next-line @typescript-eslint/no-unused-vars import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; @@ -163,4 +184,14 @@ ${output} fs.writeFileSync(`${__dirname}/../src/generated/${fileName}.ts`, output); }; -generateTags(gaTags, outputFileName); +// generate each component to a separate file +gaTags.forEach(tag => { + generateTags(new Set([tag]), tag); +}); + +output = ''; +// generate a barrel file +gaTags.forEach(tag => { + output += `export * from './${tag}';\n`; +}); +fs.writeFileSync(`${__dirname}/../src/generated/${barrelFileName}.ts`, output); diff --git a/packages/mgt-react/src/Mgt.ts b/packages/mgt-react/src/Mgt.ts index 05e6803270..8cd877ef4c 100644 --- a/packages/mgt-react/src/Mgt.ts +++ b/packages/mgt-react/src/Mgt.ts @@ -145,7 +145,8 @@ export class Mgt extends Wc { * @param {(string | Function)} tag * @returns React component */ -export const wrapMgt = (tag: string) => { +export const wrapMgt = (tag: string, registerElementFunction: () => void) => { + registerElementFunction(); const WrapMgt = (props: T, ref: React.ForwardedRef): React.CElement => React.createElement(Mgt, { wcType: tag, innerRef: ref, ...props }); const component: React.ForwardRefExoticComponent< diff --git a/packages/mgt-react/src/generated/agenda.ts b/packages/mgt-react/src/generated/agenda.ts new file mode 100644 index 0000000000..09155bf417 --- /dev/null +++ b/packages/mgt-react/src/generated/agenda.ts @@ -0,0 +1,26 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { registerMgtAgendaComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type AgendaProps = { + date?: string; + groupId?: string; + days?: number; + eventQuery?: string; + events?: MicrosoftGraph.Event[]; + showMax?: number; + groupByDay?: boolean; + preferredTimezone?: string; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + templateRendered?: (e: CustomEvent) => void; +} + +export const Agenda = wrapMgt('agenda', registerMgtAgendaComponent); + diff --git a/packages/mgt-react/src/generated/file-list.ts b/packages/mgt-react/src/generated/file-list.ts new file mode 100644 index 0000000000..44e361e5f8 --- /dev/null +++ b/packages/mgt-react/src/generated/file-list.ts @@ -0,0 +1,41 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { OfficeGraphInsightString,ViewType } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtFileListComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type FileListProps = { + fileListQuery?: string; + displayName?: string; + cardTitle?: string; + fileQueries?: string[]; + files?: MicrosoftGraph.DriveItem[]; + siteId?: string; + driveId?: string; + groupId?: string; + itemId?: string; + itemPath?: string; + userId?: string; + insightType?: OfficeGraphInsightString; + itemView?: ViewType; + fileExtensions?: string[]; + pageSize?: number; + disableOpenOnClick?: boolean; + hideMoreFilesButton?: boolean; + maxFileSize?: number; + enableFileUpload?: boolean; + maxUploadFile?: number; + excludedFileExtensions?: string[]; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + itemClick?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const FileList = wrapMgt('file-list', registerMgtFileListComponent); + diff --git a/packages/mgt-react/src/generated/file.ts b/packages/mgt-react/src/generated/file.ts new file mode 100644 index 0000000000..71cb6da9e5 --- /dev/null +++ b/packages/mgt-react/src/generated/file.ts @@ -0,0 +1,36 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { OfficeGraphInsightString,ViewType } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtFileComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type FileProps = { + fileQuery?: string; + siteId?: string; + driveId?: string; + groupId?: string; + listId?: string; + userId?: string; + itemId?: string; + itemPath?: string; + insightType?: OfficeGraphInsightString; + insightId?: string; + fileDetails?: MicrosoftGraph.DriveItem; + fileIcon?: string; + driveItem?: MicrosoftGraph.DriveItem; + line1Property?: string; + line2Property?: string; + line3Property?: string; + view?: ViewType; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + templateRendered?: (e: CustomEvent) => void; +} + +export const File = wrapMgt('file', registerMgtFileComponent); + diff --git a/packages/mgt-react/src/generated/get.ts b/packages/mgt-react/src/generated/get.ts new file mode 100644 index 0000000000..fdb3ac2de7 --- /dev/null +++ b/packages/mgt-react/src/generated/get.ts @@ -0,0 +1,29 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { ResponseType,DataChangedDetail } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtGetComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type GetProps = { + resource?: string; + scopes?: string[]; + version?: string; + type?: ResponseType; + maxPages?: number; + pollingRate?: number; + cacheEnabled?: boolean; + cacheInvalidationPeriod?: number; + response?: any; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + dataChange?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const Get = wrapMgt('get', registerMgtGetComponent); + diff --git a/packages/mgt-react/src/generated/login.ts b/packages/mgt-react/src/generated/login.ts new file mode 100644 index 0000000000..1af1d15484 --- /dev/null +++ b/packages/mgt-react/src/generated/login.ts @@ -0,0 +1,27 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { IDynamicPerson,LoginViewType } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtLoginComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type LoginProps = { + userDetails?: IDynamicPerson; + showPresence?: boolean; + loginView?: LoginViewType; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + loginInitiated?: (e: CustomEvent) => void; + loginCompleted?: (e: CustomEvent) => void; + loginFailed?: (e: CustomEvent) => void; + logoutInitiated?: (e: CustomEvent) => void; + logoutCompleted?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const Login = wrapMgt('login', registerMgtLoginComponent); + diff --git a/packages/mgt-react/src/generated/people-picker.ts b/packages/mgt-react/src/generated/people-picker.ts new file mode 100644 index 0000000000..56a4b3aa4d --- /dev/null +++ b/packages/mgt-react/src/generated/people-picker.ts @@ -0,0 +1,41 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { PersonType,GroupType,UserType,IDynamicPerson } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtPeoplePickerComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type PeoplePickerProps = { + groupId?: string; + groupIds?: string[]; + type?: PersonType; + groupType?: GroupType; + userType?: UserType; + transitiveSearch?: boolean; + people?: IDynamicPerson[]; + showMax?: number; + disableImages?: boolean; + selectedPeople?: IDynamicPerson[]; + defaultSelectedUserIds?: string[]; + defaultSelectedGroupIds?: string[]; + placeholder?: string; + disabled?: boolean; + allowAnyEmail?: boolean; + selectionMode?: string; + userIds?: string[]; + userFilters?: string; + peopleFilters?: string; + groupFilters?: string; + ariaLabel?: string; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + selectionChanged?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const PeoplePicker = wrapMgt('people-picker', registerMgtPeoplePickerComponent); + diff --git a/packages/mgt-react/src/generated/people.ts b/packages/mgt-react/src/generated/people.ts new file mode 100644 index 0000000000..2c143ad035 --- /dev/null +++ b/packages/mgt-react/src/generated/people.ts @@ -0,0 +1,30 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { IDynamicPerson,PersonCardInteraction } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtPeopleComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type PeopleProps = { + groupId?: string; + userIds?: string[]; + people?: IDynamicPerson[]; + peopleQueries?: string[]; + showMax?: number; + showPresence?: boolean; + personCardInteraction?: PersonCardInteraction; + resource?: string; + version?: string; + scopes?: string[]; + fallbackDetails?: IDynamicPerson[]; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + templateRendered?: (e: CustomEvent) => void; +} + +export const People = wrapMgt('people', registerMgtPeopleComponent); + diff --git a/packages/mgt-react/src/generated/person-card.ts b/packages/mgt-react/src/generated/person-card.ts new file mode 100644 index 0000000000..2eca8933f9 --- /dev/null +++ b/packages/mgt-react/src/generated/person-card.ts @@ -0,0 +1,30 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { IDynamicPerson } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtPersonCardComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type PersonCardProps = { + personDetails?: IDynamicPerson; + personQuery?: string; + lockTabNavigation?: boolean; + userId?: string; + personImage?: string; + fetchImage?: boolean; + isExpanded?: boolean; + inheritDetails?: boolean; + showPresence?: boolean; + personPresence?: MicrosoftGraph.Presence; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + expanded?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const PersonCard = wrapMgt('person-card', registerMgtPersonCardComponent); + diff --git a/packages/mgt-react/src/generated/person.ts b/packages/mgt-react/src/generated/person.ts new file mode 100644 index 0000000000..7537ab1c62 --- /dev/null +++ b/packages/mgt-react/src/generated/person.ts @@ -0,0 +1,42 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { IDynamicPerson,AvatarSize,PersonCardInteraction,ViewType,PersonViewType } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtPersonComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type PersonProps = { + personQuery?: string; + fallbackDetails?: IDynamicPerson; + userId?: string; + usage?: string; + showPresence?: boolean; + avatarSize?: AvatarSize; + personDetails?: IDynamicPerson; + personImage?: string; + fetchImage?: boolean; + disableImageFetch?: boolean; + verticalLayout?: boolean; + avatarType?: string; + personPresence?: MicrosoftGraph.Presence; + personCardInteraction?: PersonCardInteraction; + line1Property?: string; + line2Property?: string; + line3Property?: string; + line4Property?: string; + view?: ViewType | PersonViewType; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + line1clicked?: (e: CustomEvent) => void; + line2clicked?: (e: CustomEvent) => void; + line3clicked?: (e: CustomEvent) => void; + line4clicked?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const Person = wrapMgt('person', registerMgtPersonComponent); + diff --git a/packages/mgt-react/src/generated/picker.ts b/packages/mgt-react/src/generated/picker.ts new file mode 100644 index 0000000000..1ae25b2884 --- /dev/null +++ b/packages/mgt-react/src/generated/picker.ts @@ -0,0 +1,29 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { registerMgtPickerComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type PickerProps = { + resource?: string; + version?: string; + maxPages?: number; + placeholder?: string; + keyName?: string; + entityType?: string; + scopes?: string[]; + cacheEnabled?: boolean; + cacheInvalidationPeriod?: number; + selectedValue?: string; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + selectionChanged?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const Picker = wrapMgt('picker', registerMgtPickerComponent); + diff --git a/packages/mgt-react/src/generated/react.ts b/packages/mgt-react/src/generated/react.ts index cf7a1b5cc0..1b6a2a1c88 100644 --- a/packages/mgt-react/src/generated/react.ts +++ b/packages/mgt-react/src/generated/react.ts @@ -1,350 +1,18 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable @typescript-eslint/consistent-type-definitions */ -import { OfficeGraphInsightString,ViewType,ResponseType,DataChangedDetail,IDynamicPerson,LoginViewType,PersonCardInteraction,PersonType,GroupType,UserType,AvatarSize,PersonViewType,TasksStringResource,TasksSource,TaskFilter,ITask,SelectedChannel,TodoFilter } from '@microsoft/mgt-components'; -import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; -import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; -import {wrapMgt} from '../Mgt'; - -export type AgendaProps = { - date?: string; - groupId?: string; - days?: number; - eventQuery?: string; - events?: MicrosoftGraph.Event[]; - showMax?: number; - groupByDay?: boolean; - preferredTimezone?: string; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - eventClick?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type FileProps = { - fileQuery?: string; - siteId?: string; - driveId?: string; - groupId?: string; - listId?: string; - userId?: string; - itemId?: string; - itemPath?: string; - insightType?: OfficeGraphInsightString; - insightId?: string; - fileDetails?: MicrosoftGraph.DriveItem; - fileIcon?: string; - driveItem?: MicrosoftGraph.DriveItem; - line1Property?: string; - line2Property?: string; - line3Property?: string; - view?: ViewType; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - templateRendered?: (e: CustomEvent) => void; -} - -export type FileListProps = { - fileListQuery?: string; - displayName?: string; - cardTitle?: string; - fileQueries?: string[]; - files?: MicrosoftGraph.DriveItem[]; - siteId?: string; - driveId?: string; - groupId?: string; - itemId?: string; - itemPath?: string; - userId?: string; - insightType?: OfficeGraphInsightString; - itemView?: ViewType; - fileExtensions?: string[]; - pageSize?: number; - disableOpenOnClick?: boolean; - hideMoreFilesButton?: boolean; - maxFileSize?: number; - enableFileUpload?: boolean; - maxUploadFile?: number; - excludedFileExtensions?: string[]; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - itemClick?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type GetProps = { - resource?: string; - scopes?: string[]; - version?: string; - type?: ResponseType; - maxPages?: number; - pollingRate?: number; - cacheEnabled?: boolean; - cacheInvalidationPeriod?: number; - response?: any; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - dataChange?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type LoginProps = { - userDetails?: IDynamicPerson; - showPresence?: boolean; - loginView?: LoginViewType; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - loginInitiated?: (e: CustomEvent) => void; - loginCompleted?: (e: CustomEvent) => void; - loginFailed?: (e: CustomEvent) => void; - logoutInitiated?: (e: CustomEvent) => void; - logoutCompleted?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type PeopleProps = { - groupId?: string; - userIds?: string[]; - people?: IDynamicPerson[]; - peopleQueries?: string[]; - showMax?: number; - showPresence?: boolean; - personCardInteraction?: PersonCardInteraction; - resource?: string; - version?: string; - scopes?: string[]; - fallbackDetails?: IDynamicPerson[]; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - templateRendered?: (e: CustomEvent) => void; -} - -export type PeoplePickerProps = { - groupId?: string; - groupIds?: string[]; - type?: PersonType; - groupType?: GroupType; - userType?: UserType; - transitiveSearch?: boolean; - people?: IDynamicPerson[]; - showMax?: number; - disableImages?: boolean; - selectedPeople?: IDynamicPerson[]; - defaultSelectedUserIds?: string[]; - defaultSelectedGroupIds?: string[]; - placeholder?: string; - disabled?: boolean; - allowAnyEmail?: boolean; - selectionMode?: string; - userIds?: string[]; - userFilters?: string; - peopleFilters?: string; - groupFilters?: string; - ariaLabel?: string; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - selectionChanged?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type PersonProps = { - personQuery?: string; - fallbackDetails?: IDynamicPerson; - userId?: string; - usage?: string; - showPresence?: boolean; - avatarSize?: AvatarSize; - personDetails?: IDynamicPerson; - personImage?: string; - fetchImage?: boolean; - disableImageFetch?: boolean; - verticalLayout?: boolean; - avatarType?: string; - personPresence?: MicrosoftGraph.Presence; - personCardInteraction?: PersonCardInteraction; - line1Property?: string; - line2Property?: string; - line3Property?: string; - line4Property?: string; - view?: ViewType | PersonViewType; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - line1clicked?: (e: CustomEvent) => void; - line2clicked?: (e: CustomEvent) => void; - line3clicked?: (e: CustomEvent) => void; - line4clicked?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type PersonCardProps = { - personDetails?: IDynamicPerson; - personQuery?: string; - lockTabNavigation?: boolean; - userId?: string; - personImage?: string; - fetchImage?: boolean; - isExpanded?: boolean; - inheritDetails?: boolean; - showPresence?: boolean; - personPresence?: MicrosoftGraph.Presence; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - expanded?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type PickerProps = { - resource?: string; - version?: string; - maxPages?: number; - placeholder?: string; - keyName?: string; - entityType?: string; - scopes?: string[]; - cacheEnabled?: boolean; - cacheInvalidationPeriod?: number; - selectedValue?: string; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - selectionChanged?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type SearchBoxProps = { - placeholder?: string; - searchTerm?: string; - debounceDelay?: number; - mediaQuery?: ComponentMediaQuery; - searchTermChanged?: (e: CustomEvent) => void; -} - -export type SearchResultsProps = { - queryString?: string; - queryTemplate?: string; - entityTypes?: string[]; - scopes?: string[]; - contentSources?: string[]; - version?: string; - from?: number; - size?: number; - pagingMax?: number; - fetchThumbnail?: boolean; - fields?: string[]; - enableTopResults?: boolean; - cacheEnabled?: boolean; - cacheInvalidationPeriod?: number; - currentPage?: number; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - dataChange?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type SpinnerProps = { - mediaQuery?: ComponentMediaQuery; -} - -export type TasksProps = { - res?: TasksStringResource; - isNewTaskVisible?: boolean; - readOnly?: boolean; - dataSource?: TasksSource; - targetId?: string; - targetBucketId?: string; - initialId?: string; - initialBucketId?: string; - hideHeader?: boolean; - hideOptions?: boolean; - groupId?: string; - taskFilter?: TaskFilter; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - taskAdded?: (e: CustomEvent) => void; - taskChanged?: (e: CustomEvent) => void; - taskClick?: (e: CustomEvent) => void; - taskRemoved?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type TaxonomyPickerProps = { - termsetId?: string; - termId?: string; - siteId?: string; - locale?: string; - version?: string; - placeholder?: string; - position?: string; - defaultSelectedTermId?: string; - selectedTerm?: MicrosoftGraph.TermStore.Term; - disabled?: boolean; - cacheEnabled?: boolean; - cacheInvalidationPeriod?: number; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - selectionChanged?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type TeamsChannelPickerProps = { - selectedItem?: SelectedChannel; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - selectionChanged?: (e: CustomEvent) => void; - templateRendered?: (e: CustomEvent) => void; -} - -export type ThemeToggleProps = { - darkModeActive?: boolean; - mediaQuery?: ComponentMediaQuery; - darkmodechanged?: (e: CustomEvent) => void; -} - -export type TodoProps = { - taskFilter?: TodoFilter; - readOnly?: boolean; - hideHeader?: boolean; - hideOptions?: boolean; - targetId?: string; - initialId?: string; - templateContext?: TemplateContext; - mediaQuery?: ComponentMediaQuery; - templateRendered?: (e: CustomEvent) => void; -} - -export const Agenda = wrapMgt('agenda'); - -export const File = wrapMgt('file'); - -export const FileList = wrapMgt('file-list'); - -export const Get = wrapMgt('get'); - -export const Login = wrapMgt('login'); - -export const People = wrapMgt('people'); - -export const PeoplePicker = wrapMgt('people-picker'); - -export const Person = wrapMgt('person'); - -export const PersonCard = wrapMgt('person-card'); - -export const Picker = wrapMgt('picker'); - -export const SearchBox = wrapMgt('search-box'); - -export const SearchResults = wrapMgt('search-results'); - -export const Spinner = wrapMgt('spinner'); - -export const Tasks = wrapMgt('tasks'); - -export const TaxonomyPicker = wrapMgt('taxonomy-picker'); - -export const TeamsChannelPicker = wrapMgt('teams-channel-picker'); - -export const ThemeToggle = wrapMgt('theme-toggle'); - -export const Todo = wrapMgt('todo'); - +export * from './person'; +export * from './person-card'; +export * from './agenda'; +export * from './get'; +export * from './login'; +export * from './people-picker'; +export * from './people'; +export * from './tasks'; +export * from './teams-channel-picker'; +export * from './todo'; +export * from './file'; +export * from './file-list'; +export * from './picker'; +export * from './taxonomy-picker'; +export * from './theme-toggle'; +export * from './search-box'; +export * from './search-results'; +export * from './spinner'; diff --git a/packages/mgt-react/src/generated/search-box.ts b/packages/mgt-react/src/generated/search-box.ts new file mode 100644 index 0000000000..9bab52ecf3 --- /dev/null +++ b/packages/mgt-react/src/generated/search-box.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { registerMgtSearchBoxComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { ComponentMediaQuery } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type SearchBoxProps = { + placeholder?: string; + searchTerm?: string; + debounceDelay?: number; + mediaQuery?: ComponentMediaQuery; + searchTermChanged?: (e: CustomEvent) => void; +} + +export const SearchBox = wrapMgt('search-box', registerMgtSearchBoxComponent); + diff --git a/packages/mgt-react/src/generated/search-results.ts b/packages/mgt-react/src/generated/search-results.ts new file mode 100644 index 0000000000..4ab0fd7ce1 --- /dev/null +++ b/packages/mgt-react/src/generated/search-results.ts @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { DataChangedDetail } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtSearchResultsComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type SearchResultsProps = { + queryString?: string; + queryTemplate?: string; + entityTypes?: string[]; + scopes?: string[]; + contentSources?: string[]; + version?: string; + from?: number; + size?: number; + pagingMax?: number; + fetchThumbnail?: boolean; + fields?: string[]; + enableTopResults?: boolean; + cacheEnabled?: boolean; + cacheInvalidationPeriod?: number; + currentPage?: number; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + dataChange?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const SearchResults = wrapMgt('search-results', registerMgtSearchResultsComponent); + diff --git a/packages/mgt-react/src/generated/spinner.ts b/packages/mgt-react/src/generated/spinner.ts new file mode 100644 index 0000000000..4e9e97adc5 --- /dev/null +++ b/packages/mgt-react/src/generated/spinner.ts @@ -0,0 +1,16 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { registerMgtSpinnerComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { ComponentMediaQuery } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type SpinnerProps = { + mediaQuery?: ComponentMediaQuery; +} + +export const Spinner = wrapMgt('spinner', registerMgtSpinnerComponent); + diff --git a/packages/mgt-react/src/generated/tasks.ts b/packages/mgt-react/src/generated/tasks.ts new file mode 100644 index 0000000000..23fe41b7bf --- /dev/null +++ b/packages/mgt-react/src/generated/tasks.ts @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { TasksStringResource,TasksSource,TaskFilter,ITask } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtTasksComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type TasksProps = { + res?: TasksStringResource; + isNewTaskVisible?: boolean; + readOnly?: boolean; + dataSource?: TasksSource; + targetId?: string; + targetBucketId?: string; + initialId?: string; + initialBucketId?: string; + hideHeader?: boolean; + hideOptions?: boolean; + groupId?: string; + taskFilter?: TaskFilter; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + taskAdded?: (e: CustomEvent) => void; + taskChanged?: (e: CustomEvent) => void; + taskClick?: (e: CustomEvent) => void; + taskRemoved?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const Tasks = wrapMgt('tasks', registerMgtTasksComponent); + diff --git a/packages/mgt-react/src/generated/taxonomy-picker.ts b/packages/mgt-react/src/generated/taxonomy-picker.ts new file mode 100644 index 0000000000..b5046056d5 --- /dev/null +++ b/packages/mgt-react/src/generated/taxonomy-picker.ts @@ -0,0 +1,31 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { registerMgtTaxonomyPickerComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type TaxonomyPickerProps = { + termsetId?: string; + termId?: string; + siteId?: string; + locale?: string; + version?: string; + placeholder?: string; + position?: string; + defaultSelectedTermId?: string; + selectedTerm?: MicrosoftGraph.TermStore.Term; + disabled?: boolean; + cacheEnabled?: boolean; + cacheInvalidationPeriod?: number; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + selectionChanged?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const TaxonomyPicker = wrapMgt('taxonomy-picker', registerMgtTaxonomyPickerComponent); + diff --git a/packages/mgt-react/src/generated/teams-channel-picker.ts b/packages/mgt-react/src/generated/teams-channel-picker.ts new file mode 100644 index 0000000000..d3fa76487b --- /dev/null +++ b/packages/mgt-react/src/generated/teams-channel-picker.ts @@ -0,0 +1,21 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { SelectedChannel } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtTeamsChannelPickerComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type TeamsChannelPickerProps = { + selectedItem?: SelectedChannel; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + selectionChanged?: (e: CustomEvent) => void; + templateRendered?: (e: CustomEvent) => void; +} + +export const TeamsChannelPicker = wrapMgt('teams-channel-picker', registerMgtTeamsChannelPickerComponent); + diff --git a/packages/mgt-react/src/generated/theme-toggle.ts b/packages/mgt-react/src/generated/theme-toggle.ts new file mode 100644 index 0000000000..897e03f695 --- /dev/null +++ b/packages/mgt-react/src/generated/theme-toggle.ts @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { registerMgtThemeToggleComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { ComponentMediaQuery } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type ThemeToggleProps = { + darkModeActive?: boolean; + mediaQuery?: ComponentMediaQuery; + darkmodechanged?: (e: CustomEvent) => void; +} + +export const ThemeToggle = wrapMgt('theme-toggle', registerMgtThemeToggleComponent); + diff --git a/packages/mgt-react/src/generated/todo.ts b/packages/mgt-react/src/generated/todo.ts new file mode 100644 index 0000000000..8470b394ef --- /dev/null +++ b/packages/mgt-react/src/generated/todo.ts @@ -0,0 +1,25 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ +import { TodoFilter } from '@microsoft/mgt-components/dist/es6/exports'; +import { registerMgtTodoComponent } from '@microsoft/mgt-components/dist/es6/components/components'; +import { TemplateContext,ComponentMediaQuery,TemplateRenderedData } from '@microsoft/mgt-element'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as MicrosoftGraphBeta from '@microsoft/microsoft-graph-types-beta'; +import {wrapMgt} from '../Mgt'; + +export type TodoProps = { + taskFilter?: TodoFilter; + readOnly?: boolean; + hideHeader?: boolean; + hideOptions?: boolean; + targetId?: string; + initialId?: string; + templateContext?: TemplateContext; + mediaQuery?: ComponentMediaQuery; + templateRendered?: (e: CustomEvent) => void; +} + +export const Todo = wrapMgt('todo', registerMgtTodoComponent); + diff --git a/packages/mgt-react/src/index.ts b/packages/mgt-react/src/index.ts index 99c522f012..cccdb613a1 100644 --- a/packages/mgt-react/src/index.ts +++ b/packages/mgt-react/src/index.ts @@ -8,5 +8,5 @@ export * from './Mgt'; export * from './MgtTemplateProps'; export * from './generated/react'; -export * from '@microsoft/mgt-components'; +export * from '@microsoft/mgt-components/dist/es6/exports'; export * from '@microsoft/mgt-element'; diff --git a/packages/mgt-spfx-utils/package.json b/packages/mgt-spfx-utils/package.json index 29ec1cf8bc..f81b80fc1a 100644 --- a/packages/mgt-spfx-utils/package.json +++ b/packages/mgt-spfx-utils/package.json @@ -25,6 +25,7 @@ "lint": "eslint -c ../../.eslintrc.js 'src/**/*.ts'", "postpack": "cpx *.tgz ../../artifacts" }, + "sideEffects": false, "homepage": "https://github.com/microsoftgraph/microsoft-graph-toolkit", "bugs": { "url": "https://github.com/microsoftgraph/microsoft-graph-toolkit/issues" diff --git a/packages/mgt-spfx/package.json b/packages/mgt-spfx/package.json index 44f1116207..a1f67f3b24 100644 --- a/packages/mgt-spfx/package.json +++ b/packages/mgt-spfx/package.json @@ -35,6 +35,7 @@ "@microsoft/mgt-sharepoint-provider": "*", "tslib": "2.3.1" }, + "sideEffects": false, "devDependencies": { "@microsoft/eslint-config-spfx": "1.18.0", "@microsoft/eslint-plugin-spfx": "1.18.0", diff --git a/packages/mgt/package.json b/packages/mgt/package.json index 67835fb37a..5dff7b9658 100644 --- a/packages/mgt/package.json +++ b/packages/mgt/package.json @@ -42,6 +42,7 @@ "test": "jest", "test:watch": "jest --watch" }, + "sideEffects": false, "dependencies": { "@microsoft/mgt-components": "*", "@microsoft/mgt-element": "*", diff --git a/packages/providers/mgt-electron-provider/package.json b/packages/providers/mgt-electron-provider/package.json index 1664a2b781..831724dcf9 100644 --- a/packages/providers/mgt-electron-provider/package.json +++ b/packages/providers/mgt-electron-provider/package.json @@ -40,6 +40,7 @@ "lint:provider": "eslint -c .eslintrc.provider.js 'src/Provider/**/*.ts'", "postpack": "cpx *.tgz ../../../artifacts" }, + "sideEffects": false, "dependencies": { "@azure/msal-node": "^1.0.3", "@microsoft/mgt-element": "*", diff --git a/packages/providers/mgt-mock-provider/README.md b/packages/providers/mgt-mock-provider/README.md index 8f1cc8a4c0..3abb28b2c5 100644 --- a/packages/providers/mgt-mock-provider/README.md +++ b/packages/providers/mgt-mock-provider/README.md @@ -20,7 +20,7 @@ The `@microsoft/mgt-proxy-provider` package exposes the `ProxyProvider` class wh ```ts import {Providers} from '@microsoft/mgt-element'; - import {ProxyProvider} from '@microsoft/mgt-proxy-provider'; + import {ProxyProvider} from '@microsoft/mgt-proxy-provider/exports'; // initialize the auth provider globally Providers.globalProvider = new ProxyProvider("https://myurl.com/api/GraphProxy"); diff --git a/packages/providers/mgt-mock-provider/package.json b/packages/providers/mgt-mock-provider/package.json index 1162edcda0..bccf9cb573 100644 --- a/packages/providers/mgt-mock-provider/package.json +++ b/packages/providers/mgt-mock-provider/package.json @@ -37,6 +37,10 @@ "lint": "eslint -c ../../../.eslintrc.js 'src/**/*.ts'", "postpack": "cpx *.tgz ../../../artifacts" }, + "sideEffects": [ + "./dist/es6/index.js", + "./src/index.ts" + ], "dependencies": { "@microsoft/mgt-element": "*" }, diff --git a/packages/providers/mgt-mock-provider/src/index.ts b/packages/providers/mgt-mock-provider/src/index.ts index 01bc05e4b7..6e9e624037 100644 --- a/packages/providers/mgt-mock-provider/src/index.ts +++ b/packages/providers/mgt-mock-provider/src/index.ts @@ -4,5 +4,8 @@ * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ +import { registerMgtMockProvider } from './mgt-mock-provider'; + +registerMgtMockProvider(); export * from './mgt-mock-provider'; diff --git a/packages/providers/mgt-mock-provider/src/mgt-mock-provider.ts b/packages/providers/mgt-mock-provider/src/mgt-mock-provider.ts index 0736bb4e05..4c86d62b91 100644 --- a/packages/providers/mgt-mock-provider/src/mgt-mock-provider.ts +++ b/packages/providers/mgt-mock-provider/src/mgt-mock-provider.ts @@ -9,7 +9,12 @@ import { property } from 'lit/decorators.js'; import { MgtBaseProvider } from '@microsoft/mgt-element'; import { Providers } from '@microsoft/mgt-element'; import { MockProvider } from '@microsoft/mgt-element'; -import { customElement } from '@microsoft/mgt-element'; +import { registerComponent } from '@microsoft/mgt-element'; + +export const registerMgtMockProvider = () => { + registerComponent('mock-provider', MgtMockProvider); +}; + /** * Sets global provider to a mock Provider * @@ -17,7 +22,6 @@ import { customElement } from '@microsoft/mgt-element'; * @class MgtMockProvider * @extends {LitElement} */ -@customElement('mock-provider') export class MgtMockProvider extends MgtBaseProvider { /** * A property to allow the developer to start the sample logged out if they desired. diff --git a/packages/providers/mgt-msal2-provider/README.md b/packages/providers/mgt-msal2-provider/README.md index 13adc5e3c8..4c5e10cbe3 100644 --- a/packages/providers/mgt-msal2-provider/README.md +++ b/packages/providers/mgt-msal2-provider/README.md @@ -19,7 +19,7 @@ The `@microsoft/mgt-msal2-provider` package exposes the `Msal2Provider` class wh ```ts import {Providers, LoginType} from '@microsoft/mgt-element'; - import {Msal2Provider, PromptType} from '@microsoft/mgt-msal2-provider'; + import {Msal2Provider, PromptType} from '@microsoft/mgt-msal2-provider/dist/es6/exports'; // initialize the auth provider globally Providers.globalProvider = new Msal2Provider({ @@ -44,7 +44,7 @@ The `@microsoft/mgt-msal2-provider` package exposes the `Msal2Provider` class wh ```ts import {Providers, LoginType} from '@microsoft/mgt-element'; - import {Msal2Provider, PromptType} from '@microsoft/mgt-msal2-provider'; + import {Msal2Provider, PromptType} from '@microsoft/mgt-msal2-provider/dist/es6/exports'; import {PublicClientApplication} from '@azure/msal-browser'; // initialize the auth provider globally @@ -96,7 +96,7 @@ The `@microsoft/mgt-msal2-provider` package exposes the `Msal2Provider` class wh ```ts import {Providers, LoginType} from '@microsoft/mgt-element'; - import {Msal2Provider, PromptType} from '@microsoft/mgt-msal2-provider'; + import {Msal2Provider, PromptType} from '@microsoft/mgt-msal2-provider/dist/es6/exports'; // initialize the auth provider globally Providers.globalProvider = new Msal2Provider({ diff --git a/packages/providers/mgt-msal2-provider/package.json b/packages/providers/mgt-msal2-provider/package.json index 69be2bb766..add24c57ac 100644 --- a/packages/providers/mgt-msal2-provider/package.json +++ b/packages/providers/mgt-msal2-provider/package.json @@ -38,6 +38,10 @@ "lint": "eslint -c ../../../.eslintrc.js 'src/**/*.ts'", "postpack": "cpx *.tgz ../../../artifacts" }, + "sideEffects": [ + "./dist/es6/index.js", + "./src/index.ts" + ], "dependencies": { "@azure/msal-browser": "^2.22.0", "@microsoft/mgt-element": "*", diff --git a/packages/providers/mgt-msal2-provider/src/exports.ts b/packages/providers/mgt-msal2-provider/src/exports.ts new file mode 100644 index 0000000000..9bc3a2de1e --- /dev/null +++ b/packages/providers/mgt-msal2-provider/src/exports.ts @@ -0,0 +1,2 @@ +export * from './Msal2Provider'; +export * from './mgt-msal2-provider'; diff --git a/packages/providers/mgt-msal2-provider/src/index.ts b/packages/providers/mgt-msal2-provider/src/index.ts index eeae918924..7cd9a0f500 100644 --- a/packages/providers/mgt-msal2-provider/src/index.ts +++ b/packages/providers/mgt-msal2-provider/src/index.ts @@ -4,6 +4,6 @@ * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ - -export * from './Msal2Provider'; -export * from './mgt-msal2-provider'; +import { registerMgtMsal2Provider } from './mgt-msal2-provider'; +registerMgtMsal2Provider(); +export * from './exports'; diff --git a/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts b/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts index cd68e3158f..88ba2f8dc6 100644 --- a/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts +++ b/packages/providers/mgt-msal2-provider/src/mgt-msal2-provider.ts @@ -6,8 +6,13 @@ */ import { property } from 'lit/decorators.js'; -import { Providers, LoginType, MgtBaseProvider, customElement } from '@microsoft/mgt-element'; +import { Providers, LoginType, MgtBaseProvider, registerComponent } from '@microsoft/mgt-element'; import { Msal2Config, Msal2Provider, PromptType } from './Msal2Provider'; + +export const registerMgtMsal2Provider = () => { + registerComponent('msal2-provider', MgtMsal2Provider); +}; + /** * Authentication Library Provider for Microsoft personal accounts * @@ -15,9 +20,7 @@ import { Msal2Config, Msal2Provider, PromptType } from './Msal2Provider'; * @class MgtMsalProvider * @extends {MgtBaseProvider} */ -@customElement('msal2-provider') -// @customElement('mgt-msal2-provider') -export class MgtMsal2Provider extends MgtBaseProvider { +class MgtMsal2Provider extends MgtBaseProvider { /** * String alphanumerical value relation to a specific user * diff --git a/packages/providers/mgt-proxy-provider/README.md b/packages/providers/mgt-proxy-provider/README.md index 522a77ba5d..24429abd18 100644 --- a/packages/providers/mgt-proxy-provider/README.md +++ b/packages/providers/mgt-proxy-provider/README.md @@ -20,7 +20,7 @@ The `@microsoft/mgt-proxy-provider` package exposes the `ProxyProvider` class wh ```ts import {Providers} from '@microsoft/mgt-element'; - import {ProxyProvider} from '@microsoft/mgt-proxy-provider'; + import {ProxyProvider} from '@microsoft/mgt-proxy-provider/exports'; // initialize the auth provider globally Providers.globalProvider = new ProxyProvider("https://myurl.com/api/GraphProxy"); diff --git a/packages/providers/mgt-proxy-provider/package.json b/packages/providers/mgt-proxy-provider/package.json index d80cb89b16..a7513a8d50 100644 --- a/packages/providers/mgt-proxy-provider/package.json +++ b/packages/providers/mgt-proxy-provider/package.json @@ -36,6 +36,10 @@ "lint": "eslint -c ../../../.eslintrc.js 'src/**/*.ts'", "postpack": "cpx *.tgz ../../../artifacts" }, + "sideEffects": [ + "./dist/es6/index.js", + "./src/index.ts" + ], "dependencies": { "@microsoft/mgt-element": "*", "@microsoft/microsoft-graph-client": "3.0.2" diff --git a/packages/providers/mgt-proxy-provider/src/exports.ts b/packages/providers/mgt-proxy-provider/src/exports.ts new file mode 100644 index 0000000000..e597818a40 --- /dev/null +++ b/packages/providers/mgt-proxy-provider/src/exports.ts @@ -0,0 +1,2 @@ +export * from './mgt-proxy-provider'; +export * from './ProxyProvider'; diff --git a/packages/providers/mgt-proxy-provider/src/index.ts b/packages/providers/mgt-proxy-provider/src/index.ts index 475ebbc856..542eb26fa2 100644 --- a/packages/providers/mgt-proxy-provider/src/index.ts +++ b/packages/providers/mgt-proxy-provider/src/index.ts @@ -4,6 +4,8 @@ * See License in the project root for license information. * ------------------------------------------------------------------------------------------- */ +import { registerMgtProxyProvider } from './mgt-proxy-provider'; -export * from './ProxyProvider'; -export * from './mgt-proxy-provider'; +registerMgtProxyProvider(); + +export * from './exports'; diff --git a/packages/providers/mgt-proxy-provider/src/mgt-proxy-provider.ts b/packages/providers/mgt-proxy-provider/src/mgt-proxy-provider.ts index b64d785428..f47d725557 100644 --- a/packages/providers/mgt-proxy-provider/src/mgt-proxy-provider.ts +++ b/packages/providers/mgt-proxy-provider/src/mgt-proxy-provider.ts @@ -6,9 +6,13 @@ */ import { property } from 'lit/decorators.js'; -import { Providers, MgtBaseProvider, customElement } from '@microsoft/mgt-element'; +import { Providers, MgtBaseProvider, registerComponent } from '@microsoft/mgt-element'; import { ProxyProvider } from './ProxyProvider'; +export const registerMgtProxyProvider = () => { + registerComponent('proxy-provider', MgtProxyProvider); +}; + /** * Authentication component for ProxyProvider * @@ -16,8 +20,7 @@ import { ProxyProvider } from './ProxyProvider'; * @class MgtProxyProvider * @extends {LitElement} */ -@customElement('proxy-provider') -export class MgtProxyProvider extends MgtBaseProvider { +class MgtProxyProvider extends MgtBaseProvider { /** * The base url to the proxy api * diff --git a/packages/providers/mgt-sharepoint-provider/package.json b/packages/providers/mgt-sharepoint-provider/package.json index f9267cf0d9..3b3d279cc2 100644 --- a/packages/providers/mgt-sharepoint-provider/package.json +++ b/packages/providers/mgt-sharepoint-provider/package.json @@ -38,6 +38,7 @@ "lint": "eslint -c ../../../.eslintrc.js 'src/**/*.ts'", "postpack": "cpx *.tgz ../../../artifacts" }, + "sideEffects": false, "dependencies": { "@microsoft/mgt-element": "*" }, diff --git a/packages/providers/mgt-teamsfx-provider/package.json b/packages/providers/mgt-teamsfx-provider/package.json index 4143d73518..d29ac3cca8 100644 --- a/packages/providers/mgt-teamsfx-provider/package.json +++ b/packages/providers/mgt-teamsfx-provider/package.json @@ -39,6 +39,7 @@ "lint": "eslint -c ../../../.eslintrc.js 'src/**/*.ts'", "postpack": "cpx *.tgz ../../../artifacts" }, + "sideEffects": false, "dependencies": { "@azure/core-auth": "^1.3.0", "@microsoft/mgt-element": "*" diff --git a/samples/react-contoso/src/Layout.tsx b/samples/react-contoso/src/Layout.tsx index 67cc9c5537..3b136c932d 100644 --- a/samples/react-contoso/src/Layout.tsx +++ b/samples/react-contoso/src/Layout.tsx @@ -1,8 +1,7 @@ -import React from 'react'; +import React, { Suspense, lazy } from 'react'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; import { Header } from './components/Header'; import { SideNavigation } from './components/SideNavigation'; -import { HomePage } from './pages/HomePage'; import { useIsSignedIn } from './hooks/useIsSignedIn'; import { NavigationItem } from './models/NavigationItem'; import { getNavigation } from './services/Navigation'; @@ -10,6 +9,7 @@ import { FluentProvider, makeStyles, mergeClasses, shorthands } from '@fluentui/ import { tokens } from '@fluentui/react-theme'; import { applyTheme } from '@microsoft/mgt-react'; import { useAppContext } from './AppContext'; +const HomePage = lazy(() => import('./pages/HomePage')); const useStyles = makeStyles({ sidebar: { @@ -86,7 +86,14 @@ export const Layout: React.FunctionComponent = theme => { ) )} - } /> + + + + } + /> diff --git a/samples/react-contoso/src/index.tsx b/samples/react-contoso/src/index.tsx index b94813d954..eeb2f8c302 100644 --- a/samples/react-contoso/src/index.tsx +++ b/samples/react-contoso/src/index.tsx @@ -1,7 +1,7 @@ import ReactDOM from 'react-dom'; import { App } from './App'; import { mergeStyles } from '@fluentui/react'; -import { Msal2Provider } from '@microsoft/mgt-msal2-provider'; +import { Msal2Provider } from '@microsoft/mgt-msal2-provider/dist/es6/exports'; import { Providers, LoginType } from '@microsoft/mgt-element'; // Inject some global styles diff --git a/samples/react-contoso/src/pages/DashboardPage.tsx b/samples/react-contoso/src/pages/DashboardPage.tsx index 699532e6e8..0374afd3cc 100644 --- a/samples/react-contoso/src/pages/DashboardPage.tsx +++ b/samples/react-contoso/src/pages/DashboardPage.tsx @@ -18,7 +18,7 @@ const useStyles = makeStyles({ } }); -export const DashboardPage: React.FunctionComponent = () => { +const DashboardPage: React.FunctionComponent = () => { const styles = useStyles(); const [taskListId, setTaskListId] = React.useState(''); @@ -56,3 +56,5 @@ export const DashboardPage: React.FunctionComponent = () => { ); }; + +export default DashboardPage; diff --git a/samples/react-contoso/src/pages/FilesPage.tsx b/samples/react-contoso/src/pages/FilesPage.tsx index c7883d1a96..a2eb7e47d9 100644 --- a/samples/react-contoso/src/pages/FilesPage.tsx +++ b/samples/react-contoso/src/pages/FilesPage.tsx @@ -19,7 +19,7 @@ const useStyles = makeStyles({ } }); -export const FilesPage: React.FunctionComponent = () => { +const FilesPage: React.FunctionComponent = () => { const styles = useStyles(); const [selectedTab, setSelectedTab] = React.useState('my'); @@ -53,3 +53,5 @@ export const FilesPage: React.FunctionComponent = () => { ); }; + +export default FilesPage; diff --git a/samples/react-contoso/src/pages/HomePage.tsx b/samples/react-contoso/src/pages/HomePage.tsx index 052ce72249..6e8ab7d4f2 100644 --- a/samples/react-contoso/src/pages/HomePage.tsx +++ b/samples/react-contoso/src/pages/HomePage.tsx @@ -1,10 +1,12 @@ import * as React from 'react'; import { PageHeader } from '../components/PageHeader'; -export const HomePage: React.FunctionComponent = () => { +const HomePage: React.FunctionComponent = () => { return ( <> ); }; + +export default HomePage; diff --git a/samples/react-contoso/src/pages/OutlookPage.tsx b/samples/react-contoso/src/pages/OutlookPage.tsx index 616ebcffb1..8caa9d1d39 100644 --- a/samples/react-contoso/src/pages/OutlookPage.tsx +++ b/samples/react-contoso/src/pages/OutlookPage.tsx @@ -36,7 +36,7 @@ const useStyles = makeStyles({ } }); -export const OutlookPage: React.FunctionComponent = () => { +const OutlookPage: React.FunctionComponent = () => { const styles = useStyles(); const [selectedTab, setSelectedTab] = React.useState('focused'); @@ -85,3 +85,5 @@ export const OutlookPage: React.FunctionComponent = () => { ); }; + +export default OutlookPage; diff --git a/samples/react-contoso/src/pages/SearchPage.tsx b/samples/react-contoso/src/pages/SearchPage.tsx index 9d476f7fb2..149f849166 100644 --- a/samples/react-contoso/src/pages/SearchPage.tsx +++ b/samples/react-contoso/src/pages/SearchPage.tsx @@ -24,7 +24,7 @@ const useStyles = makeStyles({ } }); -export const SearchPage: React.FunctionComponent = () => { +const SearchPage: React.FunctionComponent = () => { const styles = useStyles(); const appContext = useAppContext(); const [query] = React.useState(new URLSearchParams(window.location.search).get('q')); @@ -65,3 +65,5 @@ export const SearchPage: React.FunctionComponent = () => { ); }; + +export default SearchPage; diff --git a/samples/react-contoso/src/pages/TaxonomyPage.tsx b/samples/react-contoso/src/pages/TaxonomyPage.tsx index 55c099c4e7..5a2b078894 100644 --- a/samples/react-contoso/src/pages/TaxonomyPage.tsx +++ b/samples/react-contoso/src/pages/TaxonomyPage.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { PageHeader } from '../components/PageHeader'; import { TaxonomyExplorer } from './Taxonomy/TaxonomyExplorer'; -export const TaxonomyPage: React.FunctionComponent = () => { +const TaxonomyPage: React.FunctionComponent = () => { return ( <> { ); }; + +export default TaxonomyPage; diff --git a/samples/react-contoso/src/services/Navigation.tsx b/samples/react-contoso/src/services/Navigation.tsx index f799bdd32f..97642c594b 100644 --- a/samples/react-contoso/src/services/Navigation.tsx +++ b/samples/react-contoso/src/services/Navigation.tsx @@ -1,3 +1,4 @@ +import { lazy, Suspense } from 'react'; import { NavigationItem } from '../models/NavigationItem'; import { HomeRegular, @@ -7,12 +8,12 @@ import { DocumentRegular, TagMultipleRegular } from '@fluentui/react-icons'; -import { DashboardPage } from '../pages/DashboardPage'; -import { OutlookPage } from '../pages/OutlookPage'; -import { SearchPage } from '../pages/SearchPage'; -import { HomePage } from '../pages/HomePage'; -import { FilesPage } from '../pages/FilesPage'; -import { TaxonomyPage } from '../pages/TaxonomyPage'; +const DashboardPage = lazy(() => import('../pages/DashboardPage')); +const OutlookPage = lazy(() => import('../pages/OutlookPage')); +const SearchPage = lazy(() => import('../pages/SearchPage')); +const HomePage = lazy(() => import('../pages/HomePage')); +const FilesPage = lazy(() => import('../pages/FilesPage')); +const TaxonomyPage = lazy(() => import('../pages/TaxonomyPage')); export const getNavigation = (isSignedIn: boolean) => { let navItems: NavigationItem[] = []; @@ -23,7 +24,11 @@ export const getNavigation = (isSignedIn: boolean) => { icon: , key: 'home', requiresLogin: false, - component: , + component: ( + + + + ), exact: true }); @@ -34,7 +39,11 @@ export const getNavigation = (isSignedIn: boolean) => { icon: , key: 'dashboard', requiresLogin: true, - component: , + component: ( + + + + ), exact: true }); @@ -44,7 +53,11 @@ export const getNavigation = (isSignedIn: boolean) => { icon: , key: 'outlook', requiresLogin: true, - component: , + component: ( + + + + ), exact: true }); @@ -54,7 +67,11 @@ export const getNavigation = (isSignedIn: boolean) => { icon: , key: 'files', requiresLogin: true, - component: , + component: ( + + + + ), exact: true }); @@ -64,7 +81,11 @@ export const getNavigation = (isSignedIn: boolean) => { icon: , key: 'files', requiresLogin: true, - component: , + component: ( + + + + ), exact: true }); @@ -75,7 +96,11 @@ export const getNavigation = (isSignedIn: boolean) => { icon: , key: 'search', requiresLogin: true, - component: , + component: ( + + + + ), exact: false }); }