@devsym/graph-toolkit-react 1.0.0-next.8 → 1.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +10 -0
- package/CONTRIBUTING.md +64 -0
- package/README.md +257 -0
- package/dist/components/People/People.d.ts +16 -0
- package/dist/components/People/People.d.ts.map +1 -0
- package/dist/components/People/People.types.d.ts +103 -0
- package/dist/components/People/People.types.d.ts.map +1 -0
- package/dist/components/People/index.d.ts +6 -0
- package/dist/components/People/index.d.ts.map +1 -0
- package/dist/components/PeoplePicker/PeoplePicker.d.ts +24 -0
- package/dist/components/PeoplePicker/PeoplePicker.d.ts.map +1 -0
- package/dist/components/PeoplePicker/PeoplePicker.types.d.ts +92 -0
- package/dist/components/PeoplePicker/PeoplePicker.types.d.ts.map +1 -0
- package/dist/components/PeoplePicker/index.d.ts +6 -0
- package/dist/components/PeoplePicker/index.d.ts.map +1 -0
- package/dist/components/Person/Person.d.ts.map +1 -1
- package/dist/components/Person/Person.types.d.ts +48 -0
- package/dist/components/Person/Person.types.d.ts.map +1 -1
- package/dist/components/Person/index.d.ts +1 -1
- package/dist/components/Person/index.d.ts.map +1 -1
- package/dist/hooks/usePeopleList.d.ts +74 -0
- package/dist/hooks/usePeopleList.d.ts.map +1 -0
- package/dist/hooks/usePeopleSearch.d.ts +42 -0
- package/dist/hooks/usePeopleSearch.d.ts.map +1 -0
- package/dist/hooks/usePersonData.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.mjs +1618 -631
- package/dist/providers/IPersonDataProvider.d.ts +62 -1
- package/dist/providers/IPersonDataProvider.d.ts.map +1 -1
- package/dist/providers/MockProvider.d.ts +3 -2
- package/dist/providers/MockProvider.d.ts.map +1 -1
- package/dist/providers/MsalBrowserProvider.d.ts +12 -0
- package/dist/providers/MsalBrowserProvider.d.ts.map +1 -1
- package/dist/utils/graph.d.ts +17 -0
- package/dist/utils/graph.d.ts.map +1 -1
- package/docs/assets/readme/banner.jpg +0 -0
- package/docs/assets/readme/banner.png +0 -0
- package/docs/assets/readme/provider-flow.svg +76 -0
- package/package.json +17 -15
- package/readme.md +0 -417
package/readme.md
DELETED
|
@@ -1,417 +0,0 @@
|
|
|
1
|
-
<h1 align="center">
|
|
2
|
-
Graph Toolkit React
|
|
3
|
-
</h1>
|
|
4
|
-
|
|
5
|
-
<h4 align="center">Modern React Components for <a href="https://graph.microsoft.com">Microsoft Graph</a> powered by <a href="https://react.fluentui.dev/">Fluent UI</a></h4>
|
|
6
|
-
|
|
7
|
-
<p align="center">
|
|
8
|
-
<img src="https://img.shields.io/badge/alpha-0.1.0-orange" alt="Alpha Release">
|
|
9
|
-
<img src="https://img.shields.io/badge/React-18%2F19-blue" alt="React 18/19">
|
|
10
|
-
<img src="https://img.shields.io/badge/Fluent_UI-9.72-purple" alt="Fluent UI 9">
|
|
11
|
-
<img src="https://img.shields.io/badge/TypeScript-5.9-blue" alt="TypeScript 5.9">
|
|
12
|
-
</p>
|
|
13
|
-
|
|
14
|
-
<h3 align="center">
|
|
15
|
-
<a href="#getting-started">Get Started</a> •
|
|
16
|
-
<a href="#migration-from-mgt">Migration</a> •
|
|
17
|
-
<a href="#agent-quick-reference">Agent Quick Reference</a> •
|
|
18
|
-
<a href="#storybook">Storybook</a> •
|
|
19
|
-
<a href="#contribute">Contribute</a>
|
|
20
|
-
</h3>
|
|
21
|
-
|
|
22
|
-
## 🎯 Project Vision
|
|
23
|
-
|
|
24
|
-
This project provides a **modern, React-first component library** built on top of Fluent UI to help React developers integrate with Microsoft Graph quickly and consistently.
|
|
25
|
-
|
|
26
|
-
> Note: This project is a spiritual successor to Microsoft Graph Toolkit, redesigned as a React-first library.
|
|
27
|
-
|
|
28
|
-
### Key Principles
|
|
29
|
-
|
|
30
|
-
- **React-First**: Built specifically for React applications, not framework-agnostic web components
|
|
31
|
-
- **Fluent UI Native**: Uses official Fluent UI v9 components instead of custom implementations
|
|
32
|
-
- **Single Package**: One cohesive npm package instead of a complex monorepo
|
|
33
|
-
- **Modern Stack**: TypeScript 5, Vite, Vitest, and Storybook
|
|
34
|
-
- **Developer Experience**: Simple API, excellent TypeScript support, comprehensive documentation
|
|
35
|
-
|
|
36
|
-
### Design Philosophy
|
|
37
|
-
|
|
38
|
-
Instead of maintaining the original web component approach, this fork:
|
|
39
|
-
|
|
40
|
-
1. **Leverages Fluent UI**: Uses the official `Persona` component from Fluent UI instead of custom Avatar/Text components
|
|
41
|
-
2. **Embraces React Patterns**: Components designed for React's patterns (hooks, context) from the ground up
|
|
42
|
-
3. **Reduces Complexity**: Smaller codebase enables quicker development and easier maintenance
|
|
43
|
-
4. **Focuses on Quality**: Fewer components, better implementation, comprehensive documentation
|
|
44
|
-
|
|
45
|
-
## 📦 Package
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npm install @devsym/graph-toolkit-react
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
| Package | Version | Description |
|
|
52
|
-
| ------- | ------- | ----------- |
|
|
53
|
-
| `@devsym/graph-toolkit-react` | `0.1.0-alpha.1` | React components for Microsoft Graph powered by Fluent UI |
|
|
54
|
-
|
|
55
|
-
<a id="migration-from-mgt"></a>
|
|
56
|
-
## 🔄 Migration from MGT
|
|
57
|
-
|
|
58
|
-
For migration from Microsoft Graph Toolkit (including Teams-hosted scenarios), use [`docs/MGT_MIGRATION.md`](./docs/MGT_MIGRATION.md).
|
|
59
|
-
|
|
60
|
-
The guide includes:
|
|
61
|
-
|
|
62
|
-
- Concept mapping (MGT patterns to this package)
|
|
63
|
-
- Step-by-step migration checklist
|
|
64
|
-
- Teams-specific migration section (`TeamsHostedProvider` + backend token exchange)
|
|
65
|
-
- Common migration pitfalls and validation checklist
|
|
66
|
-
|
|
67
|
-
<a id="agent-quick-reference"></a>
|
|
68
|
-
## 🤖 Agent Quick Reference
|
|
69
|
-
|
|
70
|
-
If you are using a coding agent (Copilot/Codex/Claude/etc.), use the scenario-first reference in [`AGENTS.md`](./AGENTS.md).
|
|
71
|
-
|
|
72
|
-
It includes:
|
|
73
|
-
|
|
74
|
-
- Provider decision matrix by hosting scenario
|
|
75
|
-
- Minimal copy-ready snippets for `MockProvider`, `MsalBrowserProvider`, `TeamsHostedProvider`, and custom `IProvider`
|
|
76
|
-
- Scopes-by-feature mapping
|
|
77
|
-
- Common failures and exact remediation steps
|
|
78
|
-
|
|
79
|
-
For end-to-end browser-hosted setup with MSAL, also see [`samples/react-msal-sample/README.md`](./samples/react-msal-sample/README.md).
|
|
80
|
-
|
|
81
|
-
## 🎨 Components
|
|
82
|
-
|
|
83
|
-
Currently available in alpha:
|
|
84
|
-
|
|
85
|
-
### Person Component
|
|
86
|
-
A flexible component for displaying user information from Microsoft Graph.
|
|
87
|
-
|
|
88
|
-
```tsx
|
|
89
|
-
import { Person } from '@devsym/graph-toolkit-react';
|
|
90
|
-
|
|
91
|
-
<Person
|
|
92
|
-
userId="user@contoso.com"
|
|
93
|
-
view="twolines"
|
|
94
|
-
showPresence
|
|
95
|
-
presenceOnly={false}
|
|
96
|
-
size="large"
|
|
97
|
-
textAlignment="center"
|
|
98
|
-
onClick={() => console.log('Persona clicked!')}
|
|
99
|
-
/>
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
`Person` supports Fluent UI Persona props directly.
|
|
103
|
-
|
|
104
|
-
MGT-style line customization is also supported:
|
|
105
|
-
|
|
106
|
-
```tsx
|
|
107
|
-
<Person
|
|
108
|
-
userId="me"
|
|
109
|
-
view="threelines"
|
|
110
|
-
line1Property="givenName"
|
|
111
|
-
line2Property="mail,userPrincipalName"
|
|
112
|
-
line3Property="presenceAvailability"
|
|
113
|
-
/>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
For full manual override, use React render callbacks as the replacement for MGT line templates:
|
|
117
|
-
|
|
118
|
-
```tsx
|
|
119
|
-
<Person
|
|
120
|
-
personDetails={{
|
|
121
|
-
displayName: 'Megan Bowen',
|
|
122
|
-
jobTitle: 'CEO',
|
|
123
|
-
department: 'Leadership',
|
|
124
|
-
officeLocation: 'Seattle',
|
|
125
|
-
}}
|
|
126
|
-
view="fourlines"
|
|
127
|
-
renderLine1={({ text }) => <span>Name: {text}</span>}
|
|
128
|
-
renderLine2={({ text }) => <span>Role: {text}</span>}
|
|
129
|
-
renderLine3={({ text }) => <span>Org: {text}</span>}
|
|
130
|
-
renderLine4={({ text }) => <span>Location: {text}</span>}
|
|
131
|
-
/>
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
<a id="getting-started"></a>
|
|
136
|
-
## 🚀 Getting Started
|
|
137
|
-
|
|
138
|
-
### Prerequisites
|
|
139
|
-
|
|
140
|
-
```json
|
|
141
|
-
{
|
|
142
|
-
"react": "^18.0.0 || ^19.0.0",
|
|
143
|
-
"react-dom": "^18.0.0 || ^19.0.0",
|
|
144
|
-
"@fluentui/react-components": "^9.0.0"
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Installation
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
npm install --save @devsym/graph-toolkit-react
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
Also install required peer dependencies in your app if they are not already present:
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
npm install --save react react-dom @fluentui/react-components
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
If you plan to use `MsalBrowserProvider`, also install:
|
|
161
|
-
|
|
162
|
-
```bash
|
|
163
|
-
npm install --save @azure/msal-browser
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
If you only use `TeamsHostedProvider` (Teams-hosted app with consumer-managed Teams auth), `@azure/msal-browser` is not required.
|
|
167
|
-
|
|
168
|
-
### Quick Start
|
|
169
|
-
|
|
170
|
-
```tsx
|
|
171
|
-
import { FluentProvider, webLightTheme } from '@fluentui/react-components';
|
|
172
|
-
import { GraphProvider, MockProvider, Person } from '@devsym/graph-toolkit-react';
|
|
173
|
-
|
|
174
|
-
function App() {
|
|
175
|
-
const provider = new MockProvider(); // Use MockProvider for development
|
|
176
|
-
|
|
177
|
-
return (
|
|
178
|
-
<FluentProvider theme={webLightTheme}>
|
|
179
|
-
<GraphProvider provider={provider}>
|
|
180
|
-
<Person userId="AdeleV@contoso.com" view="twolines" showPresence />
|
|
181
|
-
</GraphProvider>
|
|
182
|
-
</FluentProvider>
|
|
183
|
-
);
|
|
184
|
-
}
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Authentication Providers
|
|
188
|
-
|
|
189
|
-
The library uses a provider pattern for authentication:
|
|
190
|
-
|
|
191
|
-
- **MockProvider**: Returns mock data (Adele Vance) without API calls - perfect for development
|
|
192
|
-
- **MsalBrowserProvider**: Native MSAL browser provider included in this package
|
|
193
|
-
- **TeamsHostedProvider**: For Teams-hosted apps using consumer-managed Teams login + backend Graph token exchange
|
|
194
|
-
- **Custom Providers**: Implement `IProvider` interface to integrate with other auth systems
|
|
195
|
-
|
|
196
|
-
#### `MsalBrowserProvider` quick start
|
|
197
|
-
|
|
198
|
-
```tsx
|
|
199
|
-
import { PublicClientApplication } from '@azure/msal-browser';
|
|
200
|
-
import {
|
|
201
|
-
GraphProvider,
|
|
202
|
-
MsalBrowserProvider,
|
|
203
|
-
Person,
|
|
204
|
-
ProviderState,
|
|
205
|
-
} from '@devsym/graph-toolkit-react';
|
|
206
|
-
|
|
207
|
-
const msal = new PublicClientApplication({
|
|
208
|
-
auth: {
|
|
209
|
-
clientId: 'YOUR_CLIENT_ID',
|
|
210
|
-
authority: 'https://login.microsoftonline.com/common',
|
|
211
|
-
redirectUri: window.location.origin,
|
|
212
|
-
},
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
const provider = new MsalBrowserProvider(msal, ['User.Read']);
|
|
216
|
-
await provider.initialize();
|
|
217
|
-
|
|
218
|
-
function App() {
|
|
219
|
-
return (
|
|
220
|
-
<GraphProvider provider={provider}>
|
|
221
|
-
<Person userId="me" view="threelines" />
|
|
222
|
-
</GraphProvider>
|
|
223
|
-
);
|
|
224
|
-
}
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
#### `TeamsHostedProvider` quick start (consumer-managed Teams login)
|
|
228
|
-
|
|
229
|
-
Use this when your app is hosted in Microsoft Teams and your app code already handles TeamsJS auth for multiple APIs.
|
|
230
|
-
The provider does not open Teams login popups itself; it uses callbacks you provide.
|
|
231
|
-
|
|
232
|
-
```tsx
|
|
233
|
-
import {
|
|
234
|
-
createBackendTokenExchange,
|
|
235
|
-
GraphProvider,
|
|
236
|
-
Person,
|
|
237
|
-
TeamsHostedProvider,
|
|
238
|
-
} from '@devsym/graph-toolkit-react';
|
|
239
|
-
import { authentication } from '@microsoft/teams-js';
|
|
240
|
-
|
|
241
|
-
const exchangeForGraphToken = createBackendTokenExchange({
|
|
242
|
-
endpoint: '/api/token/exchange',
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
const provider = new TeamsHostedProvider({
|
|
246
|
-
defaultScopes: ['User.Read'],
|
|
247
|
-
getTeamsSsoToken: async (scopes) => {
|
|
248
|
-
// Consumer app owns Teams auth and can reuse token for other APIs
|
|
249
|
-
return authentication.getAuthToken({ resources: scopes });
|
|
250
|
-
},
|
|
251
|
-
exchangeForGraphToken,
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
await provider.login();
|
|
255
|
-
|
|
256
|
-
function App() {
|
|
257
|
-
return (
|
|
258
|
-
<GraphProvider provider={provider}>
|
|
259
|
-
<Person userId="me" view="threelines" />
|
|
260
|
-
</GraphProvider>
|
|
261
|
-
);
|
|
262
|
-
}
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
Use explicit mode selection in your app:
|
|
266
|
-
|
|
267
|
-
- Browser-hosted app: instantiate `MsalBrowserProvider`
|
|
268
|
-
- Teams-hosted app: instantiate `TeamsHostedProvider`
|
|
269
|
-
|
|
270
|
-
#### Scopes by feature
|
|
271
|
-
|
|
272
|
-
| Feature | Minimum delegated scope | Notes |
|
|
273
|
-
| ------- | ------------------------ | ----- |
|
|
274
|
-
| Load current user profile (`userId="me"`) | `User.Read` | Required for basic person data (`displayName`, `mail`, etc.) |
|
|
275
|
-
| Load another user by id/upn (`userId="{id}"`) | `User.ReadBasic.All` | May require admin consent depending on tenant policy |
|
|
276
|
-
| Show presence (`showPresence`) | `Presence.Read` | If not granted, person still renders without presence |
|
|
277
|
-
| Load profile photo (`fetchImage`) | `User.Read` | Falls back to initials if photo is unavailable |
|
|
278
|
-
|
|
279
|
-
```tsx
|
|
280
|
-
import { IProvider, ProviderState } from '@devsym/graph-toolkit-react';
|
|
281
|
-
|
|
282
|
-
class MyAuthProvider implements IProvider {
|
|
283
|
-
state: ProviderState = 'SignedOut';
|
|
284
|
-
|
|
285
|
-
async login(): Promise<void> { /* ... */ }
|
|
286
|
-
async logout(): Promise<void> { /* ... */ }
|
|
287
|
-
async getAccessToken(): Promise<string> { /* ... */ }
|
|
288
|
-
}
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
<a id="storybook"></a>
|
|
292
|
-
## 📚 Storybook
|
|
293
|
-
|
|
294
|
-
Explore all components interactively in our Storybook documentation:
|
|
295
|
-
|
|
296
|
-
**[View Storybook →](https://thomaspe.github.io/graph-toolkit-react/)** _(Deployed to GitHub Pages on every main branch update)_
|
|
297
|
-
|
|
298
|
-
Run locally:
|
|
299
|
-
```bash
|
|
300
|
-
npm run storybook
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
## 🛠️ Development
|
|
304
|
-
|
|
305
|
-
### Tech Stack
|
|
306
|
-
|
|
307
|
-
- **Build**: Vite 7 (ESM + CJS output)
|
|
308
|
-
- **Language**: TypeScript 5.9
|
|
309
|
-
- **Testing**: Vitest 3 + Testing Library
|
|
310
|
-
- **Documentation**: Storybook 10
|
|
311
|
-
- **UI Framework**: Fluent UI v9 (React Components)
|
|
312
|
-
- **Graph SDK**: @microsoft/microsoft-graph-client 3.0
|
|
313
|
-
|
|
314
|
-
### Build & Test
|
|
315
|
-
|
|
316
|
-
```bash
|
|
317
|
-
# Install dependencies
|
|
318
|
-
npm install
|
|
319
|
-
|
|
320
|
-
# Type check
|
|
321
|
-
npm run type-check
|
|
322
|
-
|
|
323
|
-
# Lint
|
|
324
|
-
npm run lint
|
|
325
|
-
|
|
326
|
-
# Build library
|
|
327
|
-
npm run build
|
|
328
|
-
|
|
329
|
-
# Run tests
|
|
330
|
-
npm run test
|
|
331
|
-
|
|
332
|
-
# Run Storybook
|
|
333
|
-
npm run storybook
|
|
334
|
-
|
|
335
|
-
# Build Storybook for deployment
|
|
336
|
-
npm run build-storybook
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
### Project Structure
|
|
340
|
-
|
|
341
|
-
```
|
|
342
|
-
src/
|
|
343
|
-
├── components/
|
|
344
|
-
│ └── Person/
|
|
345
|
-
│ ├── Person.tsx # Component implementation
|
|
346
|
-
│ ├── Person.types.ts # TypeScript definitions
|
|
347
|
-
│ └── __tests__/ # Component tests
|
|
348
|
-
├── providers/
|
|
349
|
-
│ ├── IProvider.ts # Provider interface
|
|
350
|
-
│ ├── MockProvider.ts # Development provider
|
|
351
|
-
│ └── ProviderContext.tsx # React context
|
|
352
|
-
├── hooks/
|
|
353
|
-
│ ├── useGraphClient.ts # Graph client hook
|
|
354
|
-
│ ├── usePersonData.ts # Person data fetching
|
|
355
|
-
│ └── useProvider.ts # Provider access
|
|
356
|
-
└── index.ts # Public API
|
|
357
|
-
|
|
358
|
-
stories/
|
|
359
|
-
└── Person.stories.tsx # Storybook stories (19 examples)
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
## 🎯 Current Status
|
|
363
|
-
|
|
364
|
-
**Alpha** ✅
|
|
365
|
-
|
|
366
|
-
- ✅ Repository restructured from monorepo to single package
|
|
367
|
-
- ✅ Provider infrastructure with MockProvider for development
|
|
368
|
-
- ✅ Person component using Fluent UI Persona
|
|
369
|
-
- ✅ Full Persona configuration support (textAlignment, textPosition, sizing)
|
|
370
|
-
- ✅ Build system (ESM + CJS + TypeScript declarations)
|
|
371
|
-
- ✅ Storybook documentation and GitHub Pages deployment
|
|
372
|
-
- ✅ CI/CD with GitHub Actions
|
|
373
|
-
- ✅ Automatic Storybook deployment to GitHub Pages
|
|
374
|
-
- ✅ Sample app with MSAL sign-in and `Person` (`userId="me"`) at `samples/react-msal-sample`
|
|
375
|
-
|
|
376
|
-
**Next Steps**:
|
|
377
|
-
- Additional components (PeoplePicker, PersonCard, Login)
|
|
378
|
-
- Expanded provider guidance and production auth examples
|
|
379
|
-
- Comprehensive test coverage
|
|
380
|
-
- First stable release (1.0.0)
|
|
381
|
-
|
|
382
|
-
<a id="contribute"></a>
|
|
383
|
-
## 🤝 Contribute
|
|
384
|
-
|
|
385
|
-
This **community-driven project** provides React developers with components for Microsoft Graph. Contributions are welcome!
|
|
386
|
-
|
|
387
|
-
### Guidelines
|
|
388
|
-
|
|
389
|
-
1. Follow the existing code style (TypeScript, ESLint, Prettier)
|
|
390
|
-
2. Use Fluent UI components whenever possible
|
|
391
|
-
3. Write tests for new components
|
|
392
|
-
4. Add Storybook stories demonstrating all component features
|
|
393
|
-
5. Update documentation
|
|
394
|
-
|
|
395
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
|
|
396
|
-
|
|
397
|
-
## 📝 License
|
|
398
|
-
|
|
399
|
-
MIT License - see [LICENSE](LICENSE) for details.
|
|
400
|
-
|
|
401
|
-
## 🙏 Acknowledgments
|
|
402
|
-
|
|
403
|
-
- **Fluent UI Team**: For the excellent React component library
|
|
404
|
-
- **Microsoft Graph**: For the powerful API that makes this all possible
|
|
405
|
-
- **Community Contributors**: For helping improve this project
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
**Note**: This is an alpha release under active development. APIs may change. Not recommended for production use yet.
|
|
410
|
-
|
|
411
|
-
## 🔗 Links
|
|
412
|
-
|
|
413
|
-
- **Fluent UI**: [react.fluentui.dev](https://react.fluentui.dev/)
|
|
414
|
-
- **Microsoft Graph**: [graph.microsoft.com](https://graph.microsoft.com)
|
|
415
|
-
- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
|
|
416
|
-
- **Publishing**: [PUBLISHING.md](PUBLISHING.md)
|
|
417
|
-
|