@copilotkit/react-ui 1.66.3 → 1.67.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.
- package/dist/index.cjs +6 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +27 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +21 -2
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +21 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +6 -2
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +6 -2
- package/dist/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/components/chat/Sidebar.tsx +30 -2
- package/src/components/chat/index.tsx +1 -0
- package/src/css/sidebar-full-height.test.ts +59 -0
- package/src/css/sidebar.css +27 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@copilotkit/react-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.67.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -49,9 +49,9 @@
|
|
|
49
49
|
"rehype-sanitize": "^6.0.0",
|
|
50
50
|
"remark-gfm": "^4.0.1",
|
|
51
51
|
"remark-math": "^6.0.0",
|
|
52
|
-
"@copilotkit/react-core": "1.
|
|
53
|
-
"@copilotkit/
|
|
54
|
-
"@copilotkit/
|
|
52
|
+
"@copilotkit/react-core": "1.67.0",
|
|
53
|
+
"@copilotkit/runtime-client-gql": "1.67.0",
|
|
54
|
+
"@copilotkit/shared": "1.67.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/react": "^19.1.0",
|
|
@@ -64,8 +64,8 @@
|
|
|
64
64
|
"tsdown": "^0.20.3",
|
|
65
65
|
"typescript": "^5.2.3",
|
|
66
66
|
"vitest": "^3.2.4",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
67
|
+
"tsconfig": "1.4.12",
|
|
68
|
+
"tailwind-config": "1.4.12"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"react": "^18 || ^19 || ^19.0.0-rc"
|
|
@@ -72,7 +72,27 @@ import React, { useState } from "react";
|
|
|
72
72
|
import type { CopilotModalProps } from "./Modal";
|
|
73
73
|
import { CopilotModal } from "./Modal";
|
|
74
74
|
|
|
75
|
-
export
|
|
75
|
+
export interface CopilotSidebarProps extends CopilotModalProps {
|
|
76
|
+
/**
|
|
77
|
+
* Make the sidebar's content wrapper exactly one viewport tall, so children
|
|
78
|
+
* can use `height: 100%` (or `flex: 1`) to fill the screen.
|
|
79
|
+
*
|
|
80
|
+
* Off by default: the wrappers are auto-height, so page content flows
|
|
81
|
+
* normally and percentage heights on children collapse to content height.
|
|
82
|
+
*
|
|
83
|
+
* ```tsx
|
|
84
|
+
* <CopilotSidebar fullHeightChildren>
|
|
85
|
+
* <div style={{ height: "100%" }}>...</div>
|
|
86
|
+
* </CopilotSidebar>
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
fullHeightChildren?: boolean;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function CopilotSidebar({
|
|
93
|
+
fullHeightChildren = false,
|
|
94
|
+
...props
|
|
95
|
+
}: CopilotSidebarProps) {
|
|
76
96
|
props = {
|
|
77
97
|
...props,
|
|
78
98
|
className: props.className
|
|
@@ -88,8 +108,16 @@ export function CopilotSidebar(props: CopilotModalProps) {
|
|
|
88
108
|
setExpandedClassName(open ? "sidebarExpanded" : "");
|
|
89
109
|
};
|
|
90
110
|
|
|
111
|
+
const contentWrapperClassName = [
|
|
112
|
+
"copilotKitSidebarContentWrapper",
|
|
113
|
+
expandedClassName,
|
|
114
|
+
fullHeightChildren ? "copilotKitSidebarFullHeightChildren" : "",
|
|
115
|
+
]
|
|
116
|
+
.filter(Boolean)
|
|
117
|
+
.join(" ");
|
|
118
|
+
|
|
91
119
|
return (
|
|
92
|
-
<div className={
|
|
120
|
+
<div className={contentWrapperClassName}>
|
|
93
121
|
<CopilotModal {...props} {...{ onSetOpen }}>
|
|
94
122
|
{props.children}
|
|
95
123
|
</CopilotModal>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./props";
|
|
2
2
|
export { CopilotPopup } from "./Popup";
|
|
3
3
|
export { CopilotSidebar } from "./Sidebar";
|
|
4
|
+
export type { CopilotSidebarProps } from "./Sidebar";
|
|
4
5
|
export { CopilotChat } from "./Chat";
|
|
5
6
|
export { CopilotModal } from "./Modal";
|
|
6
7
|
export type { CopilotModalProps } from "./Modal";
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
|
|
5
|
+
const sidebarCss = fs.readFileSync(
|
|
6
|
+
path.resolve(__dirname, "sidebar.css"),
|
|
7
|
+
"utf-8",
|
|
8
|
+
);
|
|
9
|
+
const sidebarTsx = fs.readFileSync(
|
|
10
|
+
path.resolve(__dirname, "../components/chat/Sidebar.tsx"),
|
|
11
|
+
"utf-8",
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Regression guard for #261: children of `CopilotSidebar` could not use
|
|
16
|
+
* `height: 100%`, because both wrappers around them are auto-height blocks.
|
|
17
|
+
* The fix is opt-in, so the guard has two halves — the escape hatch works,
|
|
18
|
+
* and it stays off for everyone who didn't ask for it.
|
|
19
|
+
*/
|
|
20
|
+
describe("sidebar full-height children opt-in", () => {
|
|
21
|
+
const fullHeightRule =
|
|
22
|
+
/\.copilotKitSidebarContentWrapper\.copilotKitSidebarFullHeightChildren\s*\{([^}]*)\}/;
|
|
23
|
+
const childrenWrapperRule =
|
|
24
|
+
/\.copilotKitSidebarContentWrapper\.copilotKitSidebarFullHeightChildren\s*>\s*\.copilotKitModalChildrenWrapper\s*\{([^}]*)\}/;
|
|
25
|
+
|
|
26
|
+
it("gives the content wrapper a definite height children can resolve against", () => {
|
|
27
|
+
const [, body] = sidebarCss.match(fullHeightRule) ?? [];
|
|
28
|
+
expect(body).toBeDefined();
|
|
29
|
+
expect(body).toContain("display: flex");
|
|
30
|
+
expect(body).toContain("flex-direction: column");
|
|
31
|
+
// A viewport unit, not `100%` — `100%` would silently no-op in any app
|
|
32
|
+
// that doesn't declare a height on html/body/#root.
|
|
33
|
+
expect(body).toContain("height: 100dvh");
|
|
34
|
+
expect(body).toContain("height: 100vh");
|
|
35
|
+
expect(body).not.toMatch(/height:\s*100%/);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it("lets the children wrapper fill that height without a flex min-height floor", () => {
|
|
39
|
+
const [, body] = sidebarCss.match(childrenWrapperRule) ?? [];
|
|
40
|
+
expect(body).toBeDefined();
|
|
41
|
+
expect(body).toContain("flex: 1 1 auto");
|
|
42
|
+
expect(body).toContain("min-height: 0");
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("leaves the default content wrapper auto-height", () => {
|
|
46
|
+
const [, base] =
|
|
47
|
+
sidebarCss.match(/\.copilotKitSidebarContentWrapper\s*\{([^}]*)\}/) ?? [];
|
|
48
|
+
expect(base).toBeDefined();
|
|
49
|
+
expect(base).not.toContain("height");
|
|
50
|
+
expect(base).not.toContain("display");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("applies the modifier class only when fullHeightChildren is set", () => {
|
|
54
|
+
expect(sidebarTsx).toContain("fullHeightChildren = false");
|
|
55
|
+
expect(sidebarTsx).toMatch(
|
|
56
|
+
/fullHeightChildren\s*\?\s*"copilotKitSidebarFullHeightChildren"\s*:\s*""/,
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
});
|
package/src/css/sidebar.css
CHANGED
|
@@ -44,3 +44,30 @@
|
|
|
44
44
|
margin-right: 28rem;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
|
|
48
|
+
/*
|
|
49
|
+
* Opt-in (via the `fullHeightChildren` prop on `CopilotSidebar`): let children
|
|
50
|
+
* of the sidebar use `height: 100%`.
|
|
51
|
+
*
|
|
52
|
+
* By default both wrappers CopilotSidebar puts around your app are auto-height
|
|
53
|
+
* blocks, so a percentage height on a child has no definite containing block to
|
|
54
|
+
* resolve against and collapses to content height.
|
|
55
|
+
*
|
|
56
|
+
* The viewport unit is deliberate: `height: 100%` here would only resolve if
|
|
57
|
+
* every ancestor (html/body/#root) also declared a height, which react-ui
|
|
58
|
+
* neither sets nor can guarantee. `min-height: 0` on the children wrapper
|
|
59
|
+
* overrides the flex-item `min-height: auto` default so tall content scrolls
|
|
60
|
+
* inside the child instead of stretching the wrapper past the viewport.
|
|
61
|
+
*/
|
|
62
|
+
.copilotKitSidebarContentWrapper.copilotKitSidebarFullHeightChildren {
|
|
63
|
+
display: flex;
|
|
64
|
+
flex-direction: column;
|
|
65
|
+
height: 100vh;
|
|
66
|
+
height: 100dvh;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.copilotKitSidebarContentWrapper.copilotKitSidebarFullHeightChildren
|
|
70
|
+
> .copilotKitModalChildrenWrapper {
|
|
71
|
+
flex: 1 1 auto;
|
|
72
|
+
min-height: 0;
|
|
73
|
+
}
|