@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/AGENTS.md
CHANGED
|
@@ -79,6 +79,8 @@ export function App() {
|
|
|
79
79
|
}
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
+
The provider uses redirect flow. Set the redirect URI to your app's origin and register it as a **Single-page application (SPA)** in Azure AD.
|
|
83
|
+
|
|
82
84
|
### 3) Teams-hosted app (`TeamsHostedProvider`)
|
|
83
85
|
|
|
84
86
|
```tsx
|
|
@@ -139,6 +141,8 @@ export class MyProvider implements IProvider {
|
|
|
139
141
|
| --- | --- | --- |
|
|
140
142
|
| Current user profile (`userId="me"`) | `User.Read` | Required for basic profile fields |
|
|
141
143
|
| Other user profile (`userId="{id/upn}"`) | `User.ReadBasic.All` | May require admin consent |
|
|
144
|
+
| People default suggestions | `User.ReadBasic.All` | Used for the initial `/users` directory list when no explicit people source is provided |
|
|
145
|
+
| PeoplePicker focus suggestions | `User.ReadBasic.All` | Uses the initial `/users` directory list shown before typing |
|
|
142
146
|
| Presence (`showPresence`) | `Presence.Read` | UI still renders without presence |
|
|
143
147
|
| Profile photo (`fetchImage`) | `User.Read` | Falls back to initials if unavailable |
|
|
144
148
|
|
|
@@ -159,6 +163,12 @@ export class MyProvider implements IProvider {
|
|
|
159
163
|
- Wrap components with `GraphProvider`; avoid direct token handling in UI components.
|
|
160
164
|
- If uncertain, default to `MockProvider` for local iteration, then switch to real auth provider.
|
|
161
165
|
|
|
166
|
+
## Storybook Development
|
|
167
|
+
|
|
168
|
+
- Add `tags: ['autodocs']` to each component story `meta` so Storybook generates a component-level Docs page.
|
|
169
|
+
- Use `parameters.docs.description.component` plus documented `argTypes` to make the Docs page explain the component and its feature stories.
|
|
170
|
+
- Keep component examples in a single `*.stories.tsx` file with representative feature stories instead of separate docs-only pages per feature.
|
|
171
|
+
|
|
162
172
|
## Source of Truth
|
|
163
173
|
|
|
164
174
|
- Primary docs: `README.md`
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for helping improve Graph Toolkit React. This project is a React-first component library for Microsoft Graph built with Fluent UI v9, TypeScript, Vite, Vitest, and Storybook.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
Install dependencies from the repository root:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Run the standard validation commands before opening a pull request:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run type-check
|
|
17
|
+
npm run lint
|
|
18
|
+
npm run test
|
|
19
|
+
npm run build
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Run Storybook locally when changing components or docs:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm run storybook
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Development Guidelines
|
|
29
|
+
|
|
30
|
+
- Prefer existing project patterns over new abstractions.
|
|
31
|
+
- Use Fluent UI v9 components and typings for UI surfaces.
|
|
32
|
+
- Keep Microsoft Graph scopes minimal and feature-driven.
|
|
33
|
+
- Prefer Microsoft Graph `id` values for path-based Graph calls when IDs are available.
|
|
34
|
+
- URL-encode dynamic Graph path segments before building request paths.
|
|
35
|
+
- Add or update tests for behavior changes.
|
|
36
|
+
- Add or update Storybook stories for component-facing changes.
|
|
37
|
+
- Add `tags: ['autodocs']` to component story metadata.
|
|
38
|
+
- Document public interfaces, types, functions, and story args with clear JSDoc or Storybook metadata.
|
|
39
|
+
|
|
40
|
+
## Changesets
|
|
41
|
+
|
|
42
|
+
User-facing changes should include a changeset:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm run changeset
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Choose the smallest appropriate bump and write the summary for package consumers. Documentation-only changes that affect package usage should still include a changeset when they change published guidance.
|
|
49
|
+
|
|
50
|
+
## Documentation
|
|
51
|
+
|
|
52
|
+
Update the README, Storybook docs, sample docs, or migration guide when a change affects setup, supported scenarios, permissions, public APIs, or component behavior.
|
|
53
|
+
|
|
54
|
+
For sample app changes, update [samples/react-msal-sample/README.md](samples/react-msal-sample/README.md).
|
|
55
|
+
|
|
56
|
+
## Pull Request Checklist
|
|
57
|
+
|
|
58
|
+
- Validation commands pass locally or in CI.
|
|
59
|
+
- Tests cover new behavior or regressions.
|
|
60
|
+
- Storybook covers new or changed component states.
|
|
61
|
+
- Documentation reflects user-facing behavior.
|
|
62
|
+
- A changeset is included for user-facing changes.
|
|
63
|
+
|
|
64
|
+
This project follows the [Microsoft Open Source Code of Conduct](CODE_OF_CONDUCT.md).
|
package/README.md
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Graph Toolkit React
|
|
2
|
+
|
|
3
|
+
React components for Microsoft Graph, built with Fluent UI v9 and a provider model that fits modern React applications.
|
|
4
|
+
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://www.npmjs.com/package/@devsym/graph-toolkit-react"><img src="https://img.shields.io/npm/v/@devsym/graph-toolkit-react/beta?label=npm%20beta" alt="npm beta version"></a>
|
|
7
|
+
<a href="https://github.com/ThomasPe/graph-toolkit-react/actions/workflows/pr.yml"><img src="https://github.com/ThomasPe/graph-toolkit-react/actions/workflows/pr.yml/badge.svg" alt="Build and Test"></a>
|
|
8
|
+
<a href="https://github.com/ThomasPe/graph-toolkit-react/actions/workflows/codeql-analysis.yml"><img src="https://github.com/ThomasPe/graph-toolkit-react/actions/workflows/codeql-analysis.yml/badge.svg" alt="CodeQL Security Scan"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/@devsym/graph-toolkit-react"><img src="https://img.shields.io/npm/dm/@devsym/graph-toolkit-react" alt="npm downloads"></a>
|
|
10
|
+
<a href="./LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT license"></a>
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center">
|
|
14
|
+
<img src="docs/assets/readme/banner.png" alt="Graph Toolkit React" width="100%">
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
## Status
|
|
18
|
+
|
|
19
|
+
Graph Toolkit React is in beta and published on the npm `beta` channel. It is ready for evaluation and early adopters, but public APIs may still change until the package exits prerelease mode and is published on the `latest` tag.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @devsym/graph-toolkit-react@beta
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
This package is a React-first successor inspired by Microsoft Graph Toolkit. It uses Fluent UI v9 components directly instead of wrapping framework-agnostic web components.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Install the package and required peer dependencies:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install @devsym/graph-toolkit-react@beta react react-dom @fluentui/react-components
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Install MSAL only when you use `MsalBrowserProvider`:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install @azure/msal-browser
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`@azure/msal-browser` is an optional peer dependency. Teams-hosted apps that use `TeamsHostedProvider` do not need it unless the app uses MSAL elsewhere.
|
|
42
|
+
|
|
43
|
+
## Quick Start
|
|
44
|
+
|
|
45
|
+
Use `MockProvider` for local development, demos, and Storybook-style prototyping without authentication setup.
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
import { FluentProvider, webLightTheme } from '@fluentui/react-components';
|
|
49
|
+
import { GraphProvider, MockProvider, Person } from '@devsym/graph-toolkit-react';
|
|
50
|
+
|
|
51
|
+
const provider = new MockProvider();
|
|
52
|
+
|
|
53
|
+
export function App() {
|
|
54
|
+
return (
|
|
55
|
+
<FluentProvider theme={webLightTheme}>
|
|
56
|
+
<GraphProvider provider={provider}>
|
|
57
|
+
<Person userId="AdeleV@contoso.com" view="twolines" showPresence />
|
|
58
|
+
</GraphProvider>
|
|
59
|
+
</FluentProvider>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For a complete browser-hosted app, try the deployed [React MSAL sample](https://gentle-beach-0f6fe2903.2.azurestaticapps.net) or review [samples/react-msal-sample/README.md](samples/react-msal-sample/README.md).
|
|
65
|
+
|
|
66
|
+
## Providers
|
|
67
|
+
|
|
68
|
+
Choose one provider and pass it to `GraphProvider`.
|
|
69
|
+
|
|
70
|
+
| Scenario | Provider | Notes |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| Local development and UI prototyping | `MockProvider` | Returns deterministic mock data without Graph calls. |
|
|
73
|
+
| Browser-hosted React SPA | `MsalBrowserProvider` | Uses `@azure/msal-browser` redirect flow. |
|
|
74
|
+
| Microsoft Teams-hosted app | `TeamsHostedProvider` | Uses app-owned TeamsJS login plus a backend Graph token exchange. |
|
|
75
|
+
| Existing auth stack | Custom `IProvider` | Implement token acquisition and state management yourself. |
|
|
76
|
+
|
|
77
|
+
<p align="center">
|
|
78
|
+
<img src="docs/assets/readme/provider-flow.svg" alt="Graph Toolkit React provider flow from React components through GraphProvider to Microsoft Graph" width="100%">
|
|
79
|
+
</p>
|
|
80
|
+
|
|
81
|
+
### Browser SPA With MSAL
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
import { PublicClientApplication } from '@azure/msal-browser';
|
|
85
|
+
import { GraphProvider, MsalBrowserProvider, Person } from '@devsym/graph-toolkit-react';
|
|
86
|
+
|
|
87
|
+
const msal = new PublicClientApplication({
|
|
88
|
+
auth: {
|
|
89
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
90
|
+
authority: 'https://login.microsoftonline.com/common',
|
|
91
|
+
redirectUri: window.location.origin,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const provider = new MsalBrowserProvider(msal, ['User.Read']);
|
|
96
|
+
await provider.initialize();
|
|
97
|
+
|
|
98
|
+
export function App() {
|
|
99
|
+
return (
|
|
100
|
+
<GraphProvider provider={provider}>
|
|
101
|
+
<Person userId="me" view="threelines" />
|
|
102
|
+
</GraphProvider>
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Register the redirect URI as a single-page application platform in Microsoft Entra ID.
|
|
108
|
+
|
|
109
|
+
### Teams-Hosted Apps
|
|
110
|
+
|
|
111
|
+
Use `TeamsHostedProvider` when a Teams app already owns TeamsJS authentication and exchanges tokens through a backend.
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
import {
|
|
115
|
+
createBackendTokenExchange,
|
|
116
|
+
GraphProvider,
|
|
117
|
+
Person,
|
|
118
|
+
TeamsHostedProvider,
|
|
119
|
+
} from '@devsym/graph-toolkit-react';
|
|
120
|
+
import { authentication } from '@microsoft/teams-js';
|
|
121
|
+
|
|
122
|
+
const exchangeForGraphToken = createBackendTokenExchange({
|
|
123
|
+
endpoint: '/api/token/exchange',
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const provider = new TeamsHostedProvider({
|
|
127
|
+
defaultScopes: ['User.Read'],
|
|
128
|
+
getTeamsSsoToken: scopes => authentication.getAuthToken({ resources: scopes }),
|
|
129
|
+
exchangeForGraphToken,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
await provider.login();
|
|
133
|
+
|
|
134
|
+
export function App() {
|
|
135
|
+
return (
|
|
136
|
+
<GraphProvider provider={provider}>
|
|
137
|
+
<Person userId="me" view="threelines" showPresence />
|
|
138
|
+
</GraphProvider>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Components
|
|
144
|
+
|
|
145
|
+
The README keeps component examples intentionally short so it stays useful as new components are added. Explore live examples, props, and behavior in [Storybook](https://thomaspe.github.io/graph-toolkit-react/).
|
|
146
|
+
|
|
147
|
+
| Component or hook | Purpose | Where to start |
|
|
148
|
+
| --- | --- | --- |
|
|
149
|
+
| `Person` | Render a Microsoft Graph user with Fluent UI `Persona`, profile photo, presence, and configurable text lines. | Storybook examples for profile views, line rendering, direct data, and presence. |
|
|
150
|
+
| `People` | Render compact avatar groups from direct data, explicit user IDs, group membership, or directory defaults. | Storybook examples for avatar layouts, group lookups, direct data, and overflow behavior. |
|
|
151
|
+
| `PeoplePicker` | Search, select, exclude, and manage people using Fluent UI `TagPicker`. | Storybook examples for default selections, exclusions, limits, and controlled selection. |
|
|
152
|
+
| `usePersonData` | Resolve person data for custom UI. | Use when the built-in `Person` layout is not enough. |
|
|
153
|
+
| `usePeopleList` | Resolve and optionally sort a list of people. | Use when apps need to compose their own list or grid UI. |
|
|
154
|
+
| `usePeopleSearch` | Search users for custom picker experiences. | Use when apps need a fully custom search or picker surface. |
|
|
155
|
+
|
|
156
|
+
`Person`, `People`, and `PeoplePicker` expose `onUpdated` callbacks so apps can react to direct data changes, resolved content loads, and picker state updates with trigger metadata.
|
|
157
|
+
|
|
158
|
+
## Permissions
|
|
159
|
+
|
|
160
|
+
Request the smallest set of Microsoft Graph delegated scopes needed by the features you enable.
|
|
161
|
+
|
|
162
|
+
| Feature | Minimum delegated scope | Notes |
|
|
163
|
+
| --- | --- | --- |
|
|
164
|
+
| Current user profile, `userId="me"` | `User.Read` | Required for basic profile fields. |
|
|
165
|
+
| Other user profile by ID or UPN | `User.ReadBasic.All` | May require admin consent depending on tenant policy. |
|
|
166
|
+
| `People` default directory list | `User.ReadBasic.All` | Used when no explicit people source is provided. |
|
|
167
|
+
| `People` group members via `groupId` | `GroupMember.Read.All` | Required only for direct group membership lookup. |
|
|
168
|
+
| `PeoplePicker` focus suggestions | `User.ReadBasic.All` | Uses the initial `/users` directory list shown before typing. |
|
|
169
|
+
| Presence | `Presence.Read` | UI still renders without presence if unavailable. |
|
|
170
|
+
| Profile photo | `User.Read` | Falls back to initials if no photo is available. |
|
|
171
|
+
|
|
172
|
+
## Examples and Documentation
|
|
173
|
+
|
|
174
|
+
- [Storybook](https://thomaspe.github.io/graph-toolkit-react/) for interactive component docs.
|
|
175
|
+
- [samples/react-msal-sample/README.md](samples/react-msal-sample/README.md) for a browser SPA with MSAL redirect auth.
|
|
176
|
+
- [AGENTS.md](AGENTS.md) for a scenario-first reference that coding agents can consume.
|
|
177
|
+
- [docs/COMPONENT_ROADMAP.md](docs/COMPONENT_ROADMAP.md) for planned component work.
|
|
178
|
+
|
|
179
|
+
## Support and Feedback
|
|
180
|
+
|
|
181
|
+
Use [GitHub Issues](https://github.com/ThomasPe/graph-toolkit-react/issues) for bugs, questions, and component requests. Include the package version, React version, provider type, affected component, and a minimal reproduction when possible.
|
|
182
|
+
|
|
183
|
+
## Supported Environments
|
|
184
|
+
|
|
185
|
+
| Area | Support |
|
|
186
|
+
| --- | --- |
|
|
187
|
+
| React | 18 and 19 |
|
|
188
|
+
| Fluent UI | `@fluentui/react-components` v9 |
|
|
189
|
+
| TypeScript | 5.9 |
|
|
190
|
+
| Development runtime | Node.js 24, matching CI |
|
|
191
|
+
| Package output | ESM, CommonJS, and TypeScript declarations |
|
|
192
|
+
|
|
193
|
+
## Development
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
npm install
|
|
197
|
+
npm run type-check
|
|
198
|
+
npm run lint
|
|
199
|
+
npm run test
|
|
200
|
+
npm run build
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Run Storybook locally:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npm run storybook
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
Build the static Storybook site:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npm run build-storybook
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Regenerate the README component screenshot from real Storybook renders:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npm run screenshots:readme
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Project Structure
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
src/
|
|
225
|
+
components/
|
|
226
|
+
People/
|
|
227
|
+
PeoplePicker/
|
|
228
|
+
Person/
|
|
229
|
+
hooks/
|
|
230
|
+
providers/
|
|
231
|
+
utils/
|
|
232
|
+
stories/
|
|
233
|
+
samples/react-msal-sample/
|
|
234
|
+
docs/
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## Release Process
|
|
238
|
+
|
|
239
|
+
This repository uses Changesets and npm Trusted Publishing through GitHub Actions. User-facing changes should include a changeset file under `.changeset/`.
|
|
240
|
+
|
|
241
|
+
For maintainer details, see [PUBLISHING.md](PUBLISHING.md).
|
|
242
|
+
|
|
243
|
+
## Contributing
|
|
244
|
+
|
|
245
|
+
Contributions are welcome. Start with [CONTRIBUTING.md](CONTRIBUTING.md), which covers local setup, testing expectations, docs updates, and changesets.
|
|
246
|
+
|
|
247
|
+
This project follows the [Microsoft Open Source Code of Conduct](CODE_OF_CONDUCT.md).
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT. See [LICENSE](LICENSE) for details.
|
|
252
|
+
|
|
253
|
+
## Acknowledgments
|
|
254
|
+
|
|
255
|
+
- [Fluent UI](https://react.fluentui.dev/) for the React component system.
|
|
256
|
+
- [Microsoft Graph](https://graph.microsoft.com) for the API surface behind the components.
|
|
257
|
+
- The Microsoft Graph Toolkit community for the original component patterns that inspired this React-first package.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* People component - Display a compact group of people as overlapping avatars
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { PeopleProps } from './People.types';
|
|
6
|
+
/**
|
|
7
|
+
* `People` renders a compact avatar strip similar to the MGT `mgt-people` control.
|
|
8
|
+
*
|
|
9
|
+
* The component can render a supplied list of people, resolve a list of `userIds`, load
|
|
10
|
+
* group members, or default to tenant directory users from `/users`.
|
|
11
|
+
*
|
|
12
|
+
* @param props - Avatar group configuration and people-loading options
|
|
13
|
+
* @returns A compact avatar group, a loading spinner, or `null` when no people are available
|
|
14
|
+
*/
|
|
15
|
+
export declare const People: React.FC<PeopleProps>;
|
|
16
|
+
//# sourceMappingURL=People.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"People.d.ts","sourceRoot":"","sources":["../../../src/components/People/People.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAoB,MAAM,OAAO,CAAC;AASzC,OAAO,EAAgB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AA8C3D;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAoExC,CAAC"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* People component types
|
|
3
|
+
*/
|
|
4
|
+
import type { AvatarGroupProps } from '@fluentui/react-components';
|
|
5
|
+
import type { PeopleSearchResult } from '../../providers/IPersonDataProvider';
|
|
6
|
+
import type { PersonDetails } from '../Person/Person.types';
|
|
7
|
+
/**
|
|
8
|
+
* Supported built-in sort fields for resolved people collections.
|
|
9
|
+
*/
|
|
10
|
+
export type PeopleSortField = 'displayName' | 'givenName' | 'surname';
|
|
11
|
+
/**
|
|
12
|
+
* Sort direction for resolved people collections.
|
|
13
|
+
*/
|
|
14
|
+
export type PeopleSortDirection = 'asc' | 'desc';
|
|
15
|
+
/**
|
|
16
|
+
* Triggers reported by the {@link PeopleProps.onUpdated} callback.
|
|
17
|
+
*/
|
|
18
|
+
export type PeopleUpdateTrigger = 'peopleChanged' | 'peopleLoaded' | 'peopleLoadFailed';
|
|
19
|
+
/**
|
|
20
|
+
* A person entry rendered by the {@link People} component.
|
|
21
|
+
*
|
|
22
|
+
* This extends the base people search result shape with optional presence fields used
|
|
23
|
+
* for avatar badges when {@link PeopleProps.showPresence} is enabled.
|
|
24
|
+
* Presence fields and additional custom fields are inherited from {@link PersonDetails}.
|
|
25
|
+
*/
|
|
26
|
+
export type PeoplePerson = PersonDetails & PeopleSearchResult;
|
|
27
|
+
/**
|
|
28
|
+
* Event payload reported when the {@link People} component finishes a meaningful update.
|
|
29
|
+
*/
|
|
30
|
+
export interface PeopleUpdatedEvent {
|
|
31
|
+
/**
|
|
32
|
+
* The reason the component reported the update.
|
|
33
|
+
*/
|
|
34
|
+
trigger: PeopleUpdateTrigger;
|
|
35
|
+
/**
|
|
36
|
+
* The resolved people currently rendered by the component.
|
|
37
|
+
*/
|
|
38
|
+
people: PeoplePerson[];
|
|
39
|
+
/**
|
|
40
|
+
* Whether the component is still loading data.
|
|
41
|
+
*/
|
|
42
|
+
loading: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* The most recent list-loading error, if any.
|
|
45
|
+
*/
|
|
46
|
+
error: Error | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Props for the {@link People} component.
|
|
50
|
+
*/
|
|
51
|
+
export interface PeopleProps extends Omit<AvatarGroupProps, 'children'> {
|
|
52
|
+
/**
|
|
53
|
+
* A pre-resolved list of people to render.
|
|
54
|
+
*
|
|
55
|
+
* When provided, the component skips list discovery and renders these people directly.
|
|
56
|
+
*/
|
|
57
|
+
people?: PeoplePerson[];
|
|
58
|
+
/**
|
|
59
|
+
* A list of user identifiers to resolve and render.
|
|
60
|
+
*
|
|
61
|
+
* Values can be Microsoft Graph user IDs, UPNs, email addresses, or `"me"`.
|
|
62
|
+
*/
|
|
63
|
+
userIds?: string[];
|
|
64
|
+
/**
|
|
65
|
+
* Additional Graph user fields to request when the component resolves people.
|
|
66
|
+
*/
|
|
67
|
+
selectFields?: string[];
|
|
68
|
+
/**
|
|
69
|
+
* Field used to sort the resolved people collection.
|
|
70
|
+
*/
|
|
71
|
+
sortBy?: PeopleSortField;
|
|
72
|
+
/**
|
|
73
|
+
* Direction used when {@link PeopleProps.sortBy} is provided.
|
|
74
|
+
*
|
|
75
|
+
* Defaults to `asc`.
|
|
76
|
+
*/
|
|
77
|
+
sortDirection?: PeopleSortDirection;
|
|
78
|
+
/**
|
|
79
|
+
* The ID of a Microsoft Entra ID group whose direct user members should be rendered.
|
|
80
|
+
*/
|
|
81
|
+
groupId?: string;
|
|
82
|
+
/**
|
|
83
|
+
* Maximum number of visible avatars before the remaining people are shown in overflow.
|
|
84
|
+
*
|
|
85
|
+
* Defaults to `3`, matching the MGT `mgt-people` control.
|
|
86
|
+
*/
|
|
87
|
+
showMax?: number;
|
|
88
|
+
/**
|
|
89
|
+
* Whether presence badges should be shown on each avatar.
|
|
90
|
+
*
|
|
91
|
+
* Presence is loaded when the active provider and granted scopes support it.
|
|
92
|
+
*/
|
|
93
|
+
showPresence?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Called after the component updates its resolved people collection.
|
|
96
|
+
*
|
|
97
|
+
* Use this to react to direct `people` changes, successful list loads, or failed loads.
|
|
98
|
+
*
|
|
99
|
+
* @param event - Details about the update trigger and the current resolved people state.
|
|
100
|
+
*/
|
|
101
|
+
onUpdated?: (event: PeopleUpdatedEvent) => void;
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=People.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"People.types.d.ts","sourceRoot":"","sources":["../../../src/components/People/People.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEjD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG,cAAc,GAAG,kBAAkB,CAAC;AAExF;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,OAAO,EAAE,mBAAmB,CAAC;IAC7B;;OAEG;IACH,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,gBAAgB,EAAE,UAAU,CAAC;IACrE;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IAExB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAC;IAEzB;;;;OAIG;IACH,aAAa,CAAC,EAAE,mBAAmB,CAAC;IAEpC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACjD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/People/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PeoplePicker component - Select one or more people using Microsoft Graph search
|
|
3
|
+
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { PeoplePickerProps } from './PeoplePicker.types';
|
|
6
|
+
/**
|
|
7
|
+
* PeoplePicker — a tag-picker backed by Microsoft Graph people search.
|
|
8
|
+
*
|
|
9
|
+
* In controlled mode supply `selectedPeople` + `onSelectionChange`.
|
|
10
|
+
* In uncontrolled mode supply `defaultSelectedPeople` or leave both props unset.
|
|
11
|
+
*
|
|
12
|
+
* The component automatically uses {@link MockProvider} mock data when no real
|
|
13
|
+
* Graph provider is available, making it easy to prototype UIs without auth.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* <PeoplePicker
|
|
18
|
+
* placeholder="Search for people..."
|
|
19
|
+
* onSelectionChange={(people) => console.log(people)}
|
|
20
|
+
* />
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const PeoplePicker: React.FC<PeoplePickerProps>;
|
|
24
|
+
//# sourceMappingURL=PeoplePicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PeoplePicker.d.ts","sourceRoot":"","sources":["../../../src/components/PeoplePicker/PeoplePicker.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAA4D,MAAM,OAAO,CAAC;AAkBjF,OAAO,EAAsB,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAmE7E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAuMpD,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PeoplePicker component types
|
|
3
|
+
*/
|
|
4
|
+
import type { TagPickerProps } from '@fluentui/react-components';
|
|
5
|
+
import type { PeopleSearchResult } from '../../providers/IPersonDataProvider';
|
|
6
|
+
/**
|
|
7
|
+
* A person entry used in the PeoplePicker component.
|
|
8
|
+
*
|
|
9
|
+
* This is an alias for {@link PeopleSearchResult} — both types share the same shape
|
|
10
|
+
* so they can be used interchangeably.
|
|
11
|
+
*/
|
|
12
|
+
export type PeoplePickerPerson = PeopleSearchResult;
|
|
13
|
+
/**
|
|
14
|
+
* Triggers reported by the {@link PeoplePickerProps.onUpdated} callback.
|
|
15
|
+
*/
|
|
16
|
+
export type PeoplePickerUpdateTrigger = 'searchResultsUpdated' | 'selectionChanged';
|
|
17
|
+
/**
|
|
18
|
+
* Event payload reported when the {@link PeoplePicker} component finishes a meaningful update.
|
|
19
|
+
*/
|
|
20
|
+
export interface PeoplePickerUpdatedEvent {
|
|
21
|
+
/**
|
|
22
|
+
* The reason the component reported the update.
|
|
23
|
+
*/
|
|
24
|
+
trigger: PeoplePickerUpdateTrigger;
|
|
25
|
+
/**
|
|
26
|
+
* The current picker search query.
|
|
27
|
+
*/
|
|
28
|
+
searchQuery: string;
|
|
29
|
+
/**
|
|
30
|
+
* The people currently selected in the picker.
|
|
31
|
+
*/
|
|
32
|
+
selectedPeople: PeoplePickerPerson[];
|
|
33
|
+
/**
|
|
34
|
+
* The search results currently shown by the picker.
|
|
35
|
+
*/
|
|
36
|
+
searchResults: PeoplePickerPerson[];
|
|
37
|
+
/**
|
|
38
|
+
* Whether the picker is still loading search results.
|
|
39
|
+
*/
|
|
40
|
+
loading: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Props for the {@link PeoplePicker} component.
|
|
44
|
+
*/
|
|
45
|
+
export interface PeoplePickerProps extends Pick<TagPickerProps, 'appearance' | 'size' | 'disabled'> {
|
|
46
|
+
/**
|
|
47
|
+
* Currently selected people (controlled mode).
|
|
48
|
+
* When provided, the component operates in controlled mode and does not manage its own selection state.
|
|
49
|
+
*/
|
|
50
|
+
selectedPeople?: PeoplePickerPerson[];
|
|
51
|
+
/**
|
|
52
|
+
* Initial selected people (uncontrolled mode).
|
|
53
|
+
* Ignored when {@link selectedPeople} is provided.
|
|
54
|
+
*/
|
|
55
|
+
defaultSelectedPeople?: PeoplePickerPerson[];
|
|
56
|
+
/**
|
|
57
|
+
* Called when the selection changes.
|
|
58
|
+
* @param people - The new array of selected people
|
|
59
|
+
*/
|
|
60
|
+
onSelectionChange?: (people: PeoplePickerPerson[]) => void;
|
|
61
|
+
/**
|
|
62
|
+
* Placeholder text shown in the search input when nothing is typed
|
|
63
|
+
*/
|
|
64
|
+
placeholder?: string;
|
|
65
|
+
/**
|
|
66
|
+
* Maximum number of people that can be selected.
|
|
67
|
+
* When reached the search input is hidden.
|
|
68
|
+
*/
|
|
69
|
+
maxPeople?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Minimum number of characters required before a search is triggered (default: 1)
|
|
72
|
+
*/
|
|
73
|
+
searchMinChars?: number;
|
|
74
|
+
/**
|
|
75
|
+
* Maximum number of search results to show in the dropdown (default: 10)
|
|
76
|
+
*/
|
|
77
|
+
maxSearchResults?: number;
|
|
78
|
+
/**
|
|
79
|
+
* User IDs to exclude from search results.
|
|
80
|
+
* When provided, these IDs will be filtered out of the dropdown suggestions.
|
|
81
|
+
* The search will fetch extra results to compensate so that the dropdown still
|
|
82
|
+
* shows up to {@link maxSearchResults} items after exclusion.
|
|
83
|
+
*/
|
|
84
|
+
excludeUserIds?: string[];
|
|
85
|
+
/**
|
|
86
|
+
* Called after the picker updates its search results or selection state.
|
|
87
|
+
*
|
|
88
|
+
* @param event - Details about the update trigger and the picker state after the update.
|
|
89
|
+
*/
|
|
90
|
+
onUpdated?: (event: PeoplePickerUpdatedEvent) => void;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=PeoplePicker.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PeoplePicker.types.d.ts","sourceRoot":"","sources":["../../../src/components/PeoplePicker/PeoplePicker.types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,yBAAyB,GAAG,sBAAsB,GAAG,kBAAkB,CAAC;AAEpF;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,OAAO,EAAE,yBAAyB,CAAC;IACnC;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,cAAc,EAAE,kBAAkB,EAAE,CAAC;IACrC;;OAEG;IACH,aAAa,EAAE,kBAAkB,EAAE,CAAC;IACpC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBACf,SAAQ,IAAI,CAAC,cAAc,EAAE,YAAY,GAAG,MAAM,GAAG,UAAU,CAAC;IAChE;;;OAGG;IACH,cAAc,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAEtC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE7C;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,IAAI,CAAC;IAE3D;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/PeoplePicker/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EACV,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,sBAAsB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Person.d.ts","sourceRoot":"","sources":["../../../src/components/Person/Person.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"Person.d.ts","sourceRoot":"","sources":["../../../src/components/Person/Person.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAA6B,MAAM,OAAO,CAAC;AAIlD,OAAO,EAA8D,WAAW,EAAc,MAAM,gBAAgB,CAAC;AAqKrH,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA2MxC,CAAC"}
|