@actuate-media/cms-admin 0.11.0 → 0.12.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.
Files changed (183) hide show
  1. package/LICENSE +21 -21
  2. package/dist/__tests__/components/comment-mark.test.d.ts +2 -0
  3. package/dist/__tests__/components/comment-mark.test.d.ts.map +1 -0
  4. package/dist/__tests__/components/comment-mark.test.js +89 -0
  5. package/dist/__tests__/components/comment-mark.test.js.map +1 -0
  6. package/dist/__tests__/components/comment-side-panel.test.d.ts +2 -0
  7. package/dist/__tests__/components/comment-side-panel.test.d.ts.map +1 -0
  8. package/dist/__tests__/components/comment-side-panel.test.js +291 -0
  9. package/dist/__tests__/components/comment-side-panel.test.js.map +1 -0
  10. package/dist/__tests__/components/notification-bell.test.d.ts +2 -0
  11. package/dist/__tests__/components/notification-bell.test.d.ts.map +1 -0
  12. package/dist/__tests__/components/notification-bell.test.js +200 -0
  13. package/dist/__tests__/components/notification-bell.test.js.map +1 -0
  14. package/dist/__tests__/components/offline-status.test.d.ts +2 -0
  15. package/dist/__tests__/components/offline-status.test.d.ts.map +1 -0
  16. package/dist/__tests__/components/offline-status.test.js +56 -0
  17. package/dist/__tests__/components/offline-status.test.js.map +1 -0
  18. package/dist/__tests__/components/presence-chips-helpers.test.d.ts +2 -0
  19. package/dist/__tests__/components/presence-chips-helpers.test.d.ts.map +1 -0
  20. package/dist/__tests__/components/presence-chips-helpers.test.js +35 -0
  21. package/dist/__tests__/components/presence-chips-helpers.test.js.map +1 -0
  22. package/dist/__tests__/fields/component-block-helpers.test.d.ts +7 -0
  23. package/dist/__tests__/fields/component-block-helpers.test.d.ts.map +1 -0
  24. package/dist/__tests__/fields/component-block-helpers.test.js +592 -0
  25. package/dist/__tests__/fields/component-block-helpers.test.js.map +1 -0
  26. package/dist/__tests__/lib/active-editor.test.d.ts +2 -0
  27. package/dist/__tests__/lib/active-editor.test.d.ts.map +1 -0
  28. package/dist/__tests__/lib/active-editor.test.js +57 -0
  29. package/dist/__tests__/lib/active-editor.test.js.map +1 -0
  30. package/dist/__tests__/lib/coauthor-client.test.d.ts +2 -0
  31. package/dist/__tests__/lib/coauthor-client.test.d.ts.map +1 -0
  32. package/dist/__tests__/lib/coauthor-client.test.js +173 -0
  33. package/dist/__tests__/lib/coauthor-client.test.js.map +1 -0
  34. package/dist/__tests__/lib/collaboration-provider.test.d.ts +2 -0
  35. package/dist/__tests__/lib/collaboration-provider.test.d.ts.map +1 -0
  36. package/dist/__tests__/lib/collaboration-provider.test.js +335 -0
  37. package/dist/__tests__/lib/collaboration-provider.test.js.map +1 -0
  38. package/dist/__tests__/lib/comment-anchor.test.d.ts +2 -0
  39. package/dist/__tests__/lib/comment-anchor.test.d.ts.map +1 -0
  40. package/dist/__tests__/lib/comment-anchor.test.js +173 -0
  41. package/dist/__tests__/lib/comment-anchor.test.js.map +1 -0
  42. package/dist/__tests__/lib/comments-client.test.d.ts +2 -0
  43. package/dist/__tests__/lib/comments-client.test.d.ts.map +1 -0
  44. package/dist/__tests__/lib/comments-client.test.js +202 -0
  45. package/dist/__tests__/lib/comments-client.test.js.map +1 -0
  46. package/dist/__tests__/lib/notifications-client.test.d.ts +2 -0
  47. package/dist/__tests__/lib/notifications-client.test.d.ts.map +1 -0
  48. package/dist/__tests__/lib/notifications-client.test.js +155 -0
  49. package/dist/__tests__/lib/notifications-client.test.js.map +1 -0
  50. package/dist/__tests__/lib/slash-command.test.d.ts +2 -0
  51. package/dist/__tests__/lib/slash-command.test.d.ts.map +1 -0
  52. package/dist/__tests__/lib/slash-command.test.js +123 -0
  53. package/dist/__tests__/lib/slash-command.test.js.map +1 -0
  54. package/dist/actuate-admin.css +1 -1
  55. package/dist/components/AICoauthorBubbleMenu.d.ts +18 -0
  56. package/dist/components/AICoauthorBubbleMenu.d.ts.map +1 -0
  57. package/dist/components/AICoauthorBubbleMenu.js +113 -0
  58. package/dist/components/AICoauthorBubbleMenu.js.map +1 -0
  59. package/dist/components/CoauthorResultPopover.d.ts +28 -0
  60. package/dist/components/CoauthorResultPopover.d.ts.map +1 -0
  61. package/dist/components/CoauthorResultPopover.js +42 -0
  62. package/dist/components/CoauthorResultPopover.js.map +1 -0
  63. package/dist/components/CommandPalette.d.ts +1 -1
  64. package/dist/components/CommandPalette.d.ts.map +1 -1
  65. package/dist/components/CommandPalette.js +138 -40
  66. package/dist/components/CommandPalette.js.map +1 -1
  67. package/dist/components/CommentMark.d.ts +54 -0
  68. package/dist/components/CommentMark.d.ts.map +1 -0
  69. package/dist/components/CommentMark.js +104 -0
  70. package/dist/components/CommentMark.js.map +1 -0
  71. package/dist/components/CommentSidePanel.d.ts +86 -0
  72. package/dist/components/CommentSidePanel.d.ts.map +1 -0
  73. package/dist/components/CommentSidePanel.js +165 -0
  74. package/dist/components/CommentSidePanel.js.map +1 -0
  75. package/dist/components/LivePreview.d.ts.map +1 -1
  76. package/dist/components/LivePreview.js +80 -16
  77. package/dist/components/LivePreview.js.map +1 -1
  78. package/dist/components/NotificationBell.d.ts +45 -0
  79. package/dist/components/NotificationBell.d.ts.map +1 -0
  80. package/dist/components/NotificationBell.js +90 -0
  81. package/dist/components/NotificationBell.js.map +1 -0
  82. package/dist/components/OfflineStatus.d.ts +39 -0
  83. package/dist/components/OfflineStatus.d.ts.map +1 -0
  84. package/dist/components/OfflineStatus.js +47 -0
  85. package/dist/components/OfflineStatus.js.map +1 -0
  86. package/dist/components/PresenceChips.d.ts +31 -0
  87. package/dist/components/PresenceChips.d.ts.map +1 -0
  88. package/dist/components/PresenceChips.js +58 -0
  89. package/dist/components/PresenceChips.js.map +1 -0
  90. package/dist/components/TipTapEditor.d.ts +61 -1
  91. package/dist/components/TipTapEditor.d.ts.map +1 -1
  92. package/dist/components/TipTapEditor.js +211 -8
  93. package/dist/components/TipTapEditor.js.map +1 -1
  94. package/dist/components/ui/Badge.d.ts +1 -1
  95. package/dist/fields/ComponentBlockField.d.ts +25 -0
  96. package/dist/fields/ComponentBlockField.d.ts.map +1 -0
  97. package/dist/fields/ComponentBlockField.js +74 -0
  98. package/dist/fields/ComponentBlockField.js.map +1 -0
  99. package/dist/fields/FieldRenderer.d.ts +3 -0
  100. package/dist/fields/FieldRenderer.d.ts.map +1 -1
  101. package/dist/fields/FieldRenderer.js +3 -1
  102. package/dist/fields/FieldRenderer.js.map +1 -1
  103. package/dist/fields/PropInput.d.ts +14 -0
  104. package/dist/fields/PropInput.d.ts.map +1 -0
  105. package/dist/fields/PropInput.js +163 -0
  106. package/dist/fields/PropInput.js.map +1 -0
  107. package/dist/fields/component-block-helpers.d.ts +96 -0
  108. package/dist/fields/component-block-helpers.d.ts.map +1 -0
  109. package/dist/fields/component-block-helpers.js +323 -0
  110. package/dist/fields/component-block-helpers.js.map +1 -0
  111. package/dist/fields/index.d.ts +4 -0
  112. package/dist/fields/index.d.ts.map +1 -1
  113. package/dist/fields/index.js +2 -0
  114. package/dist/fields/index.js.map +1 -1
  115. package/dist/index.d.ts +10 -0
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +5 -0
  118. package/dist/index.js.map +1 -1
  119. package/dist/lib/active-editor.d.ts +6 -0
  120. package/dist/lib/active-editor.d.ts.map +1 -0
  121. package/dist/lib/active-editor.js +35 -0
  122. package/dist/lib/active-editor.js.map +1 -0
  123. package/dist/lib/coauthor-client.d.ts +72 -0
  124. package/dist/lib/coauthor-client.d.ts.map +1 -0
  125. package/dist/lib/coauthor-client.js +98 -0
  126. package/dist/lib/coauthor-client.js.map +1 -0
  127. package/dist/lib/collaboration-provider.d.ts +142 -0
  128. package/dist/lib/collaboration-provider.d.ts.map +1 -0
  129. package/dist/lib/collaboration-provider.js +168 -0
  130. package/dist/lib/collaboration-provider.js.map +1 -0
  131. package/dist/lib/comment-anchor.d.ts +86 -0
  132. package/dist/lib/comment-anchor.d.ts.map +1 -0
  133. package/dist/lib/comment-anchor.js +139 -0
  134. package/dist/lib/comment-anchor.js.map +1 -0
  135. package/dist/lib/comments-client.d.ts +106 -0
  136. package/dist/lib/comments-client.d.ts.map +1 -0
  137. package/dist/lib/comments-client.js +138 -0
  138. package/dist/lib/comments-client.js.map +1 -0
  139. package/dist/lib/notifications-client.d.ts +68 -0
  140. package/dist/lib/notifications-client.d.ts.map +1 -0
  141. package/dist/lib/notifications-client.js +85 -0
  142. package/dist/lib/notifications-client.js.map +1 -0
  143. package/dist/lib/slash-command.d.ts +39 -0
  144. package/dist/lib/slash-command.d.ts.map +1 -0
  145. package/dist/lib/slash-command.js +50 -0
  146. package/dist/lib/slash-command.js.map +1 -0
  147. package/package.json +20 -4
  148. package/src/__tests__/components/comment-mark.test.ts +99 -0
  149. package/src/__tests__/components/comment-side-panel.test.tsx +343 -0
  150. package/src/__tests__/components/notification-bell.test.tsx +213 -0
  151. package/src/__tests__/components/offline-status.test.tsx +66 -0
  152. package/src/__tests__/components/presence-chips-helpers.test.ts +44 -0
  153. package/src/__tests__/fields/component-block-helpers.test.ts +674 -0
  154. package/src/__tests__/lib/active-editor.test.ts +70 -0
  155. package/src/__tests__/lib/coauthor-client.test.ts +213 -0
  156. package/src/__tests__/lib/collaboration-provider.test.ts +425 -0
  157. package/src/__tests__/lib/comment-anchor.test.ts +188 -0
  158. package/src/__tests__/lib/comments-client.test.ts +239 -0
  159. package/src/__tests__/lib/notifications-client.test.ts +195 -0
  160. package/src/__tests__/lib/slash-command.test.ts +146 -0
  161. package/src/components/AICoauthorBubbleMenu.tsx +187 -0
  162. package/src/components/CoauthorResultPopover.tsx +193 -0
  163. package/src/components/CommandPalette.tsx +397 -209
  164. package/src/components/CommentMark.ts +138 -0
  165. package/src/components/CommentSidePanel.tsx +521 -0
  166. package/src/components/LivePreview.tsx +117 -11
  167. package/src/components/NotificationBell.tsx +242 -0
  168. package/src/components/OfflineStatus.tsx +90 -0
  169. package/src/components/PresenceChips.tsx +150 -0
  170. package/src/components/TipTapEditor.tsx +310 -12
  171. package/src/fields/ComponentBlockField.tsx +179 -0
  172. package/src/fields/FieldRenderer.tsx +8 -0
  173. package/src/fields/PropInput.tsx +552 -0
  174. package/src/fields/component-block-helpers.ts +341 -0
  175. package/src/fields/index.ts +4 -0
  176. package/src/index.ts +27 -0
  177. package/src/lib/active-editor.ts +39 -0
  178. package/src/lib/coauthor-client.ts +160 -0
  179. package/src/lib/collaboration-provider.ts +306 -0
  180. package/src/lib/comment-anchor.ts +179 -0
  181. package/src/lib/comments-client.ts +208 -0
  182. package/src/lib/notifications-client.ts +146 -0
  183. package/src/lib/slash-command.ts +67 -0
@@ -0,0 +1,200 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment happy-dom
3
+ import { describe, expect, it, vi } from 'vitest';
4
+ import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
5
+ import { NotificationBell } from '../../components/NotificationBell.js';
6
+ function ok(value) {
7
+ return { ok: true, result: value };
8
+ }
9
+ function err(error = 'boom', status = 500) {
10
+ return { ok: false, error, status };
11
+ }
12
+ function row(overrides = {}) {
13
+ return {
14
+ id: 'n-1',
15
+ userId: 'user-1',
16
+ kind: 'comment_reply',
17
+ documentId: 'doc-1',
18
+ commentId: 'c-1',
19
+ payload: {
20
+ kind: 'comment_reply',
21
+ actorId: 'someone',
22
+ actorName: 'Someone',
23
+ excerpt: 'hi',
24
+ },
25
+ readAt: null,
26
+ createdAt: '2026-01-01T00:00:00.000Z',
27
+ ...overrides,
28
+ };
29
+ }
30
+ function createFakeApi() {
31
+ let rows = [];
32
+ const calls = [];
33
+ const api = {
34
+ list: vi.fn(async (opts) => {
35
+ calls.push({ name: 'list', args: [opts] });
36
+ return ok(opts.includeRead ? rows : rows.filter((r) => r.readAt === null));
37
+ }),
38
+ unread: vi.fn(async () => {
39
+ calls.push({ name: 'unread', args: [] });
40
+ return ok(rows.filter((r) => r.readAt === null).length);
41
+ }),
42
+ markRead: vi.fn(async (id) => {
43
+ calls.push({ name: 'markRead', args: [id] });
44
+ const target = rows.find((r) => r.id === id);
45
+ if (!target)
46
+ return err('not found', 404);
47
+ target.readAt = '2026-01-02T00:00:00.000Z';
48
+ return ok(target);
49
+ }),
50
+ markAllRead: vi.fn(async () => {
51
+ calls.push({ name: 'markAllRead', args: [] });
52
+ let n = 0;
53
+ for (const r of rows) {
54
+ if (r.readAt === null) {
55
+ r.readAt = '2026-01-02T00:00:00.000Z';
56
+ n++;
57
+ }
58
+ }
59
+ return ok(n);
60
+ }),
61
+ };
62
+ return {
63
+ api,
64
+ calls,
65
+ setRows: (next) => {
66
+ rows = next;
67
+ },
68
+ rows: () => rows,
69
+ };
70
+ }
71
+ describe('NotificationBell — badge', () => {
72
+ it('shows the unread badge from the unread() call', async () => {
73
+ const fake = createFakeApi();
74
+ fake.setRows([row(), row({ id: 'n-2' })]);
75
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0 }));
76
+ await waitFor(() => expect(screen.getByTestId('bell-badge').textContent).toBe('2'));
77
+ });
78
+ it('hides the badge when count is 0', async () => {
79
+ const fake = createFakeApi();
80
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0 }));
81
+ // Let the initial unread() settle.
82
+ await waitFor(() => expect(fake.api.unread).toHaveBeenCalled());
83
+ expect(screen.queryByTestId('bell-badge')).toBeNull();
84
+ });
85
+ it('clamps the badge at "99+"', async () => {
86
+ const fake = createFakeApi();
87
+ fake.setRows(Array.from({ length: 150 }, (_, i) => row({ id: `n-${i}` })));
88
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0 }));
89
+ await waitFor(() => expect(screen.getByTestId('bell-badge').textContent).toBe('99+'));
90
+ });
91
+ it('polls unread() at pollIntervalMs', async () => {
92
+ vi.useFakeTimers({ shouldAdvanceTime: true });
93
+ try {
94
+ const fake = createFakeApi();
95
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 5000 }));
96
+ await waitFor(() => expect(fake.api.unread).toHaveBeenCalledTimes(1));
97
+ await act(async () => {
98
+ vi.advanceTimersByTime(5000);
99
+ });
100
+ expect(fake.api.unread).toHaveBeenCalledTimes(2);
101
+ }
102
+ finally {
103
+ vi.useRealTimers();
104
+ }
105
+ });
106
+ });
107
+ describe('NotificationBell — dropdown', () => {
108
+ it('shows the empty state when there are no rows', async () => {
109
+ const fake = createFakeApi();
110
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0 }));
111
+ await waitFor(() => expect(fake.api.unread).toHaveBeenCalled());
112
+ fireEvent.click(screen.getByTestId('bell-button'));
113
+ await waitFor(() => expect(screen.getByTestId('bell-dropdown')).toBeTruthy());
114
+ await waitFor(() => expect(screen.getByText('All caught up.')).toBeTruthy());
115
+ });
116
+ it('renders one button per row with the formatted summary', async () => {
117
+ const fake = createFakeApi();
118
+ fake.setRows([
119
+ row({
120
+ id: 'n-a',
121
+ payload: {
122
+ kind: 'comment_reply',
123
+ actorId: 'x',
124
+ actorName: 'Alice',
125
+ excerpt: 'good',
126
+ },
127
+ }),
128
+ row({
129
+ id: 'n-b',
130
+ kind: 'comment_resolved',
131
+ payload: {
132
+ kind: 'comment_resolved',
133
+ actorId: 'y',
134
+ actorName: 'Bob',
135
+ rootExcerpt: 'fix',
136
+ },
137
+ }),
138
+ ]);
139
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0 }));
140
+ await waitFor(() => expect(fake.api.unread).toHaveBeenCalled());
141
+ fireEvent.click(screen.getByTestId('bell-button'));
142
+ await waitFor(() => expect(screen.getByTestId('bell-row-n-a')).toBeTruthy());
143
+ expect(screen.getByTestId('bell-row-n-a').textContent).toContain('Alice replied');
144
+ expect(screen.getByTestId('bell-row-n-b').textContent).toContain('Bob resolved');
145
+ });
146
+ it('marks a row read optimistically, then via the API', async () => {
147
+ const fake = createFakeApi();
148
+ const onSelect = vi.fn();
149
+ fake.setRows([row()]);
150
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0, onSelect: onSelect }));
151
+ await waitFor(() => expect(screen.getByTestId('bell-badge').textContent).toBe('1'));
152
+ fireEvent.click(screen.getByTestId('bell-button'));
153
+ await waitFor(() => expect(screen.getByTestId('bell-row-n-1')).toBeTruthy());
154
+ await act(async () => {
155
+ fireEvent.click(screen.getByTestId('bell-row-n-1'));
156
+ });
157
+ expect(fake.api.markRead).toHaveBeenCalledWith('n-1');
158
+ expect(onSelect).toHaveBeenCalledTimes(1);
159
+ expect(screen.queryByTestId('bell-badge')).toBeNull();
160
+ });
161
+ it('rolls back the optimistic update when markRead fails', async () => {
162
+ const fake = createFakeApi();
163
+ fake.api.markRead.mockResolvedValueOnce(err('server', 500));
164
+ const onError = vi.fn();
165
+ fake.setRows([row()]);
166
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0, onError: onError }));
167
+ await waitFor(() => expect(screen.getByTestId('bell-badge').textContent).toBe('1'));
168
+ fireEvent.click(screen.getByTestId('bell-button'));
169
+ await waitFor(() => expect(screen.getByTestId('bell-row-n-1')).toBeTruthy());
170
+ await act(async () => {
171
+ fireEvent.click(screen.getByTestId('bell-row-n-1'));
172
+ });
173
+ expect(onError).toHaveBeenCalledWith('server');
174
+ // The badge should bounce back to 1.
175
+ await waitFor(() => expect(screen.getByTestId('bell-badge').textContent).toBe('1'));
176
+ });
177
+ it('marks all read in one click and disables the button after', async () => {
178
+ const fake = createFakeApi();
179
+ fake.setRows([row(), row({ id: 'n-2' })]);
180
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0 }));
181
+ await waitFor(() => expect(screen.getByTestId('bell-badge').textContent).toBe('2'));
182
+ fireEvent.click(screen.getByTestId('bell-button'));
183
+ await waitFor(() => expect(screen.getByTestId('bell-mark-all')).toBeTruthy());
184
+ await act(async () => {
185
+ fireEvent.click(screen.getByTestId('bell-mark-all'));
186
+ });
187
+ expect(fake.api.markAllRead).toHaveBeenCalled();
188
+ expect(screen.getByTestId('bell-mark-all').disabled).toBe(true);
189
+ });
190
+ it('surfaces list() errors via onError', async () => {
191
+ const fake = createFakeApi();
192
+ fake.api.list.mockResolvedValueOnce(err('CSRF', 403));
193
+ const onError = vi.fn();
194
+ render(_jsx(NotificationBell, { api: fake.api, pollIntervalMs: 0, onError: onError }));
195
+ await waitFor(() => expect(fake.api.unread).toHaveBeenCalled());
196
+ fireEvent.click(screen.getByTestId('bell-button'));
197
+ await waitFor(() => expect(onError).toHaveBeenCalledWith('CSRF'));
198
+ });
199
+ });
200
+ //# sourceMappingURL=notification-bell.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification-bell.test.js","sourceRoot":"","sources":["../../../src/__tests__/components/notification-bell.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=offline-status.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-status.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/components/offline-status.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,56 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // @vitest-environment happy-dom
3
+ import { describe, expect, it } from 'vitest';
4
+ import { render, screen } from '@testing-library/react';
5
+ import { OfflineStatus, describeOfflineStatus } from '../../components/OfflineStatus.js';
6
+ describe('describeOfflineStatus', () => {
7
+ it('error wins over everything', () => {
8
+ expect(describeOfflineStatus('connected', 'error').tone).toBe('bad');
9
+ expect(describeOfflineStatus('disconnected', 'error').tone).toBe('bad');
10
+ });
11
+ it('reports Synced when offline is unsupported but socket is connected', () => {
12
+ const out = describeOfflineStatus('connected', 'unsupported');
13
+ expect(out.tone).toBe('good');
14
+ expect(out.label).toBe('Synced');
15
+ });
16
+ it('warns when offline is unsupported and socket is disconnected', () => {
17
+ expect(describeOfflineStatus('disconnected', 'unsupported').tone).toBe('warn');
18
+ });
19
+ it('shows Connecting… when offline is unsupported and socket is connecting', () => {
20
+ expect(describeOfflineStatus('connecting', 'unsupported').label).toBe('Connecting…');
21
+ });
22
+ it('reports Restoring local copy… while IndexedDB is loading', () => {
23
+ expect(describeOfflineStatus('connecting', 'loading').label).toMatch(/Restoring/);
24
+ expect(describeOfflineStatus('connecting', 'pending').label).toMatch(/Restoring/);
25
+ });
26
+ it('reports Saved & synced when both ready', () => {
27
+ const out = describeOfflineStatus('connected', 'ready');
28
+ expect(out.tone).toBe('good');
29
+ expect(out.label).toBe('Saved & synced');
30
+ });
31
+ it('reports Saved locally when offline is ready but socket is disconnected', () => {
32
+ const out = describeOfflineStatus('disconnected', 'ready');
33
+ expect(out.tone).toBe('warn');
34
+ expect(out.label).toMatch(/Saved locally/);
35
+ });
36
+ it('reports Saved locally — reconnecting… while reconnecting', () => {
37
+ expect(describeOfflineStatus('connecting', 'ready').label).toMatch(/reconnecting/);
38
+ });
39
+ });
40
+ describe('<OfflineStatus />', () => {
41
+ it('renders the resolved label + tone', () => {
42
+ render(_jsx(OfflineStatus, { connection: "connected", offline: "ready" }));
43
+ const chip = screen.getByTestId('offline-status');
44
+ expect(chip.textContent).toContain('Saved & synced');
45
+ expect(chip.dataset.tone).toBe('good');
46
+ });
47
+ it('switches tone when conditions change', () => {
48
+ const { rerender } = render(_jsx(OfflineStatus, { connection: "connected", offline: "ready" }));
49
+ expect(screen.getByTestId('offline-status').dataset.tone).toBe('good');
50
+ rerender(_jsx(OfflineStatus, { connection: "disconnected", offline: "ready" }));
51
+ expect(screen.getByTestId('offline-status').dataset.tone).toBe('warn');
52
+ rerender(_jsx(OfflineStatus, { connection: "connected", offline: "error" }));
53
+ expect(screen.getByTestId('offline-status').dataset.tone).toBe('bad');
54
+ });
55
+ });
56
+ //# sourceMappingURL=offline-status.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-status.test.js","sourceRoot":"","sources":["../../../src/__tests__/components/offline-status.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=presence-chips-helpers.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence-chips-helpers.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/components/presence-chips-helpers.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { nameToInitials } from '../../components/PresenceChips.js';
3
+ describe('nameToInitials', () => {
4
+ it('returns the first letter of a single name', () => {
5
+ expect(nameToInitials('Alice')).toBe('A');
6
+ });
7
+ it('returns the first letter of two name parts', () => {
8
+ expect(nameToInitials('Alice Cooper')).toBe('AC');
9
+ });
10
+ it('caps at two letters for three+ part names', () => {
11
+ expect(nameToInitials('Mary Jane Watson')).toBe('MJ');
12
+ });
13
+ it('uppercases the result', () => {
14
+ expect(nameToInitials('alice cooper')).toBe('AC');
15
+ });
16
+ it('trims surrounding whitespace before processing', () => {
17
+ expect(nameToInitials(' Alice ')).toBe('A');
18
+ });
19
+ it('collapses multiple whitespace separators', () => {
20
+ expect(nameToInitials('Alice Cooper')).toBe('AC');
21
+ });
22
+ it('falls back to "?" for an empty string', () => {
23
+ expect(nameToInitials('')).toBe('?');
24
+ });
25
+ it('falls back to "?" for a whitespace-only string', () => {
26
+ expect(nameToInitials(' ')).toBe('?');
27
+ });
28
+ it('handles a single emoji name without crashing', () => {
29
+ const result = nameToInitials('🐱 Whiskers');
30
+ // JS upper-case is a no-op for the cat — test just confirms we don't crash
31
+ // and return *something* with two character-positions.
32
+ expect(result.length).toBeGreaterThan(0);
33
+ });
34
+ });
35
+ //# sourceMappingURL=presence-chips-helpers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presence-chips-helpers.test.js","sourceRoot":"","sources":["../../../src/__tests__/components/presence-chips-helpers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAA;AAElE,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC3C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,CAAC,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/C,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,cAAc,CAAC,aAAa,CAAC,CAAA;QAC5C,2EAA2E;QAC3E,uDAAuD;QACvD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAA;IAC1C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Tests for the pure helpers that drive the ComponentBlockField admin
3
+ * form. Splitting these out of the React component lets us run them in
4
+ * node without jsdom.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=component-block-helpers.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component-block-helpers.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/fields/component-block-helpers.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}