@devsym/graph-toolkit-react 1.0.0-next.9 → 1.1.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.
Files changed (38) hide show
  1. package/AGENTS.md +8 -0
  2. package/CONTRIBUTING.md +64 -0
  3. package/README.md +257 -0
  4. package/dist/components/People/People.d.ts +16 -0
  5. package/dist/components/People/People.d.ts.map +1 -0
  6. package/dist/components/People/People.types.d.ts +103 -0
  7. package/dist/components/People/People.types.d.ts.map +1 -0
  8. package/dist/components/People/index.d.ts +6 -0
  9. package/dist/components/People/index.d.ts.map +1 -0
  10. package/dist/components/PeoplePicker/PeoplePicker.d.ts.map +1 -1
  11. package/dist/components/PeoplePicker/PeoplePicker.types.d.ts +35 -0
  12. package/dist/components/PeoplePicker/PeoplePicker.types.d.ts.map +1 -1
  13. package/dist/components/PeoplePicker/index.d.ts +1 -1
  14. package/dist/components/PeoplePicker/index.d.ts.map +1 -1
  15. package/dist/components/Person/Person.d.ts.map +1 -1
  16. package/dist/components/Person/Person.types.d.ts +48 -0
  17. package/dist/components/Person/Person.types.d.ts.map +1 -1
  18. package/dist/components/Person/index.d.ts +1 -1
  19. package/dist/components/Person/index.d.ts.map +1 -1
  20. package/dist/hooks/usePeopleList.d.ts +74 -0
  21. package/dist/hooks/usePeopleList.d.ts.map +1 -0
  22. package/dist/hooks/usePeopleSearch.d.ts +6 -1
  23. package/dist/hooks/usePeopleSearch.d.ts.map +1 -1
  24. package/dist/hooks/usePersonData.d.ts.map +1 -1
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +3 -3
  28. package/dist/index.mjs +1584 -1352
  29. package/dist/providers/IPersonDataProvider.d.ts +14 -1
  30. package/dist/providers/IPersonDataProvider.d.ts.map +1 -1
  31. package/dist/providers/MockProvider.d.ts.map +1 -1
  32. package/dist/utils/graph.d.ts +17 -0
  33. package/dist/utils/graph.d.ts.map +1 -1
  34. package/docs/assets/readme/banner.jpg +0 -0
  35. package/docs/assets/readme/banner.png +0 -0
  36. package/docs/assets/readme/provider-flow.svg +76 -0
  37. package/package.json +26 -25
  38. package/readme.md +0 -415
@@ -69,6 +69,14 @@ export interface PeopleSearchResult {
69
69
  * The unique identifier for the person
70
70
  */
71
71
  id: string;
72
+ /**
73
+ * The person's first name.
74
+ */
75
+ givenName?: string | null;
76
+ /**
77
+ * The person's last name.
78
+ */
79
+ surname?: string | null;
72
80
  /**
73
81
  * The person's display name
74
82
  */
@@ -89,6 +97,11 @@ export interface PeopleSearchResult {
89
97
  * The department the person belongs to
90
98
  */
91
99
  department?: string | null;
100
+ /**
101
+ * Optional profile photo URL for the person.
102
+ * When provided, UI components can render the avatar image without fetching it separately.
103
+ */
104
+ photoUrl?: string | null;
92
105
  }
93
106
  /**
94
107
  * Optional interface that providers can implement to support people search
@@ -96,7 +109,7 @@ export interface PeopleSearchResult {
96
109
  export interface IPeopleSearchProvider {
97
110
  /**
98
111
  * Search for people matching the given query string
99
- * @param query - The search query (display name, email, or UPN fragment)
112
+ * @param query - The search query (display name, email, or UPN fragment). An empty query may return initial suggestions.
100
113
  * @param maxResults - Maximum number of results to return (default: 10)
101
114
  * @returns Promise resolving to an array of matching people
102
115
  */
@@ -1 +1 @@
1
- {"version":3,"file":"IPersonDataProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IPersonDataProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB;;OAEG;IACH,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CACxF;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,SAAS,GAAG,IAAI,KACzB,QAAQ,IAAI,SAAS,GAAG,mBAM1B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;CACjF;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,UAAU,SAAS,GAAG,IAAI,KACzB,QAAQ,IAAI,SAAS,GAAG,qBAM1B,CAAC"}
1
+ {"version":3,"file":"IPersonDataProvider.d.ts","sourceRoot":"","sources":["../../src/providers/IPersonDataProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;OAEG;IACH,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB;;OAEG;IACH,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;CACxF;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,SAAS,GAAG,IAAI,KACzB,QAAQ,IAAI,SAAS,GAAG,mBAM1B,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IACX;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;;OAKG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;CACjF;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,GACjC,UAAU,SAAS,GAAG,IAAI,KACzB,QAAQ,IAAI,SAAS,GAAG,qBAM1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MockProvider.d.ts","sourceRoot":"","sources":["../../src/providers/MockProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAyF/B,qBAAa,YAAa,YAAW,SAAS,EAAE,mBAAmB,EAAE,qBAAqB;IACxF,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,SAAS,CAAuB;gBAC5B,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAMnE,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ3B,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IA+BtF,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAe3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,QAAQ,IAAI,aAAa;IAIzB,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIzC,yBAAyB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIpD,OAAO,CAAC,IAAI;CASb;AAED,eAAO,MAAM,0BAA0B,oBAA+C,CAAC"}
1
+ {"version":3,"file":"MockProvider.d.ts","sourceRoot":"","sources":["../../src/providers/MockProvider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,yBAAyB,EACzB,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAgH/B,qBAAa,YAAa,YAAW,SAAS,EAAE,mBAAmB,EAAE,qBAAqB;IACxF,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,SAAS,CAAuB;gBAC5B,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAMnE,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ3B,aAAa,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC;IA2CtF,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAe3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAK7B,QAAQ,IAAI,aAAa;IAIzB,cAAc,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIzC,yBAAyB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAIpD,OAAO,CAAC,IAAI;CASb;AAED,eAAO,MAAM,0BAA0B,oBAA+C,CAAC"}
@@ -11,4 +11,21 @@ export declare const createGraphClient: (provider: IProvider) => Client;
11
11
  * Extract initials from a display name
12
12
  */
13
13
  export declare const getInitials: (displayName?: string) => string;
14
+ /**
15
+ * Convert a Microsoft Graph photo response into a data URL string when possible.
16
+ *
17
+ * The Graph SDK may return a string, `Blob`, or `ArrayBuffer` depending on the
18
+ * environment and request adapter. Unsupported response shapes resolve to `null`.
19
+ *
20
+ * @param photoResponse - Raw response returned from the Graph photo endpoint
21
+ * @returns A data URL string or `null` when the response cannot be converted
22
+ */
23
+ export declare const photoResponseToDataUrl: (photoResponse: unknown) => Promise<string | null>;
24
+ /**
25
+ * Encode a dynamic Microsoft Graph path segment for safe interpolation into request URLs.
26
+ *
27
+ * @param value - Raw path segment value such as a user identifier or group ID
28
+ * @returns The trimmed and URL-encoded path segment
29
+ */
30
+ export declare const encodeGraphPathSegment: (value: string) => string;
14
31
  //# sourceMappingURL=graph.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/utils/graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,SAAS,KAAG,MAWvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,cAAc,MAAM,KAAG,MASlD,CAAC"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/utils/graph.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD;;GAEG;AACH,eAAO,MAAM,iBAAiB,GAAI,UAAU,SAAS,KAAG,MAWvD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,GAAI,cAAc,MAAM,KAAG,MASlD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,GAAU,eAAe,OAAO,KAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CA0B1F,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,MAAM,KAAG,MAA0C,CAAC"}
Binary file
Binary file
@@ -0,0 +1,76 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1100" height="430" viewBox="0 0 1100 430" role="img" aria-labelledby="title desc">
2
+ <title id="title">Graph Toolkit React provider flow</title>
3
+ <desc id="desc">A diagram showing React components inside GraphProvider using MockProvider, MsalBrowserProvider, TeamsHostedProvider, or a custom provider to access Microsoft Graph.</desc>
4
+ <defs>
5
+ <marker id="arrow" markerWidth="10" markerHeight="10" refX="9" refY="5" orient="auto" markerUnits="strokeWidth">
6
+ <path d="M 0 0 L 10 5 L 0 10 z" fill="#64748b"/>
7
+ </marker>
8
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
9
+ <feDropShadow dx="0" dy="8" stdDeviation="12" flood-color="#111827" flood-opacity="0.12"/>
10
+ </filter>
11
+ </defs>
12
+
13
+ <rect width="1100" height="430" fill="#f7f9fb"/>
14
+
15
+ <g transform="translate(58 54)">
16
+ <rect width="238" height="300" rx="8" fill="#ffffff" stroke="#d1d5db" filter="url(#shadow)"/>
17
+ <text x="26" y="42" font-family="Segoe UI, Arial, sans-serif" font-size="18" font-weight="600" fill="#111827">React application</text>
18
+ <text x="26" y="70" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#4b5563">Components render normal React UI</text>
19
+
20
+ <rect x="26" y="104" width="186" height="44" rx="6" fill="#eef6ff" stroke="#b3d6f2"/>
21
+ <text x="48" y="132" font-family="Segoe UI, Arial, sans-serif" font-size="14" font-weight="600" fill="#0f4c81">Person</text>
22
+
23
+ <rect x="26" y="164" width="186" height="44" rx="6" fill="#eefcf7" stroke="#b7ead7"/>
24
+ <text x="48" y="192" font-family="Segoe UI, Arial, sans-serif" font-size="14" font-weight="600" fill="#0f6b50">People</text>
25
+
26
+ <rect x="26" y="224" width="186" height="44" rx="6" fill="#fff7ed" stroke="#fed7aa"/>
27
+ <text x="48" y="252" font-family="Segoe UI, Arial, sans-serif" font-size="14" font-weight="600" fill="#9a3412">PeoplePicker</text>
28
+ </g>
29
+
30
+ <g transform="translate(378 86)">
31
+ <rect width="344" height="236" rx="8" fill="#111827" filter="url(#shadow)"/>
32
+ <text x="28" y="44" font-family="Segoe UI, Arial, sans-serif" font-size="20" font-weight="600" fill="#ffffff">GraphProvider</text>
33
+ <text x="28" y="74" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#d1d5db">One provider instance for token and state</text>
34
+
35
+ <rect x="28" y="104" width="132" height="38" rx="6" fill="#ffffff" fill-opacity="0.08" stroke="#374151"/>
36
+ <text x="48" y="128" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#e5e7eb">MockProvider</text>
37
+
38
+ <rect x="184" y="104" width="132" height="38" rx="6" fill="#ffffff" fill-opacity="0.08" stroke="#374151"/>
39
+ <text x="202" y="128" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#e5e7eb">MSAL browser</text>
40
+
41
+ <rect x="28" y="160" width="132" height="38" rx="6" fill="#ffffff" fill-opacity="0.08" stroke="#374151"/>
42
+ <text x="47" y="184" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#e5e7eb">Teams hosted</text>
43
+
44
+ <rect x="184" y="160" width="132" height="38" rx="6" fill="#ffffff" fill-opacity="0.08" stroke="#374151"/>
45
+ <text x="203" y="184" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#e5e7eb">Custom auth</text>
46
+ </g>
47
+
48
+ <g transform="translate(804 54)">
49
+ <rect width="238" height="300" rx="8" fill="#ffffff" stroke="#d1d5db" filter="url(#shadow)"/>
50
+ <text x="26" y="42" font-family="Segoe UI, Arial, sans-serif" font-size="18" font-weight="600" fill="#111827">Microsoft Graph</text>
51
+ <text x="26" y="70" font-family="Segoe UI, Arial, sans-serif" font-size="13" fill="#4b5563">Scoped user and directory data</text>
52
+
53
+ <circle cx="72" cy="128" r="28" fill="#0f6cbd"/>
54
+ <text x="72" y="138" text-anchor="middle" font-family="Segoe UI, Arial, sans-serif" font-size="22" font-weight="600" fill="#ffffff">U</text>
55
+ <text x="118" y="124" font-family="Segoe UI, Arial, sans-serif" font-size="14" font-weight="600" fill="#111827">Users</text>
56
+ <text x="118" y="146" font-family="Segoe UI, Arial, sans-serif" font-size="12" fill="#6b7280">profile and photo</text>
57
+
58
+ <circle cx="72" cy="200" r="28" fill="#13a10e"/>
59
+ <text x="72" y="210" text-anchor="middle" font-family="Segoe UI, Arial, sans-serif" font-size="22" font-weight="600" fill="#ffffff">P</text>
60
+ <text x="118" y="196" font-family="Segoe UI, Arial, sans-serif" font-size="14" font-weight="600" fill="#111827">Presence</text>
61
+ <text x="118" y="218" font-family="Segoe UI, Arial, sans-serif" font-size="12" fill="#6b7280">availability state</text>
62
+
63
+ <circle cx="72" cy="272" r="28" fill="#8764b8"/>
64
+ <text x="72" y="282" text-anchor="middle" font-family="Segoe UI, Arial, sans-serif" font-size="22" font-weight="600" fill="#ffffff">G</text>
65
+ <text x="118" y="268" font-family="Segoe UI, Arial, sans-serif" font-size="14" font-weight="600" fill="#111827">Groups</text>
66
+ <text x="118" y="290" font-family="Segoe UI, Arial, sans-serif" font-size="12" fill="#6b7280">members and lists</text>
67
+ </g>
68
+
69
+ <line x1="318" y1="204" x2="356" y2="204" stroke="#64748b" stroke-width="3" marker-end="url(#arrow)"/>
70
+ <line x1="724" y1="204" x2="780" y2="204" stroke="#64748b" stroke-width="3" marker-end="url(#arrow)"/>
71
+
72
+ <g transform="translate(396 358)">
73
+ <rect width="308" height="42" rx="8" fill="#e8f2ff" stroke="#b3d6f2"/>
74
+ <text x="24" y="27" font-family="Segoe UI, Arial, sans-serif" font-size="14" fill="#0f4c81">Keep auth outside UI components</text>
75
+ </g>
76
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devsym/graph-toolkit-react",
3
- "version": "1.0.0-next.9",
3
+ "version": "1.1.0",
4
4
  "description": "React components for Microsoft Graph powered by Fluent UI",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -16,7 +16,8 @@
16
16
  "dist",
17
17
  "README.md",
18
18
  "AGENTS.md",
19
- "MGT_MIGRATION.md",
19
+ "CONTRIBUTING.md",
20
+ "docs/assets/readme",
20
21
  "LICENSE"
21
22
  ],
22
23
  "scripts": {
@@ -24,7 +25,7 @@
24
25
  "dev": "vite build --watch",
25
26
  "changeset": "changeset",
26
27
  "version-packages": "changeset version",
27
- "publish-packages": "changeset publish --provenance",
28
+ "publish-packages": "changeset publish",
28
29
  "type-check": "tsc --noEmit",
29
30
  "lint": "eslint src --ext .ts,.tsx",
30
31
  "lint:fix": "eslint src --ext .ts,.tsx --fix",
@@ -51,7 +52,7 @@
51
52
  },
52
53
  "publishConfig": {
53
54
  "access": "public",
54
- "tag": "next"
55
+ "tag": "latest"
55
56
  },
56
57
  "peerDependencies": {
57
58
  "@azure/msal-browser": "^4.0.0 || ^5.0.0",
@@ -69,34 +70,34 @@
69
70
  "@microsoft/microsoft-graph-types": "^2.40.0"
70
71
  },
71
72
  "devDependencies": {
72
- "@azure/msal-browser": "^5.2.0",
73
- "@changesets/cli": "^2.29.7",
74
- "@fluentui/react-components": "^9.72.6",
75
- "@storybook/addon-a11y": "^10.0.6",
76
- "@storybook/addon-docs": "^10.0.6",
77
- "@storybook/addon-links": "^10.0.6",
78
- "@storybook/react-vite": "^10.0.6",
73
+ "@azure/msal-browser": "^5.15.0",
74
+ "@changesets/cli": "^2.31.0",
75
+ "@fluentui/react-components": "^9.74.3",
76
+ "@storybook/addon-a11y": "^10.4.6",
77
+ "@storybook/addon-docs": "^10.4.6",
78
+ "@storybook/addon-links": "^10.4.6",
79
+ "@storybook/react-vite": "^10.4.6",
79
80
  "@testing-library/dom": "^10.4.1",
80
81
  "@testing-library/react": "^16.3.0",
81
82
  "@types/react": "^18.2.0",
82
83
  "@types/react-dom": "^18.2.0",
83
- "@typescript-eslint/eslint-plugin": "^8.46.3",
84
- "@typescript-eslint/parser": "^8.46.3",
85
- "@vitejs/plugin-react": "^5.1.0",
84
+ "@typescript-eslint/eslint-plugin": "^8.62.1",
85
+ "@typescript-eslint/parser": "^8.62.1",
86
+ "@vitejs/plugin-react": "^6.0.3",
86
87
  "eslint": "^9.39.1",
87
88
  "eslint-config-prettier": "^10.1.8",
88
89
  "eslint-plugin-react": "^7.33.2",
89
- "eslint-plugin-react-hooks": "^7.0.1",
90
- "eslint-plugin-storybook": "^10.2.8",
91
- "globals": "^17.3.0",
92
- "jsdom": "^27.1.0",
93
- "prettier": "^3.2.5",
90
+ "eslint-plugin-react-hooks": "^7.1.1",
91
+ "eslint-plugin-storybook": "^10.4.6",
92
+ "globals": "^17.7.0",
93
+ "jsdom": "^29.1.1",
94
+ "prettier": "^3.8.3",
94
95
  "react": "^18.2.0",
95
96
  "react-dom": "^18.2.0",
96
- "storybook": "^10.0.6",
97
- "typescript": "^5.9.3",
98
- "vite": "^7.2.2",
99
- "vite-plugin-dts": "^4.5.4",
100
- "vitest": "^4.0.18"
97
+ "storybook": "^10.3.6",
98
+ "typescript": "^6.0.3",
99
+ "vite": "^8.0.10",
100
+ "vite-plugin-dts": "^5.0.3",
101
+ "vitest": "^4.1.9"
101
102
  }
102
- }
103
+ }
package/readme.md DELETED
@@ -1,415 +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
- <a href="https://www.npmjs.com/package/@devsym/graph-toolkit-react"><img src="https://img.shields.io/badge/alpha-0.1.0-orange" alt="Alpha Release"></a>
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
- ## 🔄 Migration from MGT
56
-
57
- For migration from Microsoft Graph Toolkit (including Teams-hosted scenarios), use [`docs/MGT_MIGRATION.md`](./docs/MGT_MIGRATION.md).
58
-
59
- The guide includes:
60
-
61
- - Concept mapping (MGT patterns to this package)
62
- - Step-by-step migration checklist
63
- - Teams-specific migration section (`TeamsHostedProvider` + backend token exchange)
64
- - Common migration pitfalls and validation checklist
65
-
66
- ## 🤖 Agent Quick Reference
67
-
68
- If you are using a coding agent (Copilot/Codex/Claude/etc.), use the scenario-first reference in [`AGENTS.md`](./AGENTS.md).
69
-
70
- It includes:
71
-
72
- - Provider decision matrix by hosting scenario
73
- - Minimal copy-ready snippets for `MockProvider`, `MsalBrowserProvider`, `TeamsHostedProvider`, and custom `IProvider`
74
- - Scopes-by-feature mapping
75
- - Common failures and exact remediation steps
76
-
77
- For end-to-end browser-hosted setup with MSAL, also see [`samples/react-msal-sample/README.md`](./samples/react-msal-sample/README.md).
78
-
79
- ## 🎨 Components
80
-
81
- Currently available in alpha:
82
-
83
- ### Person Component
84
- A flexible component for displaying user information from Microsoft Graph.
85
-
86
- ```tsx
87
- import { Person } from '@devsym/graph-toolkit-react';
88
-
89
- <Person
90
- userId="user@contoso.com"
91
- view="twolines"
92
- showPresence
93
- presenceOnly={false}
94
- size="large"
95
- textAlignment="center"
96
- onClick={() => console.log('Persona clicked!')}
97
- />
98
- ```
99
-
100
- `Person` supports Fluent UI Persona props directly.
101
-
102
- MGT-style line customization is also supported:
103
-
104
- ```tsx
105
- <Person
106
- userId="me"
107
- view="threelines"
108
- line1Property="givenName"
109
- line2Property="mail,userPrincipalName"
110
- line3Property="presenceAvailability"
111
- />
112
- ```
113
-
114
- For full manual override, use React render callbacks as the replacement for MGT line templates:
115
-
116
- ```tsx
117
- <Person
118
- personDetails={{
119
- displayName: 'Megan Bowen',
120
- jobTitle: 'CEO',
121
- department: 'Leadership',
122
- officeLocation: 'Seattle',
123
- }}
124
- view="fourlines"
125
- renderLine1={({ text }) => <span>Name: {text}</span>}
126
- renderLine2={({ text }) => <span>Role: {text}</span>}
127
- renderLine3={({ text }) => <span>Org: {text}</span>}
128
- renderLine4={({ text }) => <span>Location: {text}</span>}
129
- />
130
- ```
131
-
132
-
133
- ## 🚀 Getting Started
134
-
135
- ### Prerequisites
136
-
137
- ```json
138
- {
139
- "react": "^18.0.0 || ^19.0.0",
140
- "react-dom": "^18.0.0 || ^19.0.0",
141
- "@fluentui/react-components": "^9.0.0"
142
- }
143
- ```
144
-
145
- ### Installation
146
-
147
- ```bash
148
- npm install --save @devsym/graph-toolkit-react
149
- ```
150
-
151
- Also install required peer dependencies in your app if they are not already present:
152
-
153
- ```bash
154
- npm install --save react react-dom @fluentui/react-components
155
- ```
156
-
157
- If you plan to use `MsalBrowserProvider`, also install:
158
-
159
- ```bash
160
- npm install --save @azure/msal-browser
161
- ```
162
-
163
- If you only use `TeamsHostedProvider` (Teams-hosted app with consumer-managed Teams auth), `@azure/msal-browser` is not required.
164
-
165
- ### Quick Start
166
-
167
- ```tsx
168
- import { FluentProvider, webLightTheme } from '@fluentui/react-components';
169
- import { GraphProvider, MockProvider, Person } from '@devsym/graph-toolkit-react';
170
-
171
- function App() {
172
- const provider = new MockProvider(); // Use MockProvider for development
173
-
174
- return (
175
- <FluentProvider theme={webLightTheme}>
176
- <GraphProvider provider={provider}>
177
- <Person userId="AdeleV@contoso.com" view="twolines" showPresence />
178
- </GraphProvider>
179
- </FluentProvider>
180
- );
181
- }
182
- ```
183
-
184
- ### Authentication Providers
185
-
186
- The library uses a provider pattern for authentication:
187
-
188
- - **MockProvider**: Returns mock data (Adele Vance) without API calls - perfect for development
189
- - **MsalBrowserProvider**: Native MSAL browser provider included in this package
190
- - **TeamsHostedProvider**: For Teams-hosted apps using consumer-managed Teams login + backend Graph token exchange
191
- - **Custom Providers**: Implement `IProvider` interface to integrate with other auth systems
192
-
193
- #### `MsalBrowserProvider` quick start
194
-
195
- ```tsx
196
- import { PublicClientApplication } from '@azure/msal-browser';
197
- import {
198
- GraphProvider,
199
- MsalBrowserProvider,
200
- Person,
201
- ProviderState,
202
- } from '@devsym/graph-toolkit-react';
203
-
204
- const msal = new PublicClientApplication({
205
- auth: {
206
- clientId: 'YOUR_CLIENT_ID',
207
- authority: 'https://login.microsoftonline.com/common',
208
- redirectUri: window.location.origin,
209
- },
210
- });
211
-
212
- const provider = new MsalBrowserProvider(msal, ['User.Read']);
213
- await provider.initialize();
214
-
215
- function App() {
216
- return (
217
- <GraphProvider provider={provider}>
218
- <Person userId="me" view="threelines" />
219
- </GraphProvider>
220
- );
221
- }
222
- ```
223
-
224
- The provider uses redirect flow. Set the redirect URI to your app's origin and register it as a **Single-page application (SPA)** platform in Azure AD.
225
-
226
- #### `TeamsHostedProvider` quick start (consumer-managed Teams login)
227
-
228
- Use this when your app is hosted in Microsoft Teams and your app code already handles TeamsJS auth for multiple APIs.
229
- The provider does not open Teams login popups itself; it uses callbacks you provide.
230
-
231
- ```tsx
232
- import {
233
- createBackendTokenExchange,
234
- GraphProvider,
235
- Person,
236
- TeamsHostedProvider,
237
- } from '@devsym/graph-toolkit-react';
238
- import { authentication } from '@microsoft/teams-js';
239
-
240
- const exchangeForGraphToken = createBackendTokenExchange({
241
- endpoint: '/api/token/exchange',
242
- });
243
-
244
- const provider = new TeamsHostedProvider({
245
- defaultScopes: ['User.Read'],
246
- getTeamsSsoToken: async (scopes) => {
247
- // Consumer app owns Teams auth and can reuse token for other APIs
248
- return authentication.getAuthToken({ resources: scopes });
249
- },
250
- exchangeForGraphToken,
251
- });
252
-
253
- await provider.login();
254
-
255
- function App() {
256
- return (
257
- <GraphProvider provider={provider}>
258
- <Person userId="me" view="threelines" />
259
- </GraphProvider>
260
- );
261
- }
262
- ```
263
-
264
- Use explicit mode selection in your app:
265
-
266
- - Browser-hosted app: instantiate `MsalBrowserProvider`
267
- - Teams-hosted app: instantiate `TeamsHostedProvider`
268
-
269
- #### Scopes by feature
270
-
271
- | Feature | Minimum delegated scope | Notes |
272
- | ------- | ------------------------ | ----- |
273
- | Load current user profile (`userId="me"`) | `User.Read` | Required for basic person data (`displayName`, `mail`, etc.) |
274
- | Load another user by id/upn (`userId="{id}"`) | `User.ReadBasic.All` | May require admin consent depending on tenant policy |
275
- | Show presence (`showPresence`) | `Presence.Read` | If not granted, person still renders without presence |
276
- | Load profile photo (`fetchImage`) | `User.Read` | Falls back to initials if photo is unavailable |
277
-
278
- ```tsx
279
- import { IProvider, ProviderState } from '@devsym/graph-toolkit-react';
280
-
281
- class MyAuthProvider implements IProvider {
282
- state: ProviderState = 'SignedOut';
283
-
284
- async login(): Promise<void> { /* ... */ }
285
- async logout(): Promise<void> { /* ... */ }
286
- async getAccessToken(): Promise<string> { /* ... */ }
287
- }
288
- ```
289
-
290
- ## 📚 Storybook
291
-
292
- Explore all components interactively in our Storybook documentation:
293
-
294
- **[View Storybook →](https://thomaspe.github.io/graph-toolkit-react/)** _(Deployed to GitHub Pages on every main branch update)_
295
-
296
- Run locally:
297
- ```bash
298
- npm run storybook
299
- ```
300
-
301
- ## 🛠️ Development
302
-
303
- ### Tech Stack
304
-
305
- - **Build**: Vite 7 (ESM + CJS output)
306
- - **Language**: TypeScript 5.9
307
- - **Testing**: Vitest 3 + Testing Library
308
- - **Documentation**: Storybook 10
309
- - **UI Framework**: Fluent UI v9 (React Components)
310
- - **Graph SDK**: @microsoft/microsoft-graph-client 3.0
311
-
312
- ### Build & Test
313
-
314
- ```bash
315
- # Install dependencies
316
- npm install
317
-
318
- # Type check
319
- npm run type-check
320
-
321
- # Lint
322
- npm run lint
323
-
324
- # Build library
325
- npm run build
326
-
327
- # Run tests
328
- npm run test
329
-
330
- # Run Storybook
331
- npm run storybook
332
-
333
- # Build Storybook for deployment
334
- npm run build-storybook
335
- ```
336
-
337
- ### Project Structure
338
-
339
- ```
340
- src/
341
- ├── components/
342
- │ └── Person/
343
- │ ├── Person.tsx # Component implementation
344
- │ ├── Person.types.ts # TypeScript definitions
345
- │ └── __tests__/ # Component tests
346
- ├── providers/
347
- │ ├── IProvider.ts # Provider interface
348
- │ ├── MockProvider.ts # Development provider
349
- │ └── ProviderContext.tsx # React context
350
- ├── hooks/
351
- │ ├── useGraphClient.ts # Graph client hook
352
- │ ├── usePersonData.ts # Person data fetching
353
- │ └── useProvider.ts # Provider access
354
- └── index.ts # Public API
355
-
356
- stories/
357
- └── Person.stories.tsx # Storybook stories (19 examples)
358
- ```
359
-
360
- ## 🎯 Current Status
361
-
362
- **Alpha** ✅
363
-
364
- - ✅ Repository restructured from monorepo to single package
365
- - ✅ Provider infrastructure with MockProvider for development
366
- - ✅ Person component using Fluent UI Persona
367
- - ✅ Full Persona configuration support (textAlignment, textPosition, sizing)
368
- - ✅ Build system (ESM + CJS + TypeScript declarations)
369
- - ✅ Storybook documentation and GitHub Pages deployment
370
- - ✅ CI/CD with GitHub Actions
371
- - ✅ Automatic Storybook deployment to GitHub Pages
372
- - ✅ Sample app with MSAL sign-in and `Person` (`userId="me"`) at `samples/react-msal-sample`
373
-
374
- **Next Steps**:
375
- - Additional components (PeoplePicker, PersonCard, Login) — see [`docs/COMPONENT_ROADMAP.md`](./docs/COMPONENT_ROADMAP.md) for the full ranked list
376
- - Expanded provider guidance and production auth examples
377
- - Comprehensive test coverage
378
- - First stable release (1.0.0)
379
-
380
- ## 🤝 Contribute
381
-
382
- This **community-driven project** provides React developers with components for Microsoft Graph. Contributions are welcome!
383
-
384
- ### Guidelines
385
-
386
- 1. Follow the existing code style (TypeScript, ESLint, Prettier)
387
- 2. Use Fluent UI components whenever possible
388
- 3. Write tests for new components
389
- 4. Add Storybook stories demonstrating all component features
390
- 5. Update documentation
391
-
392
- See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
393
-
394
- ## 📝 License
395
-
396
- MIT License - see [LICENSE](LICENSE) for details.
397
-
398
- ## 🙏 Acknowledgments
399
-
400
- - **Fluent UI Team**: For the excellent React component library
401
- - **Microsoft Graph**: For the powerful API that makes this all possible
402
- - **Community Contributors**: For helping improve this project
403
-
404
- ---
405
-
406
- **Note**: This is an alpha release under active development. APIs may change. Not recommended for production use yet.
407
-
408
- ## 🔗 Links
409
-
410
- - **Fluent UI**: [react.fluentui.dev](https://react.fluentui.dev/)
411
- - **Microsoft Graph**: [graph.microsoft.com](https://graph.microsoft.com)
412
- - **Component Roadmap**: [docs/COMPONENT_ROADMAP.md](./docs/COMPONENT_ROADMAP.md)
413
- - **Changelog**: [CHANGELOG.md](CHANGELOG.md)
414
- - **Publishing**: [PUBLISHING.md](PUBLISHING.md)
415
-