Skip to content

Commit d1dcfaa

Browse files
authored
Demo: full-width top toolbar + forward chatWelcomeSuggestions to sidebar/popup (#455)
* feat(chat): forward chatWelcomeSuggestions slot from chat-sidebar + chat-popup * feat(demo): full-width toolbar at top, push fixed chrome below it * chore(release): bump publishable libs to 0.0.41 * fix(demo): collapse chat-sidebar host in sidebar mode, constrain sidenav height Three fixes that together eliminate the /sidebar overflow + close-button occlusion the user reported after PR #444's full-width toolbar landed: 1. chat-sidebar's only visible chrome is position: fixed (panel + launcher). Set its host to display: contents in sidebar-mode so it drops from the layout flow and doesn't stack below .sidebar-mode__background. 2. The chat-sidebar default content slot (.chat-sidebar__content) has min-height: 100vh — meant for push-mode consumers' page content. The demo doesn't use that slot; display: none on it here, so it doesn't add a second 100vh row to the demo's main column. 3. chat-sidenav's host has height: 100% plus position: fixed and bottom: 0. With our top: var(--demo-toolbar-height) override, the explicit height kept the sidenav at full viewport (extending ~51px past the bottom). Clamp it to calc(100% - var(--demo-toolbar-height)).
1 parent e86a882 commit d1dcfaa

12 files changed

Lines changed: 95 additions & 60 deletions

File tree

examples/chat/angular/src/app/modes/sidebar-mode.component.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,25 @@ import { WelcomeSuggestionsComponent } from './welcome-suggestions.component';
3030
</chat-sidebar>
3131
`,
3232
styles: [`
33-
:host { display: block; flex: 1; min-height: 0; }
33+
/* chat-sidebar's visible chrome is position: fixed (panel + launcher),
34+
* so its host element doesn't need to take layout space. Use
35+
* display: contents on the host to drop it from the flow, and let
36+
* the sibling .sidebar-mode__background fill the visible area. */
37+
:host { display: block; flex: 1; min-height: 0; position: relative; }
3438
.sidebar-mode__background {
3539
display: grid;
3640
place-items: center;
3741
height: 100%;
3842
color: #8a92a3;
3943
font-size: 14px;
4044
}
45+
:host ::ng-deep > chat-sidebar { display: contents; }
46+
/* The chat-sidebar default content slot (.chat-sidebar__content) is
47+
* meant for the consumer's page content when chat-sidebar is in
48+
* push mode. The demo uses .sidebar-mode__background instead, so
49+
* hide the default content slot — its min-height: 100vh would
50+
* otherwise stack below the background and overflow the page. */
51+
:host ::ng-deep .chat-sidebar__content { display: none; }
4152
`],
4253
})
4354
export class SidebarMode {

examples/chat/angular/src/app/shell/demo-shell.component.css

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55

66
.demo-shell {
77
position: relative;
8-
display: block;
8+
display: flex;
9+
flex-direction: column;
910
height: 100%;
11+
/* Publish the toolbar height as a CSS var so fixed-position overlays
12+
* (chat-sidenav, chat-sidebar panel) can clear it. */
13+
--demo-toolbar-height: 51px;
1014
}
1115

1216
.demo-shell__hamburger {
@@ -34,7 +38,8 @@
3438
}
3539

3640
.demo-shell__main {
37-
height: 100%;
41+
flex: 1;
42+
min-height: 0;
3843
transition: padding-left 200ms ease;
3944
padding-left: 0;
4045
display: flex;
@@ -177,3 +182,20 @@
177182
background: var(--ngaf-chat-surface-alt);
178183
color: var(--ngaf-chat-text);
179184
}
185+
186+
/* The toolbar is full-width at the top of the page. Fixed-position
187+
* chrome (chat-sidenav, chat-sidebar panel) lives at top:0 by default
188+
* — push them down by the toolbar height so they don't render
189+
* underneath. Scoped to .demo-shell so the chat library's own
190+
* positioning is unchanged for consumers without a top toolbar. */
191+
.demo-shell ::ng-deep chat-sidenav {
192+
top: var(--demo-toolbar-height);
193+
/* chat-sidenav has `height: 100%` on :host plus position: fixed + bottom: 0.
194+
* With our top override the explicit height "wins" and the sidenav extends
195+
* past the viewport (top + 100% > 100vh). Constrain the height to the
196+
* viewport minus the toolbar. */
197+
height: calc(100% - var(--demo-toolbar-height));
198+
}
199+
.demo-shell ::ng-deep .chat-sidebar__panel {
200+
top: var(--demo-toolbar-height);
201+
}

examples/chat/angular/src/app/shell/demo-shell.component.html

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,56 @@
99
></button>
1010
}
1111

12+
<div class="demo-shell__toolbar" role="toolbar" aria-label="Demo controls">
13+
<div class="demo-shell__segmented" aria-label="Mode">
14+
@for (option of modeOptions; track option.value) {
15+
<button
16+
type="button"
17+
class="demo-shell__segmented-button"
18+
[class.is-active]="mode() === option.value"
19+
[attr.aria-pressed]="mode() === option.value"
20+
(click)="onModeChange(option.value)"
21+
>{{ option.label }}</button>
22+
}
23+
</div>
24+
25+
<div class="demo-shell__field demo-shell__field--first" data-field="model">
26+
<chat-select
27+
[options]="modelOptions()"
28+
[value]="model()"
29+
menuLabel="Model"
30+
(valueChange)="onModelChange($event)"
31+
/>
32+
</div>
33+
34+
<div class="demo-shell__field" data-field="effort">
35+
<chat-select
36+
[options]="effortOptions()"
37+
[value]="effort()"
38+
menuLabel="Effort"
39+
(valueChange)="onEffortChange($event)"
40+
/>
41+
</div>
42+
43+
<div class="demo-shell__field" data-field="genui">
44+
<chat-select
45+
[options]="genUiOptions()"
46+
[value]="genUiMode()"
47+
menuLabel="Gen UI"
48+
(valueChange)="onGenUiModeChange($event)"
49+
/>
50+
</div>
51+
52+
<div class="demo-shell__field" data-field="theme">
53+
<chat-select
54+
[options]="themeOptions()"
55+
[value]="theme()"
56+
menuLabel="Theme"
57+
(valueChange)="onThemeChange($event)"
58+
/>
59+
</div>
60+
</div>
61+
1262
<chat-sidenav
1363
[threads]="visibleThreads()"
1464
[archivedThreads]="threadsSvc.archivedThreads()"
@@ -62,56 +112,6 @@
62112
class="demo-shell__main"
63113
[attr.data-sidenav-mode]="sidenavMode() !== 'drawer' ? sidenavMode() : null"
64114
>
65-
<div class="demo-shell__toolbar" role="toolbar" aria-label="Demo controls">
66-
<div class="demo-shell__segmented" aria-label="Mode">
67-
@for (option of modeOptions; track option.value) {
68-
<button
69-
type="button"
70-
class="demo-shell__segmented-button"
71-
[class.is-active]="mode() === option.value"
72-
[attr.aria-pressed]="mode() === option.value"
73-
(click)="onModeChange(option.value)"
74-
>{{ option.label }}</button>
75-
}
76-
</div>
77-
78-
<div class="demo-shell__field demo-shell__field--first" data-field="model">
79-
<chat-select
80-
[options]="modelOptions()"
81-
[value]="model()"
82-
menuLabel="Model"
83-
(valueChange)="onModelChange($event)"
84-
/>
85-
</div>
86-
87-
<div class="demo-shell__field" data-field="effort">
88-
<chat-select
89-
[options]="effortOptions()"
90-
[value]="effort()"
91-
menuLabel="Effort"
92-
(valueChange)="onEffortChange($event)"
93-
/>
94-
</div>
95-
96-
<div class="demo-shell__field" data-field="genui">
97-
<chat-select
98-
[options]="genUiOptions()"
99-
[value]="genUiMode()"
100-
menuLabel="Gen UI"
101-
(valueChange)="onGenUiModeChange($event)"
102-
/>
103-
</div>
104-
105-
<div class="demo-shell__field" data-field="theme">
106-
<chat-select
107-
[options]="themeOptions()"
108-
[value]="theme()"
109-
menuLabel="Theme"
110-
(valueChange)="onThemeChange($event)"
111-
/>
112-
</div>
113-
</div>
114-
115115
<router-outlet />
116116
@if (agent.interrupt && agent.interrupt()) {
117117
<div class="demo-shell__interrupt-panel" role="region" aria-label="Approval required">

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.40",
3+
"version": "0.0.41",
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.40",
3+
"version": "0.0.41",
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.40",
3+
"version": "0.0.41",
44
"exports": {
55
"./chat.css": "./chat.css",
66
"./themes/default-dark.css": "./themes/default-dark.css",

libs/chat/src/lib/compositions/chat-popup/chat-popup.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ import { CHAT_HOST_TOKENS, ensureChatRootStyles } from '../../styles/chat-tokens
7575
(forkRequested)="forkRequested.emit($event)"
7676
>
7777
<ng-content select="[chatHeader]" chatHeader />
78+
<ng-content select="[chatWelcomeSuggestions]" chatWelcomeSuggestions />
7879
</chat>
7980
</div>
8081
`,

libs/chat/src/lib/compositions/chat-sidebar/chat-sidebar.component.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ import { CHAT_HOST_TOKENS, ensureChatRootStyles } from '../../styles/chat-tokens
9292
(forkRequested)="forkRequested.emit($event)"
9393
>
9494
<ng-content select="[chatHeader]" chatHeader />
95+
<ng-content select="[chatWelcomeSuggestions]" chatWelcomeSuggestions />
9596
</chat>
9697
</aside>
9798
`,

libs/langgraph/package.json

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

libs/licensing/package.json

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

0 commit comments

Comments
 (0)