@trycourier/courier-ui-inbox 1.0.8-beta → 1.0.9-beta

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/README.md ADDED
@@ -0,0 +1,380 @@
1
+ # `@trycourier/courier-ui-inbox`
2
+
3
+ Web components for Courier Inbox.
4
+
5
+ ## 1. Install
6
+
7
+ ```sh
8
+ npm i @trycourier/courier-ui-inbox@1.0.9-beta
9
+ ```
10
+
11
+ > **Using React?** We suggest you use [@trycourier/courier-react](../courier-react/README.md) package instead.
12
+
13
+ ## 2. Authenticate
14
+
15
+ To use the SDK, you need to generate a JWT (JSON Web Token) for your user. **This JWT should always be generated by your backend server, never in client-side code.**
16
+
17
+ **How it works:**
18
+
19
+ 1. **Your frontend calls your backend:**
20
+ - When your app needs to authenticate a user, your frontend should make a request to your own backend (e.g., `/api/generate-courier-jwt`).
21
+
22
+ 2. **Your backend calls Courier to issue a JWT:**
23
+ - In your backend endpoint, use your Courier API Key to call the [Courier JWT Token Endpoint](https://www.courier.com/docs/reference/auth/issue-token) and generate a JWT for the user.
24
+ - Your backend then returns the JWT to your frontend.
25
+
26
+ > **Where do I get my API Key?** Go to your [Courier API Keys](https://app.courier.com/settings/api-keys) page.
27
+
28
+ **Example: Quick Testing with cURL**
29
+
30
+ To quickly test JWT generation (for development only), you can use the following cURL command to call Courier's API directly. **Do not use this in production or from client-side code.**
31
+
32
+ ```sh
33
+ curl --request POST \
34
+ --url https://api.courier.com/auth/issue-token \
35
+ --header 'Accept: application/json' \
36
+ --header 'Authorization: Bearer $YOUR_API_KEY' \
37
+ --header 'Content-Type: application/json' \
38
+ --data \
39
+ '{
40
+ "scope": "user_id:$YOUR_USER_ID write:user-tokens inbox:read:messages inbox:write:events read:preferences write:preferences read:brands",
41
+ "expires_in": "$YOUR_NUMBER days"
42
+ }'
43
+ ```
44
+
45
+ ## 3. Add Inbox Component
46
+
47
+ ### `courier-inbox`
48
+
49
+ <img width="688" alt="Screenshot 2025-06-25 at 2 32 30 PM" src="https://github.com/user-attachments/assets/93246c34-3c5a-475e-8e83-7df6acf9bdf3" />
50
+
51
+ ```html
52
+ <body>
53
+
54
+ <courier-inbox id="inbox"></courier-inbox>
55
+
56
+ <script type="module">
57
+ import { Courier } from '@trycourier/courier-ui-inbox';
58
+
59
+ // Generate a JWT for your user (do this on your backend server)
60
+ const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Replace with actual JWT
61
+
62
+ // Authenticate the user with the inbox
63
+ Courier.shared.signIn({
64
+ userId: $YOUR_USER_ID,
65
+ jwt: jwt
66
+ });
67
+ </script>
68
+
69
+ </body>
70
+ ```
71
+
72
+ ### `courier-inbox-popup-menu`
73
+
74
+ <img width="602" alt="Screenshot 2025-06-25 at 2 33 17 PM" src="https://github.com/user-attachments/assets/c3b7f4cc-26c1-4be6-9ed5-a3fc3c0b335b" />
75
+
76
+ ```html
77
+ <body>
78
+
79
+ <div style="padding: 24px;">
80
+ <courier-inbox-popup-menu id="inbox"></courier-inbox-popup-menu>
81
+ </div>
82
+
83
+ <script type="module">
84
+ import { Courier } from '@trycourier/courier-ui-inbox';
85
+
86
+ // Generate a JWT for your user (do this on your backend server)
87
+ const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Replace with actual JWT
88
+
89
+ // Authenticate the user with the inbox
90
+ Courier.shared.signIn({
91
+ userId: $YOUR_USER_ID,
92
+ jwt: jwt
93
+ });
94
+ </script>
95
+
96
+ </body>
97
+ ```
98
+
99
+ ## Handle Clicks and Presses
100
+
101
+ ```html
102
+ <body>
103
+
104
+ <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu -->
105
+
106
+ <script type="module">
107
+ import { Courier } from '@trycourier/courier-ui-inbox';
108
+
109
+ // Generate a JWT for your user (do this on your backend server)
110
+ const jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'; // Replace with actual JWT
111
+
112
+ // Authenticate the user with the inbox
113
+ Courier.shared.signIn({
114
+ userId: $YOUR_USER_ID,
115
+ jwt: jwt
116
+ });
117
+
118
+ // Reference the element
119
+ const inbox = document.getElementById('inbox');
120
+
121
+ // Handle message clicks
122
+ inbox.onMessageClick(({ message, index }) => {
123
+ alert("Message clicked at index " + index + ":\n" + JSON.stringify(message, null, 2));
124
+ });
125
+
126
+ // Handle message action clicks (These are buttons on individial messages)
127
+ inbox.onMessageActionClick(({ message, action, index }) => {
128
+ alert(
129
+ "Message action clicked at index " + index + ":\n" +
130
+ "Action: " + JSON.stringify(action, null, 2) + "\n" +
131
+ "Message: " + JSON.stringify(message, null, 2)
132
+ );
133
+ });
134
+
135
+ // Handle message long presses (Useful for mobile web)
136
+ inbox.onMessageLongPress(({ message, index }) => {
137
+ alert("Message long pressed at index " + index + ":\n" + JSON.stringify(message, null, 2));
138
+ });
139
+ </script>
140
+
141
+ </body>
142
+ ```
143
+
144
+ ## Styles and Theming
145
+
146
+ ### Light & Dark Themes
147
+
148
+ The fastest way to style the Inbox to match your app. This example shows unread indicator styling, but you can customize fonts, icons, text, and more.
149
+
150
+ > **🎨 Theme Reference:** [All available theme values](./docs/theme.md)
151
+
152
+ <img width="688" alt="Screenshot 2025-06-25 at 2 36 20 PM" src="https://github.com/user-attachments/assets/982164fe-fe0d-4e66-82d1-b5a6571f1aa4" />
153
+
154
+ ```html
155
+ <body>
156
+
157
+ <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu -->
158
+
159
+ <script type="module">
160
+ ...
161
+
162
+ // Reference the element
163
+ const inbox = document.getElementById('inbox');
164
+
165
+ const theme = {
166
+ inbox: {
167
+ header: {
168
+ filters: {
169
+ unreadIndicator: {
170
+ backgroundColor: "#8B5CF6"
171
+ }
172
+ }
173
+ },
174
+ list: {
175
+ item: {
176
+ unreadIndicatorColor: "#8B5CF6"
177
+ }
178
+ }
179
+ }
180
+ }
181
+
182
+ // Set the theme
183
+ inbox.setLightTheme(theme);
184
+ inbox.setDarkTheme(theme);
185
+
186
+ // Set the mode
187
+ // This will force light, dark or system theme mode
188
+ inbox.setMode('light');
189
+
190
+ </script>
191
+
192
+ </body>
193
+ ```
194
+
195
+ ### Popup Alignment, Positioning, and Dimensions
196
+
197
+ ```html
198
+ <body>
199
+
200
+ <div style="display: flex; justify-content: center; align-items: center; padding: 100px;">
201
+ <!-- Available alignments: 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center' | 'center-right' | 'center-left' | 'center-center' -->
202
+ <courier-inbox-popup-menu
203
+ popup-alignment="top-right"
204
+ top="44px"
205
+ right="44px"
206
+ popup-width="340px"
207
+ popup-height="400px">
208
+ </courier-inbox-popup-menu>
209
+ </div>
210
+
211
+ ...
212
+ </body>
213
+ ```
214
+
215
+ ### Custom height `courier-inbox`
216
+
217
+ > **Important:** The default `courier-inbox` height is auto. It will set it's height based on it's children.
218
+
219
+ ```html
220
+ <body>
221
+
222
+ <courier-inbox height="50vh"></courier-inbox>
223
+
224
+ ...
225
+
226
+ </body>
227
+ ```
228
+
229
+ ## Custom Elements
230
+
231
+ Customize the inbox UI with any element you want.
232
+
233
+ ### List Items
234
+
235
+ <img width="688" alt="Screenshot 2025-06-25 at 2 37 29 PM" src="https://github.com/user-attachments/assets/53da26d1-ed9a-461d-ad92-2e74ee3e91bf" />
236
+
237
+ ```html
238
+ <body>
239
+
240
+ <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu -->
241
+
242
+ <script type="module">
243
+ ...
244
+
245
+ // Reference the courier-inbox element
246
+ const inbox = document.getElementById('inbox');
247
+
248
+ // Set a custom list item
249
+ inbox.setListItem(({ message, index }) => {
250
+ const pre = document.createElement('pre');
251
+ pre.style.padding = '24px';
252
+ pre.style.borderBottom = '1px solid #e0e0e0';
253
+ pre.style.margin = '0';
254
+ pre.textContent = JSON.stringify(({ message, index }), null, 2);
255
+ return pre;
256
+ });
257
+ </script>
258
+
259
+ </body>
260
+ ```
261
+
262
+ ### Header
263
+
264
+ <img width="688" alt="Screenshot 2025-06-25 at 2 38 45 PM" src="https://github.com/user-attachments/assets/d393f77d-695e-4fed-a60a-7f7b59909772" />
265
+
266
+ ```html
267
+ <body>
268
+
269
+ <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu -->
270
+
271
+ <script type="module">
272
+ ...
273
+
274
+ // Reference the courier-inbox element
275
+ const inbox = document.getElementById('inbox');
276
+
277
+ // Remove the header
278
+ inbox.removeHeader();
279
+
280
+ // Set a custom header
281
+ inbox.setHeader(({ feedType, unreadCount, messageCount }) => {
282
+ const headerDiv = document.createElement('div');
283
+ headerDiv.style.background = 'red';
284
+ headerDiv.style.fontSize = '24px';
285
+ headerDiv.style.padding = '24px';
286
+ headerDiv.style.width = '100%';
287
+ headerDiv.textContent = feedType;
288
+ return headerDiv;
289
+ });
290
+
291
+ // Change the feed type
292
+ // "inbox" and "archive" are available
293
+ inbox.setFeedType('archive');
294
+ </script>
295
+
296
+ </body>
297
+ ```
298
+
299
+ ### Popup Menu Button
300
+
301
+ <img width="688" alt="Screenshot 2025-06-25 at 2 39 49 PM" src="https://github.com/user-attachments/assets/5eeb32ae-13ff-4622-b6ea-b302f04509f3" />
302
+
303
+ ```html
304
+ <body>
305
+
306
+ <div style="display: flex; justify-content: center; align-items: center; padding: 100px;">
307
+ <courier-inbox-popup-menu id="inbox"></courier-inbox-popup-menu>
308
+ </div>
309
+
310
+ <script type="module">
311
+ ...
312
+
313
+ // Reference the courier-inbox element
314
+ const inbox = document.getElementById('inbox');
315
+
316
+ // Set a custom menu button
317
+ inbox.setMenuButton(({ unreadCount }) => {
318
+ const button = document.createElement('button');
319
+ button.textContent = `Open the Inbox Popup. Unread message count: ${unreadCount}`;
320
+ return button;
321
+ });
322
+ </script>
323
+
324
+ </body>
325
+ ```
326
+
327
+ ### Loading, Empty, Error & Pagination
328
+
329
+ ```html
330
+ <body>
331
+
332
+ <courier-inbox id="inbox"></courier-inbox> <!-- or use courier-inbox-popup-menu -->
333
+
334
+ <script type="module">
335
+ ...
336
+
337
+ // Reference the courier-inbox element
338
+ const inbox = document.getElementById('inbox');
339
+
340
+ // Set a custom loading state
341
+ inbox.setLoadingState(props => {
342
+ const loading = document.createElement('div');
343
+ loading.style.padding = '24px';
344
+ loading.style.background = 'red';
345
+ loading.textContent = 'Custom Loading State';
346
+ return loading;
347
+ });
348
+
349
+ // Set a custom empty state
350
+ inbox.setEmptyState(props => {
351
+ const empty = document.createElement('div');
352
+ empty.style.padding = '24px';
353
+ empty.style.background = 'green';
354
+ empty.textContent = 'Custom Empty State';
355
+ return empty;
356
+ });
357
+
358
+ // Set a custom error state
359
+ inbox.setErrorState(props => {
360
+ const error = document.createElement('div');
361
+ error.style.padding = '24px';
362
+ error.style.background = 'blue';
363
+ error.textContent = 'Custom Error State';
364
+ return error;
365
+ });
366
+
367
+ // Set a custom pagination state
368
+ inbox.setPaginationItem(props => {
369
+ const pagination = document.createElement('div');
370
+ pagination.style.padding = '24px';
371
+ pagination.style.background = 'yellow';
372
+ pagination.textContent = 'Custom Pagination Item';
373
+ return pagination;
374
+ });
375
+ </script>
376
+
377
+ </body>
378
+ ```
379
+
380
+ > **Using React?** We suggest you use [@trycourier/courier-react](../courier-react/README.md) package instead.
@@ -2,7 +2,7 @@ import { CourierInboxDatastoreEvents } from '../datastore/datatore-events';
2
2
  import { CourierInboxHeaderFactoryProps, CourierInboxListItemActionFactoryProps, CourierInboxListItemFactoryProps, CourierInboxMenuButtonFactoryProps, CourierInboxPaginationItemFactoryProps, CourierInboxStateEmptyFactoryProps, CourierInboxStateErrorFactoryProps, CourierInboxStateLoadingFactoryProps } from '../types/factories';
3
3
  import { CourierInboxFeedType } from '../types/feed-type';
4
4
  import { CourierInboxTheme } from '../types/courier-inbox-theme';
5
- import { CourierBaseElement } from '@trycourier/courier-ui-core';
5
+ import { CourierComponentThemeMode, CourierBaseElement } from '@trycourier/courier-ui-core';
6
6
  export type CourierInboxPopupAlignment = 'top-right' | 'top-left' | 'top-center' | 'bottom-right' | 'bottom-left' | 'bottom-center' | 'center-right' | 'center-left' | 'center-center';
7
7
  export declare class CourierInboxPopupMenu extends CourierBaseElement implements CourierInboxDatastoreEvents {
8
8
  static get id(): string;
@@ -17,6 +17,7 @@ export declare class CourierInboxPopupMenu extends CourierBaseElement implements
17
17
  get theme(): CourierInboxTheme;
18
18
  setLightTheme(theme: CourierInboxTheme): void;
19
19
  setDarkTheme(theme: CourierInboxTheme): void;
20
+ setMode(mode: CourierComponentThemeMode): void;
20
21
  private _triggerButton?;
21
22
  private _popup?;
22
23
  private _inbox?;
@@ -42,13 +43,13 @@ export declare class CourierInboxPopupMenu extends CourierBaseElement implements
42
43
  setSize(width: string, height: string): void;
43
44
  setPosition(position: CourierInboxPopupAlignment): void;
44
45
  setFeedType(feedType: CourierInboxFeedType): void;
45
- setPopupHeader(factory: (props: CourierInboxHeaderFactoryProps | undefined | null) => HTMLElement): void;
46
- removePopupHeader(): void;
47
- setPopupLoadingState(factory: (props: CourierInboxStateLoadingFactoryProps | undefined | null) => HTMLElement): void;
48
- setPopupEmptyState(factory: (props: CourierInboxStateEmptyFactoryProps | undefined | null) => HTMLElement): void;
49
- setPopupErrorState(factory: (props: CourierInboxStateErrorFactoryProps | undefined | null) => HTMLElement): void;
50
- setPopupListItem(factory: (props: CourierInboxListItemFactoryProps | undefined | null) => HTMLElement): void;
51
- setPopupPaginationItem(factory: (props: CourierInboxPaginationItemFactoryProps | undefined | null) => HTMLElement): void;
52
- setPopupMenuButton(factory: (props: CourierInboxMenuButtonFactoryProps | undefined | null) => HTMLElement): void;
46
+ setHeader(factory: (props: CourierInboxHeaderFactoryProps | undefined | null) => HTMLElement): void;
47
+ removeHeader(): void;
48
+ setLoadingState(factory: (props: CourierInboxStateLoadingFactoryProps | undefined | null) => HTMLElement): void;
49
+ setEmptyState(factory: (props: CourierInboxStateEmptyFactoryProps | undefined | null) => HTMLElement): void;
50
+ setErrorState(factory: (props: CourierInboxStateErrorFactoryProps | undefined | null) => HTMLElement): void;
51
+ setListItem(factory: (props: CourierInboxListItemFactoryProps | undefined | null) => HTMLElement): void;
52
+ setPaginationItem(factory: (props: CourierInboxPaginationItemFactoryProps | undefined | null) => HTMLElement): void;
53
+ setMenuButton(factory: (props: CourierInboxMenuButtonFactoryProps | undefined | null) => HTMLElement): void;
53
54
  private render;
54
55
  }
@@ -1,4 +1,4 @@
1
- import { CourierBaseElement } from '@trycourier/courier-ui-core';
1
+ import { CourierBaseElement, CourierComponentThemeMode } from '@trycourier/courier-ui-core';
2
2
  import { CourierInboxFeedType } from '../types/feed-type';
3
3
  import { CourierInboxHeaderFactoryProps, CourierInboxListItemActionFactoryProps, CourierInboxListItemFactoryProps, CourierInboxPaginationItemFactoryProps, CourierInboxStateEmptyFactoryProps, CourierInboxStateErrorFactoryProps, CourierInboxStateLoadingFactoryProps } from '../types/factories';
4
4
  import { CourierInboxTheme } from '../types/courier-inbox-theme';
@@ -10,6 +10,7 @@ export declare class CourierInbox extends CourierBaseElement {
10
10
  get theme(): CourierInboxTheme;
11
11
  setLightTheme(theme: CourierInboxTheme): void;
12
12
  setDarkTheme(theme: CourierInboxTheme): void;
13
+ setMode(mode: CourierComponentThemeMode): void;
13
14
  private _inboxStyle?;
14
15
  private _unreadIndicatorStyle?;
15
16
  private _list?;
package/dist/index.d.ts CHANGED
@@ -11,3 +11,5 @@ export * from './types/inbox-data-set';
11
11
  export * from './datastore/datastore';
12
12
  export * from './datastore/datastore-listener';
13
13
  export * from './datastore/datatore-events';
14
+ export { Courier } from '@trycourier/courier-js';
15
+ export type { CourierProps, CourierClientOptions, CourierBrand, CourierApiUrls, CourierUserPreferences, CourierUserPreferencesStatus, CourierUserPreferencesChannel, CourierUserPreferencesPaging, CourierUserPreferencesTopic, CourierUserPreferencesTopicResponse, CourierDevice, CourierToken, CourierGetInboxMessageResponse, CourierGetInboxMessagesResponse, InboxMessage, InboxAction, InboxMessageEventEnvelope, } from '@trycourier/courier-js';