panelui-web 0.4.0 → 0.5.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/components/button/index.d.ts +111 -0
- package/dist/components/button/index.js +45 -0
- package/dist/components/input/index.d.ts +55 -0
- package/dist/components/input/index.js +89 -0
- package/dist/components/menu/index.d.ts +202 -0
- package/dist/components/menu/index.js +188 -0
- package/dist/components/planet/index.js +4 -1
- package/dist/components/prompt/index.d.ts +414 -0
- package/dist/components/prompt/index.js +779 -0
- package/dist/components/select/index.d.ts +134 -0
- package/dist/components/select/index.js +164 -0
- package/dist/components/sheet/index.js +46 -5
- package/dist/components/textarea/index.d.ts +43 -0
- package/dist/components/textarea/index.js +101 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/package.json +1 -1
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
/**
|
|
4
|
+
* Menu — a list of actions that opens from a button.
|
|
5
|
+
*
|
|
6
|
+
* ```tsx
|
|
7
|
+
* <Menu>
|
|
8
|
+
* <Menu.Trigger render={<Button variant="outline" />}>Options</Menu.Trigger>
|
|
9
|
+
* <Menu.Content>
|
|
10
|
+
* <Menu.Item onClick={rename}>
|
|
11
|
+
* <PencilIcon /> Rename <Menu.Shortcut>⌘R</Menu.Shortcut>
|
|
12
|
+
* </Menu.Item>
|
|
13
|
+
* <Menu.Sub>
|
|
14
|
+
* <Menu.SubTrigger><ShareIcon /> Share</Menu.SubTrigger>
|
|
15
|
+
* <Menu.SubContent>
|
|
16
|
+
* <Menu.Item>Copy link</Menu.Item>
|
|
17
|
+
* </Menu.SubContent>
|
|
18
|
+
* </Menu.Sub>
|
|
19
|
+
* <Menu.Separator />
|
|
20
|
+
* <Menu.CheckboxItem checked={pinned} onCheckedChange={setPinned}>Pinned</Menu.CheckboxItem>
|
|
21
|
+
* <Menu.Item variant="destructive">Delete</Menu.Item>
|
|
22
|
+
* </Menu.Content>
|
|
23
|
+
* </Menu>
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* ## One row shape
|
|
27
|
+
*
|
|
28
|
+
* Every row is the same: an icon, the label, and whatever belongs at the end
|
|
29
|
+
* of it, a shortcut, a badge, a check or the chevron of a submenu. Icons are
|
|
30
|
+
* written as the row's first child and sized by the row, so rows with and
|
|
31
|
+
* without them still line up when every row in a group has one.
|
|
32
|
+
*
|
|
33
|
+
* ## Submenus
|
|
34
|
+
*
|
|
35
|
+
* A submenu opens to the side when its row is hovered or pressed, or with
|
|
36
|
+
* the right arrow key, and closes with the left one. The pointer can cross
|
|
37
|
+
* diagonally to it without closing it on the way.
|
|
38
|
+
*
|
|
39
|
+
* ## Items that stay open
|
|
40
|
+
*
|
|
41
|
+
* Pressing an item closes the menu. A check item or a radio item keeps it
|
|
42
|
+
* open, so several can be switched in a row; pass `closeOnClick` to change
|
|
43
|
+
* either.
|
|
44
|
+
*/
|
|
45
|
+
import { Menu as BaseMenu } from '@base-ui/react/menu';
|
|
46
|
+
import { tv } from 'tailwind-variants';
|
|
47
|
+
const menuVariants = tv({
|
|
48
|
+
slots: {
|
|
49
|
+
positioner: 'z-50 outline-none',
|
|
50
|
+
popup: [
|
|
51
|
+
'min-w-48 origin-(--transform-origin) rounded-xl border bg-popover p-1 text-popover-foreground shadow-lg outline-none',
|
|
52
|
+
'max-h-(--available-height) overflow-y-auto [scrollbar-color:var(--border)_transparent] [scrollbar-width:thin]',
|
|
53
|
+
'transition-[opacity,scale] duration-150 ease-out',
|
|
54
|
+
'data-starting-style:scale-95 data-starting-style:opacity-0 data-ending-style:scale-95 data-ending-style:opacity-0',
|
|
55
|
+
'motion-reduce:transition-none',
|
|
56
|
+
],
|
|
57
|
+
item: [
|
|
58
|
+
// The label never wraps; a description beside it is cut short instead.
|
|
59
|
+
'flex min-h-8 cursor-default items-center gap-2.5 whitespace-nowrap rounded-lg px-2 py-1.5 text-sm outline-none select-none',
|
|
60
|
+
'data-highlighted:bg-accent data-highlighted:text-accent-foreground',
|
|
61
|
+
'data-disabled:pointer-events-none data-disabled:opacity-50',
|
|
62
|
+
// A submenu's row stays lit while its submenu is open, so it is clear what it belongs to.
|
|
63
|
+
'data-popup-open:bg-accent',
|
|
64
|
+
'[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=size-])]:size-4',
|
|
65
|
+
'[&>svg:first-child]:text-muted-foreground data-highlighted:[&>svg:first-child]:text-current',
|
|
66
|
+
],
|
|
67
|
+
end: 'ms-auto flex items-center ps-3',
|
|
68
|
+
check: 'ms-auto flex size-4 items-center justify-center ps-0 text-foreground',
|
|
69
|
+
description: 'min-w-0 truncate text-muted-foreground',
|
|
70
|
+
shortcut: 'ms-auto ps-3 text-xs tracking-wide text-muted-foreground',
|
|
71
|
+
badge: 'ms-auto inline-flex h-5 items-center gap-1 rounded-md bg-muted px-1.5 text-xs font-medium tabular-nums text-muted-foreground [&_svg:not([class*=size-])]:size-3',
|
|
72
|
+
chevron: 'ms-auto text-muted-foreground',
|
|
73
|
+
group: 'flex flex-col',
|
|
74
|
+
groupLabel: 'px-2 pb-1 pt-2 text-xs font-medium text-muted-foreground',
|
|
75
|
+
separator: 'mx-2 my-1 h-px bg-border',
|
|
76
|
+
},
|
|
77
|
+
variants: {
|
|
78
|
+
variant: {
|
|
79
|
+
default: {},
|
|
80
|
+
destructive: {
|
|
81
|
+
item: 'text-destructive data-highlighted:bg-destructive/10 data-highlighted:text-destructive [&>svg:first-child]:text-destructive',
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
/** Holds whether the menu is open. Takes `open`/`onOpenChange`, `defaultOpen` and `modal`. */
|
|
87
|
+
function MenuRoot(props) {
|
|
88
|
+
return _jsx(BaseMenu.Root, { ...props });
|
|
89
|
+
}
|
|
90
|
+
MenuRoot.displayName = 'Menu';
|
|
91
|
+
/** The button that opens the menu. `render` draws it as another element, such as a `Button`. */
|
|
92
|
+
function MenuTrigger(props) {
|
|
93
|
+
return _jsx(BaseMenu.Trigger, { "data-slot": "menu-trigger", ...props });
|
|
94
|
+
}
|
|
95
|
+
MenuTrigger.displayName = 'Menu.Trigger';
|
|
96
|
+
/** The list, opened in a layer over the page. It moves to the other side when there is no room. */
|
|
97
|
+
function MenuContent({ side = 'bottom', align = 'start', sideOffset = 6, alignOffset, container, anchor, className, ...props }) {
|
|
98
|
+
const slots = menuVariants();
|
|
99
|
+
return (_jsx(BaseMenu.Portal, { container: container, children: _jsx(BaseMenu.Positioner, { side: side, align: align, sideOffset: sideOffset, alignOffset: alignOffset, anchor: anchor, className: slots.positioner(), children: _jsx(BaseMenu.Popup, { "data-slot": "menu-content", className: slots.popup({ className }), ...props }) }) }));
|
|
100
|
+
}
|
|
101
|
+
MenuContent.displayName = 'Menu.Content';
|
|
102
|
+
/** One action. Put an icon first, then the label, then a `Menu.Shortcut` or `Menu.Badge` if it has one. */
|
|
103
|
+
function MenuItem({ variant, className, ...props }) {
|
|
104
|
+
return _jsx(BaseMenu.Item, { "data-slot": "menu-item", className: menuVariants({ variant }).item({ className }), ...props });
|
|
105
|
+
}
|
|
106
|
+
MenuItem.displayName = 'Menu.Item';
|
|
107
|
+
const Check = () => (_jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.25", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("path", { d: "M20 6 9 17l-5-5" }) }));
|
|
108
|
+
/** An item that is switched on and off, with a check at its end while on. The menu stays open. */
|
|
109
|
+
function MenuCheckboxItem({ className, children, ...props }) {
|
|
110
|
+
const slots = menuVariants();
|
|
111
|
+
return (_jsxs(BaseMenu.CheckboxItem, { "data-slot": "menu-checkbox-item", className: slots.item({ className }), ...props, children: [children, _jsx("span", { className: slots.check(), children: _jsx(BaseMenu.CheckboxItemIndicator, { className: "flex", children: _jsx(Check, {}) }) })] }));
|
|
112
|
+
}
|
|
113
|
+
MenuCheckboxItem.displayName = 'Menu.CheckboxItem';
|
|
114
|
+
/** Radio items of which one is chosen. Takes `value` and `onValueChange`. */
|
|
115
|
+
function MenuRadioGroup({ className, ...props }) {
|
|
116
|
+
return _jsx(BaseMenu.RadioGroup, { "data-slot": "menu-radio-group", className: menuVariants().group({ className }), ...props });
|
|
117
|
+
}
|
|
118
|
+
MenuRadioGroup.displayName = 'Menu.RadioGroup';
|
|
119
|
+
/** One choice in a radio group, with a check at its end while chosen. */
|
|
120
|
+
function MenuRadioItem({ className, children, ...props }) {
|
|
121
|
+
const slots = menuVariants();
|
|
122
|
+
return (_jsxs(BaseMenu.RadioItem, { "data-slot": "menu-radio-item", className: slots.item({ className }), ...props, children: [children, _jsx("span", { className: slots.check(), children: _jsx(BaseMenu.RadioItemIndicator, { className: "flex", children: _jsx(Check, {}) }) })] }));
|
|
123
|
+
}
|
|
124
|
+
MenuRadioItem.displayName = 'Menu.RadioItem';
|
|
125
|
+
/** A submenu: a `Menu.SubTrigger` row and the `Menu.SubContent` it opens. */
|
|
126
|
+
function MenuSub(props) {
|
|
127
|
+
return _jsx(BaseMenu.SubmenuRoot, { ...props });
|
|
128
|
+
}
|
|
129
|
+
MenuSub.displayName = 'Menu.Sub';
|
|
130
|
+
/** The row that opens a submenu, with a chevron at its end. It opens on hover as well as on press. */
|
|
131
|
+
function MenuSubTrigger({ className, children, end, openOnHover = true, delay = 80, ...props }) {
|
|
132
|
+
const slots = menuVariants();
|
|
133
|
+
return (_jsxs(BaseMenu.SubmenuTrigger, { "data-slot": "menu-sub-trigger", openOnHover: openOnHover, delay: delay, className: slots.item({ className }), ...props, children: [children, _jsxs("span", { className: slots.end(), children: [end, _jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: slots.chevron({ className: end ? 'ms-2' : undefined }), children: _jsx("path", { d: "m9 18 6-6-6-6" }) })] })] }));
|
|
134
|
+
}
|
|
135
|
+
MenuSubTrigger.displayName = 'Menu.SubTrigger';
|
|
136
|
+
/** The submenu's list, opened beside its row with the first item level with it. */
|
|
137
|
+
function MenuSubContent({ side = 'inline-end', align = 'start', sideOffset = 6, alignOffset = -5, ...props }) {
|
|
138
|
+
return _jsx(MenuContent, { side: side, align: align, sideOffset: sideOffset, alignOffset: alignOffset, ...props });
|
|
139
|
+
}
|
|
140
|
+
MenuSubContent.displayName = 'Menu.SubContent';
|
|
141
|
+
/** Items that belong together, under a `Menu.GroupLabel`. */
|
|
142
|
+
function MenuGroup({ className, ...props }) {
|
|
143
|
+
return _jsx(BaseMenu.Group, { "data-slot": "menu-group", className: menuVariants().group({ className }), ...props });
|
|
144
|
+
}
|
|
145
|
+
MenuGroup.displayName = 'Menu.Group';
|
|
146
|
+
/** The heading of a group. Screen readers announce the group by it. */
|
|
147
|
+
function MenuGroupLabel({ className, ...props }) {
|
|
148
|
+
return _jsx(BaseMenu.GroupLabel, { "data-slot": "menu-group-label", className: menuVariants().groupLabel({ className }), ...props });
|
|
149
|
+
}
|
|
150
|
+
MenuGroupLabel.displayName = 'Menu.GroupLabel';
|
|
151
|
+
/** A rule between groups of items. */
|
|
152
|
+
function MenuSeparator({ className, ...props }) {
|
|
153
|
+
return _jsx("div", { role: "separator", "data-slot": "menu-separator", className: menuVariants().separator({ className }), ...props });
|
|
154
|
+
}
|
|
155
|
+
MenuSeparator.displayName = 'Menu.Separator';
|
|
156
|
+
/** What an item does, in quieter words after its label. */
|
|
157
|
+
function MenuDescription({ className, ...props }) {
|
|
158
|
+
return _jsx("span", { "data-slot": "menu-description", className: menuVariants().description({ className }), ...props });
|
|
159
|
+
}
|
|
160
|
+
MenuDescription.displayName = 'Menu.Description';
|
|
161
|
+
/** The keys for an item, at its end. It only shows them: wire the keys up where the action lives. */
|
|
162
|
+
function MenuShortcut({ className, ...props }) {
|
|
163
|
+
return _jsx("kbd", { "data-slot": "menu-shortcut", className: menuVariants().shortcut({ className }), ...props });
|
|
164
|
+
}
|
|
165
|
+
MenuShortcut.displayName = 'Menu.Shortcut';
|
|
166
|
+
/** A small count or flag at an item's end: how many need attention, or that something is new. */
|
|
167
|
+
function MenuBadge({ className, ...props }) {
|
|
168
|
+
return _jsx("span", { "data-slot": "menu-badge", className: menuVariants().badge({ className }), ...props });
|
|
169
|
+
}
|
|
170
|
+
MenuBadge.displayName = 'Menu.Badge';
|
|
171
|
+
export const Menu = Object.assign(MenuRoot, {
|
|
172
|
+
Trigger: MenuTrigger,
|
|
173
|
+
Content: MenuContent,
|
|
174
|
+
Item: MenuItem,
|
|
175
|
+
CheckboxItem: MenuCheckboxItem,
|
|
176
|
+
RadioGroup: MenuRadioGroup,
|
|
177
|
+
RadioItem: MenuRadioItem,
|
|
178
|
+
Sub: MenuSub,
|
|
179
|
+
SubTrigger: MenuSubTrigger,
|
|
180
|
+
SubContent: MenuSubContent,
|
|
181
|
+
Group: MenuGroup,
|
|
182
|
+
GroupLabel: MenuGroupLabel,
|
|
183
|
+
Separator: MenuSeparator,
|
|
184
|
+
Description: MenuDescription,
|
|
185
|
+
Shortcut: MenuShortcut,
|
|
186
|
+
Badge: MenuBadge,
|
|
187
|
+
});
|
|
188
|
+
export { MenuTrigger, MenuContent, MenuItem, MenuCheckboxItem, MenuRadioGroup, MenuRadioItem, MenuSub, MenuSubTrigger, MenuSubContent, MenuGroup, MenuGroupLabel, MenuSeparator, MenuDescription, MenuShortcut, MenuBadge, };
|
|
@@ -47,7 +47,10 @@ import { tv } from 'tailwind-variants';
|
|
|
47
47
|
import { LAND, LAND_COLUMNS, LAND_ROWS } from './land.js';
|
|
48
48
|
const planetVariants = tv({
|
|
49
49
|
slots: {
|
|
50
|
-
|
|
50
|
+
// `isolate` keeps the markers' depth ordering inside the planet. Each marker
|
|
51
|
+
// sets its own z-index, and without a stacking context of its own those
|
|
52
|
+
// numbers compete with the page's sidebars and menus, and win.
|
|
53
|
+
root: 'isolate flex w-full flex-col items-center gap-4 text-foreground',
|
|
51
54
|
// `touch-pan-y` leaves a vertical swipe to the page. A globe that traps
|
|
52
55
|
// the scroll it sits in is worse than one that only turns sideways.
|
|
53
56
|
globe: 'relative aspect-square w-full max-w-md cursor-grab touch-pan-y select-none rounded-full outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-4 focus-visible:ring-offset-background active:cursor-grabbing',
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt — where a message to an assistant is written, with what goes with
|
|
3
|
+
* it: files, a model, tools, and a button that sends it.
|
|
4
|
+
*
|
|
5
|
+
* ```tsx
|
|
6
|
+
* <Prompt onSubmit={({ text, files }) => send(text, files)} status={status} onStop={stop}>
|
|
7
|
+
* <Prompt.Field>
|
|
8
|
+
* <Prompt.Attachments />
|
|
9
|
+
* <Prompt.Textarea placeholder="Ask anything" />
|
|
10
|
+
* <Prompt.Footer>
|
|
11
|
+
* <Prompt.Tools>
|
|
12
|
+
* <Prompt.Menu>
|
|
13
|
+
* <Prompt.AttachItem />
|
|
14
|
+
* </Prompt.Menu>
|
|
15
|
+
* <Prompt.Model items={models} defaultValue="swift" />
|
|
16
|
+
* </Prompt.Tools>
|
|
17
|
+
* <Prompt.Submit />
|
|
18
|
+
* </Prompt.Footer>
|
|
19
|
+
* </Prompt.Field>
|
|
20
|
+
* <Prompt.Status>Reading the files</Prompt.Status>
|
|
21
|
+
* </Prompt>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* ## A field in a tray
|
|
25
|
+
*
|
|
26
|
+
* The field is a raised card. What is said about it, rather than in it, sits
|
|
27
|
+
* in bands that the card overlaps: `Prompt.Banner` above for something to do
|
|
28
|
+
* first, `Prompt.Status` below for what the answer is doing, and
|
|
29
|
+
* `Prompt.Context` below, inset, for where the message is going. A band opens
|
|
30
|
+
* and closes with its `open` prop, folding under the card, so a band can come
|
|
31
|
+
* and go without the page jumping by more than its own height.
|
|
32
|
+
*
|
|
33
|
+
* ## Sending
|
|
34
|
+
*
|
|
35
|
+
* Enter sends and Shift+Enter starts a new line; Enter while a character is
|
|
36
|
+
* still being composed is left to the input method. `onSubmit` is handed the
|
|
37
|
+
* text, trimmed, and the files, and the field is cleared. Nothing is sent
|
|
38
|
+
* while it is empty or while `status` is `submitted` or `streaming`.
|
|
39
|
+
*
|
|
40
|
+
* ## One button, four jobs
|
|
41
|
+
*
|
|
42
|
+
* `Prompt.Submit` sends. While the answer is on its way it stops it instead,
|
|
43
|
+
* calling `onStop`, with a ring turning round it. Given `onVoice`, it is a
|
|
44
|
+
* voice button while the field is empty, and its bars move while `listening`.
|
|
45
|
+
* The icons cross-fade in place, so the button never moves under the pointer.
|
|
46
|
+
*
|
|
47
|
+
* ## Files
|
|
48
|
+
*
|
|
49
|
+
* Files arrive from `Prompt.AttachItem` in the menu or `Prompt.Attach`, from
|
|
50
|
+
* ⌘U or Ctrl+U in the field, from a paste, or dropped on the field.
|
|
51
|
+
* `accept` and `maxFiles` decide which are taken, and `onReject` is told about
|
|
52
|
+
* the rest. Images are shown as thumbnails, anything else as a chip with its
|
|
53
|
+
* name and size.
|
|
54
|
+
*/
|
|
55
|
+
import { type ComponentProps, type ReactNode } from 'react';
|
|
56
|
+
import { type ButtonProps } from '../button/index.js';
|
|
57
|
+
import { type MenuContentProps, type MenuItemProps } from '../menu/index.js';
|
|
58
|
+
import { type TextareaProps } from '../textarea/index.js';
|
|
59
|
+
export type PromptState = 'idle' | 'submitted' | 'streaming' | 'error';
|
|
60
|
+
export interface PromptMessage {
|
|
61
|
+
/** What was written, trimmed. */
|
|
62
|
+
text: string;
|
|
63
|
+
/** The files that were attached, in the order they were added. */
|
|
64
|
+
files: File[];
|
|
65
|
+
}
|
|
66
|
+
export interface PromptAttachment {
|
|
67
|
+
id: string;
|
|
68
|
+
file: File;
|
|
69
|
+
/** An object URL for an image, to show it by. */
|
|
70
|
+
preview?: string;
|
|
71
|
+
}
|
|
72
|
+
export type PromptRejectReason = 'accept' | 'max-files';
|
|
73
|
+
export interface PromptProps extends Omit<ComponentProps<'form'>, 'onSubmit' | 'defaultValue'> {
|
|
74
|
+
/** What is written in the field, when the caller holds it. */
|
|
75
|
+
value?: string;
|
|
76
|
+
/** What the field starts with, when the caller does not hold it. */
|
|
77
|
+
defaultValue?: string;
|
|
78
|
+
/** Called with what is written, each time it changes, and with `''` when it is sent. */
|
|
79
|
+
onValueChange?: (value: string) => void;
|
|
80
|
+
/** Called with the text and the files when the message is sent. */
|
|
81
|
+
onSubmit?: (message: PromptMessage) => void;
|
|
82
|
+
/**
|
|
83
|
+
* Where the answer is. `submitted` and `streaming` stop the field being
|
|
84
|
+
* sent and turn the submit button into a stop button; `error` marks the
|
|
85
|
+
* field. Default `idle`.
|
|
86
|
+
*/
|
|
87
|
+
status?: PromptState;
|
|
88
|
+
/** Called when the stop button is pressed. Without it, the button cannot be pressed while busy. */
|
|
89
|
+
onStop?: () => void;
|
|
90
|
+
/** Turns the whole prompt off. */
|
|
91
|
+
disabled?: boolean;
|
|
92
|
+
/** Files attached to begin with, such as those of a message being edited and sent again. */
|
|
93
|
+
defaultFiles?: File[];
|
|
94
|
+
/** Which files can be attached, as for `<input type="file">`: `image/*,.pdf`. Default any. */
|
|
95
|
+
accept?: string;
|
|
96
|
+
/** How many files can be attached at once. Default no limit. */
|
|
97
|
+
maxFiles?: number;
|
|
98
|
+
/** Called with the files that were not taken, and why. */
|
|
99
|
+
onReject?: (files: File[], reason: PromptRejectReason) => void;
|
|
100
|
+
}
|
|
101
|
+
declare function PromptRoot({ value: controlledValue, defaultValue, onValueChange, onSubmit, status, onStop, disabled, defaultFiles, accept, maxFiles, onReject, className, children, ...props }: PromptProps): import("react").JSX.Element;
|
|
102
|
+
declare namespace PromptRoot {
|
|
103
|
+
var displayName: string;
|
|
104
|
+
}
|
|
105
|
+
export interface PromptBannerProps extends ComponentProps<'div'> {
|
|
106
|
+
/** Whether it is shown. It folds under the field when it is not. Default `true`. */
|
|
107
|
+
open?: boolean;
|
|
108
|
+
}
|
|
109
|
+
/** A band above the field, for something to do before or while writing: connect an account, pick a project. */
|
|
110
|
+
declare function PromptBanner({ open, ...props }: PromptBannerProps): import("react").JSX.Element;
|
|
111
|
+
declare namespace PromptBanner {
|
|
112
|
+
var displayName: string;
|
|
113
|
+
}
|
|
114
|
+
export interface PromptBannerActionProps extends ButtonProps {
|
|
115
|
+
}
|
|
116
|
+
/** The banner's button, at its end. */
|
|
117
|
+
declare function PromptBannerAction({ className, size, shape, ...props }: PromptBannerActionProps): import("react").JSX.Element;
|
|
118
|
+
declare namespace PromptBannerAction {
|
|
119
|
+
var displayName: string;
|
|
120
|
+
}
|
|
121
|
+
export interface PromptStatusProps extends ComponentProps<'div'> {
|
|
122
|
+
/** Whether it is shown. Default: while `status` is `submitted` or `streaming`. */
|
|
123
|
+
open?: boolean;
|
|
124
|
+
/** Something before the words: the model's mark, a tool's icon. */
|
|
125
|
+
icon?: ReactNode;
|
|
126
|
+
/** Whether a spinner turns at its end. Default `true`. */
|
|
127
|
+
spinner?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/** A band under the field saying what the answer is doing, with the words lit by a moving sweep. */
|
|
130
|
+
declare function PromptStatus({ open, icon, spinner, children, ...props }: PromptStatusProps): import("react").JSX.Element;
|
|
131
|
+
declare namespace PromptStatus {
|
|
132
|
+
var displayName: string;
|
|
133
|
+
}
|
|
134
|
+
export interface PromptContextProps extends ComponentProps<'div'> {
|
|
135
|
+
}
|
|
136
|
+
/** A strip under the field, inset from its edges, for where the message is going: a branch, a folder, a ticket. */
|
|
137
|
+
declare function PromptContext({ className, ...props }: PromptContextProps): import("react").JSX.Element;
|
|
138
|
+
declare namespace PromptContext {
|
|
139
|
+
var displayName: string;
|
|
140
|
+
}
|
|
141
|
+
export interface PromptContextItemProps extends ComponentProps<'span'> {
|
|
142
|
+
/** Called when it is pressed. Passing this makes the item a button. */
|
|
143
|
+
onSelect?: () => void;
|
|
144
|
+
}
|
|
145
|
+
/** One fact in the context strip, with an icon before it. */
|
|
146
|
+
declare function PromptContextItem({ onSelect, className, children, ...props }: PromptContextItemProps): import("react").JSX.Element;
|
|
147
|
+
declare namespace PromptContextItem {
|
|
148
|
+
var displayName: string;
|
|
149
|
+
}
|
|
150
|
+
export interface PromptHintProps extends ComponentProps<'p'> {
|
|
151
|
+
}
|
|
152
|
+
/** A quiet line under the prompt. Keys written in `<kbd>` are drawn as keys. */
|
|
153
|
+
declare function PromptHint({ className, children, ...props }: PromptHintProps): import("react").JSX.Element;
|
|
154
|
+
declare namespace PromptHint {
|
|
155
|
+
var displayName: string;
|
|
156
|
+
}
|
|
157
|
+
export interface PromptFieldProps extends ComponentProps<'div'> {
|
|
158
|
+
/**
|
|
159
|
+
* `stacked` puts the text above a footer. `inline` puts every part in one
|
|
160
|
+
* row, the text between them, for a one-line composer; the row wraps as
|
|
161
|
+
* the text grows. Default `stacked`.
|
|
162
|
+
*/
|
|
163
|
+
layout?: 'stacked' | 'inline';
|
|
164
|
+
}
|
|
165
|
+
/** The card that holds the text, the files and the footer. Files can be dropped on it. */
|
|
166
|
+
declare function PromptField({ layout, className, onDragOver, onDragLeave, onDrop, ...props }: PromptFieldProps): import("react").JSX.Element;
|
|
167
|
+
declare namespace PromptField {
|
|
168
|
+
var displayName: string;
|
|
169
|
+
}
|
|
170
|
+
export interface PromptTextareaProps extends Omit<TextareaProps, 'value' | 'defaultValue' | 'onChange' | 'variant'> {
|
|
171
|
+
}
|
|
172
|
+
/** Where the message is written. Enter sends, Shift+Enter starts a new line, and pasted files are attached. */
|
|
173
|
+
declare function PromptTextarea({ className, minRows, maxRows, onKeyDown, onPaste, 'aria-label': ariaLabel, ...props }: PromptTextareaProps): import("react").JSX.Element;
|
|
174
|
+
declare namespace PromptTextarea {
|
|
175
|
+
var displayName: string;
|
|
176
|
+
}
|
|
177
|
+
export interface PromptAttachmentsProps extends ComponentProps<'ul'> {
|
|
178
|
+
}
|
|
179
|
+
/** The files attached so far: images as thumbnails, anything else as a chip. Takes no room while there are none. */
|
|
180
|
+
declare function PromptAttachments({ className, 'aria-label': ariaLabel, ...props }: PromptAttachmentsProps): import("react").JSX.Element | null;
|
|
181
|
+
declare namespace PromptAttachments {
|
|
182
|
+
var displayName: string;
|
|
183
|
+
}
|
|
184
|
+
export interface PromptFooterProps extends ComponentProps<'div'> {
|
|
185
|
+
}
|
|
186
|
+
/** The row under the text: tools at the start, the submit button at the end. */
|
|
187
|
+
declare function PromptFooter({ className, ...props }: PromptFooterProps): import("react").JSX.Element;
|
|
188
|
+
declare namespace PromptFooter {
|
|
189
|
+
var displayName: string;
|
|
190
|
+
}
|
|
191
|
+
export interface PromptToolsProps extends ComponentProps<'div'> {
|
|
192
|
+
}
|
|
193
|
+
/** The tools at the start of the footer. Wraps onto a second line where it has to. */
|
|
194
|
+
declare function PromptTools({ className, ...props }: PromptToolsProps): import("react").JSX.Element;
|
|
195
|
+
declare namespace PromptTools {
|
|
196
|
+
var displayName: string;
|
|
197
|
+
}
|
|
198
|
+
export interface PromptToolProps extends Omit<ButtonProps, 'aria-pressed'> {
|
|
199
|
+
/** What it does, for a screen reader and for the tooltip. Shown beside the icon with `showLabel`. */
|
|
200
|
+
label: string;
|
|
201
|
+
/** Whether it is switched on, for a tool that stays on. Leave it out for one that acts once. */
|
|
202
|
+
pressed?: boolean;
|
|
203
|
+
/** Called with the new state when a tool with `pressed` is pressed. */
|
|
204
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
205
|
+
/** Writes the label beside the icon. */
|
|
206
|
+
showLabel?: boolean;
|
|
207
|
+
}
|
|
208
|
+
/** A round button in the footer, holding an icon. With `pressed`, it switches on and off. */
|
|
209
|
+
declare function PromptTool({ label, pressed, onPressedChange, showLabel, onClick, className, children, variant, ...props }: PromptToolProps): import("react").JSX.Element;
|
|
210
|
+
declare namespace PromptTool {
|
|
211
|
+
var displayName: string;
|
|
212
|
+
}
|
|
213
|
+
export interface PromptAttachProps extends Omit<PromptToolProps, 'label' | 'pressed' | 'onPressedChange'> {
|
|
214
|
+
/** Default `Attach files`. */
|
|
215
|
+
label?: string;
|
|
216
|
+
}
|
|
217
|
+
/** A tool that opens the file picker. Files can also be pasted, or dropped on the field. */
|
|
218
|
+
declare function PromptAttach({ label, onClick, children, ...props }: PromptAttachProps): import("react").JSX.Element;
|
|
219
|
+
declare namespace PromptAttach {
|
|
220
|
+
var displayName: string;
|
|
221
|
+
}
|
|
222
|
+
export interface PromptModelItem {
|
|
223
|
+
value: string;
|
|
224
|
+
label: string;
|
|
225
|
+
/** Shown before the label, in the list and on the button once chosen. */
|
|
226
|
+
icon?: ReactNode;
|
|
227
|
+
/** A second line in the list. */
|
|
228
|
+
description?: ReactNode;
|
|
229
|
+
}
|
|
230
|
+
export interface PromptModelProps {
|
|
231
|
+
/** The models to choose from. */
|
|
232
|
+
items: readonly PromptModelItem[];
|
|
233
|
+
/** The chosen model, when the caller holds it. */
|
|
234
|
+
value?: string;
|
|
235
|
+
/** The model chosen to begin with, when the caller does not hold it. */
|
|
236
|
+
defaultValue?: string;
|
|
237
|
+
/** Called with the model's `value` when another is chosen. */
|
|
238
|
+
onValueChange?: (value: string) => void;
|
|
239
|
+
/** `pill` has an edge, like the tools beside it. `ghost` has none until hovered. Default `pill`. */
|
|
240
|
+
variant?: 'pill' | 'ghost';
|
|
241
|
+
/** What a screen reader calls the button. Default `Model`. */
|
|
242
|
+
label?: string;
|
|
243
|
+
className?: string;
|
|
244
|
+
}
|
|
245
|
+
/** Chooses the model the message goes to. The button shows the chosen one's icon and name. */
|
|
246
|
+
declare function PromptModel({ items, value, defaultValue, onValueChange, variant, label, className, }: PromptModelProps): import("react").JSX.Element;
|
|
247
|
+
declare namespace PromptModel {
|
|
248
|
+
var displayName: string;
|
|
249
|
+
}
|
|
250
|
+
export interface PromptMenuProps extends Omit<MenuContentProps, 'children'> {
|
|
251
|
+
/** What a screen reader and the tooltip call the button. Default `Add`. */
|
|
252
|
+
label?: string;
|
|
253
|
+
/** Replaces the plus on the button. */
|
|
254
|
+
icon?: ReactNode;
|
|
255
|
+
/** The menu: `Prompt.AttachItem`, and any `Menu` items, check items and submenus. */
|
|
256
|
+
children?: ReactNode;
|
|
257
|
+
/** `field` opens the menu as wide as the field, lined up with it, for items with descriptions. Default `auto`. */
|
|
258
|
+
width?: 'auto' | 'field';
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* One round button that opens a menu of everything that can be added to the
|
|
262
|
+
* message: files, tools, modes. It keeps the footer to one button however
|
|
263
|
+
* many there are.
|
|
264
|
+
*/
|
|
265
|
+
declare function PromptMenu({ label, icon, children, side, align, width, className, ...props }: PromptMenuProps): import("react").JSX.Element;
|
|
266
|
+
declare namespace PromptMenu {
|
|
267
|
+
var displayName: string;
|
|
268
|
+
}
|
|
269
|
+
export interface PromptAttachItemProps extends Omit<MenuItemProps, 'children'> {
|
|
270
|
+
/** Default `Add files`. */
|
|
271
|
+
children?: ReactNode;
|
|
272
|
+
/** The keys shown at its end. Default `⌘U`; pass `null` for none. ⌘U and Ctrl+U in the field open the picker. */
|
|
273
|
+
shortcut?: ReactNode;
|
|
274
|
+
}
|
|
275
|
+
/** The menu item that opens the file picker. */
|
|
276
|
+
declare function PromptAttachItem({ children, shortcut, onClick, ...props }: PromptAttachItemProps): import("react").JSX.Element;
|
|
277
|
+
declare namespace PromptAttachItem {
|
|
278
|
+
var displayName: string;
|
|
279
|
+
}
|
|
280
|
+
export interface PromptSubmitProps extends Omit<ButtonProps, 'type' | 'children'> {
|
|
281
|
+
/** Makes the button a voice button while the field is empty. Called when it is pressed. */
|
|
282
|
+
onVoice?: () => void;
|
|
283
|
+
/** Whether voice is being heard. The bars move while it is. */
|
|
284
|
+
listening?: boolean;
|
|
285
|
+
/** What a screen reader calls the button while it sends. Default `Send`. */
|
|
286
|
+
sendLabel?: string;
|
|
287
|
+
/** While it stops the answer. Default `Stop`. */
|
|
288
|
+
stopLabel?: string;
|
|
289
|
+
/** While it starts voice. Default `Speak`. */
|
|
290
|
+
voiceLabel?: string;
|
|
291
|
+
}
|
|
292
|
+
/** Sends the message. While busy it stops the answer, and with `onVoice` it starts voice while the field is empty. */
|
|
293
|
+
declare function PromptSubmit({ onVoice, listening, sendLabel, stopLabel, voiceLabel, onClick, className, disabled, ...props }: PromptSubmitProps): import("react").JSX.Element;
|
|
294
|
+
declare namespace PromptSubmit {
|
|
295
|
+
var displayName: string;
|
|
296
|
+
}
|
|
297
|
+
export type PromptTaskStatus = 'pending' | 'active' | 'done' | 'error';
|
|
298
|
+
export interface PromptTasksProps extends Omit<ComponentProps<'div'>, 'title'> {
|
|
299
|
+
/** Whether the band is shown. It folds under the field when it is not. Default `true`. */
|
|
300
|
+
open?: boolean;
|
|
301
|
+
/** What the agent is doing, on the band's one line: "Preparing the release". */
|
|
302
|
+
title: ReactNode;
|
|
303
|
+
/** Whether the list is open under the title, when the caller holds it. */
|
|
304
|
+
expanded?: boolean;
|
|
305
|
+
/** Whether the list starts open, when the caller does not hold it. Default `false`. */
|
|
306
|
+
defaultExpanded?: boolean;
|
|
307
|
+
/** Called when the title is pressed to open or close the list. */
|
|
308
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
309
|
+
/** How tall the list grows before it scrolls, as a CSS length. Default `10rem`. */
|
|
310
|
+
maxHeight?: string;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* A band above the field with an agent's tasks: one line with a ring that
|
|
314
|
+
* fills as they are done, opening into the list. The list scrolls past
|
|
315
|
+
* `maxHeight`, and keeps the task in progress in view.
|
|
316
|
+
*/
|
|
317
|
+
declare function PromptTasks({ open, title, expanded, defaultExpanded, onExpandedChange, maxHeight, className, children, ...props }: PromptTasksProps): import("react").JSX.Element;
|
|
318
|
+
declare namespace PromptTasks {
|
|
319
|
+
var displayName: string;
|
|
320
|
+
}
|
|
321
|
+
export interface PromptTaskProps extends ComponentProps<'li'> {
|
|
322
|
+
/** `pending`, `active` (its words are lit while it runs), `done` (a check) or `error`. Default `pending`. */
|
|
323
|
+
status?: PromptTaskStatus;
|
|
324
|
+
}
|
|
325
|
+
/** One task in `Prompt.Tasks`. */
|
|
326
|
+
declare function PromptTask({ status, className, children, ...props }: PromptTaskProps): import("react").JSX.Element;
|
|
327
|
+
declare namespace PromptTask {
|
|
328
|
+
var displayName: string;
|
|
329
|
+
}
|
|
330
|
+
export interface PromptCommandItem {
|
|
331
|
+
/** What is typed after the trigger to reach it: `summarise` for `/summarise`. */
|
|
332
|
+
value: string;
|
|
333
|
+
/** Its name in the list. Default the trigger and the value. */
|
|
334
|
+
label?: ReactNode;
|
|
335
|
+
/** What it does, after the name. */
|
|
336
|
+
description?: ReactNode;
|
|
337
|
+
icon?: ReactNode;
|
|
338
|
+
}
|
|
339
|
+
export interface PromptCommandsProps {
|
|
340
|
+
/** The commands. */
|
|
341
|
+
items: readonly PromptCommandItem[];
|
|
342
|
+
/** The character that opens the list when the field starts with it. Default `/`. */
|
|
343
|
+
trigger?: string;
|
|
344
|
+
/**
|
|
345
|
+
* Called with the command chosen. With it, the field is cleared and the
|
|
346
|
+
* command is yours to show; without it, the command is written into the field.
|
|
347
|
+
*/
|
|
348
|
+
onSelect?: (item: PromptCommandItem) => void;
|
|
349
|
+
/** The heading over the list. Default `Commands`. */
|
|
350
|
+
label?: ReactNode;
|
|
351
|
+
/** How tall the list grows before it scrolls, as a CSS length. Default `12rem`. */
|
|
352
|
+
maxHeight?: string;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* A band above the field listing commands while the text is a trigger and a
|
|
356
|
+
* word, `/sum`. The arrow keys move through it, Enter or Tab chooses, Escape
|
|
357
|
+
* puts it away.
|
|
358
|
+
*/
|
|
359
|
+
declare function PromptCommands({ items, trigger, onSelect, label, maxHeight }: PromptCommandsProps): import("react").JSX.Element;
|
|
360
|
+
declare namespace PromptCommands {
|
|
361
|
+
var displayName: string;
|
|
362
|
+
}
|
|
363
|
+
export interface PromptRecorderProps extends ComponentProps<'div'> {
|
|
364
|
+
/** What has been heard so far, written in as it arrives. */
|
|
365
|
+
transcript?: ReactNode;
|
|
366
|
+
/** Shown, lit by a moving sweep, until there is a transcript. Default `Listening…`. */
|
|
367
|
+
placeholder?: ReactNode;
|
|
368
|
+
/** Called when the cross is pressed, to throw the recording away. */
|
|
369
|
+
onCancel?: () => void;
|
|
370
|
+
/** Called when the check is pressed, to keep it. */
|
|
371
|
+
onDone?: () => void;
|
|
372
|
+
/**
|
|
373
|
+
* How loud the input is now, from 0 to 1, to draw from a real microphone.
|
|
374
|
+
* Without it the wave moves on its own, as a sign that it is listening.
|
|
375
|
+
*/
|
|
376
|
+
level?: number;
|
|
377
|
+
/** What a screen reader calls the cross. Default `Cancel recording`. */
|
|
378
|
+
cancelLabel?: string;
|
|
379
|
+
/** And the check. Default `Finish recording`. */
|
|
380
|
+
doneLabel?: string;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Takes the place of the text and the footer while voice is recorded: what
|
|
384
|
+
* has been heard so far, the sound as a wave scrolling to the left, how long
|
|
385
|
+
* it has been, and buttons to throw it away or keep it.
|
|
386
|
+
*/
|
|
387
|
+
declare function PromptRecorder({ transcript, placeholder, onCancel, onDone, level, cancelLabel, doneLabel, className, ...props }: PromptRecorderProps): import("react").JSX.Element;
|
|
388
|
+
declare namespace PromptRecorder {
|
|
389
|
+
var displayName: string;
|
|
390
|
+
}
|
|
391
|
+
export declare const Prompt: typeof PromptRoot & {
|
|
392
|
+
Banner: typeof PromptBanner;
|
|
393
|
+
BannerAction: typeof PromptBannerAction;
|
|
394
|
+
Field: typeof PromptField;
|
|
395
|
+
Attachments: typeof PromptAttachments;
|
|
396
|
+
Textarea: typeof PromptTextarea;
|
|
397
|
+
Footer: typeof PromptFooter;
|
|
398
|
+
Tools: typeof PromptTools;
|
|
399
|
+
Tool: typeof PromptTool;
|
|
400
|
+
Attach: typeof PromptAttach;
|
|
401
|
+
Menu: typeof PromptMenu;
|
|
402
|
+
AttachItem: typeof PromptAttachItem;
|
|
403
|
+
Model: typeof PromptModel;
|
|
404
|
+
Submit: typeof PromptSubmit;
|
|
405
|
+
Status: typeof PromptStatus;
|
|
406
|
+
Tasks: typeof PromptTasks;
|
|
407
|
+
Task: typeof PromptTask;
|
|
408
|
+
Commands: typeof PromptCommands;
|
|
409
|
+
Recorder: typeof PromptRecorder;
|
|
410
|
+
Context: typeof PromptContext;
|
|
411
|
+
ContextItem: typeof PromptContextItem;
|
|
412
|
+
Hint: typeof PromptHint;
|
|
413
|
+
};
|
|
414
|
+
export { PromptBanner, PromptBannerAction, PromptField, PromptAttachments, PromptTextarea, PromptFooter, PromptTools, PromptTool, PromptAttach, PromptMenu, PromptAttachItem, PromptModel, PromptSubmit, PromptStatus, PromptTasks, PromptTask, PromptCommands, PromptRecorder, PromptContext, PromptContextItem, PromptHint, };
|