jcicl 1.0.79 → 1.1.2

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 (51) hide show
  1. package/.chunks/EventType.js +650 -0
  2. package/.chunks/chevron-down.js +11 -0
  3. package/.chunks/user.js +41 -0
  4. package/AuthContext/AuthProvider.d.ts +63 -0
  5. package/AuthContext/AuthProvider.js +227 -0
  6. package/AuthContext/index.d.ts +4 -0
  7. package/AuthContext/index.js +8 -0
  8. package/AuthContext/msalConfig.d.ts +56 -0
  9. package/AuthContext/msalConfig.js +9157 -0
  10. package/AuthenticatedApiClient.d.ts +42 -0
  11. package/AuthenticatedApiClient.js +30 -0
  12. package/Button/Button.d.ts +2 -3
  13. package/Button/Button.js +20 -20
  14. package/ChevronOval/ChevronOval.d.ts +8 -0
  15. package/ChevronOval/ChevronOval.js +22 -0
  16. package/ChevronOval/index.d.ts +3 -0
  17. package/ChevronOval/index.js +5 -0
  18. package/ClientMatchCard/ClientMatchCard.d.ts +21 -0
  19. package/ClientMatchCard/ClientMatchCard.js +121 -0
  20. package/ClientMatchCard/index.d.ts +3 -0
  21. package/ClientMatchCard/index.js +5 -0
  22. package/ContactCard/ContactCard.js +18 -52
  23. package/DefaultTemplate/DefaultTemplate.js +81 -72
  24. package/DetailPageComponents/DetailPageComponents.d.ts +21 -2
  25. package/DetailPageComponents/DetailPageComponents.js +80 -44
  26. package/ExpandableSection/ExpandableSection.d.ts +19 -0
  27. package/ExpandableSection/ExpandableSection.js +23 -0
  28. package/ExpandableSection/index.d.ts +3 -0
  29. package/ExpandableSection/index.js +5 -0
  30. package/FormFields/FormFields.js +20 -13
  31. package/LoginPage/LoginPage.d.ts +15 -0
  32. package/LoginPage/LoginPage.js +77 -0
  33. package/LoginPage/index.d.ts +1 -0
  34. package/LoginPage/index.js +4 -0
  35. package/Pill/Pill.d.ts +13 -0
  36. package/Pill/Pill.js +36 -38
  37. package/ScrollContainer/ScrollContainer.js +1076 -984
  38. package/Table/Table.js +13013 -10032
  39. package/assets/style.css +2 -2
  40. package/assets/tailwind.css +1 -1
  41. package/camelToKebab.d.ts +12 -0
  42. package/camelToKebab.js +4 -0
  43. package/createUseApi.d.ts +22 -0
  44. package/createUseApi.js +11 -0
  45. package/format.d.ts +48 -0
  46. package/format.js +31 -0
  47. package/index.d.ts +23 -0
  48. package/index.js +113 -64
  49. package/package.json +3 -1
  50. package/theme.d.ts +0 -2
  51. package/theme.js +0 -2
@@ -0,0 +1,63 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { IPublicClientApplication, AccountInfo } from '@azure/msal-browser';
3
+ export interface AuthContextValue {
4
+ /** The currently authenticated account, or null if not logged in */
5
+ account: AccountInfo | null;
6
+ /** Whether a user is currently authenticated */
7
+ isAuthenticated: boolean;
8
+ /**
9
+ * True while any auth interaction is in progress (startup, redirect, token
10
+ * acquisition). Use this to block UI until auth state is settled.
11
+ */
12
+ isLoading: boolean;
13
+ /** App roles assigned to the current user, sourced from the ID token claims. Empty array if not authenticated. */
14
+ roles: string[];
15
+ /** Returns true if the current user has the specified app role. */
16
+ hasRole: (role: string) => boolean;
17
+ /** Initiates Microsoft login via redirect */
18
+ login: () => void;
19
+ /** Logs out the current user via redirect */
20
+ logout: () => void;
21
+ /**
22
+ * Silently acquires an access token. Falls back to redirect if interaction
23
+ * is required (e.g. token expired, consent needed).
24
+ * This is the standard MSAL "silent first, interactive as fallback" pattern.
25
+ * @param scopes - Override scopes. Defaults to the configured apiScope.
26
+ */
27
+ acquireToken: (scopes?: string[]) => Promise<string>;
28
+ }
29
+ /** Exported so tests and Storybook can mock the auth context directly. */
30
+ export declare const AuthContext: import('react').Context<AuthContextValue | null>;
31
+ export interface AuthProviderProps {
32
+ /** PublicClientApplication created by createMsalInstance() */
33
+ msalInstance: IPublicClientApplication;
34
+ /**
35
+ * The API scope URI used for token acquisition and login consent.
36
+ * Example: "api://<clientId>/access_as_user"
37
+ */
38
+ apiScope: string;
39
+ }
40
+ /**
41
+ * Wrap your application root with AuthProvider to enable Microsoft Identity
42
+ * Platform authentication for all child components.
43
+ *
44
+ * ```tsx
45
+ * import { AuthProvider, createMsalInstance } from 'jcicl/AuthContext';
46
+ *
47
+ * const msalInstance = createMsalInstance({
48
+ * clientId: import.meta.env.VITE_AZURE_CLIENT_ID,
49
+ * tenantId: import.meta.env.VITE_AZURE_TENANT_ID,
50
+ * apiScope: import.meta.env.VITE_API_SCOPE,
51
+ * });
52
+ *
53
+ * <AuthProvider msalInstance={msalInstance} apiScope={import.meta.env.VITE_API_SCOPE}>
54
+ * <App />
55
+ * </AuthProvider>
56
+ * ```
57
+ */
58
+ export declare function AuthProvider({ msalInstance, apiScope, children }: PropsWithChildren<AuthProviderProps>): import("react/jsx-runtime").JSX.Element;
59
+ /**
60
+ * Hook to access the current auth state and actions.
61
+ * Must be rendered inside AuthProvider.
62
+ */
63
+ export declare function useAuthContext(): AuthContextValue;
@@ -0,0 +1,227 @@
1
+ import { jsx as m } from "react/jsx-runtime";
2
+ import * as I from "react";
3
+ import _, { useEffect as T, useMemo as L, useReducer as w, useContext as b, createContext as O } from "react";
4
+ import { c, s, E as l, I as P, a as i, L as j, W as U, b as q } from "../.chunks/EventType.js";
5
+ /*! @azure/msal-browser v5.10.0 2026-05-07 */
6
+ const x = {
7
+ initialize: () => Promise.reject(c(s)),
8
+ acquireTokenPopup: () => Promise.reject(c(s)),
9
+ acquireTokenRedirect: () => Promise.reject(c(s)),
10
+ acquireTokenSilent: () => Promise.reject(c(s)),
11
+ acquireTokenByCode: () => Promise.reject(c(s)),
12
+ getAllAccounts: () => [],
13
+ getAccount: () => null,
14
+ handleRedirectPromise: () => Promise.reject(c(s)),
15
+ loginPopup: () => Promise.reject(c(s)),
16
+ loginRedirect: () => Promise.reject(c(s)),
17
+ logoutRedirect: () => Promise.reject(c(s)),
18
+ logoutPopup: () => Promise.reject(c(s)),
19
+ ssoSilent: () => Promise.reject(c(s)),
20
+ addEventCallback: () => null,
21
+ removeEventCallback: () => {
22
+ },
23
+ addPerformanceCallback: () => "",
24
+ removePerformanceCallback: () => !1,
25
+ getLogger: () => {
26
+ throw c(s);
27
+ },
28
+ setLogger: () => {
29
+ },
30
+ setActiveAccount: () => {
31
+ },
32
+ getActiveAccount: () => null,
33
+ initializeWrapperLibrary: () => {
34
+ },
35
+ setNavigationClient: () => {
36
+ },
37
+ getConfiguration: () => {
38
+ throw c(s);
39
+ },
40
+ hydrateCache: () => Promise.reject(c(s)),
41
+ clearCache: () => Promise.reject(c(s))
42
+ };
43
+ /*! @azure/msal-browser v5.10.0 2026-05-07 */
44
+ class M {
45
+ /**
46
+ * Gets interaction status from event message
47
+ * @param message
48
+ * @param currentStatus
49
+ */
50
+ static getInteractionStatusFromEvent(n, r) {
51
+ switch (n.eventType) {
52
+ case l.ACQUIRE_TOKEN_START:
53
+ if (n.interactionType === P.Redirect || n.interactionType === P.Popup)
54
+ return i.AcquireToken;
55
+ break;
56
+ case l.HANDLE_REDIRECT_START:
57
+ return i.HandleRedirect;
58
+ case l.LOGOUT_START:
59
+ return i.Logout;
60
+ case l.LOGOUT_END:
61
+ if (r && r !== i.Logout)
62
+ break;
63
+ return i.None;
64
+ case l.HANDLE_REDIRECT_END:
65
+ if (r && r !== i.HandleRedirect)
66
+ break;
67
+ return i.None;
68
+ case l.ACQUIRE_TOKEN_SUCCESS:
69
+ case l.ACQUIRE_TOKEN_FAILURE:
70
+ case l.RESTORE_FROM_BFCACHE:
71
+ if (n.interactionType === P.Redirect || n.interactionType === P.Popup) {
72
+ if (r && r !== i.AcquireToken)
73
+ break;
74
+ return i.None;
75
+ }
76
+ break;
77
+ }
78
+ return null;
79
+ }
80
+ }
81
+ /*! @azure/msal-react v5.4.0 2026-05-07 */
82
+ const S = {
83
+ instance: x,
84
+ inProgress: i.None,
85
+ accounts: [],
86
+ logger: new j({})
87
+ }, h = I.createContext(S);
88
+ h.Consumer;
89
+ /*! @azure/msal-react v5.4.0 2026-05-07 */
90
+ function v(e, n) {
91
+ if (e.length !== n.length)
92
+ return !1;
93
+ const r = [...n];
94
+ return e.every((t) => {
95
+ const o = r.shift();
96
+ return !t || !o ? !1 : t.homeAccountId === o.homeAccountId && t.localAccountId === o.localAccountId && t.username === o.username;
97
+ });
98
+ }
99
+ /*! @azure/msal-react v5.4.0 2026-05-07 */
100
+ const K = "@azure/msal-react", k = "5.4.0";
101
+ /*! @azure/msal-react v5.4.0 2026-05-07 */
102
+ const A = {
103
+ UNBLOCK_INPROGRESS: "UNBLOCK_INPROGRESS",
104
+ EVENT: "EVENT"
105
+ }, B = (e, n) => {
106
+ const { type: r, payload: t } = n;
107
+ let o = e.inProgress;
108
+ switch (r) {
109
+ case A.UNBLOCK_INPROGRESS:
110
+ e.inProgress === i.Startup && (o = i.None, t.logger.info("MsalProvider - handleRedirectPromise resolved, setting inProgress to 'none'", ""));
111
+ break;
112
+ case A.EVENT:
113
+ const u = t.message, d = M.getInteractionStatusFromEvent(u, e.inProgress);
114
+ d && (t.logger.info(`MsalProvider - '${u.eventType}' results in setting inProgress from '${e.inProgress}' to '${d}'`, ""), o = d);
115
+ break;
116
+ default:
117
+ throw new Error(`Unknown action type: ${r}`);
118
+ }
119
+ if (o === i.Startup)
120
+ return e;
121
+ const a = t.instance.getAllAccounts();
122
+ return o !== e.inProgress && !v(a, e.accounts) ? {
123
+ ...e,
124
+ inProgress: o,
125
+ accounts: a
126
+ } : o !== e.inProgress ? {
127
+ ...e,
128
+ inProgress: o
129
+ } : v(a, e.accounts) ? e : {
130
+ ...e,
131
+ accounts: a
132
+ };
133
+ };
134
+ function D({ instance: e, children: n }) {
135
+ T(() => {
136
+ e.initializeWrapperLibrary(U.React, k);
137
+ }, [e]);
138
+ const r = L(() => e.getLogger().clone(K, k), [e]), [t, o] = w(B, void 0, () => ({
139
+ inProgress: i.Startup,
140
+ accounts: []
141
+ }));
142
+ T(() => {
143
+ const u = e.addEventCallback((d) => {
144
+ o({
145
+ payload: {
146
+ instance: e,
147
+ logger: r,
148
+ message: d
149
+ },
150
+ type: A.EVENT
151
+ });
152
+ });
153
+ return r.verbose(`MsalProvider - Registered event callback with id: '${u}'`, ""), e.initialize().then(() => {
154
+ e.handleRedirectPromise().catch(() => {
155
+ }).finally(() => {
156
+ o({
157
+ payload: {
158
+ instance: e,
159
+ logger: r
160
+ },
161
+ type: A.UNBLOCK_INPROGRESS
162
+ });
163
+ });
164
+ }).catch(() => {
165
+ }), () => {
166
+ u && (r.verbose(`MsalProvider - Removing event callback '${u}'`, ""), e.removeEventCallback(u));
167
+ };
168
+ }, [e, r]);
169
+ const a = {
170
+ instance: e,
171
+ inProgress: t.inProgress,
172
+ accounts: t.accounts,
173
+ logger: r
174
+ };
175
+ return _.createElement(h.Provider, { value: a }, n);
176
+ }
177
+ /*! @azure/msal-react v5.4.0 2026-05-07 */
178
+ const G = () => b(h), N = O(null);
179
+ function $({ children: e, apiScope: n }) {
180
+ const { instance: r, accounts: t, inProgress: o } = G();
181
+ T(() => {
182
+ t.length > 0 && !r.getActiveAccount() && r.setActiveAccount(t[0]);
183
+ }, [t, r]);
184
+ const a = r.getActiveAccount() ?? t[0] ?? null, u = !!a, d = o !== i.None, g = a == null ? void 0 : a.idTokenClaims, C = Array.isArray(g == null ? void 0 : g.roles) ? g.roles : [], y = {
185
+ account: a,
186
+ isAuthenticated: u,
187
+ isLoading: d,
188
+ roles: C,
189
+ hasRole: (E) => C.includes(E),
190
+ login: () => {
191
+ r.loginRedirect({ scopes: [n] });
192
+ },
193
+ logout: () => {
194
+ r.logoutRedirect({ account: a ?? void 0 });
195
+ },
196
+ acquireToken: async (E) => {
197
+ const f = r.getActiveAccount() ?? t[0];
198
+ if (!f)
199
+ throw new Error("[Auth] No active account. The user must sign in first.");
200
+ const p = E ?? [n];
201
+ try {
202
+ return (await r.acquireTokenSilent({
203
+ scopes: p,
204
+ account: f
205
+ })).accessToken;
206
+ } catch (R) {
207
+ if (R instanceof q)
208
+ return r.acquireTokenRedirect({ scopes: p, account: f }), "";
209
+ throw R;
210
+ }
211
+ }
212
+ };
213
+ return /* @__PURE__ */ m(N.Provider, { value: y, children: e });
214
+ }
215
+ function X({ msalInstance: e, apiScope: n, children: r }) {
216
+ return /* @__PURE__ */ m(D, { instance: e, children: /* @__PURE__ */ m($, { apiScope: n, children: r }) });
217
+ }
218
+ function Y() {
219
+ const e = b(N);
220
+ if (!e) throw new Error("useAuthContext must be used inside <AuthProvider>");
221
+ return e;
222
+ }
223
+ export {
224
+ N as AuthContext,
225
+ X as AuthProvider,
226
+ Y as useAuthContext
227
+ };
@@ -0,0 +1,4 @@
1
+ export { AuthProvider, useAuthContext, AuthContext } from './AuthProvider';
2
+ export type { AuthProviderProps, AuthContextValue } from './AuthProvider';
3
+ export { createMsalInstance } from './msalConfig';
4
+ export type { AuthConfig } from './msalConfig';
@@ -0,0 +1,8 @@
1
+ import { AuthContext as o, AuthProvider as r, useAuthContext as n } from "./AuthProvider.js";
2
+ import { createMsalInstance as x } from "./msalConfig.js";
3
+ export {
4
+ o as AuthContext,
5
+ r as AuthProvider,
6
+ x as createMsalInstance,
7
+ n as useAuthContext
8
+ };
@@ -0,0 +1,56 @@
1
+ import { PublicClientApplication } from '@azure/msal-browser';
2
+ /**
3
+ * Configuration for a single Azure AD app registration that covers both the
4
+ * React SPA and the .NET API backend.
5
+ *
6
+ * Setup in the Azure portal:
7
+ * 1. Use the existing API app registration (the one your .NET backend already validates against).
8
+ * 2. Under "Authentication", add a Single-page application platform with your SPA redirect URI.
9
+ * 3. Under "Expose an API", ensure a scope exists (e.g. "access_as_user").
10
+ * 4. Under "App roles", define any roles you want to gate UI or API access with.
11
+ *
12
+ * The same clientId is used by both the SPA (to log in and acquire tokens) and
13
+ * the .NET backend (as the expected token audience). App roles defined here
14
+ * appear in both the ID token (readable by the SPA via idTokenClaims) and the
15
+ * access token (validated by the API).
16
+ */
17
+ export interface AuthConfig {
18
+ /**
19
+ * The application (client) ID of the single app registration.
20
+ * This is the same ID your .NET backend uses as its audience.
21
+ */
22
+ clientId: string;
23
+ /** Azure AD directory (tenant) ID */
24
+ tenantId: string;
25
+ /**
26
+ * A scope exposed by this app registration.
27
+ * Must be in the form "api://<clientId>/<scopeName>".
28
+ * Requesting this scope causes Azure AD to issue an access token
29
+ * whose audience matches what your .NET backend expects.
30
+ */
31
+ apiScope: string;
32
+ /**
33
+ * Redirect URI after login/logout.
34
+ * Defaults to window.location.origin.
35
+ */
36
+ redirectUri?: string;
37
+ }
38
+ /**
39
+ * Creates a configured PublicClientApplication instance for use with AuthProvider.
40
+ *
41
+ * Tokens are stored in sessionStorage (not localStorage) to prevent cross-tab
42
+ * token sharing and reduce XSS exposure surface.
43
+ *
44
+ * ```typescript
45
+ * import { createMsalInstance } from 'jcicl/AuthContext';
46
+ *
47
+ * // All three values come from the same app registration in the Azure portal.
48
+ * // VITE_API_SCOPE is the scope exposed by that registration, e.g. "api://social-services/access_as_user".
49
+ * const msalInstance = createMsalInstance({
50
+ * clientId: import.meta.env.VITE_AZURE_CLIENT_ID,
51
+ * tenantId: import.meta.env.VITE_AZURE_TENANT_ID,
52
+ * apiScope: import.meta.env.VITE_API_SCOPE,
53
+ * });
54
+ * ```
55
+ */
56
+ export declare function createMsalInstance(config: AuthConfig): PublicClientApplication;