@box-kite/react 2.0.0 → 2.1.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/.claude/rules/box-kite-rules.md +16 -0
- package/.claude/skills/box-kite/SKILL.md +16 -0
- package/.claude/skills/box-kite/references/components.md +8 -3
- package/.claude/skills/box-kite/references/patterns.md +23 -0
- package/.cursor/rules/box-kite.mdc +16 -0
- package/AGENTS.md +19 -0
- package/BOX_AI_CONTEXT.md +562 -1
- package/BOX_KITE_AI_CONTEXT.md +562 -1
- package/README.md +39 -7
- package/catalog.cjs +1 -0
- package/catalog.d.ts +8 -0
- package/catalog.mjs +2333 -0
- package/client.cjs +1 -1
- package/client.mjs +40 -42
- package/components/agent.cjs +1 -0
- package/components/agent.d.ts +215 -0
- package/components/agent.mjs +405 -0
- package/components/chart.d.ts +1 -0
- package/components/dashboard.cjs +1 -0
- package/components/dashboard.d.ts +121 -0
- package/components/dashboard.mjs +690 -0
- package/components/dataGrid/components/dataGridBody.d.ts +2 -1
- package/components/dataGrid/components/dataGridDetailRow.d.ts +13 -2
- package/components/dataGrid/components/dataGridGroupRow.d.ts +13 -2
- package/components/dataGrid/components/dataGridRow.d.ts +13 -2
- package/components/dataGrid/contracts/dataGridContract.d.ts +66 -2
- package/components/dataGrid/models/cellModel.d.ts +3 -0
- package/components/dataGrid/models/editModel.d.ts +27 -0
- package/components/dataGrid/models/exportModel.d.ts +2 -1
- package/components/dataGrid/models/gridModel.d.ts +3 -0
- package/components/dataGrid/models/rangeModel.d.ts +119 -0
- package/components/dataGrid/models/viewportModel.d.ts +23 -2
- package/components/dataGrid/useGridNavigation.d.ts +10 -2
- package/components/dataGrid.cjs +4 -1
- package/components/dataGrid.d.ts +3 -0
- package/components/dataGrid.mjs +1056 -765
- package/components/markdown.cjs +1 -0
- package/components/markdown.d.ts +55 -0
- package/components/markdown.mjs +179 -0
- package/components/semantics.d.ts +29 -29
- package/components/skeleton.cjs +1 -0
- package/components/skeleton.d.ts +34 -0
- package/components/skeleton.mjs +25 -0
- package/dashboardSchema.cjs +1 -0
- package/dashboardSchema.mjs +78 -0
- package/docs/a11y.md +2 -3
- package/docs/catalog.md +451 -0
- package/docs/components.md +4 -0
- package/docs/index.md +3 -0
- package/docs/interop.md +237 -0
- package/docs/mcp.md +69 -0
- package/docs/props.md +3 -3
- package/interop.cjs +1 -0
- package/interop.d.ts +51 -0
- package/interop.mjs +454 -0
- package/mcp/src/data.d.ts +88 -0
- package/mcp/src/data.test.d.ts +1 -0
- package/mcp/src/engine.d.ts +23 -0
- package/mcp/src/index.d.ts +1 -0
- package/mcp/src/search.d.ts +26 -0
- package/mcp/src/search.test.d.ts +1 -0
- package/mcp/src/server.d.ts +18 -0
- package/mcp/src/server.test.d.ts +1 -0
- package/mcp/src/styles.d.ts +27 -0
- package/mcp/src/styles.test.d.ts +1 -0
- package/mcp/src/tools.d.ts +18 -0
- package/mcp/src/vocabulary.d.ts +41 -0
- package/package.json +124 -17
- package/react/spec/renderSpec.d.ts +51 -0
- package/react/spec/specBoundary.d.ts +25 -0
- package/react/spec/specRegistry.d.ts +42 -0
- package/react/spec/specRenderer.d.ts +10 -0
- package/registry/blocks/dashboard-shell/dashboard-shell.d.ts +22 -0
- package/registry/blocks/dashboard-shell/dashboard-stats.d.ts +13 -0
- package/registry/blocks/data-grid/invoice-rows.d.ts +15 -0
- package/registry/blocks/data-grid/invoices-grid.d.ts +1 -0
- package/registry/blocks/settings-form/settings-form.d.ts +17 -0
- package/spec.cjs +2 -0
- package/spec.d.ts +12 -0
- package/spec.mjs +382 -0
- package/specData.cjs +1 -0
- package/specData.mjs +69 -0
- package/specDefs.cjs +1 -0
- package/specDefs.mjs +33 -0
- package/specSchema.cjs +1 -0
- package/specSchema.mjs +88 -0
- package/utils/agent/agentUtils.d.ts +81 -0
- package/utils/catalog/catalogContracts.d.ts +19 -0
- package/utils/catalog/catalogManifest.d.ts +8 -0
- package/utils/dashboard/dashboardSchema.d.ts +18 -0
- package/utils/dashboard/dashboardUtils.d.ts +97 -0
- package/utils/interop/a2uiInterop.d.ts +82 -0
- package/utils/interop/assistantUiInterop.d.ts +34 -0
- package/utils/interop/toolInterop.d.ts +30 -0
- package/utils/spec/specData.d.ts +19 -0
- package/utils/spec/specDefs.d.ts +11 -0
- package/utils/spec/specProps.d.ts +15 -0
- package/utils/spec/specSchema.d.ts +23 -0
- package/utils/spec/specTypes.d.ts +71 -0
- package/utils/spec/specValidate.d.ts +10 -0
package/client.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs"),n=require("./platform.cjs"),r=require("./effects.cjs"),i=require("./box.cjs");let a=require("react");a=e.t(a,1);let o=require("@box-kite/core"),s=require("react/jsx-runtime");function c(e){let{node:t=null,event:r=`click`,hideOnScroll:i=!1,hideOnResize:o=!1,hideOnEscape:s=!0}=e??{},[c,l]=(0,a.useState)(!1),u=(0,a.useRef)(null);return(0,a.useEffect)(()=>{function e(e){let r=t??u.current;r&&!n.l(e,[r])&&l(!1)}function a(){l(!1)}function d(e){e.key===`Escape`&&l(!1)}let f=new AbortController;return c&&(window.addEventListener(r,e,f),s&&window.addEventListener(`keydown`,d,f),o&&window.addEventListener(`resize`,a,f),i&&window.addEventListener(`scroll`,e,{signal:f.signal,capture:!0})),()=>{f.abort()}},[t,c,r,s,o,i]),[c,l,u]}var l=r.t;function u(e,n){let{classNames:r,signature:i,styleElements:a}=t.l(e,n);return l(()=>{(0,o.getDefaultEngine)().flushSync()},[i??e]),{classNames:r,styleElements:a}}function d(e,n){let r=e?(0,o.getDefaultEngine)().addGlobalStyles(e,n):void 0;return l(()=>{(0,o.getDefaultEngine)().flushSync()},[e,n]),t.u(r)}var f;(function(e){function t(){(0,o.getDefaultEngine)().flushSync()}e.flushSync=t;function n(){(0,o.getDefaultEngine)().clear()}e.clear=n;function r(){return(0,o.getDefaultEngine)().getStyles()}e.getStyles=r;function i(){return(0,o.getDefaultEngine)().styleElementId}e.styleElementId=i;function a(e){(0,o.getDefaultEngine)().configure(e)}e.configure=a})(f||={});var p=`[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19`;function m(e){if(typeof e.createContext!=`function`)throw Error(p)}m(a.default);var h=a.default.createContext({theme:``,setTheme:()=>{}});function g(e){let{children:t,theme:n,use:r=`local`,storageKey:c,globalStyles:l}=e,u=d(r===`global`?l:void 0,`html`),[f,p]=(0,a.useState)(n??o.defaultThemeName),[m,g]=(0,a.useState)(n!==void 0),_=(0,a.
|
|
1
|
+
const e=require("./rolldown-runtime.cjs"),t=require("./react-shared.cjs"),n=require("./platform.cjs"),r=require("./effects.cjs"),i=require("./box.cjs");let a=require("react");a=e.t(a,1);let o=require("@box-kite/core"),s=require("react/jsx-runtime");function c(e){let{node:t=null,event:r=`click`,hideOnScroll:i=!1,hideOnResize:o=!1,hideOnEscape:s=!0}=e??{},[c,l]=(0,a.useState)(!1),u=(0,a.useRef)(null);return(0,a.useEffect)(()=>{function e(e){let r=t??u.current;r&&!n.l(e,[r])&&l(!1)}function a(){l(!1)}function d(e){e.key===`Escape`&&l(!1)}let f=new AbortController;return c&&(window.addEventListener(r,e,f),s&&window.addEventListener(`keydown`,d,f),o&&window.addEventListener(`resize`,a,f),i&&window.addEventListener(`scroll`,e,{signal:f.signal,capture:!0})),()=>{f.abort()}},[t,c,r,s,o,i]),[c,l,u]}var l=r.t;function u(e,n){let{classNames:r,signature:i,styleElements:a}=t.l(e,n);return l(()=>{(0,o.getDefaultEngine)().flushSync()},[i??e]),{classNames:r,styleElements:a}}function d(e,n){let r=e?(0,o.getDefaultEngine)().addGlobalStyles(e,n):void 0;return l(()=>{(0,o.getDefaultEngine)().flushSync()},[e,n]),t.u(r)}var f;(function(e){function t(){(0,o.getDefaultEngine)().flushSync()}e.flushSync=t;function n(){(0,o.getDefaultEngine)().clear()}e.clear=n;function r(){return(0,o.getDefaultEngine)().getStyles()}e.getStyles=r;function i(){return(0,o.getDefaultEngine)().styleElementId}e.styleElementId=i;function a(e){(0,o.getDefaultEngine)().configure(e)}e.configure=a})(f||={});var p=`[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19`;function m(e){if(typeof e.createContext!=`function`)throw Error(p)}m(a.default);var h=a.default.createContext({theme:``,setTheme:()=>{}});function g(e){let{children:t,theme:n,use:r=`local`,storageKey:c,globalStyles:l}=e,u=d(r===`global`?l:void 0,`html`),[f,p]=(0,a.useState)(n??o.defaultThemeName),[m,g]=(0,a.useState)(n!==void 0),_=(0,a.useCallback)(e=>{e===null?(c&&(0,o.clearStoredTheme)(c),g(!1)):(c&&(0,o.writeStoredTheme)(c,e),p(e),g(!0))},[c]),[v,y]=(0,a.useState)(n);return n!==v&&(y(n),n===void 0?g(!1):(p(n),g(!0))),(0,a.useLayoutEffect)(()=>{if(m)return;let e=c?(0,o.readStoredTheme)(c):null;if(e){p(e),g(!0);return}return p((0,o.getSystemTheme)()),(0,o.watchSystemTheme)(p)},[m,c]),(0,a.useLayoutEffect)(()=>{if(r===`local`)return;let e=(0,o.documentRoot)();if(e)return(0,o.applyThemeToElement)(e,f)},[f,r]),r===`local`?(0,s.jsxs)(h.Provider,{value:{theme:f,setTheme:_},children:[u,(0,s.jsx)(i.default,{className:f,props:{"data-theme":f},children:t})]}):(0,s.jsxs)(h.Provider,{value:{theme:f,setTheme:_},children:[u,t]})}(function(e){function t(){let{theme:e,setTheme:t}=(0,a.useContext)(h);return[e,t]}e.useTheme=t})(g||={});var _=g,v=new WeakMap;function y(e){let t=v.get(e);return t||(t=new Map,v.set(e,t)),t}function b(e=!0){let[t]=_.useTheme(),r=(0,a.useMemo)(()=>{if(!e)return null;let t=n.t();if(!t)return null;let r=`box-kite-portal`,i=t.getElementById(r);return i||(i=document.createElement(`div`),i.id=r,document.body.appendChild(i)),i},[e]);return(0,a.useLayoutEffect)(()=>{if(!t||!r)return;let e=y(r),n=e.get(t)??0;return e.set(t,n+1),n===0&&r.classList.add(t),()=>{let n=(e.get(t)??1)-1;n<=0?(e.delete(t),r.classList.remove(t)):e.set(t,n)}},[r,t]),r}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return b}});
|
package/client.mjs
CHANGED
|
@@ -3,10 +3,10 @@ import { l as n, t as r } from "./platform.mjs";
|
|
|
3
3
|
import { t as i } from "./effects.mjs";
|
|
4
4
|
import a from "./box.mjs";
|
|
5
5
|
import o, { useCallback as s, useContext as c, useEffect as l, useLayoutEffect as u, useMemo as d, useRef as f, useState as p } from "react";
|
|
6
|
-
import { applyThemeToElement as m, clearStoredTheme as h, defaultThemeName as g, documentRoot as _, getDefaultEngine as v, getSystemTheme as y, readStoredTheme as b,
|
|
7
|
-
import { jsx as
|
|
6
|
+
import { applyThemeToElement as m, clearStoredTheme as h, defaultThemeName as g, documentRoot as _, getDefaultEngine as v, getSystemTheme as y, readStoredTheme as b, watchSystemTheme as x, writeStoredTheme as S } from "@box-kite/core";
|
|
7
|
+
import { jsx as C, jsxs as w } from "react/jsx-runtime";
|
|
8
8
|
//#region src/react/hooks/useVisibility.ts
|
|
9
|
-
function
|
|
9
|
+
function T(e) {
|
|
10
10
|
let { node: t = null, event: r = "click", hideOnScroll: i = !1, hideOnResize: a = !1, hideOnEscape: o = !0 } = e ?? {}, [s, c] = p(!1), u = f(null);
|
|
11
11
|
return l(() => {
|
|
12
12
|
function e(e) {
|
|
@@ -41,23 +41,23 @@ function E(e) {
|
|
|
41
41
|
}
|
|
42
42
|
//#endregion
|
|
43
43
|
//#region src/react/useStyles.ts
|
|
44
|
-
var
|
|
45
|
-
function
|
|
44
|
+
var E = i;
|
|
45
|
+
function D(t, n) {
|
|
46
46
|
let { classNames: r, signature: i, styleElements: a } = e(t, n);
|
|
47
|
-
return
|
|
47
|
+
return E(() => {
|
|
48
48
|
v().flushSync();
|
|
49
49
|
}, [i ?? t]), {
|
|
50
50
|
classNames: r,
|
|
51
51
|
styleElements: a
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
-
function
|
|
54
|
+
function O(e, n) {
|
|
55
55
|
let r = e ? v().addGlobalStyles(e, n) : void 0;
|
|
56
|
-
return
|
|
56
|
+
return E(() => {
|
|
57
57
|
v().flushSync();
|
|
58
58
|
}, [e, n]), t(r);
|
|
59
59
|
}
|
|
60
|
-
var
|
|
60
|
+
var k;
|
|
61
61
|
(function(e) {
|
|
62
62
|
function t() {
|
|
63
63
|
v().flushSync();
|
|
@@ -79,72 +79,70 @@ var A;
|
|
|
79
79
|
v().configure(e);
|
|
80
80
|
}
|
|
81
81
|
e.configure = a;
|
|
82
|
-
})(
|
|
82
|
+
})(k ||= {});
|
|
83
83
|
//#endregion
|
|
84
84
|
//#region src/react/clientRuntime.ts
|
|
85
|
-
var
|
|
86
|
-
function
|
|
87
|
-
if (typeof e.createContext != "function") throw Error(
|
|
85
|
+
var A = "[box-kite] The client build was loaded into a React Server Component graph, where React has no createContext. Import '@box-kite/react' by its package name — the react-server condition resolves it to a Box that renders on the server — and import the components that hold state (Dropdown, Tooltip, DataGrid, Checkbox, Select, Form) from a 'use client' module. See https://github.com/box-kite/box-kite#react-server-components-react-19";
|
|
86
|
+
function j(e) {
|
|
87
|
+
if (typeof e.createContext != "function") throw Error(A);
|
|
88
88
|
}
|
|
89
89
|
//#endregion
|
|
90
90
|
//#region src/react/theme/themeContext.ts
|
|
91
|
-
|
|
92
|
-
var
|
|
91
|
+
j(o);
|
|
92
|
+
var M = o.createContext({
|
|
93
93
|
theme: "",
|
|
94
94
|
setTheme: () => {}
|
|
95
95
|
});
|
|
96
96
|
//#endregion
|
|
97
97
|
//#region src/react/theme/theme.tsx
|
|
98
|
-
function
|
|
99
|
-
let { children: t, theme: n, use: r = "local", storageKey: i, globalStyles: o } = e, c =
|
|
100
|
-
e === null ? (i && h(i),
|
|
101
|
-
}, [i]), [
|
|
102
|
-
return n !==
|
|
103
|
-
if (
|
|
98
|
+
function N(e) {
|
|
99
|
+
let { children: t, theme: n, use: r = "local", storageKey: i, globalStyles: o } = e, c = O(r === "global" ? o : void 0, "html"), [l, d] = p(n ?? g), [f, v] = p(n !== void 0), T = s((e) => {
|
|
100
|
+
e === null ? (i && h(i), v(!1)) : (i && S(i, e), d(e), v(!0));
|
|
101
|
+
}, [i]), [E, D] = p(n);
|
|
102
|
+
return n !== E && (D(n), n === void 0 ? v(!1) : (d(n), v(!0))), u(() => {
|
|
103
|
+
if (f) return;
|
|
104
104
|
let e = i ? b(i) : null;
|
|
105
105
|
if (e) {
|
|
106
|
-
d(e),
|
|
106
|
+
d(e), v(!0);
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
-
return d(y()),
|
|
110
|
-
}, [
|
|
109
|
+
return d(y()), x(d);
|
|
110
|
+
}, [f, i]), u(() => {
|
|
111
111
|
if (r === "local") return;
|
|
112
112
|
let e = _();
|
|
113
113
|
if (e) return m(e, l);
|
|
114
|
-
}, [l, r]),
|
|
115
|
-
r !== "local" || !D.current || x(D.current, l);
|
|
116
|
-
}, [l, r]), r === "local" ? /* @__PURE__ */ T(N.Provider, {
|
|
114
|
+
}, [l, r]), r === "local" ? /* @__PURE__ */ w(M.Provider, {
|
|
117
115
|
value: {
|
|
118
116
|
theme: l,
|
|
119
|
-
setTheme:
|
|
117
|
+
setTheme: T
|
|
120
118
|
},
|
|
121
|
-
children: [c, /* @__PURE__ */
|
|
122
|
-
ref: D,
|
|
119
|
+
children: [c, /* @__PURE__ */ C(a, {
|
|
123
120
|
className: l,
|
|
121
|
+
props: { "data-theme": l },
|
|
124
122
|
children: t
|
|
125
123
|
})]
|
|
126
|
-
}) : /* @__PURE__ */
|
|
124
|
+
}) : /* @__PURE__ */ w(M.Provider, {
|
|
127
125
|
value: {
|
|
128
126
|
theme: l,
|
|
129
|
-
setTheme:
|
|
127
|
+
setTheme: T
|
|
130
128
|
},
|
|
131
129
|
children: [c, t]
|
|
132
130
|
});
|
|
133
131
|
}
|
|
134
132
|
(function(e) {
|
|
135
133
|
function t() {
|
|
136
|
-
let { theme: e, setTheme: t } = c(
|
|
134
|
+
let { theme: e, setTheme: t } = c(M);
|
|
137
135
|
return [e, t];
|
|
138
136
|
}
|
|
139
137
|
e.useTheme = t;
|
|
140
|
-
})(
|
|
141
|
-
var
|
|
142
|
-
function
|
|
143
|
-
let t =
|
|
144
|
-
return t || (t = /* @__PURE__ */ new Map(),
|
|
138
|
+
})(N ||= {});
|
|
139
|
+
var P = N, F = /* @__PURE__ */ new WeakMap();
|
|
140
|
+
function I(e) {
|
|
141
|
+
let t = F.get(e);
|
|
142
|
+
return t || (t = /* @__PURE__ */ new Map(), F.set(e, t)), t;
|
|
145
143
|
}
|
|
146
|
-
function
|
|
147
|
-
let [t] =
|
|
144
|
+
function L(e = !0) {
|
|
145
|
+
let [t] = P.useTheme(), n = d(() => {
|
|
148
146
|
if (!e) return null;
|
|
149
147
|
let t = r();
|
|
150
148
|
if (!t) return null;
|
|
@@ -153,7 +151,7 @@ function R(e = !0) {
|
|
|
153
151
|
}, [e]);
|
|
154
152
|
return u(() => {
|
|
155
153
|
if (!t || !n) return;
|
|
156
|
-
let e =
|
|
154
|
+
let e = I(n), r = e.get(t) ?? 0;
|
|
157
155
|
return e.set(t, r + 1), r === 0 && n.classList.add(t), () => {
|
|
158
156
|
let r = (e.get(t) ?? 1) - 1;
|
|
159
157
|
r <= 0 ? (e.delete(t), n.classList.remove(t)) : e.set(t, r);
|
|
@@ -161,4 +159,4 @@ function R(e = !0) {
|
|
|
161
159
|
}, [n, t]), n;
|
|
162
160
|
}
|
|
163
161
|
//#endregion
|
|
164
|
-
export {
|
|
162
|
+
export { T as a, D as i, P as n, k as r, L as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../box.cjs"),t=require("../behavior.cjs"),n=require("../identity.cjs");let r=require("react"),i=require("react/jsx-runtime");var a;(function(e){let t={pending:`Pending`,running:`Running`,success:`Done`,error:`Failed`};function n(e){return t[e]??t.pending}e.statusLabel=n;let r={approved:`Approved`,rejected:`Rejected`};function i(e){return r[e]??``}e.decisionLabel=i;let a=e.VALUE_LIMIT=2e4;function o(e){if(typeof e==`string`)return e;try{let t=JSON.stringify(e,s,2);return typeof t==`string`?t:String(e)}catch{return String(e)}}function s(e,t){return typeof t==`bigint`?`${t}`:typeof t==`function`?`[Function]`:t}function c(e,t=a){let n=o(e);return n.length<=t?{text:n,truncated:0}:{text:n.slice(0,t),truncated:n.length-t}}e.formatValue=c;function l(e){return e!=null}e.hasValue=l;function u(e){return`${Math.trunc(e)}`.replace(/\B(?=(\d{3})+(?!\d))/g,`,`)}e.formatCount=u;function d(e){if(!Number.isFinite(e)||e<0)return``;if(e<1e3)return`${Math.round(e)}ms`;let t=e/1e3;if(t<60)return`${t<10?Math.round(t*10)/10:Math.round(t)}s`;let n=Math.floor(t/60);return`${n}m ${Math.round(t-n*60)}s`}e.formatDuration=d;let f=e.STREAM_WINDOW=8;function p(e){return{settled:e,segments:[],nextKey:0}}e.initialStream=p;function m(e){return e.segments.reduce((e,t)=>e+t.text,e.settled)}e.streamText=m;function h(e,t,n=f){let r=m(e);if(t===r)return e;if(!t.startsWith(r))return{settled:t,segments:[],nextKey:e.nextKey};let i=[...e.segments,{key:e.nextKey,text:t.slice(r.length)}],a=Math.max(0,i.length-Math.max(0,n));return{settled:i.slice(0,a).reduce((e,t)=>e+t.text,e.settled),segments:i.slice(a),nextKey:e.nextKey+1}}e.advanceStream=h})(a||={});var o=a;function s({part:t,open:n}){return(0,i.jsx)(e.default,{tag:`span`,component:t,variant:{open:n},props:{"aria-hidden":!0}})}var c={section:`toolCall.section`,label:`toolCall.label`,value:`toolCall.value`,truncated:`toolCall.truncated`},l={section:`approval.section`,label:`approval.label`,value:`approval.value`,truncated:`approval.truncated`};function u({parts:t,label:n,value:r,limit:a}){let{text:s,truncated:c}=o.formatValue(r,a);return(0,i.jsxs)(e.default,{component:t.section,children:[(0,i.jsx)(e.default,{component:t.label,children:n}),(0,i.jsx)(e.default,{tag:`pre`,component:t.value,children:s}),c>0&&(0,i.jsx)(e.default,{component:t.truncated,children:`${o.formatCount(c)} more characters, not shown`})]})}function d(r){let{name:a,description:l,status:d=`pending`,input:f,output:p,error:m,open:h,defaultOpen:g=!1,onOpenChange:_,collapsible:v=!0,inputLabel:y=`Input`,outputLabel:b=`Output`,errorLabel:x=`Error`,valueLimit:S,children:C,props:w,...T}=r,E=n.t(`toolcall`),D=`${E}-header`,O=`${E}-body`,[k,A]=t.i({value:h,defaultValue:g,onChange:_}),j=t.a(e=>A(e=>!e,{reason:`trigger`,event:e})),M=[{key:`input`,label:y,value:f},{key:`output`,label:b,value:p},{key:`error`,label:x,value:m}].filter(e=>o.hasValue(e.value)),N=v&&(M.length>0||C!==void 0),P=N&&k,F=(0,i.jsxs)(i.Fragment,{children:[(0,i.jsxs)(e.default,{tag:`span`,component:`toolCall.summary`,children:[(0,i.jsx)(e.default,{tag:`span`,component:`toolCall.name`,children:a}),l!==void 0&&(0,i.jsx)(e.default,{tag:`span`,component:`toolCall.description`,children:l})]}),(0,i.jsxs)(e.default,{tag:`span`,component:`toolCall.status`,variant:d,children:[(0,i.jsx)(e.default,{tag:`span`,component:`toolCall.status.dot`,variant:{running:d===`running`},props:{"aria-hidden":!0}}),o.statusLabel(d)]}),N&&(0,i.jsx)(s,{part:`toolCall.arrow`,open:P})]});return(0,i.jsxs)(e.default,{component:`toolCall`,...T,props:{"aria-busy":d===`running`||void 0,...w},children:[N?(0,i.jsx)(e.default,{tag:`button`,component:`toolCall.header`,variant:{interactive:!0},id:D,props:{type:`button`,"aria-expanded":P,"aria-controls":O,onClick:j},children:F}):(0,i.jsx)(e.default,{component:`toolCall.header`,id:D,children:F}),N&&(0,i.jsx)(e.default,{component:`toolCall.track`,variant:{closed:!P},children:(0,i.jsx)(e.default,{component:`toolCall.clip`,children:(0,i.jsxs)(e.default,{component:`toolCall.body`,id:O,children:[M.map(e=>(0,i.jsx)(u,{parts:c,label:e.label,value:e.value,limit:S},e.key)),C]})})})]})}var f=d;f.displayName=`ToolCallCard`;function p(r){let{title:a,description:s,input:c,inputLabel:d=`Request`,decision:f,defaultDecision:p=null,onDecisionChange:m,busy:h=!1,approveLabel:g=`Approve`,rejectLabel:_=`Reject`,autoFocus:v=!1,valueLimit:y,children:b,props:x,...S}=r,C=`${n.t(`approval`)}-title`,[w,T]=t.i({value:f,defaultValue:p,onChange:m}),E=(e,t)=>n=>T(e,{reason:t,event:n});return(0,i.jsxs)(e.default,{component:`approval`,...S,variant:[S.variant,{approved:w===`approved`,rejected:w===`rejected`}],props:{role:`group`,"aria-labelledby":C,"aria-busy":h||void 0,...x},children:[(0,i.jsx)(e.default,{component:`approval.title`,id:C,children:a}),s!==void 0&&(0,i.jsx)(e.default,{component:`approval.description`,children:s}),o.hasValue(c)&&(0,i.jsx)(u,{parts:l,label:d,value:c,limit:y}),b,(0,i.jsxs)(e.default,{component:`approval.footer`,children:[w===null&&(0,i.jsxs)(e.default,{component:`approval.actions`,children:[(0,i.jsx)(e.default,{tag:`button`,component:`approval.button`,variant:{reject:!0},disabled:h,props:{type:`button`,autoFocus:v,onClick:E(`rejected`,`reject`)},children:_}),(0,i.jsx)(e.default,{tag:`button`,component:`approval.button`,variant:{approve:!0},disabled:h,props:{type:`button`,onClick:E(`approved`,`approve`)},children:g})]}),(0,i.jsx)(e.default,{component:`approval.decision`,variant:{approved:w===`approved`,rejected:w===`rejected`},props:{role:`status`},children:w===null?null:o.decisionLabel(w)})]})]})}var m=p;m.displayName=`ApprovalCard`;function h(r){let{label:a,children:c,open:l,defaultOpen:u=!1,onOpenChange:d,streaming:f=!1,duration:p,props:m,...h}=r,g=n.t(`reasoning`),_=`${g}-trigger`,v=`${g}-body`,[y,b]=t.i({value:l,defaultValue:u,onChange:d}),x=t.a(e=>b(e=>!e,{reason:`trigger`,event:e})),S=p===void 0?``:o.formatDuration(p);return(0,i.jsxs)(e.default,{component:`reasoning`,...h,props:{"aria-busy":f||void 0,...m},children:[(0,i.jsxs)(e.default,{tag:`button`,component:`reasoning.trigger`,variant:{streaming:f},id:_,props:{type:`button`,"aria-expanded":y,"aria-controls":v,onClick:x},children:[(0,i.jsx)(s,{part:`reasoning.arrow`,open:y}),a??(f?`Thinking…`:`Reasoning`),!f&&S!==``&&(0,i.jsx)(e.default,{tag:`span`,component:`reasoning.duration`,children:`Thought for ${S}`})]}),(0,i.jsx)(e.default,{component:`reasoning.track`,variant:{closed:!y},children:(0,i.jsx)(e.default,{component:`reasoning.clip`,children:(0,i.jsx)(e.default,{component:`reasoning.body`,id:v,children:c})})})]})}var g=h;g.displayName=`Reasoning`;function _(t){let{text:n,streaming:a=!1,window:s=o.STREAM_WINDOW,caret:c=!0,props:l,...u}=t,[d,f]=(0,r.useState)(()=>o.initialStream(n)),p=o.advanceStream(d,n,s);return p!==d&&f(p),(0,i.jsxs)(e.default,{component:`streamingText`,...u,props:{"aria-busy":a||void 0,...l},children:[p.settled,p.segments.map(t=>(0,i.jsx)(e.default,{tag:`span`,component:`streamingText.segment`,children:t.text},t.key)),a&&c&&(0,i.jsx)(e.default,{tag:`span`,component:`streamingText.caret`,props:{"aria-hidden":!0}})]})}var v=_;v.displayName=`StreamingText`,exports.AgentUtils=o,exports.ApprovalCard=m,exports.Reasoning=g,exports.StreamingText=v,exports.ToolCallCard=f;
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { BoxProps } from '../box';
|
|
3
|
+
import { ChangeHandler } from '../react/a11y/useControllableState';
|
|
4
|
+
import { ComponentsAndVariants } from '@box-kite/core/types';
|
|
5
|
+
import { default as AgentUtils, ApprovalDecision, ToolCallStatus } from '../utils/agent/agentUtils';
|
|
6
|
+
export { AgentUtils };
|
|
7
|
+
export type { ApprovalDecision, ToolCallStatus };
|
|
8
|
+
/** Why a card opened or closed: a press on its header, which is also what Enter and Space on it produce. */
|
|
9
|
+
export type DisclosureReason = 'trigger';
|
|
10
|
+
/** Which button was pressed. The decision says what it meant; this says what the person did. */
|
|
11
|
+
export type ApprovalReason = 'approve' | 'reject';
|
|
12
|
+
export interface ToolCallCardProps<TKey extends keyof ComponentsAndVariants = 'toolCall'> extends Omit<BoxProps<'div', TKey>, 'open'> {
|
|
13
|
+
/** The tool's name, as the model called it. It is what the header reads. */
|
|
14
|
+
name: ReactNode;
|
|
15
|
+
/** A line under the name: what this call is for, in the app's own words. */
|
|
16
|
+
description?: ReactNode;
|
|
17
|
+
/** Where the call is. Default `pending`. */
|
|
18
|
+
status?: ToolCallStatus;
|
|
19
|
+
/** The arguments. A string is shown as it stands, anything else as the JSON a reader can check. */
|
|
20
|
+
input?: unknown;
|
|
21
|
+
/** What came back, shown the same way. */
|
|
22
|
+
output?: unknown;
|
|
23
|
+
/** What went wrong, shown in place of the output. */
|
|
24
|
+
error?: unknown;
|
|
25
|
+
/** Controlled: whether the body is open. */
|
|
26
|
+
open?: boolean;
|
|
27
|
+
/** Whether it starts open. Default `false` — a transcript of tool calls is a list, not a wall of JSON. */
|
|
28
|
+
defaultOpen?: boolean;
|
|
29
|
+
/** Fires when the header is pressed, with the body's new state. */
|
|
30
|
+
onOpenChange?: ChangeHandler<boolean, DisclosureReason>;
|
|
31
|
+
/** Whether the body can be opened at all. Default `true`; `false` leaves the header a plain row. */
|
|
32
|
+
collapsible?: boolean;
|
|
33
|
+
/** The word above the arguments. Default `Input`. */
|
|
34
|
+
inputLabel?: ReactNode;
|
|
35
|
+
/** The word above what came back. Default `Output`. */
|
|
36
|
+
outputLabel?: ReactNode;
|
|
37
|
+
/** The word above what went wrong. Default `Error`. */
|
|
38
|
+
errorLabel?: ReactNode;
|
|
39
|
+
/** How much of a value is shown before it is cut. Default `AgentUtils.VALUE_LIMIT` (20,000 characters). */
|
|
40
|
+
valueLimit?: number;
|
|
41
|
+
/** Anything else that belongs in the body, under the values. */
|
|
42
|
+
children?: ReactNode;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* One call an agent made: what it ran, where it got to, and — when the header is opened — what went in
|
|
46
|
+
* and what came back.
|
|
47
|
+
*
|
|
48
|
+
* ```tsx
|
|
49
|
+
* <ToolCallCard name="searchOrders" status="success" input={{ query: 'refunds' }} output={rows} />
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* **The status is a word, not a colour.** Every state carries its own label beside the dot, because a
|
|
53
|
+
* forced-colors mode throws a tint away and a screen reader never had it — the same rule the library's
|
|
54
|
+
* own state styling follows.
|
|
55
|
+
*
|
|
56
|
+
* **A value is whatever the model produced**, so it is formatted rather than trusted: a circular
|
|
57
|
+
* structure, a `BigInt` and a four-megabyte result all reach the page as text, capped at `valueLimit`
|
|
58
|
+
* with a line saying how much was left. The judgement is `AgentUtils`, which needs no React.
|
|
59
|
+
*
|
|
60
|
+
* The four statuses are the ones every agent runtime reports under its own spelling — AI SDK's
|
|
61
|
+
* `input-streaming`/`input-available`/`output-available`/`output-error` map onto them one for one.
|
|
62
|
+
*
|
|
63
|
+
* @a11y The header is a real `<button>` carrying `aria-expanded` and `aria-controls` when there is a body
|
|
64
|
+
* to open, and a plain row when there is not — a control that discloses nothing is a control nobody wants
|
|
65
|
+
* to land on.
|
|
66
|
+
* @a11y `aria-busy` while the call is running, so a reader is told the card is not finished rather than
|
|
67
|
+
* reading a half-written result as the answer.
|
|
68
|
+
* @a11y The card announces nothing itself. The transcript it is rendered into is what does that, and a
|
|
69
|
+
* live region inserted together with its content is not reliably announced.
|
|
70
|
+
* @keyboard Tab — Focuses the header, and again leaves it. Nothing inside a closed body is reachable.
|
|
71
|
+
* @keyboard Enter, Space — Opens the body, or closes it.
|
|
72
|
+
*/
|
|
73
|
+
declare function ToolCallCardImpl<TKey extends keyof ComponentsAndVariants = 'toolCall'>(props: ToolCallCardProps<TKey>): import("react").JSX.Element;
|
|
74
|
+
export declare const ToolCallCard: typeof ToolCallCardImpl;
|
|
75
|
+
export interface ApprovalCardProps<TKey extends keyof ComponentsAndVariants = 'approval'> extends BoxProps<'div', TKey> {
|
|
76
|
+
/** What is about to happen, in one line. It names the card. */
|
|
77
|
+
title: ReactNode;
|
|
78
|
+
/** The consequence, where a title cannot carry it: what this will change, and whether it can be undone. */
|
|
79
|
+
description?: ReactNode;
|
|
80
|
+
/** The call itself, shown the way a `ToolCallCard` shows its input. */
|
|
81
|
+
input?: unknown;
|
|
82
|
+
/** The word above it. Default `Request`. */
|
|
83
|
+
inputLabel?: ReactNode;
|
|
84
|
+
/** Controlled: what has been decided. `null` is "not yet", and is what shows the two buttons. */
|
|
85
|
+
decision?: ApprovalDecision | null;
|
|
86
|
+
/** What it starts as. Default `null`. */
|
|
87
|
+
defaultDecision?: ApprovalDecision | null;
|
|
88
|
+
/** Fires when a button is pressed, with the decision and which button made it. */
|
|
89
|
+
onDecisionChange?: ChangeHandler<ApprovalDecision | null, ApprovalReason>;
|
|
90
|
+
/** The decision is on its way to a server: both buttons are disabled and the card reports `aria-busy`. */
|
|
91
|
+
busy?: boolean;
|
|
92
|
+
/** What the approving button says. Default `Approve`. */
|
|
93
|
+
approveLabel?: ReactNode;
|
|
94
|
+
/** What the refusing button says. Default `Reject`. */
|
|
95
|
+
rejectLabel?: ReactNode;
|
|
96
|
+
/**
|
|
97
|
+
* Whether to put focus on the card when it mounts. Default `false` — an agent's turn arrives while the
|
|
98
|
+
* reader is somewhere else, and taking focus from them is how a decision gets pressed by accident. It
|
|
99
|
+
* lands on the *reject* button, which is APG's rule for a decision: the least destructive action.
|
|
100
|
+
*/
|
|
101
|
+
autoFocus?: boolean;
|
|
102
|
+
/** How much of the input is shown before it is cut. Default `AgentUtils.VALUE_LIMIT`. */
|
|
103
|
+
valueLimit?: number;
|
|
104
|
+
/** Anything else that belongs above the buttons. */
|
|
105
|
+
children?: ReactNode;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The gate in front of something an agent wants to do: what it is, and the two answers.
|
|
109
|
+
*
|
|
110
|
+
* ```tsx
|
|
111
|
+
* <ApprovalCard
|
|
112
|
+
* title="Refund order #4182"
|
|
113
|
+
* description="6,400 MDL back to the customer. This cannot be undone."
|
|
114
|
+
* input={{ orderId: 4182 }}
|
|
115
|
+
* onDecisionChange={(decision) => respond(decision === 'approved')}
|
|
116
|
+
* />
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* **One channel, not two.** `onDecisionChange(decision, { reason })` is the whole API: the decision says
|
|
120
|
+
* what was chosen and the reason says which button chose it, which is the shape every other component in
|
|
121
|
+
* the library reports through. It maps straight onto AI SDK 6's `needsApproval`, CopilotKit's
|
|
122
|
+
* `renderAndWaitForResponse` and AG-UI's `INTERRUPT`.
|
|
123
|
+
*
|
|
124
|
+
* **The decision's own line is a live region that exists before there is anything in it**, so a reader is
|
|
125
|
+
* told the card was answered. A region rendered together with its text is not reliably announced — the
|
|
126
|
+
* rule the toaster's viewport already follows.
|
|
127
|
+
*
|
|
128
|
+
* @a11y `role="group"` named by the title, so the two buttons are read as belonging to one decision
|
|
129
|
+
* rather than as loose controls in a transcript.
|
|
130
|
+
* @a11y Focus is not taken on mount unless `autoFocus` is set, and then it lands on the least destructive
|
|
131
|
+
* button. A card that grabs the keyboard is one that gets answered by accident.
|
|
132
|
+
* @a11y `aria-busy` while `busy`, which is also when both buttons are disabled.
|
|
133
|
+
* @keyboard Tab — Reaches the two buttons in order; Enter or Space presses one.
|
|
134
|
+
*/
|
|
135
|
+
declare function ApprovalCardImpl<TKey extends keyof ComponentsAndVariants = 'approval'>(props: ApprovalCardProps<TKey>): import("react").JSX.Element;
|
|
136
|
+
export declare const ApprovalCard: typeof ApprovalCardImpl;
|
|
137
|
+
export interface ReasoningProps<TKey extends keyof ComponentsAndVariants = 'reasoning'> extends Omit<BoxProps<'div', TKey>, 'open'> {
|
|
138
|
+
/** The header's words. Default `Reasoning`, or `Thinking…` while `streaming`. */
|
|
139
|
+
label?: ReactNode;
|
|
140
|
+
/** The thought itself. */
|
|
141
|
+
children?: ReactNode;
|
|
142
|
+
/** Controlled: whether it is open. */
|
|
143
|
+
open?: boolean;
|
|
144
|
+
/** Whether it starts open. Default `false` — a chain of thought is an aside, not the answer. */
|
|
145
|
+
defaultOpen?: boolean;
|
|
146
|
+
/** Fires when the header is pressed. */
|
|
147
|
+
onOpenChange?: ChangeHandler<boolean, DisclosureReason>;
|
|
148
|
+
/** Still arriving: the header says so and shimmers. Opening it is the app's — pass `open={streaming}`. */
|
|
149
|
+
streaming?: boolean;
|
|
150
|
+
/** How long the thought took, in milliseconds. Rendered beside the label as "Thought for 4s". */
|
|
151
|
+
duration?: number;
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* What the model was thinking, folded away.
|
|
155
|
+
*
|
|
156
|
+
* ```tsx
|
|
157
|
+
* <Reasoning duration={4200}>{reasoningText}</Reasoning>
|
|
158
|
+
* <Reasoning streaming open>{partial}</Reasoning>
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* **Closed by default**, because a chain of thought is an aside and a transcript of them is unreadable.
|
|
162
|
+
* `streaming` changes what the header says and shimmers it; whether it also *opens* is the app's call,
|
|
163
|
+
* since that is a value somebody may be controlling — `open={streaming}` is the usual answer.
|
|
164
|
+
*
|
|
165
|
+
* The same one-row grid `Collapsible` opens in, so nothing is measured and two identical rules share
|
|
166
|
+
* one class.
|
|
167
|
+
*
|
|
168
|
+
* @a11y The header is a `<button>` with `aria-expanded` and `aria-controls`; the thought itself has no
|
|
169
|
+
* role, because a region wants a name and a disclosure's trigger is not a heading.
|
|
170
|
+
* @a11y `aria-busy` while it is streaming.
|
|
171
|
+
* @keyboard Tab — Focuses the header, and again leaves it.
|
|
172
|
+
* @keyboard Enter, Space — Opens the thought, or closes it.
|
|
173
|
+
*/
|
|
174
|
+
declare function ReasoningImpl<TKey extends keyof ComponentsAndVariants = 'reasoning'>(props: ReasoningProps<TKey>): import("react").JSX.Element;
|
|
175
|
+
export declare const Reasoning: typeof ReasoningImpl;
|
|
176
|
+
export interface StreamingTextProps<TKey extends keyof ComponentsAndVariants = 'streamingText'> extends BoxProps<'div', TKey> {
|
|
177
|
+
/** The message so far. Append to it — anything else is a different message and settles without fading. */
|
|
178
|
+
text: string;
|
|
179
|
+
/** Whether more is still coming. The caret shows while it is true, and the element reports `aria-busy`. */
|
|
180
|
+
streaming?: boolean;
|
|
181
|
+
/**
|
|
182
|
+
* How many of the runs that arrived most recently stay faded in at once; the rest settle. Default
|
|
183
|
+
* `AgentUtils.STREAM_WINDOW` (8), and `0` turns the entrance off altogether. A run is settled once this
|
|
184
|
+
* many newer ones have arrived rather than after a time, so a stream fast enough to fill the window
|
|
185
|
+
* inside one `--transitionTime` cuts the tail of the fade short — raise it if that shows.
|
|
186
|
+
*/
|
|
187
|
+
window?: number;
|
|
188
|
+
/** Whether to draw the caret while streaming. Default `true`. */
|
|
189
|
+
caret?: boolean;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* What the agent is saying, as it arrives.
|
|
193
|
+
*
|
|
194
|
+
* ```tsx
|
|
195
|
+
* <StreamingText text={message} streaming={status === 'streaming'} />
|
|
196
|
+
* ```
|
|
197
|
+
*
|
|
198
|
+
* **Only what arrived fades in.** The text is one settled string plus the last few runs to arrive, so a
|
|
199
|
+
* message that is already whole — a prerendered page, a transcript being read back — paints at once with
|
|
200
|
+
* no animation, and one that is still arriving costs the same at the ten-thousandth token as at the
|
|
201
|
+
* first. The judgement is `AgentUtils.advanceStream`, which needs no React.
|
|
202
|
+
*
|
|
203
|
+
* **The entrance is `@starting-style`, not a keyframe**, so it rides `--transitionTime` and disappears
|
|
204
|
+
* under `prefers-reduced-motion` with nothing declared for it. The caret is the `pulse` preset, which
|
|
205
|
+
* stops itself for the same reason.
|
|
206
|
+
*
|
|
207
|
+
* It takes `text` rather than children, because knowing what is new means comparing the message with the
|
|
208
|
+
* message a moment ago, and a React tree is not a string.
|
|
209
|
+
*
|
|
210
|
+
* @a11y `aria-busy` while `streaming`. The element is **not** a live region: a region announcing every
|
|
211
|
+
* token would read the message out a word at a time and again when it finished. What announces an
|
|
212
|
+
* agent's turn is the transcript it lands in.
|
|
213
|
+
*/
|
|
214
|
+
declare function StreamingTextImpl<TKey extends keyof ComponentsAndVariants = 'streamingText'>(props: StreamingTextProps<TKey>): import("react").JSX.Element;
|
|
215
|
+
export declare const StreamingText: typeof StreamingTextImpl;
|