@happyvertical/smrt-chat 0.30.0 → 0.31.0

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 (31) hide show
  1. package/dist/chunks/{ChatService-Dpzc1Pa5.js → ChatService-ByEPKa30.js} +2 -2
  2. package/dist/chunks/{ChatService-Dpzc1Pa5.js.map → ChatService-ByEPKa30.js.map} +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/internal/agent-runtime.js +1 -1
  5. package/dist/manifest.json +2 -2
  6. package/dist/services/ChatService.d.ts.map +1 -1
  7. package/dist/smrt-knowledge.json +4 -4
  8. package/dist/svelte/components/agent/AgentChat.svelte +6 -0
  9. package/dist/svelte/components/agent/ToolCallDisplay.svelte +4 -19
  10. package/dist/svelte/components/agent/ToolCallDisplay.svelte.d.ts.map +1 -1
  11. package/dist/svelte/components/agent/__tests__/ToolCallDisplay.test.js +44 -0
  12. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte +101 -158
  13. package/dist/svelte/components/dialogs/RoomCreateDialog.svelte.d.ts.map +1 -1
  14. package/dist/svelte/components/layout/ChatLayout.svelte +11 -2
  15. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts +2 -0
  16. package/dist/svelte/components/layout/ChatLayout.svelte.d.ts.map +1 -1
  17. package/dist/svelte/components/layout/MemberList.svelte +5 -3
  18. package/dist/svelte/components/layout/MemberList.svelte.d.ts.map +1 -1
  19. package/dist/svelte/components/layout/__tests__/ChatLayout.test.js +67 -0
  20. package/dist/svelte/components/messages/MessageItem.svelte +115 -1
  21. package/dist/svelte/components/messages/MessageItem.svelte.d.ts.map +1 -1
  22. package/dist/svelte/components/messages/__tests__/MessageItem.test.js +108 -0
  23. package/dist/svelte/components/shared/MentionAutocomplete.svelte +5 -1
  24. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts +2 -0
  25. package/dist/svelte/components/shared/MentionAutocomplete.svelte.d.ts.map +1 -1
  26. package/dist/svelte/components/shared/UserPresence.svelte +3 -3
  27. package/dist/svelte/components/shared/__tests__/MentionAutocomplete.test.js +66 -0
  28. package/dist/svelte/i18n.messages.d.ts +1 -0
  29. package/dist/svelte/i18n.messages.d.ts.map +1 -1
  30. package/dist/svelte/i18n.messages.js +1 -0
  31. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ObjectRegistry } from "@happyvertical/smrt-core";
2
- import { A, C, a, b, c, d, e } from "./chunks/ChatService-Dpzc1Pa5.js";
2
+ import { A, C, a, b, c, d, e } from "./chunks/ChatService-ByEPKa30.js";
3
3
  import { CHAT_MODULE_META, CHAT_UI_SLOTS } from "./ui.js";
4
4
  ObjectRegistry.registerPackageManifest(
5
5
  new URL("./manifest.json", import.meta.url)
@@ -1,4 +1,4 @@
1
- import { s } from "../chunks/ChatService-Dpzc1Pa5.js";
1
+ import { s } from "../chunks/ChatService-ByEPKa30.js";
2
2
  export {
3
3
  s as sendAgentReply
4
4
  };
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "version": "1.0.0",
3
- "timestamp": 1782177125181,
3
+ "timestamp": 1782183823146,
4
4
  "packageName": "@happyvertical/smrt-chat",
5
- "packageVersion": "0.30.0",
5
+ "packageVersion": "0.31.0",
6
6
  "objects": {
7
7
  "@happyvertical/smrt-chat:AgentSessionCollection": {
8
8
  "name": "agentsessioncollection",
@@ -1 +1 @@
1
- {"version":3,"file":"ChatService.d.ts","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,KAAK,EAEV,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,YAAY,EACb,MAAM,aAAa,CAAC;AAuBrB;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wEAAwE;AACxE,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,iEAAiE;AACjE,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,QAAA,MAAM,eAAe,eAAoC,CAAC;AAE1D,qBAAa,WAAW;;IAatB,OAAO;WAgBM,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC;IA6DrE,6DAA6D;IACvD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;;;;;;OAOG;IACG,UAAU,CAAC,MAAM,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,YAAY,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;IAqBD;;;;;;;;;;;;;;OAcG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,eAAe,CAAC;QAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAClC;IA2HD;;;;;;;;;;;;OAYG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB;IA4BD;;;;;;;;OAQG;IACG,cAAc,CAAC,MAAM,EAAE;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,CAAC,EAAE,mBAAmB,CAAC;KAC5B;IAmDD;;;;;;OAMG;IACG,iBAAiB,CAAC,MAAM,EAAE;QAC9B,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB;IAgCD;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,cAAc,CAAC;KACzB;IAqBD;;;;;;;;OAQG;IACG,WAAW,CAAC,MAAM,EAAE;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf;IAgCD;;;;;;OAMG;IACG,cAAc,CAAC,MAAM,EAAE;QAC3B,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpB;;;;;;;OAOG;IACG,aAAa,CAAC,MAAM,EAAE;QAC1B,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB;IA+BD;;;;;;;;;;;;;;;;;;OAkBG;IACG,kBAAkB,CAAC,MAAM,EAAE;QAC/B,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B;;;;IA0FD;;;;;;;;;OASG;IACG,oBAAoB,CAAC,MAAM,EAAE;QACjC,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,eAAe,CAAC;KAC/B;IA0FD;;;;;;;;;;;OAWG;IACG,eAAe,CAAC,MAAM,EAAE;QAC5B,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB;IAYD;;;;;;;;OAQG;IACG,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM;IAQlB;;;;;;;;OAQG;IACG,eAAe,CACnB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAQ/B;;;;;;;OAOG;IACG,uBAAuB,CAAC,MAAM,EAAE;QACpC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAY3B;;;;;;OAMG;IACG,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAQjE;;;;;;OAMG;IACG,eAAe,CAAC,MAAM,EAAE;QAC5B,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAYzB;;;;;;;OAOG;IACG,iBAAiB,CAAC,MAAM,EAAE;QAC9B,QAAQ,EAAE,MAAM,CAAC;QACjB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAyB1B;;;;;;;OAOG;IACG,wBAAwB,CAAC,MAAM,EAAE;QACrC,cAAc,EAAE,MAAM,CAAC;QACvB,cAAc,EAAE,MAAM,CAAC;QACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB;IA8ED;;;;;;;;;;OAUG;IACH,MAAM,CAAC,CAAC,eAAe,CAAC,CACtB,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,gBAAgB;CAO3B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AAEhE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,gBAAgB,wBAGzB"}
1
+ {"version":3,"file":"ChatService.d.ts","sourceRoot":"","sources":["../../src/services/ChatService.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "generatedAt": "2026-06-23T01:12:05.520Z",
3
+ "generatedAt": "2026-06-23T03:03:43.484Z",
4
4
  "packageName": "@happyvertical/smrt-chat",
5
- "packageVersion": "0.30.0",
5
+ "packageVersion": "0.31.0",
6
6
  "sourceManifestPath": "dist/manifest.json",
7
7
  "agentDocPath": "AGENTS.md",
8
8
  "sourceHashes": {
9
- "manifest": "60c8eb52b192ffae7154d85d461e13eb8bc29a577fb4348e4d1c7ecdd6c1363d",
10
- "packageJson": "c390a11b1e803bc96928ec2700e460859b575a486289a78dcbe4fe4e8659226c",
9
+ "manifest": "e33b60a730af26a0a46683a56c05ae81295488e7cc488630ea61c30cb788c5d6",
10
+ "packageJson": "b52b6860e95e31f9e5da5e00c66e3df702b3ed14b50f56ca96f8c5e89ba096a0",
11
11
  "agents": "e0a8c6788fbd48c2619a353295d4538e9ff6863d483bcd354af522fb7c6a31bc"
12
12
  },
13
13
  "exports": [
@@ -539,4 +539,10 @@ $effect(() => {
539
539
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
540
540
  30% { transform: translateY(-4px); opacity: 1; }
541
541
  }
542
+
543
+ @media (prefers-reduced-motion: reduce) {
544
+ .thinking-dots span {
545
+ animation: none;
546
+ }
547
+ }
542
548
  </style>
@@ -19,21 +19,6 @@ const { t } = useI18n();
19
19
 
20
20
  let isExpanded = $state(false);
21
21
 
22
- const statusIcon = $derived.by(() => {
23
- switch (toolCall.status) {
24
- case 'pending':
25
- return '...';
26
- case 'running':
27
- return '...';
28
- case 'success':
29
- return '...';
30
- case 'error':
31
- return '...';
32
- default:
33
- return '';
34
- }
35
- });
36
-
37
22
  const statusLabel = $derived.by(() => {
38
23
  switch (toolCall.status) {
39
24
  case 'pending':
@@ -145,11 +130,11 @@ function formatDuration(ms: number | undefined): string {
145
130
  }
146
131
 
147
132
  .tool-call--success {
148
- border-left: 3px solid var(--smrt-color-success, #4caf50);
133
+ border-left: 3px solid var(--smrt-color-success, #1e8e3e);
149
134
  }
150
135
 
151
136
  .tool-call--error {
152
- border-left: 3px solid var(--smrt-color-error, #ba1a1a);
137
+ border-left: 3px solid var(--smrt-color-error, #b3261e);
153
138
  }
154
139
 
155
140
  .tool-call__header {
@@ -193,11 +178,11 @@ function formatDuration(ms: number | undefined): string {
193
178
  }
194
179
 
195
180
  .tool-call--success .tool-call__status-dot {
196
- background: var(--smrt-color-success, #4caf50);
181
+ background: var(--smrt-color-success, #1e8e3e);
197
182
  }
198
183
 
199
184
  .tool-call--error .tool-call__status-dot {
200
- background: var(--smrt-color-error, #ba1a1a);
185
+ background: var(--smrt-color-error, #b3261e);
201
186
  }
202
187
 
203
188
  .tool-call__name {
@@ -1 +1 @@
1
- {"version":3,"file":"ToolCallDisplay.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/agent/ToolCallDisplay.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,MAAM,WAAW,KAAK;IACpB,qBAAqB;IACrB,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAiHD,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"ToolCallDisplay.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/agent/ToolCallDisplay.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,MAAM,WAAW,KAAK;IACpB,qBAAqB;IACrB,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAkGD,QAAA,MAAM,eAAe,2CAAwC,CAAC;AAC9D,KAAK,eAAe,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;AAC1D,eAAe,eAAe,CAAC"}
@@ -0,0 +1,44 @@
1
+ // @vitest-environment jsdom
2
+ /**
3
+ * Component coverage for ToolCallDisplay via the shared S11 harness (#1416).
4
+ *
5
+ * Locks the T2 #1391 dead-code removal: the unused `statusIcon` $derived (which
6
+ * returned '...'/'' for every branch and was never rendered) was removed. The
7
+ * component must still render the tool name and status, and expand on click.
8
+ */
9
+ import { expectNoA11yViolations, render, screen, userEvent, } from '@happyvertical/smrt-vitest/svelte';
10
+ import { describe, expect, it } from 'vitest';
11
+ import ToolCallDisplay from '../ToolCallDisplay.svelte';
12
+ function makeToolCall(overrides = {}) {
13
+ return {
14
+ toolName: 'search',
15
+ toolCallId: 'tc-1',
16
+ arguments: { q: 'hello' },
17
+ status: 'success',
18
+ result: ['a', 'b'],
19
+ duration: 1200,
20
+ ...overrides,
21
+ };
22
+ }
23
+ describe('ToolCallDisplay', () => {
24
+ it('renders the tool name and a human status label', () => {
25
+ render(ToolCallDisplay, { props: { toolCall: makeToolCall() } });
26
+ expect(screen.getByText('search')).toBeInTheDocument();
27
+ expect(screen.getByText('Completed')).toBeInTheDocument();
28
+ });
29
+ it('expands to reveal arguments and result on click', async () => {
30
+ render(ToolCallDisplay, { props: { toolCall: makeToolCall() } });
31
+ const header = screen.getByRole('button');
32
+ expect(header).toHaveAttribute('aria-expanded', 'false');
33
+ await userEvent.click(header);
34
+ expect(header).toHaveAttribute('aria-expanded', 'true');
35
+ expect(screen.getByText('Arguments')).toBeInTheDocument();
36
+ expect(screen.getByText('Result')).toBeInTheDocument();
37
+ });
38
+ it('is axe-clean', async () => {
39
+ const { container } = render(ToolCallDisplay, {
40
+ props: { toolCall: makeToolCall({ status: 'error', error: 'boom' }) },
41
+ });
42
+ await expectNoA11yViolations(container);
43
+ });
44
+ });
@@ -1,8 +1,13 @@
1
1
  <script lang="ts">
2
2
  /**
3
3
  * RoomCreateDialog - Modal dialog for creating a new chat room
4
- * Provides name, type selector, and description fields
4
+ * Provides name, type selector, and description fields.
5
+ *
6
+ * Built on the shared smrt-ui `Modal` (T2 #1391) so it inherits a focus trap,
7
+ * Escape handling, scrim, and focus-restore-to-trigger on close — the
8
+ * hand-rolled backdrop it replaced had none of those.
5
9
  */
10
+ import { Modal } from '@happyvertical/smrt-ui/feedback';
6
11
  import { useI18n } from '@happyvertical/smrt-ui/i18n';
7
12
  import { M } from '../../i18n.js';
8
13
 
@@ -74,27 +79,8 @@ function resetForm() {
74
79
  description = '';
75
80
  }
76
81
 
77
- function handleKeydown(event: KeyboardEvent) {
78
- if (event.key === 'Escape') {
79
- handleClose();
80
- }
81
- }
82
-
83
- $effect(() => {
84
- if (!isOpen || typeof window === 'undefined') {
85
- return;
86
- }
87
-
88
- const onWindowKeydown = (event: KeyboardEvent) => {
89
- handleKeydown(event);
90
- };
91
-
92
- window.addEventListener('keydown', onWindowKeydown);
93
- return () => {
94
- window.removeEventListener('keydown', onWindowKeydown);
95
- };
96
- });
97
-
82
+ // Modal traps focus and moves it to the dialog itself; nudge initial focus to
83
+ // the name field once the dialog is open and the input is mounted.
98
84
  $effect(() => {
99
85
  if (isOpen && nameInput) {
100
86
  nameInput.focus();
@@ -102,146 +88,110 @@ $effect(() => {
102
88
  });
103
89
  </script>
104
90
 
105
- {#if isOpen}
106
- <div class="dialog-backdrop">
91
+ <Modal
92
+ open={isOpen}
93
+ onClose={handleClose}
94
+ title={t(M['chat.room_create_dialog.title'])}
95
+ size="md"
96
+ ariaLabel={t(M['chat.room_create_dialog.title'])}
97
+ >
98
+ <form
99
+ class="dialog__form"
100
+ onsubmit={(e) => { e.preventDefault(); handleSubmit(); }}
101
+ >
102
+ <div class="field">
103
+ <label class="field__label" for="room-name">
104
+ {t(M['chat.room_create_dialog.room_name'])} <span class="field__required" aria-label={t(M['chat.room_create_dialog.required'])}>*</span>
105
+ </label>
106
+ <input
107
+ bind:this={nameInput}
108
+ bind:value={name}
109
+ id="room-name"
110
+ type="text"
111
+ class="field__input"
112
+ placeholder={t(M['chat.room_create_dialog.name_placeholder'])}
113
+ maxlength="100"
114
+ autocomplete="off"
115
+ />
116
+ </div>
117
+
118
+ <fieldset class="field">
119
+ <legend class="field__label">{t(M['chat.room_create_dialog.room_type'])}</legend>
120
+ <div class="type-options">
121
+ {#each roomTypes as option (option.value)}
122
+ <label
123
+ class="type-option"
124
+ class:type-option--selected={roomType === option.value}
125
+ >
126
+ <input
127
+ type="radio"
128
+ name="roomType"
129
+ value={option.value}
130
+ bind:group={roomType}
131
+ class="type-option__radio"
132
+ />
133
+ <span class="type-option__content">
134
+ <span class="type-option__label">{option.label}</span>
135
+ <span class="type-option__description">{option.description}</span>
136
+ </span>
137
+ </label>
138
+ {/each}
139
+ </div>
140
+ </fieldset>
141
+
142
+ <div class="field">
143
+ <label class="field__label" for="room-description">Description</label>
144
+ <textarea
145
+ bind:value={description}
146
+ id="room-description"
147
+ class="field__textarea"
148
+ placeholder={t(M['chat.room_create_dialog.description_placeholder'])}
149
+ rows="3"
150
+ maxlength="500"
151
+ ></textarea>
152
+ <span class="field__hint">{description.length}/500</span>
153
+ </div>
154
+
155
+ <!-- Hidden submit keeps Enter-to-submit working inside the Modal body. -->
156
+ <button type="submit" class="visually-hidden" tabindex="-1" disabled={!canCreate} aria-hidden="true"></button>
157
+ </form>
158
+
159
+ {#snippet footer()}
107
160
  <button
108
161
  type="button"
109
- class="dialog-backdrop__dismiss"
110
- tabindex="-1"
111
- aria-label={t(M['chat.room_create_dialog.close'])}
162
+ class="btn btn--secondary"
112
163
  onclick={handleClose}
113
- ></button>
114
- <div
115
- class="dialog"
116
- role="dialog"
117
- aria-modal="true"
118
- aria-labelledby="create-room-title"
119
- tabindex="-1"
120
164
  >
121
- <h2 id="create-room-title" class="dialog__title">{t(M['chat.room_create_dialog.title'])}</h2>
122
-
123
- <form
124
- class="dialog__form"
125
- onsubmit={(e) => { e.preventDefault(); handleSubmit(); }}
126
- >
127
- <div class="field">
128
- <label class="field__label" for="room-name">
129
- {t(M['chat.room_create_dialog.room_name'])} <span class="field__required" aria-label={t(M['chat.room_create_dialog.required'])}>*</span>
130
- </label>
131
- <input
132
- bind:this={nameInput}
133
- bind:value={name}
134
- id="room-name"
135
- type="text"
136
- class="field__input"
137
- placeholder={t(M['chat.room_create_dialog.name_placeholder'])}
138
- maxlength="100"
139
- autocomplete="off"
140
- />
141
- </div>
142
-
143
- <fieldset class="field">
144
- <legend class="field__label">{t(M['chat.room_create_dialog.room_type'])}</legend>
145
- <div class="type-options">
146
- {#each roomTypes as option (option.value)}
147
- <label
148
- class="type-option"
149
- class:type-option--selected={roomType === option.value}
150
- >
151
- <input
152
- type="radio"
153
- name="roomType"
154
- value={option.value}
155
- bind:group={roomType}
156
- class="type-option__radio"
157
- />
158
- <span class="type-option__content">
159
- <span class="type-option__label">{option.label}</span>
160
- <span class="type-option__description">{option.description}</span>
161
- </span>
162
- </label>
163
- {/each}
164
- </div>
165
- </fieldset>
166
-
167
- <div class="field">
168
- <label class="field__label" for="room-description">Description</label>
169
- <textarea
170
- bind:value={description}
171
- id="room-description"
172
- class="field__textarea"
173
- placeholder={t(M['chat.room_create_dialog.description_placeholder'])}
174
- rows="3"
175
- maxlength="500"
176
- ></textarea>
177
- <span class="field__hint">{description.length}/500</span>
178
- </div>
179
-
180
- <div class="dialog__actions">
181
- <button
182
- type="button"
183
- class="btn btn--secondary"
184
- onclick={handleClose}
185
- >
186
- Cancel
187
- </button>
188
- <button
189
- type="submit"
190
- class="btn btn--primary"
191
- disabled={!canCreate}
192
- >
193
- {t(M['chat.room_create_dialog.create_room'])}
194
- </button>
195
- </div>
196
- </form>
197
- </div>
198
- </div>
199
- {/if}
165
+ Cancel
166
+ </button>
167
+ <button
168
+ type="button"
169
+ class="btn btn--primary"
170
+ disabled={!canCreate}
171
+ onclick={handleSubmit}
172
+ >
173
+ {t(M['chat.room_create_dialog.create_room'])}
174
+ </button>
175
+ {/snippet}
176
+ </Modal>
200
177
 
201
178
  <style>
202
- .dialog-backdrop {
203
- position: fixed;
204
- inset: 0;
205
- background: var(--smrt-color-scrim, rgba(0, 0, 0, 0.32));
179
+ .dialog__form {
206
180
  display: flex;
207
- align-items: center;
208
- justify-content: center;
209
- padding: 1rem;
210
- z-index: var(--smrt-z-index-dialog, 1300);
211
- position: relative;
181
+ flex-direction: column;
182
+ gap: 1.25rem;
212
183
  }
213
184
 
214
- .dialog-backdrop__dismiss {
185
+ .visually-hidden {
215
186
  position: absolute;
216
- inset: 0;
187
+ width: 1px;
188
+ height: 1px;
217
189
  padding: 0;
190
+ margin: -1px;
191
+ overflow: hidden;
192
+ clip: rect(0, 0, 0, 0);
193
+ white-space: nowrap;
218
194
  border: 0;
219
- background: transparent;
220
- }
221
-
222
- .dialog {
223
- background: var(--smrt-color-surface, #fefbff);
224
- border-radius: var(--smrt-radius-extra-large, 28px);
225
- box-shadow: var(--smrt-elevation-3, 0 4px 8px 3px rgba(0, 0, 0, 0.15), 0 1px 3px rgba(0, 0, 0, 0.3));
226
- width: 100%;
227
- max-width: 32rem;
228
- padding: 1.5rem;
229
- max-height: calc(100vh - 2rem);
230
- overflow-y: auto;
231
- position: relative;
232
- z-index: 1;
233
- }
234
-
235
- .dialog__title {
236
- margin: 0 0 1.25rem;
237
- font: var(--smrt-typography-headline-small-font, 400 1.5rem / 2rem sans-serif);
238
- color: var(--smrt-color-on-surface, #1a1c1e);
239
- }
240
-
241
- .dialog__form {
242
- display: flex;
243
- flex-direction: column;
244
- gap: 1.25rem;
245
195
  }
246
196
 
247
197
  .field {
@@ -259,7 +209,7 @@ $effect(() => {
259
209
  }
260
210
 
261
211
  .field__required {
262
- color: var(--smrt-color-error, #ba1a1a);
212
+ color: var(--smrt-color-error, #b3261e);
263
213
  }
264
214
 
265
215
  .field__input {
@@ -351,13 +301,6 @@ $effect(() => {
351
301
  color: var(--smrt-color-on-surface-variant, #43474e);
352
302
  }
353
303
 
354
- .dialog__actions {
355
- display: flex;
356
- justify-content: flex-end;
357
- gap: 0.5rem;
358
- margin-top: 0.25rem;
359
- }
360
-
361
304
  .btn {
362
305
  display: inline-flex;
363
306
  align-items: center;
@@ -1 +1 @@
1
- {"version":3,"file":"RoomCreateDialog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/dialogs/RoomCreateDialog.svelte.ts"],"names":[],"mappings":"AAWA,MAAM,WAAW,KAAK;IACpB,iCAAiC;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,QAAQ,EAAE,CAAC,MAAM,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,KAAK,IAAI,CAAC;CACZ;AA8ID,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"RoomCreateDialog.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/dialogs/RoomCreateDialog.svelte.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,KAAK;IACpB,iCAAiC;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,mCAAmC;IACnC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,oCAAoC;IACpC,QAAQ,EAAE,CAAC,MAAM,EAAE;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,KAAK,IAAI,CAAC;CACZ;AAwHD,QAAA,MAAM,gBAAgB,2CAAwC,CAAC;AAC/D,KAAK,gBAAgB,GAAG,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAC5D,eAAe,gBAAgB,CAAC"}
@@ -20,12 +20,20 @@ export interface Props {
20
20
  currentProfileId: string;
21
21
  /** Callback when a room is selected */
22
22
  onselectroom: (roomId: string) => void;
23
+ /** Callback to open the create-room affordance in the room list */
24
+ oncreateroom?: () => void;
23
25
  /** Main content slot */
24
26
  children: Snippet;
25
27
  }
26
28
 
27
- let { rooms, currentRoomId, currentProfileId, onselectroom, children }: Props =
28
- $props();
29
+ let {
30
+ rooms,
31
+ currentRoomId,
32
+ currentProfileId,
33
+ onselectroom,
34
+ oncreateroom,
35
+ children,
36
+ }: Props = $props();
29
37
 
30
38
  let sidebarWidth = $state(260);
31
39
  let isResizing = $state(false);
@@ -60,6 +68,7 @@ function handlePointerUp() {
60
68
  {rooms}
61
69
  {currentRoomId}
62
70
  {onselectroom}
71
+ {oncreateroom}
63
72
  />
64
73
  </aside>
65
74
 
@@ -9,6 +9,8 @@ export interface Props {
9
9
  currentProfileId: string;
10
10
  /** Callback when a room is selected */
11
11
  onselectroom: (roomId: string) => void;
12
+ /** Callback to open the create-room affordance in the room list */
13
+ oncreateroom?: () => void;
12
14
  /** Main content slot */
13
15
  children: Snippet;
14
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ChatLayout.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/ChatLayout.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInD,MAAM,WAAW,KAAK;IACpB,2BAA2B;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,iCAAiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,wBAAwB;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAyDD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"ChatLayout.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/ChatLayout.svelte.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAInD,MAAM,WAAW,KAAK;IACpB,2BAA2B;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,iCAAiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,gBAAgB,EAAE,MAAM,CAAC;IACzB,uCAAuC;IACvC,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,wBAAwB;IACxB,QAAQ,EAAE,OAAO,CAAC;CACnB;AA+DD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -32,12 +32,14 @@ const offlineMembers = $derived(
32
32
 
33
33
  function getStatusColor(status: string): string {
34
34
  switch (status) {
35
+ // "online" reconciled to the success token (was --smrt-color-tertiary)
36
+ // so it matches UserPresence and stays semantically green (T2 #1391).
35
37
  case 'online':
36
- return 'var(--smrt-color-tertiary, #006c4f)';
38
+ return 'var(--smrt-color-success, #1e8e3e)';
37
39
  case 'away':
38
- return 'var(--smrt-color-warning, #f0a000)';
40
+ return 'var(--smrt-color-warning, #f9ab00)';
39
41
  case 'dnd':
40
- return 'var(--smrt-color-error, #ba1a1a)';
42
+ return 'var(--smrt-color-error, #b3261e)';
41
43
  default:
42
44
  return 'var(--smrt-color-outline, #74777f)';
43
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MemberList.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/MemberList.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,MAAM,WAAW,KAAK;IACpB,wBAAwB;IACxB,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,yCAAyC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAwLD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"MemberList.svelte.d.ts","sourceRoot":"","sources":["../../../../src/svelte/components/layout/MemberList.svelte.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,MAAM,WAAW,KAAK;IACpB,wBAAwB;IACxB,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,yCAAyC;IACzC,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA0LD,QAAA,MAAM,UAAU,2CAAwC,CAAC;AACzD,KAAK,UAAU,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAChD,eAAe,UAAU,CAAC"}
@@ -0,0 +1,67 @@
1
+ // @vitest-environment jsdom
2
+ /**
3
+ * Component coverage for ChatLayout via the shared S11 harness (#1416).
4
+ *
5
+ * Regression for T2 #1391: ChatLayout rendered RoomList but never forwarded
6
+ * `oncreateroom`, so the bundled layout's create-room affordance was dead.
7
+ * ChatLayout must now accept and forward `oncreateroom` to RoomList.
8
+ */
9
+ import { expectNoA11yViolations, render, screen, userEvent, } from '@happyvertical/smrt-vitest/svelte';
10
+ import { createRawSnippet } from 'svelte';
11
+ import { describe, expect, it, vi } from 'vitest';
12
+ import ChatLayout from '../ChatLayout.svelte';
13
+ const ROOMS = [
14
+ {
15
+ id: 'room-1',
16
+ name: 'General',
17
+ description: '',
18
+ roomType: 'public',
19
+ topic: '',
20
+ participantCount: 1,
21
+ unreadCount: 0,
22
+ },
23
+ ];
24
+ // Minimal main-content snippet for the required `children` prop.
25
+ const content = createRawSnippet(() => ({
26
+ render: () => '<div data-testid="main">Main content</div>',
27
+ }));
28
+ describe('ChatLayout', () => {
29
+ it('forwards oncreateroom to RoomList so the create affordance is wired', async () => {
30
+ const oncreateroom = vi.fn();
31
+ render(ChatLayout, {
32
+ props: {
33
+ rooms: ROOMS,
34
+ currentProfileId: 'p1',
35
+ onselectroom: vi.fn(),
36
+ oncreateroom,
37
+ children: content,
38
+ },
39
+ });
40
+ const createBtn = screen.getByRole('button', { name: 'Create new room' });
41
+ await userEvent.click(createBtn);
42
+ expect(oncreateroom).toHaveBeenCalledTimes(1);
43
+ });
44
+ it('omits the create affordance when no oncreateroom is supplied', () => {
45
+ render(ChatLayout, {
46
+ props: {
47
+ rooms: ROOMS,
48
+ currentProfileId: 'p1',
49
+ onselectroom: vi.fn(),
50
+ children: content,
51
+ },
52
+ });
53
+ expect(screen.queryByRole('button', { name: 'Create new room' })).toBeNull();
54
+ });
55
+ it('is axe-clean', async () => {
56
+ const { container } = render(ChatLayout, {
57
+ props: {
58
+ rooms: ROOMS,
59
+ currentProfileId: 'p1',
60
+ onselectroom: vi.fn(),
61
+ oncreateroom: vi.fn(),
62
+ children: content,
63
+ },
64
+ });
65
+ await expectNoA11yViolations(container);
66
+ });
67
+ });