@the-portland-company/shell 0.1.0 → 0.2.1

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/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
2
3
  import { ReactNode, CSSProperties } from 'react';
3
4
  import { User, Session, SupabaseClient } from '@supabase/supabase-js';
4
5
 
@@ -122,6 +123,16 @@ interface ShellProviderProps {
122
123
  appRegistry?: AppRegistryEntry[];
123
124
  /** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
124
125
  basename?: string;
126
+ /** If provided, shell renders <OrgSelector /> in the header. */
127
+ organization?: ShellOrganizationValue;
128
+ /** If provided, UserMenu shows account switcher + add-account button. */
129
+ linkedAccounts?: ShellLinkedAccountsValue;
130
+ /** If provided, shell renders <SupportRequestButton /> in the header. */
131
+ support?: ShellSupportValue;
132
+ /** Optional element rendered in the header (typically <DevNotesMenu /> from @the-portland-company/devnotes). */
133
+ devNotesMenu?: ReactNode;
134
+ /** href used by the UserMenu "My Profile" link. Defaults to '/my-profile'. */
135
+ myProfileHref?: string;
125
136
  }
126
137
  /** Return value of useShellAuth(). */
127
138
  interface ShellAuthValue {
@@ -130,14 +141,109 @@ interface ShellAuthValue {
130
141
  session: Session | null;
131
142
  signOut: () => Promise<void>;
132
143
  }
144
+ /**
145
+ * Organization that the current user belongs to. Apps supply this via
146
+ * ShellProvider so the shell can render <OrgSelector /> in the header.
147
+ */
148
+ interface ShellOrganization {
149
+ id: string;
150
+ name: string;
151
+ logoUrl?: string | null;
152
+ /** Brand color as a hex string (e.g., '#0066cc'). Used for the org badge fallback. */
153
+ brandColor?: string | null;
154
+ }
155
+ interface ShellOrganizationValue {
156
+ currentOrg: ShellOrganization | null;
157
+ /** All orgs the user belongs to. */
158
+ organizations: ShellOrganization[];
159
+ /** Switch to the org with the given id. App owns the side effects. */
160
+ switchOrganization: (orgId: string) => Promise<void> | void;
161
+ /** Optional link rendered at the bottom of the org menu, e.g., '/organizations/new'. */
162
+ createOrgHref?: string;
163
+ }
164
+ /**
165
+ * An alternate user account the current user can switch into without signing
166
+ * out. App supplies the data + handlers; shell renders the UI inside UserMenu.
167
+ */
168
+ interface ShellLinkedAccount {
169
+ id: string;
170
+ email: string;
171
+ displayName?: string | null;
172
+ avatarUrl?: string | null;
173
+ }
174
+ interface ShellLinkedAccountsValue {
175
+ linkedAccounts: ShellLinkedAccount[];
176
+ switchToAccount: (accountId: string) => Promise<void> | void;
177
+ /** Called when the user clicks "Add account" in UserMenu. App opens its own modal. */
178
+ onAddAccount: () => void;
179
+ /** Called when the user wants to remove a linked account. App opens its own confirm. */
180
+ onRemoveAccount: (accountId: string) => void;
181
+ }
182
+ /** Context emitted to the host's submitSupportRequest handler. */
183
+ interface ShellSupportContext {
184
+ pathname: string;
185
+ search: string;
186
+ pageTitle?: string;
187
+ organizationName?: string;
188
+ }
189
+ interface ShellSupportValue {
190
+ /**
191
+ * Submit a support request. Host app handles persistence/email/etc.
192
+ * Shell renders the modal and calls this on submit.
193
+ */
194
+ submitSupportRequest: (input: {
195
+ email: string;
196
+ phone: string;
197
+ message: string;
198
+ context: ShellSupportContext;
199
+ }) => Promise<void>;
200
+ }
133
201
 
134
- declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
202
+ declare const ShellOrgContext: react.Context<ShellOrganizationValue | null>;
203
+ declare const ShellLinkedAccountsContext: react.Context<ShellLinkedAccountsValue | null>;
204
+ declare const ShellSupportProviderContext: react.Context<ShellSupportValue | null>;
205
+ interface ShellChromeValue$1 {
206
+ devNotesMenu: ReactNode | null;
207
+ myProfileHref: string;
208
+ }
209
+ declare const ShellChromeContext: react.Context<ShellChromeValue$1 | null>;
210
+ declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
135
211
 
136
212
  declare function useShellAuth(): ShellAuthValue;
137
213
 
138
214
  declare function useAppRegistry(): AppRegistryEntry[];
139
215
  declare function useCurrentApp(): string;
140
216
 
217
+ /**
218
+ * Returns the organization value supplied to ShellProvider, or null if the
219
+ * host app didn't pass an `organization` prop. Returning null lets chrome
220
+ * components (e.g., <OrgSelector />) render nothing instead of erroring.
221
+ */
222
+ declare function useShellOrganization(): ShellOrganizationValue | null;
223
+
224
+ /**
225
+ * Returns the linked-accounts value supplied to ShellProvider, or null if not
226
+ * provided. UserMenu uses this to decide whether to render the
227
+ * "switch account" section.
228
+ */
229
+ declare function useShellLinkedAccounts(): ShellLinkedAccountsValue | null;
230
+
231
+ /**
232
+ * Returns the support handler supplied to ShellProvider, or null if not
233
+ * provided. SupportRequestButton uses this to decide whether to render.
234
+ */
235
+ declare function useShellSupport(): ShellSupportValue | null;
236
+
237
+ interface ShellChromeValue {
238
+ devNotesMenu: ReactNode | null;
239
+ myProfileHref: string;
240
+ }
241
+ /**
242
+ * Returns chrome-level options supplied to ShellProvider (devNotesMenu slot,
243
+ * myProfileHref). Throws if used outside <ShellProvider>.
244
+ */
245
+ declare function useShellChrome(): ShellChromeValue;
246
+
141
247
  interface AppLayoutProps extends ShellSlots {
142
248
  children: ReactNode;
143
249
  buildInfo?: string;
@@ -161,6 +267,53 @@ interface FooterProps {
161
267
  }
162
268
  declare function Footer({ buildInfo }: FooterProps): react_jsx_runtime.JSX.Element;
163
269
 
270
+ /**
271
+ * Avatar dropdown rendered at the right side of the header. Reads auth,
272
+ * linked-accounts, and chrome context from ShellProvider.
273
+ */
274
+ declare function UserMenu(): react_jsx_runtime.JSX.Element | null;
275
+
276
+ /**
277
+ * Organization switcher rendered in the header. Reads from
278
+ * useShellOrganization(); renders nothing when no `organization` prop was
279
+ * supplied to ShellProvider.
280
+ */
281
+ declare function OrgSelector(): react_jsx_runtime.JSX.Element | null;
282
+
283
+ /**
284
+ * Support icon + modal rendered in the header. Reads auth, org, and support
285
+ * handler from ShellProvider. Renders nothing when the host app didn't supply
286
+ * a `support` prop.
287
+ */
288
+ declare function SupportRequestButton(): react_jsx_runtime.JSX.Element | null;
289
+
290
+ interface ShellChromeProps {
291
+ children: ReactNode;
292
+ /** Drives <OrgSelector /> in the header. */
293
+ organization?: ShellOrganizationValue | null;
294
+ /** Drives the UserMenu Switch-account section. */
295
+ linkedAccounts?: ShellLinkedAccountsValue | null;
296
+ /** Drives <SupportRequestButton /> and modal submission. */
297
+ support?: ShellSupportValue | null;
298
+ /** Rendered in the header (typically <DevNotesMenu />). */
299
+ devNotesMenu?: ReactNode;
300
+ /** UserMenu profile link target. Defaults to '/my-profile'. */
301
+ myProfileHref?: string;
302
+ }
303
+ /**
304
+ * Drop-in chrome binding for apps where the org/linked-account/support data
305
+ * lives in React contexts nested BELOW <ShellProvider> (e.g., an
306
+ * <OrganizationProvider> that itself depends on <AuthProvider>).
307
+ *
308
+ * Use this component inside those providers to feed the values into the
309
+ * shell's chrome contexts. Nested <Context.Provider> overrides the empty
310
+ * defaults set by <ShellProvider> at the top of the tree.
311
+ *
312
+ * Apps that have all the data available at the ShellProvider construction
313
+ * site can pass the same props to <ShellProvider> directly instead.
314
+ */
315
+ declare function ShellChrome({ children, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellChromeProps): react_jsx_runtime.JSX.Element;
316
+
164
317
  interface RegisterShellPrecacheOptions {
165
318
  /** Path the host app serves the SW from. Default: '/sw-shell.js'. */
166
319
  scriptUrl?: string;
@@ -187,4 +340,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
187
340
  */
188
341
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
189
342
 
190
- export { AppLayout, type AppRegistryEntry, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, PageContainer, PageHeader, type ShellAuthStatus, type ShellAuthValue, ShellProvider, type ShellProviderProps, type ShellSlots, type ShellUser, Sidebar, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth };
343
+ export { AppLayout, type AppRegistryEntry, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, OrgSelector, PageContainer, PageHeader, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellLinkedAccounts, useShellOrganization, useShellSupport };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as react from 'react';
2
3
  import { ReactNode, CSSProperties } from 'react';
3
4
  import { User, Session, SupabaseClient } from '@supabase/supabase-js';
4
5
 
@@ -122,6 +123,16 @@ interface ShellProviderProps {
122
123
  appRegistry?: AppRegistryEntry[];
123
124
  /** Optional override for the base path if the app is mounted under a sub-path (e.g., '/contacts'). */
124
125
  basename?: string;
126
+ /** If provided, shell renders <OrgSelector /> in the header. */
127
+ organization?: ShellOrganizationValue;
128
+ /** If provided, UserMenu shows account switcher + add-account button. */
129
+ linkedAccounts?: ShellLinkedAccountsValue;
130
+ /** If provided, shell renders <SupportRequestButton /> in the header. */
131
+ support?: ShellSupportValue;
132
+ /** Optional element rendered in the header (typically <DevNotesMenu /> from @the-portland-company/devnotes). */
133
+ devNotesMenu?: ReactNode;
134
+ /** href used by the UserMenu "My Profile" link. Defaults to '/my-profile'. */
135
+ myProfileHref?: string;
125
136
  }
126
137
  /** Return value of useShellAuth(). */
127
138
  interface ShellAuthValue {
@@ -130,14 +141,109 @@ interface ShellAuthValue {
130
141
  session: Session | null;
131
142
  signOut: () => Promise<void>;
132
143
  }
144
+ /**
145
+ * Organization that the current user belongs to. Apps supply this via
146
+ * ShellProvider so the shell can render <OrgSelector /> in the header.
147
+ */
148
+ interface ShellOrganization {
149
+ id: string;
150
+ name: string;
151
+ logoUrl?: string | null;
152
+ /** Brand color as a hex string (e.g., '#0066cc'). Used for the org badge fallback. */
153
+ brandColor?: string | null;
154
+ }
155
+ interface ShellOrganizationValue {
156
+ currentOrg: ShellOrganization | null;
157
+ /** All orgs the user belongs to. */
158
+ organizations: ShellOrganization[];
159
+ /** Switch to the org with the given id. App owns the side effects. */
160
+ switchOrganization: (orgId: string) => Promise<void> | void;
161
+ /** Optional link rendered at the bottom of the org menu, e.g., '/organizations/new'. */
162
+ createOrgHref?: string;
163
+ }
164
+ /**
165
+ * An alternate user account the current user can switch into without signing
166
+ * out. App supplies the data + handlers; shell renders the UI inside UserMenu.
167
+ */
168
+ interface ShellLinkedAccount {
169
+ id: string;
170
+ email: string;
171
+ displayName?: string | null;
172
+ avatarUrl?: string | null;
173
+ }
174
+ interface ShellLinkedAccountsValue {
175
+ linkedAccounts: ShellLinkedAccount[];
176
+ switchToAccount: (accountId: string) => Promise<void> | void;
177
+ /** Called when the user clicks "Add account" in UserMenu. App opens its own modal. */
178
+ onAddAccount: () => void;
179
+ /** Called when the user wants to remove a linked account. App opens its own confirm. */
180
+ onRemoveAccount: (accountId: string) => void;
181
+ }
182
+ /** Context emitted to the host's submitSupportRequest handler. */
183
+ interface ShellSupportContext {
184
+ pathname: string;
185
+ search: string;
186
+ pageTitle?: string;
187
+ organizationName?: string;
188
+ }
189
+ interface ShellSupportValue {
190
+ /**
191
+ * Submit a support request. Host app handles persistence/email/etc.
192
+ * Shell renders the modal and calls this on submit.
193
+ */
194
+ submitSupportRequest: (input: {
195
+ email: string;
196
+ phone: string;
197
+ message: string;
198
+ context: ShellSupportContext;
199
+ }) => Promise<void>;
200
+ }
133
201
 
134
- declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
202
+ declare const ShellOrgContext: react.Context<ShellOrganizationValue | null>;
203
+ declare const ShellLinkedAccountsContext: react.Context<ShellLinkedAccountsValue | null>;
204
+ declare const ShellSupportProviderContext: react.Context<ShellSupportValue | null>;
205
+ interface ShellChromeValue$1 {
206
+ devNotesMenu: ReactNode | null;
207
+ myProfileHref: string;
208
+ }
209
+ declare const ShellChromeContext: react.Context<ShellChromeValue$1 | null>;
210
+ declare function ShellProvider({ children, supabaseClient, currentApp, appRegistry, basename, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellProviderProps): react_jsx_runtime.JSX.Element;
135
211
 
136
212
  declare function useShellAuth(): ShellAuthValue;
137
213
 
138
214
  declare function useAppRegistry(): AppRegistryEntry[];
139
215
  declare function useCurrentApp(): string;
140
216
 
217
+ /**
218
+ * Returns the organization value supplied to ShellProvider, or null if the
219
+ * host app didn't pass an `organization` prop. Returning null lets chrome
220
+ * components (e.g., <OrgSelector />) render nothing instead of erroring.
221
+ */
222
+ declare function useShellOrganization(): ShellOrganizationValue | null;
223
+
224
+ /**
225
+ * Returns the linked-accounts value supplied to ShellProvider, or null if not
226
+ * provided. UserMenu uses this to decide whether to render the
227
+ * "switch account" section.
228
+ */
229
+ declare function useShellLinkedAccounts(): ShellLinkedAccountsValue | null;
230
+
231
+ /**
232
+ * Returns the support handler supplied to ShellProvider, or null if not
233
+ * provided. SupportRequestButton uses this to decide whether to render.
234
+ */
235
+ declare function useShellSupport(): ShellSupportValue | null;
236
+
237
+ interface ShellChromeValue {
238
+ devNotesMenu: ReactNode | null;
239
+ myProfileHref: string;
240
+ }
241
+ /**
242
+ * Returns chrome-level options supplied to ShellProvider (devNotesMenu slot,
243
+ * myProfileHref). Throws if used outside <ShellProvider>.
244
+ */
245
+ declare function useShellChrome(): ShellChromeValue;
246
+
141
247
  interface AppLayoutProps extends ShellSlots {
142
248
  children: ReactNode;
143
249
  buildInfo?: string;
@@ -161,6 +267,53 @@ interface FooterProps {
161
267
  }
162
268
  declare function Footer({ buildInfo }: FooterProps): react_jsx_runtime.JSX.Element;
163
269
 
270
+ /**
271
+ * Avatar dropdown rendered at the right side of the header. Reads auth,
272
+ * linked-accounts, and chrome context from ShellProvider.
273
+ */
274
+ declare function UserMenu(): react_jsx_runtime.JSX.Element | null;
275
+
276
+ /**
277
+ * Organization switcher rendered in the header. Reads from
278
+ * useShellOrganization(); renders nothing when no `organization` prop was
279
+ * supplied to ShellProvider.
280
+ */
281
+ declare function OrgSelector(): react_jsx_runtime.JSX.Element | null;
282
+
283
+ /**
284
+ * Support icon + modal rendered in the header. Reads auth, org, and support
285
+ * handler from ShellProvider. Renders nothing when the host app didn't supply
286
+ * a `support` prop.
287
+ */
288
+ declare function SupportRequestButton(): react_jsx_runtime.JSX.Element | null;
289
+
290
+ interface ShellChromeProps {
291
+ children: ReactNode;
292
+ /** Drives <OrgSelector /> in the header. */
293
+ organization?: ShellOrganizationValue | null;
294
+ /** Drives the UserMenu Switch-account section. */
295
+ linkedAccounts?: ShellLinkedAccountsValue | null;
296
+ /** Drives <SupportRequestButton /> and modal submission. */
297
+ support?: ShellSupportValue | null;
298
+ /** Rendered in the header (typically <DevNotesMenu />). */
299
+ devNotesMenu?: ReactNode;
300
+ /** UserMenu profile link target. Defaults to '/my-profile'. */
301
+ myProfileHref?: string;
302
+ }
303
+ /**
304
+ * Drop-in chrome binding for apps where the org/linked-account/support data
305
+ * lives in React contexts nested BELOW <ShellProvider> (e.g., an
306
+ * <OrganizationProvider> that itself depends on <AuthProvider>).
307
+ *
308
+ * Use this component inside those providers to feed the values into the
309
+ * shell's chrome contexts. Nested <Context.Provider> overrides the empty
310
+ * defaults set by <ShellProvider> at the top of the tree.
311
+ *
312
+ * Apps that have all the data available at the ShellProvider construction
313
+ * site can pass the same props to <ShellProvider> directly instead.
314
+ */
315
+ declare function ShellChrome({ children, organization, linkedAccounts, support, devNotesMenu, myProfileHref, }: ShellChromeProps): react_jsx_runtime.JSX.Element;
316
+
164
317
  interface RegisterShellPrecacheOptions {
165
318
  /** Path the host app serves the SW from. Default: '/sw-shell.js'. */
166
319
  scriptUrl?: string;
@@ -187,4 +340,4 @@ declare function registerShellPrecache(opts?: RegisterShellPrecacheOptions): Pro
187
340
  */
188
341
  declare function buildSpeculationRules(currentApp: string, registry: AppRegistryEntry[]): string | null;
189
342
 
190
- export { AppLayout, type AppRegistryEntry, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, PageContainer, PageHeader, type ShellAuthStatus, type ShellAuthValue, ShellProvider, type ShellProviderProps, type ShellSlots, type ShellUser, Sidebar, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth };
343
+ export { AppLayout, type AppRegistryEntry, BreadcrumbBar, Card, Footer, GlobalUiIdProvider, Header, HeaderTabBar, type HeaderTabBarItem, OrgSelector, PageContainer, PageHeader, type ShellAuthStatus, type ShellAuthValue, ShellChrome, ShellChromeContext, type ShellChromeProps, type ShellLinkedAccount, ShellLinkedAccountsContext, type ShellLinkedAccountsValue, ShellOrgContext, type ShellOrganization, type ShellOrganizationValue, ShellProvider, type ShellProviderProps, type ShellSlots, type ShellSupportContext, ShellSupportProviderContext, type ShellSupportValue, type ShellUser, Sidebar, SupportRequestButton, UserMenu, buildSpeculationRules, politogyTheme, registerShellPrecache, useAppRegistry, useCurrentApp, useShellAuth, useShellChrome, useShellLinkedAccounts, useShellOrganization, useShellSupport };