Skip to content

Commit c4e57f8

Browse files
authored
Polish pass 4: message overlap, fonts, header line, dropdown width (#422)
* fix(chat): drop absolute positioning on chat-message controls * feat(chat): unify sidenav action button font family + size * feat(chat): drop top border above New chat (remove sidenav header underline) * feat(demo): widen More prompts dropdown menu to fit long labels * chore(release): bump publishable libs to 0.0.40
1 parent bc2b8b3 commit c4e57f8

15 files changed

Lines changed: 107 additions & 15 deletions

examples/chat/angular/src/app/modes/welcome-suggestions.component.spec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ describe('WelcomeSuggestionsComponent', () => {
5252
expect(captured).toBe(FEATURED_SUGGESTIONS[0].value);
5353
});
5454

55+
// JSDOM does not cascade ::ng-deep overrides from Angular component <style>
56+
// tags, so we assert against the component's compiled styles string instead
57+
// of relying on getComputedStyle — same approach used for border-width above.
58+
it('widens the More prompts dropdown menu in the component styles', () => {
59+
const cls: any = WelcomeSuggestionsComponent;
60+
const styles = ((cls['ɵcmp'] as { styles?: string[] })?.styles ?? []).join(' ');
61+
expect(styles).toMatch(/chat-select__menu[^}]*min-width:\s*320px/);
62+
expect(styles).toMatch(/chat-select__menu[^}]*max-width:\s*480px/);
63+
});
64+
5565
it('overrides the More prompts trigger to match the featured chip styling', () => {
5666
// The component's styles block must include ::ng-deep overrides for the
5767
// chat-select trigger so it visually matches chat-welcome-suggestion.

examples/chat/angular/src/app/modes/welcome-suggestions.component.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ import { FEATURED_SUGGESTIONS, MORE_SUGGESTIONS } from './welcome-suggestions';
7575
border-color: var(--ngaf-chat-text-muted);
7676
color: var(--ngaf-chat-text);
7777
}
78+
.welcome-suggestions__row ::ng-deep chat-select .chat-select__menu {
79+
min-width: 320px;
80+
max-width: 480px;
81+
width: max-content;
82+
}
7883
`,
7984
],
8085
})

libs/a2ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ngaf/a2ui",
3-
"version": "0.0.39",
3+
"version": "0.0.40",
44
"license": "MIT",
55
"repository": {
66
"type": "git",

libs/ag-ui/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ngaf/ag-ui",
3-
"version": "0.0.39",
3+
"version": "0.0.40",
44
"peerDependencies": {
55
"@ngaf/chat": "*",
66
"@ngaf/licensing": "*",

libs/chat/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ngaf/chat",
3-
"version": "0.0.39",
3+
"version": "0.0.40",
44
"exports": {
55
".": {
66
"types": "./index.d.ts",
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// libs/chat/src/lib/styles/chat-message.styles.spec.ts
2+
// SPDX-License-Identifier: MIT
3+
import { describe, it, expect } from 'vitest';
4+
import { CHAT_MESSAGE_STYLES } from './chat-message.styles';
5+
6+
describe('CHAT_MESSAGE_STYLES — controls positioning', () => {
7+
const normalized = CHAT_MESSAGE_STYLES.replace(/\s+/g, ' ');
8+
it('does NOT absolute-position the actions controls (so they flow inside .chat-message__main, indented past the gutter)', () => {
9+
expect(normalized).not.toMatch(
10+
/\.chat-message__controls\s*\{[^}]*position:\s*absolute/,
11+
);
12+
});
13+
it('does NOT pin the controls to a negative bottom offset (would overlap with the next message)', () => {
14+
expect(normalized).not.toMatch(
15+
/\.chat-message__controls\s*\{[^}]*bottom:\s*-/,
16+
);
17+
});
18+
});

libs/chat/src/lib/styles/chat-message.styles.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ export const CHAT_MESSAGE_STYLES = `
9090
9191
.chat-message__controls {
9292
display: none;
93-
position: absolute;
94-
left: 0;
95-
bottom: -28px;
9693
gap: 1rem;
9794
opacity: 0;
9895
transition: opacity 200ms ease;

libs/chat/src/lib/styles/chat-project-list.styles.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,28 @@ describe('CHAT_PROJECT_LIST_STYLES — New project button', () => {
4242
});
4343
});
4444

45+
describe('CHAT_PROJECT_LIST_STYLES — New project button font', () => {
46+
const normalized = CHAT_PROJECT_LIST_STYLES.replace(/\s+/g, ' ');
47+
48+
it('uses font-family: inherit (matches sidenav action buttons)', () => {
49+
expect(normalized).toMatch(
50+
/\.chat-project-list__new\s*\{[^}]*font-family:\s*inherit\s*;/,
51+
);
52+
});
53+
54+
it('uses font-size: var(--ngaf-chat-font-size-sm) (not hard-coded 12px)', () => {
55+
expect(normalized).toMatch(
56+
/\.chat-project-list__new\s*\{[^}]*font-size:\s*var\(--ngaf-chat-font-size-sm\)\s*;/,
57+
);
58+
});
59+
60+
it('does NOT use hard-coded 12px for font-size', () => {
61+
expect(normalized).not.toMatch(
62+
/\.chat-project-list__new\s*\{[^}]*font-size:\s*12px/,
63+
);
64+
});
65+
});
66+
4567
describe('CHAT_PROJECT_LIST_STYLES — active item', () => {
4668
const normalized = CHAT_PROJECT_LIST_STYLES.replace(/\s+/g, ' ');
4769
it('does NOT use a left-accent box-shadow for the active item (symmetric bg-only indication)', () => {

libs/chat/src/lib/styles/chat-project-list.styles.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ export const CHAT_PROJECT_LIST_STYLES = `
7979
border: 0;
8080
padding: 10px 16px;
8181
border-radius: 8px;
82-
font-size: 12px;
82+
font-family: inherit;
83+
font-size: var(--ngaf-chat-font-size-sm);
84+
font-weight: 400;
8385
display: flex;
8486
align-items: center;
8587
gap: 8px;

libs/chat/src/lib/styles/chat-sidenav.styles.spec.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,43 @@ describe('CHAT_SIDENAV_STYLES — New chat button', () => {
4242
});
4343
});
4444

45+
describe('CHAT_SIDENAV_STYLES — header chrome', () => {
46+
const normalized = CHAT_SIDENAV_STYLES.replace(/\s+/g, ' ');
47+
it('does NOT draw a border-bottom on .chat-sidenav__header (removes the line above New chat)', () => {
48+
expect(normalized).not.toMatch(
49+
/\.chat-sidenav__header\s*\{[^}]*border-bottom:/,
50+
);
51+
});
52+
});
53+
54+
describe('CHAT_SIDENAV_STYLES — action button font', () => {
55+
const normalized = CHAT_SIDENAV_STYLES.replace(/\s+/g, ' ');
56+
57+
it('generic .chat-sidenav__action has font-family: inherit', () => {
58+
expect(normalized).toMatch(
59+
/\.chat-sidenav__action\s*\{[^}]*font-family:\s*inherit\s*;/,
60+
);
61+
});
62+
63+
it('generic .chat-sidenav__action has font-size: var(--ngaf-chat-font-size-sm)', () => {
64+
expect(normalized).toMatch(
65+
/\.chat-sidenav__action\s*\{[^}]*font-size:\s*var\(--ngaf-chat-font-size-sm\)\s*;/,
66+
);
67+
});
68+
69+
it('late-cascade New chat uses font-size: var(--ngaf-chat-font-size-sm) (not 13px)', () => {
70+
expect(normalized).toMatch(
71+
/\.chat-sidenav__action\.chat-sidenav__action--new\s*\{[^}]*font-size:\s*var\(--ngaf-chat-font-size-sm\)\s*;/,
72+
);
73+
});
74+
75+
it('does NOT use hard-coded 13px for New chat font-size', () => {
76+
expect(normalized).not.toMatch(
77+
/\.chat-sidenav__action\.chat-sidenav__action--new\s*\{[^}]*font-size:\s*13px/,
78+
);
79+
});
80+
});
81+
4582
describe('CHAT_SIDENAV_STYLES — Archived disclosure', () => {
4683
const normalized = CHAT_SIDENAV_STYLES.replace(/\s+/g, ' ');
4784

0 commit comments

Comments
 (0)