@naviedu/room-platform-react 0.0.1 → 0.0.4

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/README.md +258 -0
  2. package/index.d.ts +1042 -32
  3. package/index.esm.js +11479 -1235
  4. package/package.json +4 -7
  5. package/styles.css +584 -0
  6. package/extensions/room-platform-extensions.d.ts +0 -8
  7. package/room-action-button.d.ts +0 -11
  8. package/room-participant-actions.d.ts +0 -9
  9. package/room-participant-list.d.ts +0 -7
  10. package/room-participant-tab.d.ts +0 -6
  11. package/room-platform-active-speaker.d.ts +0 -4
  12. package/room-platform-background-settings.d.ts +0 -15
  13. package/room-platform-camera-background-presets.d.ts +0 -8
  14. package/room-platform-camera-background-storage.d.ts +0 -38
  15. package/room-platform-control-anchor.d.ts +0 -10
  16. package/room-platform-control-bar.d.ts +0 -11
  17. package/room-platform-control-state.d.ts +0 -12
  18. package/room-platform-current-operation-strip.d.ts +0 -13
  19. package/room-platform-device-selection.d.ts +0 -7
  20. package/room-platform-device-settings.d.ts +0 -8
  21. package/room-platform-local-preview.d.ts +0 -6
  22. package/room-platform-media-controls.d.ts +0 -1
  23. package/room-platform-media-runtime.d.ts +0 -2
  24. package/room-platform-monitor-stage.d.ts +0 -7
  25. package/room-platform-monitor-video-tile.d.ts +0 -20
  26. package/room-platform-monitor-viewer.d.ts +0 -8
  27. package/room-platform-private-room-connection.d.ts +0 -11
  28. package/room-platform-private-room-context.d.ts +0 -8
  29. package/room-platform-private-room-control-bar.d.ts +0 -12
  30. package/room-platform-private-room-experience.d.ts +0 -14
  31. package/room-platform-private-room-overlay.d.ts +0 -7
  32. package/room-platform-private-room-stage.d.ts +0 -9
  33. package/room-platform-private-room-status-banner.d.ts +0 -8
  34. package/room-platform-provider.d.ts +0 -35
  35. package/room-platform-room.d.ts +0 -2
  36. package/room-platform-screen-share-whiteboard-frame.d.ts +0 -11
  37. package/room-platform-shell.d.ts +0 -17
  38. package/room-platform-speak-queue.d.ts +0 -16
  39. package/room-platform-stage-selection.d.ts +0 -14
  40. package/room-platform-stage.d.ts +0 -13
  41. package/room-platform-surface-boundary.d.ts +0 -13
  42. package/room-platform-top-bar.d.ts +0 -7
  43. package/room-platform-types.d.ts +0 -154
  44. package/room-platform-ui-primitives.d.ts +0 -60
  45. package/room-platform-video-tile.d.ts +0 -13
  46. package/room-platform-video-tracks.d.ts +0 -6
  47. package/use-room-platform-camera-background.d.ts +0 -34
  48. package/use-room-platform-private-room-control-actions.d.ts +0 -21
  49. package/use-room-platform-private-room.d.ts +0 -43
  50. package/use-room-platform-stage.d.ts +0 -2
  51. package/use-room-presence.d.ts +0 -2
package/README.md ADDED
@@ -0,0 +1,258 @@
1
+ # @naviedu/room-platform-react
2
+
3
+ Embeddable React UI and runtime for NaviEdu Room Platform rooms. The package
4
+ owns the default room experience, LiveKit connection, media controls, speaker
5
+ requests, private rooms, responsive layout, and optional chat and whiteboard
6
+ surfaces.
7
+
8
+ ## Requirements
9
+
10
+ - React 18 or 19
11
+ - A Room Platform launch ticket issued by the host backend
12
+ - A public Room Platform API base URL
13
+ - A browser running in a secure context when camera, microphone, or screen
14
+ sharing is required
15
+
16
+ The launch ticket is short-lived and must be obtained server-side. Do not put
17
+ backend credentials or long-lived signing secrets in the browser bundle.
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ npm install @naviedu/room-platform-react
23
+ ```
24
+
25
+ `react` and `react-dom` are peer dependencies. Room Platform's published
26
+ runtime dependencies are installed automatically with the package.
27
+
28
+ ## Basic usage
29
+
30
+ Import the package stylesheet once, then render `RoomPlatformRoom` with the
31
+ launch ticket returned by your backend:
32
+
33
+ ```tsx
34
+ 'use client'
35
+
36
+ import { type RoomLaunchTicketRenewalReason, RoomPlatformRoom } from '@naviedu/room-platform-react'
37
+ import '@naviedu/room-platform-react/styles.css'
38
+
39
+ type RoomTicketResponse = { launchToken: string }
40
+
41
+ export function Room({ launchToken }: { launchToken: string }) {
42
+ async function renewLaunchTicket(_reason: RoomLaunchTicketRenewalReason): Promise<RoomTicketResponse> {
43
+ const response = await fetch('/api/room-platform/launch-ticket', {
44
+ method: 'POST',
45
+ credentials: 'include',
46
+ })
47
+
48
+ if (!response.ok) throw new Error('Unable to renew the Room Platform launch ticket')
49
+
50
+ return (await response.json()) as RoomTicketResponse
51
+ }
52
+
53
+ return (
54
+ <RoomPlatformRoom
55
+ apiBaseUrl="https://api.example.com/room-platform"
56
+ launchToken={launchToken}
57
+ onLaunchTicketRequired={renewLaunchTicket}
58
+ onExit={() => window.history.back()}
59
+ />
60
+ )
61
+ }
62
+ ```
63
+
64
+ `apiBaseUrl` is the URL prefix before `/rooms`. The package calls these routes
65
+ relative to it:
66
+
67
+ - `POST /rooms/exchange`
68
+ - `GET /rooms/:roomId/control-state`
69
+ - `POST /rooms/:roomId/actions`
70
+
71
+ For example, with `apiBaseUrl="https://api.example.com/room-platform"`, the
72
+ exchange request is sent to
73
+ `https://api.example.com/room-platform/rooms/exchange`.
74
+
75
+ The package renders a full viewport room (`100dvh`). Mount it in a page or
76
+ layout that allows the room to occupy the viewport.
77
+
78
+ ## `RoomPlatformRoom` props
79
+
80
+ | Prop | Required | Description |
81
+ | ------------------------ | -------- | ------------------------------------------------------------------------------------ |
82
+ | `apiBaseUrl` | Yes | Room Platform API prefix. Do not append `/rooms`. |
83
+ | `launchToken` | Yes | Initial server-issued launch ticket. |
84
+ | `onLaunchTicketRequired` | Yes | Returns `{ launchToken }` when the current ticket or access session must be renewed. |
85
+ | `extensions` | No | Host-provided top-bar, workspace, sidebar, monitor, and participant extensions. |
86
+ | `integrations` | No | Chat and whiteboard configuration. |
87
+ | `isPracticeMode` | No | Enables practice-room presentation behavior. |
88
+ | `showLocalPreview` | No | Shows the local preview in the sidebar. Defaults to `true`. |
89
+ | `primaryCameraSelector` | No | Selects the primary camera track when the default selection is not suitable. |
90
+ | `onError` | No | Receives connection, media, and action errors. |
91
+ | `onLifecycleEvent` | No | Receives exchange, renewal, and reconnect lifecycle events. |
92
+ | `onExit` | No | Called when the user chooses to leave the room. |
93
+ | `children` | No | Replaces the default workspace while keeping the provider and room runtime. |
94
+
95
+ ### Error and lifecycle callbacks
96
+
97
+ ```tsx
98
+ <RoomPlatformRoom
99
+ // ...required props
100
+ onError={({ error, recoverable, scope }) => {
101
+ console.error(`[room-platform:${scope}]`, error)
102
+ if (!recoverable) {
103
+ // Show the host application's unavailable-room state.
104
+ }
105
+ }}
106
+ onLifecycleEvent={(event) => {
107
+ // Send telemetry to the host backend if needed.
108
+ console.info('Room Platform lifecycle:', event)
109
+ }}
110
+ />
111
+ ```
112
+
113
+ Lifecycle events are `exchange.succeeded`, `exchange.failed`,
114
+ `renewal.succeeded`, `renewal.failed`, `reconnect.succeeded`, and
115
+ `reconnect.failed`.
116
+
117
+ ## Chat and whiteboard integrations
118
+
119
+ Integrations are optional. The host supplies already-authorized configuration;
120
+ the room package does not issue chat or whiteboard credentials.
121
+
122
+ ```tsx
123
+ <RoomPlatformRoom
124
+ // ...required props
125
+ integrations={{
126
+ chat: {
127
+ endpoint: 'https://api.example.com/chat',
128
+ realtimeEndpoint: 'wss://realtime.example.com/chat',
129
+ token: chatToken,
130
+ tokenExpiresAt: chatTokenExpiresAt,
131
+ refreshToken: refreshChatToken,
132
+ refreshTokenExpiresAt: refreshChatTokenExpiresAt,
133
+ rooms: chatRooms,
134
+ currentRoomId: roomId,
135
+ },
136
+ whiteboard: {
137
+ joinState: whiteboardJoinState,
138
+ runtime: {
139
+ realtimeEndpoint: whiteboardRealtimeEndpoint,
140
+ recoveryPort: whiteboardRecoveryPort,
141
+ },
142
+ },
143
+ }}
144
+ />
145
+ ```
146
+
147
+ When chat is configured, the default sidebar includes the chat tab and unread
148
+ badge. When whiteboard access is available, a shared screen can display the
149
+ whiteboard surface. Omit either integration when the host does not use it.
150
+
151
+ ## Extensions
152
+
153
+ Extensions keep host-specific UI outside the shared room implementation. Every
154
+ extension receives `RoomPlatformExtensionProps`:
155
+
156
+ ```tsx
157
+ import type { RoomPlatformExtensionProps } from '@naviedu/room-platform-react'
158
+
159
+ function HostToolbar({ actions, capabilities, connectionStatus, roomId }: RoomPlatformExtensionProps) {
160
+ const canModerate = capabilities.includes('room:moderate')
161
+
162
+ return (
163
+ <div>
164
+ <span>{connectionStatus}</span>
165
+ <span>{roomId}</span>
166
+ {canModerate ? (
167
+ <button type="button" onClick={() => void actions.perform('speak.request')}>
168
+ Request to speak
169
+ </button>
170
+ ) : null}
171
+ </div>
172
+ )
173
+ }
174
+
175
+ ;<RoomPlatformRoom
176
+ // ...required props
177
+ extensions={{
178
+ topBarTrailing: HostToolbar,
179
+ sidebarTabs: [{ id: 'materials', title: 'Materials', component: HostMaterialsTab }],
180
+ mainWorkspace: {
181
+ placement: 'alongside-stage',
182
+ component: HostWorkspace,
183
+ },
184
+ }}
185
+ />
186
+ ```
187
+
188
+ Available extension slots are:
189
+
190
+ - `topBarLeading` and `topBarTrailing`
191
+ - `mainWorkspace` with `overlay` or `alongside-stage` placement
192
+ - `sidebarTabs`
193
+ - `participantTab` in `default` or `replace` mode
194
+ - `monitor` with a host-provided participant roster and eligibility flag
195
+
196
+ `actions.perform` sends a Room Platform action and accepts an optional string
197
+ payload. Check `actions.hasCapability(...)` before rendering privileged
198
+ controls, and use `actions.isPending(...)` to disable controls during an
199
+ in-flight action.
200
+
201
+ ## Advanced composition
202
+
203
+ Use `RoomPlatformProvider` and `useRoomPlatform` when the host needs to render
204
+ a custom room surface instead of `RoomPlatformRoom`'s default workspace:
205
+
206
+ ```tsx
207
+ import { RoomPlatformProvider, type RoomPlatformProviderProps, useRoomPlatform } from '@naviedu/room-platform-react'
208
+
209
+ function CustomRoomSurface() {
210
+ const { localMedia, setLocalMediaEnabled, status } = useRoomPlatform()
211
+
212
+ return (
213
+ <button
214
+ type="button"
215
+ disabled={status !== 'connected'}
216
+ onClick={() => void setLocalMediaEnabled('camera', !localMedia.camera)}
217
+ >
218
+ {localMedia.camera ? 'Turn camera off' : 'Turn camera on'}
219
+ </button>
220
+ )
221
+ }
222
+
223
+ export function CustomRoom(props: {
224
+ apiBaseUrl: string
225
+ launchToken: string
226
+ onLaunchTicketRequired: RoomPlatformProviderProps['onLaunchTicketRequired']
227
+ }) {
228
+ return (
229
+ <RoomPlatformProvider {...props}>
230
+ <CustomRoomSurface />
231
+ </RoomPlatformProvider>
232
+ )
233
+ }
234
+ ```
235
+
236
+ Use `RoomPlatformRoom` unless a custom surface is required. It composes the
237
+ provider, LiveKit media runtime, private-room runtime, default stage, controls,
238
+ and sidebar for you.
239
+
240
+ ## Publishing and local verification
241
+
242
+ From the repository root:
243
+
244
+ ```bash
245
+ yarn nx run @naviedu/room-platform-react:build
246
+ ```
247
+
248
+ The publishable package is written to
249
+ `dist/libs/features/room-platform-react`. Inspect it before publishing:
250
+
251
+ ```bash
252
+ cd dist/libs/features/room-platform-react
253
+ npm pack --dry-run
254
+ npm publish --access public
255
+ ```
256
+
257
+ The package embeds the required shared UI source during bundling, so consumers
258
+ do not need private workspace aliases such as `@navi/ui` or `@navi/utils`.