@mihe-dev/react 0.0.0-stage → 0.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/LICENSE +21 -0
- package/README.md +68 -2
- package/dist/card.d.ts +21 -0
- package/dist/card.d.ts.map +1 -0
- package/dist/card.js +74 -0
- package/dist/card.js.map +1 -0
- package/dist/hooks.d.ts +189 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +302 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher-icon.d.ts +19 -0
- package/dist/launcher-icon.d.ts.map +1 -0
- package/dist/launcher-icon.js +36 -0
- package/dist/launcher-icon.js.map +1 -0
- package/dist/mark.d.ts +18 -0
- package/dist/mark.d.ts.map +1 -0
- package/dist/mark.js +15 -0
- package/dist/mark.js.map +1 -0
- package/dist/orb.d.ts +56 -0
- package/dist/orb.d.ts.map +1 -0
- package/dist/orb.js +578 -0
- package/dist/orb.js.map +1 -0
- package/dist/provider.d.ts +28 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +52 -0
- package/dist/provider.js.map +1 -0
- package/dist/widget.d.ts +105 -0
- package/dist/widget.d.ts.map +1 -0
- package/dist/widget.js +414 -0
- package/dist/widget.js.map +1 -0
- package/package.json +42 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Neek Digital Solutions Ltd
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,69 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @mihe-dev/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Mihe is an assistant you embed in your React app. It knows your screens,
|
|
4
|
+
components and actions, and it operates the app for your users, under your
|
|
5
|
+
own permission model: it finds things, opens screens, fills in and points
|
|
6
|
+
at forms, and runs actions, asking for approval wherever you say it must.
|
|
7
|
+
Users can type or talk to it.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @mihe-dev/react
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
React 18 or later. The package is ES modules with TypeScript types, and it
|
|
16
|
+
marks itself `"use client"`, so it works in Next.js App Router, Vite and
|
|
17
|
+
other bundlers without extra configuration.
|
|
18
|
+
|
|
19
|
+
## A first integration
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { AssistantProvider, AssistantWidget, useAssistantScreen } from "@mihe-dev/react";
|
|
23
|
+
|
|
24
|
+
export function Root({ children }: { children: React.ReactNode }) {
|
|
25
|
+
return (
|
|
26
|
+
<AssistantProvider
|
|
27
|
+
url="wss://runtime.mihe.dev/v1/ws"
|
|
28
|
+
publicKey={process.env.NEXT_PUBLIC_MIHE_PUBLIC_KEY!}
|
|
29
|
+
// Your server mints this token for the signed-in user, signed with
|
|
30
|
+
// your app secret. It carries who they are and what they may do.
|
|
31
|
+
getUserToken={() => fetch("/api/mihe/token").then((r) => r.text())}
|
|
32
|
+
navigate={(route) => router.push(route)}
|
|
33
|
+
>
|
|
34
|
+
{children}
|
|
35
|
+
<AssistantWidget />
|
|
36
|
+
</AssistantProvider>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function OrdersPage() {
|
|
41
|
+
// Tell the assistant where the user is and what they can see.
|
|
42
|
+
useAssistantScreen({
|
|
43
|
+
screenId: "orders.list",
|
|
44
|
+
route: "/orders",
|
|
45
|
+
title: "Orders",
|
|
46
|
+
visibleData: { pending: 16 },
|
|
47
|
+
});
|
|
48
|
+
// …
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Create an app and its keys in the [dashboard](https://app.mihe.dev), then
|
|
53
|
+
follow the [quickstart](https://mihe.dev/docs/quickstart).
|
|
54
|
+
|
|
55
|
+
## Documentation
|
|
56
|
+
|
|
57
|
+
- [Quickstart](https://mihe.dev/docs/quickstart)
|
|
58
|
+
- [Screens and components](https://mihe.dev/docs/screens-and-components):
|
|
59
|
+
what the assistant can see and point at
|
|
60
|
+
- [Actions](https://mihe.dev/docs/actions) and
|
|
61
|
+
[permissions and risk](https://mihe.dev/docs/permissions-and-risk):
|
|
62
|
+
what it can do, and what needs approval
|
|
63
|
+
- [User tokens](https://mihe.dev/docs/user-tokens)
|
|
64
|
+
- [The widget](https://mihe.dev/docs/widget) and [voice](https://mihe.dev/docs/voice)
|
|
65
|
+
- [SDK reference](https://mihe.dev/docs/sdk-reference)
|
|
66
|
+
|
|
67
|
+
## License
|
|
68
|
+
|
|
69
|
+
MIT © Neek Digital Solutions Ltd
|
package/dist/card.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The approval surface for a proposed action, shared by the panel and the orb.
|
|
3
|
+
*
|
|
4
|
+
* It renders `label`, `description` and `input` from the proposal payload,
|
|
5
|
+
* which the runtime copies from its registry, never from the assistant's
|
|
6
|
+
* prose. Text smuggled into a product name or a document therefore cannot
|
|
7
|
+
* change what a user is shown they are about to approve.
|
|
8
|
+
*/
|
|
9
|
+
import { formatValue, humanizeKey, type ProposalPayload } from "@mihe-dev/js";
|
|
10
|
+
export { formatValue, humanizeKey };
|
|
11
|
+
/**
|
|
12
|
+
* The approval surface for a proposed action.
|
|
13
|
+
*
|
|
14
|
+
* High-risk actions require this tap — the runtime refuses a spoken or typed
|
|
15
|
+
* "yes" for them — so this component is a security boundary, not decoration.
|
|
16
|
+
*/
|
|
17
|
+
export declare function ConfirmationCard({ proposal, onRespond, }: {
|
|
18
|
+
proposal: ProposalPayload;
|
|
19
|
+
onRespond: (proposalId: string, confirmed: boolean) => void;
|
|
20
|
+
}): import("react").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.d.ts","sourceRoot":"","sources":["../../../react/src/card.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AAIpC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,SAAS,GACV,EAAE;IACD,QAAQ,EAAE,eAAe,CAAC;IAC1B,SAAS,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC7D,+BAiDA"}
|
package/dist/card.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { formatValue, humanizeKey } from "@mihe-dev/js";
|
|
3
|
+
export { formatValue, humanizeKey };
|
|
4
|
+
const FONT = "system-ui, -apple-system, 'Segoe UI', sans-serif";
|
|
5
|
+
/**
|
|
6
|
+
* The approval surface for a proposed action.
|
|
7
|
+
*
|
|
8
|
+
* High-risk actions require this tap — the runtime refuses a spoken or typed
|
|
9
|
+
* "yes" for them — so this component is a security boundary, not decoration.
|
|
10
|
+
*/
|
|
11
|
+
export function ConfirmationCard({ proposal, onRespond, }) {
|
|
12
|
+
const entries = Object.entries(proposal.input ?? {});
|
|
13
|
+
return (_jsxs("div", { style: styles.card, role: "group", "aria-label": `Confirm: ${proposal.label}`, children: [_jsxs("div", { style: styles.cardHeader, children: [_jsx("strong", { children: proposal.label }), _jsx("span", { style: {
|
|
14
|
+
...styles.riskBadge,
|
|
15
|
+
background: proposal.risk === "high" ? "#fee2e2" : "#fef3c7",
|
|
16
|
+
color: proposal.risk === "high" ? "#991b1b" : "#92400e",
|
|
17
|
+
}, children: proposal.risk === "high" ? "Needs care" : "Confirm" })] }), _jsx("p", { style: styles.cardDescription, children: proposal.description }), entries.length > 0 && (_jsx("dl", { style: styles.cardInput, children: entries.map(([key, value]) => (_jsxs("div", { style: styles.cardRow, children: [_jsx("dt", { style: styles.cardKey, children: humanizeKey(key) }), _jsx("dd", { style: styles.cardValue, children: _jsx(InputValue, { value: value }) })] }, key))) })), _jsxs("div", { style: styles.cardActions, children: [_jsx("button", { type: "button", onClick: () => onRespond(proposal.proposalId, false), style: styles.secondaryButton, children: "Cancel" }), _jsx("button", { type: "button", onClick: () => onRespond(proposal.proposalId, true), style: styles.primaryButton, children: "Confirm" })] })] }));
|
|
18
|
+
}
|
|
19
|
+
/** Lists stay separate so a user can check each line before approving. */
|
|
20
|
+
function InputValue({ value }) {
|
|
21
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
22
|
+
return (_jsx("ol", { style: styles.inputList, children: value.map((item, index) => (_jsx("li", { children: _jsx(InputValue, { value: item }) }, index))) }));
|
|
23
|
+
}
|
|
24
|
+
return _jsx("span", { style: styles.inputText, children: formatValue(value) });
|
|
25
|
+
}
|
|
26
|
+
const styles = {
|
|
27
|
+
card: {
|
|
28
|
+
border: "1px solid #e2e8f0",
|
|
29
|
+
borderRadius: 10,
|
|
30
|
+
padding: 12,
|
|
31
|
+
background: "#fff",
|
|
32
|
+
boxShadow: "0 2px 8px rgba(15,23,42,0.06)",
|
|
33
|
+
},
|
|
34
|
+
cardHeader: {
|
|
35
|
+
display: "flex",
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
justifyContent: "space-between",
|
|
38
|
+
gap: 8,
|
|
39
|
+
marginBottom: 6,
|
|
40
|
+
},
|
|
41
|
+
riskBadge: {
|
|
42
|
+
fontSize: 11,
|
|
43
|
+
fontWeight: 600,
|
|
44
|
+
padding: "2px 8px",
|
|
45
|
+
borderRadius: 999,
|
|
46
|
+
whiteSpace: "nowrap",
|
|
47
|
+
},
|
|
48
|
+
cardDescription: { margin: "0 0 10px", color: "#475569", fontSize: 13 },
|
|
49
|
+
cardInput: { margin: "0 0 12px", display: "flex", flexDirection: "column", gap: 8, maxHeight: "40vh", overflowY: "auto" },
|
|
50
|
+
cardRow: { display: "flex", flexWrap: "wrap", gap: 8, fontSize: 13 },
|
|
51
|
+
cardKey: { color: "#64748b", minWidth: 90, margin: 0 },
|
|
52
|
+
cardValue: { margin: 0, fontWeight: 500, overflowWrap: "anywhere", minWidth: 0, flex: "1 1 160px" },
|
|
53
|
+
inputList: { margin: 0, paddingLeft: 20, display: "grid", gap: 8 },
|
|
54
|
+
inputText: { whiteSpace: "pre-wrap" },
|
|
55
|
+
cardActions: { display: "flex", gap: 8, justifyContent: "flex-end" },
|
|
56
|
+
secondaryButton: {
|
|
57
|
+
padding: "7px 14px",
|
|
58
|
+
borderRadius: 8,
|
|
59
|
+
border: "1px solid #cbd5e1",
|
|
60
|
+
background: "#fff",
|
|
61
|
+
cursor: "pointer",
|
|
62
|
+
font: `500 13px ${FONT}`,
|
|
63
|
+
},
|
|
64
|
+
primaryButton: {
|
|
65
|
+
padding: "7px 14px",
|
|
66
|
+
borderRadius: 8,
|
|
67
|
+
border: "none",
|
|
68
|
+
background: "#4f7cff",
|
|
69
|
+
color: "#fff",
|
|
70
|
+
cursor: "pointer",
|
|
71
|
+
font: `600 13px ${FONT}`,
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=card.js.map
|
package/dist/card.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","sourceRoot":"","sources":["../../../react/src/card.tsx"],"names":[],"mappings":"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"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three registration hooks (spec §8.3–8.5).
|
|
3
|
+
*
|
|
4
|
+
* All three are declarative: a screen or component is registered while it is
|
|
5
|
+
* mounted and gone when it unmounts, so the assistant's picture of the app can
|
|
6
|
+
* never describe something the user is no longer looking at.
|
|
7
|
+
*/
|
|
8
|
+
import { COMPONENT_ATTRIBUTE, type ActionHandler, type AssistantChart, type AssistantTable, type AssistantTabs, type ComponentDeclaration, type ScreenDeclaration } from "@mihe-dev/js";
|
|
9
|
+
export type { AssistantChart, AssistantQueryParam, AssistantTable, AssistantTableColumn, AssistantTableQuery, AssistantTabs, } from "@mihe-dev/js";
|
|
10
|
+
/**
|
|
11
|
+
* Declare the screen the user is on.
|
|
12
|
+
*
|
|
13
|
+
* Call once per page or view. `visibleData` is what makes answers concrete —
|
|
14
|
+
* "you have 7 low-stock products" rather than "check your stock levels" — so
|
|
15
|
+
* include the summary values already on screen, and only those.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useAssistantScreen(screen: ScreenDeclaration): void;
|
|
18
|
+
/**
|
|
19
|
+
* Declare a component the assistant can talk about or point at, and get back
|
|
20
|
+
* the props that make it findable.
|
|
21
|
+
*
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const props = useAssistantComponent("products.addButton", {
|
|
24
|
+
* type: "button",
|
|
25
|
+
* label: "Add Product",
|
|
26
|
+
* description: "Opens the form to create a new product",
|
|
27
|
+
* });
|
|
28
|
+
* return <button {...props}>Add Product</button>;
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* The returned props must be spread onto a real DOM element. Without them the
|
|
32
|
+
* component is described to the assistant but cannot be highlighted, which
|
|
33
|
+
* produces the confusing case of an assistant confidently pointing at nothing.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useAssistantComponent(componentKey: string, meta: ComponentDeclaration): {
|
|
36
|
+
[COMPONENT_ATTRIBUTE]: string;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Register a handler for an action the assistant may run in the browser.
|
|
40
|
+
*
|
|
41
|
+
* The action itself — its risk tier, permissions, and whether it needs
|
|
42
|
+
* confirmation — is configured in the dashboard, not here. This only supplies
|
|
43
|
+
* the code that runs once the runtime has decided it may.
|
|
44
|
+
*
|
|
45
|
+
* Whatever the handler returns becomes the tool result the model sees, so
|
|
46
|
+
* return something descriptive: `{ shown: 7 }` tells it more than `undefined`.
|
|
47
|
+
* Throwing is fine and reports honestly — the assistant will tell the user it
|
|
48
|
+
* failed rather than claiming success.
|
|
49
|
+
*/
|
|
50
|
+
export declare function useAssistantAction(action: ActionHandler): void;
|
|
51
|
+
/**
|
|
52
|
+
* Let the assistant see which tab is open and switch to another.
|
|
53
|
+
*
|
|
54
|
+
* ```tsx
|
|
55
|
+
* const [tab, setTab] = useState("sales");
|
|
56
|
+
* useAssistantTabs({
|
|
57
|
+
* id: "reports.tabs",
|
|
58
|
+
* label: "Report",
|
|
59
|
+
* tabs: [{ value: "sales", label: "Sales" }, { value: "stock", label: "Stock" }],
|
|
60
|
+
* value: tab,
|
|
61
|
+
* onChange: setTab,
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* Tabs are built a dozen ways — a UI library's component, a route segment, a
|
|
66
|
+
* query parameter, plain state — so the SDK never touches them. It reports
|
|
67
|
+
* what you declare and calls your `onChange`, and the runtime only ever asks
|
|
68
|
+
* for a value you listed (amendment 67).
|
|
69
|
+
*
|
|
70
|
+
* Pass the tab that is really showing as `value`. The assistant is told it,
|
|
71
|
+
* and a switch is not reported done until `value` matches what was asked.
|
|
72
|
+
*/
|
|
73
|
+
export declare function useAssistantTabs(tabs: AssistantTabs): void;
|
|
74
|
+
/**
|
|
75
|
+
* Let the assistant read a table on the screen.
|
|
76
|
+
*
|
|
77
|
+
* ```tsx
|
|
78
|
+
* useAssistantTable({
|
|
79
|
+
* id: "orders.table",
|
|
80
|
+
* label: "Orders",
|
|
81
|
+
* columns: [
|
|
82
|
+
* { key: "orderNumber", label: "Order" },
|
|
83
|
+
* { key: "total", label: "Total" },
|
|
84
|
+
* ],
|
|
85
|
+
* rows: orders,
|
|
86
|
+
* rowId: (order) => order.id,
|
|
87
|
+
* rowIdName: "orderId",
|
|
88
|
+
* total,
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
*
|
|
92
|
+
* The rows are not sent with the screen. The model is told the table and its
|
|
93
|
+
* columns, and reads rows with `read_table` when a question needs them, so a
|
|
94
|
+
* table costs a line per answer rather than its contents (amendment 67).
|
|
95
|
+
* Only the declared columns ever leave the browser, and cell text is treated
|
|
96
|
+
* as data, never instructions.
|
|
97
|
+
*/
|
|
98
|
+
export declare function useAssistantTable<Row>(table: AssistantTable<Row>): void;
|
|
99
|
+
/**
|
|
100
|
+
* Add the figures a component shows to the screen's `visibleData`, under
|
|
101
|
+
* `key`.
|
|
102
|
+
*
|
|
103
|
+
* For values that live below the page that calls `useAssistantScreen`: the
|
|
104
|
+
* stat cards inside a tab, a summary panel. They are dropped when the
|
|
105
|
+
* component unmounts or the screen changes, and held back while the screen
|
|
106
|
+
* says it is loading, as `visibleData` is.
|
|
107
|
+
*
|
|
108
|
+
* ```tsx
|
|
109
|
+
* useAssistantValues("stockSummary", { currentStockValue, periodInflow });
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
export declare function useAssistantValues(key: string, values: Record<string, unknown>): void;
|
|
113
|
+
/**
|
|
114
|
+
* Let the assistant explain a chart.
|
|
115
|
+
*
|
|
116
|
+
* ```tsx
|
|
117
|
+
* useAssistantChart({
|
|
118
|
+
* id: "stock.trend",
|
|
119
|
+
* title: "Stock trend",
|
|
120
|
+
* data: series,
|
|
121
|
+
* x: { key: "bucket", label: "Month", format: (v) => monthLabel(String(v)) },
|
|
122
|
+
* series: [
|
|
123
|
+
* { key: "inflowValue", name: "Stock in", unit: "NGN" },
|
|
124
|
+
* { key: "outflowValue", name: "Stock out", unit: "NGN" },
|
|
125
|
+
* ],
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* Each series is summarised here, in the browser, and the summary is what
|
|
130
|
+
* the model gets with the screen: start, end, high, low, total and the
|
|
131
|
+
* largest steps. That answers most questions about a trend in a few dozen
|
|
132
|
+
* tokens a series. The points are read with `read_chart` when an exact value
|
|
133
|
+
* is wanted (amendment 67). A picture of the chart is never sent.
|
|
134
|
+
*/
|
|
135
|
+
export declare function useAssistantChart<Datum>(chart: AssistantChart<Datum>): void;
|
|
136
|
+
/** Props that turn any element into an assistant trigger. */
|
|
137
|
+
export interface AssistantTriggerProps {
|
|
138
|
+
onClick: () => void;
|
|
139
|
+
onKeyDown: (event: {
|
|
140
|
+
key: string;
|
|
141
|
+
preventDefault: () => void;
|
|
142
|
+
}) => void;
|
|
143
|
+
role: "button";
|
|
144
|
+
tabIndex: 0;
|
|
145
|
+
"aria-expanded": boolean;
|
|
146
|
+
"aria-controls": string;
|
|
147
|
+
"aria-haspopup": "dialog";
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Make anything open the assistant — a nav button, a menu item, a card, a
|
|
151
|
+
* plain div.
|
|
152
|
+
*
|
|
153
|
+
* ```tsx
|
|
154
|
+
* const trigger = useAssistantTrigger();
|
|
155
|
+
* return <div {...trigger}>Ask the assistant</div>;
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* The `role`, `tabIndex`, and `onKeyDown` are why this is a hook rather than
|
|
159
|
+
* advice to call `toggle()` yourself: a `div` with only an `onClick` is
|
|
160
|
+
* invisible to keyboards and screen readers, and that is the most common way
|
|
161
|
+
* a custom trigger ships broken. On a real `<button>` they are harmless.
|
|
162
|
+
*
|
|
163
|
+
* **Returns `null` when there is no assistant**, so the caller can render
|
|
164
|
+
* nothing rather than a control that does not work. Triggers live in shared
|
|
165
|
+
* chrome — a command palette, a nav item, a help link — which is exactly the
|
|
166
|
+
* code that renders whether or not a host app has configured the assistant.
|
|
167
|
+
* Throwing there would make the whole surface conditional on something it has
|
|
168
|
+
* no reason to know about.
|
|
169
|
+
*/
|
|
170
|
+
export declare function useAssistantTrigger(): AssistantTriggerProps | null;
|
|
171
|
+
/**
|
|
172
|
+
* A one-tap "ask this" trigger, for suggestion chips and contextual help
|
|
173
|
+
* links.
|
|
174
|
+
*
|
|
175
|
+
* ```tsx
|
|
176
|
+
* <button onClick={useAssistantPrompt("How do I add a product?")}>
|
|
177
|
+
* How do I add a product?
|
|
178
|
+
* </button>
|
|
179
|
+
* ```
|
|
180
|
+
*
|
|
181
|
+
* Sending opens the assistant, so the reply is visible without the host app
|
|
182
|
+
* having to coordinate two calls.
|
|
183
|
+
*
|
|
184
|
+
* `null` when there is no assistant, for the same reason as
|
|
185
|
+
* [`useAssistantTrigger`]: a chip that silently does nothing is worse than one
|
|
186
|
+
* that was never rendered.
|
|
187
|
+
*/
|
|
188
|
+
export declare function useAssistantPrompt(text: string): (() => void) | null;
|
|
189
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../../react/src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EACL,mBAAmB,EAOnB,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AAItB,YAAY,EACV,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAalE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,oBAAoB,GACzB;IAAE,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAE,CAiBnC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAgB9D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,CAsB1D;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,KAAK,EAAE,cAAc,CAAC,GAAG,CAAC,GAAG,IAAI,CAoBvE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAarF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,cAAc,CAAC,KAAK,CAAC,GAAG,IAAI,CAiB3E;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IACxE,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,CAAC,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,QAAQ,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,IAAI,qBAAqB,GAAG,IAAI,CAuBlE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAKpE"}
|