@robr0/design-system 0.3.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/README.md +30 -27
- package/components/AgentStatus/AgentStatus.css +496 -0
- package/components/AgentStatus/AgentStatus.d.ts +41 -0
- package/components/AgentStatus/AgentStatus.js +85 -0
- package/components/AgentStatus/AgentStatusPatterns.d.ts +17 -0
- package/components/AgentStatus/AgentStatusPatterns.js +20 -0
- package/components/AiButton/AiButton.css +163 -0
- package/components/AiButton/AiButton.d.ts +36 -0
- package/components/AiButton/AiButton.js +58 -0
- package/components/AlertDialog/AlertDialog.css +5 -5
- package/components/Button/Button.d.ts +14 -2
- package/components/ButtonGroup/ButtonGroup.js +2 -9
- package/components/ChatHeader/ChatHeader.css +35 -0
- package/components/ChatHeader/ChatHeader.d.ts +30 -0
- package/components/ChatHeader/ChatHeader.js +17 -0
- package/components/ChatMarker/ChatMarker.css +52 -0
- package/components/ChatMarker/ChatMarker.d.ts +22 -0
- package/components/ChatMarker/ChatMarker.js +18 -0
- package/components/ChatMessage/ChatMessage.css +304 -0
- package/components/ChatMessage/ChatMessage.d.ts +68 -0
- package/components/ChatMessage/ChatMessage.js +69 -0
- package/components/ChatThread/ChatThread.css +171 -0
- package/components/ChatThread/ChatThread.d.ts +41 -0
- package/components/ChatThread/ChatThread.js +174 -0
- package/components/Checkbox/Checkbox.d.ts +17 -3
- package/components/Chip/Chip.css +27 -0
- package/components/Chip/Chip.d.ts +2 -2
- package/components/CircularButton/CircularButton.d.ts +31 -10
- package/components/CircularButton/CircularButton.js +54 -50
- package/components/CodeBlock/CodeBlock.css +2 -2
- package/components/Combobox/Combobox.d.ts +10 -2
- package/components/Composer/Composer.css +164 -0
- package/components/Composer/Composer.d.ts +67 -0
- package/components/Composer/Composer.js +120 -0
- package/components/ContextMenu/ContextMenu.css +0 -4
- package/components/DateInput/DateInput.d.ts +5 -1
- package/components/Dialog/Dialog.css +5 -5
- package/components/DocumentChip/DocumentChip.css +181 -0
- package/components/DocumentChip/DocumentChip.d.ts +41 -0
- package/components/DocumentChip/DocumentChip.js +78 -0
- package/components/Dropdown/Dropdown.css +2 -4
- package/components/Dropdown/Dropdown.d.ts +10 -2
- package/components/DropdownMenu/DropdownMenu.css +2 -4
- package/components/FileInput/FileInput.d.ts +5 -1
- package/components/Input/Input.d.ts +5 -1
- package/components/InterruptCard/InterruptCard.css +164 -0
- package/components/InterruptCard/InterruptCard.d.ts +55 -0
- package/components/InterruptCard/InterruptCard.js +57 -0
- package/components/LinkList/LinkList.d.ts +1 -0
- package/components/MessageActions/MessageActions.css +76 -0
- package/components/MessageActions/MessageActions.d.ts +38 -0
- package/components/MessageActions/MessageActions.js +33 -0
- package/components/MessageCard/MessageCard.css +112 -0
- package/components/MessageCard/MessageCard.d.ts +35 -0
- package/components/MessageCard/MessageCard.js +28 -0
- package/components/NavList/NavList.css +155 -0
- package/components/NavList/NavList.d.ts +56 -0
- package/components/NavList/NavList.js +99 -0
- package/components/PromptSuggestions/PromptSuggestions.css +87 -0
- package/components/PromptSuggestions/PromptSuggestions.d.ts +51 -0
- package/components/PromptSuggestions/PromptSuggestions.js +34 -0
- package/components/Prose/Prose.css +252 -0
- package/components/Prose/Prose.d.ts +21 -0
- package/components/Prose/Prose.js +14 -0
- package/components/RadioButton/RadioButton.d.ts +17 -3
- package/components/Reasoning/Reasoning.css +276 -0
- package/components/Reasoning/Reasoning.d.ts +55 -0
- package/components/Reasoning/Reasoning.js +98 -0
- package/components/SelectionCard/SelectionCard.d.ts +5 -1
- package/components/Slider/Slider.d.ts +5 -1
- package/components/SourceChip/SourceChip.css +102 -0
- package/components/SourceChip/SourceChip.d.ts +32 -0
- package/components/SourceChip/SourceChip.js +31 -0
- package/components/Stat/Stat.css +2 -2
- package/components/Textarea/Textarea.d.ts +5 -1
- package/components/Timeline/Timeline.d.ts +2 -0
- package/components/ToggleGroup/ToggleGroup.d.ts +10 -2
- package/components/ToggleSwitch/ToggleSwitch.d.ts +10 -2
- package/components/ToolCall/ToolCall.css +213 -0
- package/components/ToolCall/ToolCall.d.ts +43 -0
- package/components/ToolCall/ToolCall.js +89 -0
- package/components/registry.json +145 -8
- package/components/registry.json.d.ts +145 -8
- package/components/registry.json.js +2 -2
- package/index.d.ts +18 -0
- package/index.js +36 -0
- package/package.json +8 -4
- package/tokens/registry.json +13 -0
- package/tokens/registry.json.d.ts +13 -0
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-dark.css +13 -0
- package/tokens/tokens-light.css +42 -0
- package/tokens/tokens-motion.css +3 -1
- package/tokens/tokens-typography.css +24 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useId, useState, useRef, useEffect, useCallback } from "react";
|
|
3
|
+
import "./Reasoning.css";
|
|
4
|
+
import "../../fonts/material-symbols.css";
|
|
5
|
+
const Reasoning = React.forwardRef(
|
|
6
|
+
({
|
|
7
|
+
streaming = false,
|
|
8
|
+
duration,
|
|
9
|
+
label,
|
|
10
|
+
summary,
|
|
11
|
+
summaryOnly = false,
|
|
12
|
+
size = "default",
|
|
13
|
+
open,
|
|
14
|
+
defaultOpen,
|
|
15
|
+
onOpenChange,
|
|
16
|
+
className = "",
|
|
17
|
+
children,
|
|
18
|
+
...rest
|
|
19
|
+
}, ref) => {
|
|
20
|
+
const baseClass = "ds-reasoning";
|
|
21
|
+
const id = useId();
|
|
22
|
+
const panelId = `${id}-panel`;
|
|
23
|
+
const triggerId = `${id}-trigger`;
|
|
24
|
+
const isControlled = open !== void 0;
|
|
25
|
+
const [uncontrolledOpen, setUncontrolledOpen] = useState(defaultOpen ?? streaming);
|
|
26
|
+
const isOpen = isControlled ? open : uncontrolledOpen;
|
|
27
|
+
const [leaving, setLeaving] = useState(null);
|
|
28
|
+
const prevSummary = useRef(summary);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (prevSummary.current != null && summary == null) {
|
|
31
|
+
setLeaving(prevSummary.current);
|
|
32
|
+
}
|
|
33
|
+
prevSummary.current = summary;
|
|
34
|
+
}, [summary]);
|
|
35
|
+
const readerDecided = useRef(false);
|
|
36
|
+
const wasStreaming = useRef(streaming);
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
if (streaming === wasStreaming.current) return;
|
|
39
|
+
wasStreaming.current = streaming;
|
|
40
|
+
if (readerDecided.current) return;
|
|
41
|
+
if (!isControlled) setUncontrolledOpen(streaming);
|
|
42
|
+
onOpenChange?.(streaming);
|
|
43
|
+
}, [streaming, isControlled, onOpenChange]);
|
|
44
|
+
const toggle = useCallback(() => {
|
|
45
|
+
readerDecided.current = true;
|
|
46
|
+
const next = !isOpen;
|
|
47
|
+
if (!isControlled) setUncontrolledOpen(next);
|
|
48
|
+
onOpenChange?.(next);
|
|
49
|
+
}, [isOpen, isControlled, onOpenChange]);
|
|
50
|
+
const summaryText = label ?? (streaming ? "Thinking" : duration !== void 0 ? `Thought for ${duration}s` : "Thought process");
|
|
51
|
+
const classes = [
|
|
52
|
+
baseClass,
|
|
53
|
+
`${baseClass}--${size}`,
|
|
54
|
+
isOpen ? `${baseClass}--open` : "",
|
|
55
|
+
streaming ? `${baseClass}--streaming` : "",
|
|
56
|
+
className
|
|
57
|
+
].filter(Boolean).join(" ");
|
|
58
|
+
const summaryLine = /* @__PURE__ */ jsxs(
|
|
59
|
+
"span",
|
|
60
|
+
{
|
|
61
|
+
className: `${baseClass}__summary${summary ? ` ${baseClass}__summary--node` : ""}${leaving != null && summary == null ? ` ${baseClass}__summary--entering` : ""}`,
|
|
62
|
+
role: summary ? void 0 : "status",
|
|
63
|
+
onAnimationEnd: (e) => {
|
|
64
|
+
if (e.target === e.currentTarget) setLeaving(null);
|
|
65
|
+
},
|
|
66
|
+
children: [
|
|
67
|
+
leaving != null && summary == null && /* @__PURE__ */ jsx("span", { className: `${baseClass}__summary-leaving`, "aria-hidden": "true", children: leaving }),
|
|
68
|
+
summary ?? summaryText
|
|
69
|
+
]
|
|
70
|
+
}
|
|
71
|
+
);
|
|
72
|
+
if (summaryOnly) {
|
|
73
|
+
return /* @__PURE__ */ jsx("div", { ...rest, ref, className: classes, children: /* @__PURE__ */ jsx("span", { className: `${baseClass}__trigger ${baseClass}__trigger--static`, children: summaryLine }) });
|
|
74
|
+
}
|
|
75
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes, children: [
|
|
76
|
+
/* @__PURE__ */ jsxs(
|
|
77
|
+
"button",
|
|
78
|
+
{
|
|
79
|
+
type: "button",
|
|
80
|
+
id: triggerId,
|
|
81
|
+
className: `${baseClass}__trigger`,
|
|
82
|
+
"aria-expanded": isOpen,
|
|
83
|
+
"aria-controls": panelId,
|
|
84
|
+
onClick: toggle,
|
|
85
|
+
children: [
|
|
86
|
+
summaryLine,
|
|
87
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__chevron material-symbols-rounded`, "aria-hidden": "true", children: "expand_more" })
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
),
|
|
91
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__panel`, id: panelId, role: "region", "aria-labelledby": triggerId, children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__content`, children }) })
|
|
92
|
+
] });
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
Reasoning.displayName = "Reasoning";
|
|
96
|
+
export {
|
|
97
|
+
Reasoning
|
|
98
|
+
};
|
|
@@ -23,7 +23,11 @@ type SelectionCardOwnProps = {
|
|
|
23
23
|
name?: string;
|
|
24
24
|
/** Additional CSS classes */
|
|
25
25
|
className?: string;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Legacy change handler, kept for backwards compatibility.
|
|
28
|
+
*
|
|
29
|
+
* @deprecated Use `onValueChange` instead.
|
|
30
|
+
*/
|
|
27
31
|
onChange?: (value: string | string[]) => void;
|
|
28
32
|
};
|
|
29
33
|
export interface SelectionCardProps extends SelectionCardOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof SelectionCardOwnProps> {
|
|
@@ -19,7 +19,11 @@ type SliderOwnProps = {
|
|
|
19
19
|
onValueChange?: (value: number) => void;
|
|
20
20
|
/** Additional CSS classes — applied to the wrapper, not the <input> */
|
|
21
21
|
className?: string;
|
|
22
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Legacy accessible-name prop.
|
|
24
|
+
*
|
|
25
|
+
* @deprecated Pass the native `aria-label` attribute instead.
|
|
26
|
+
*/
|
|
23
27
|
ariaLabel?: string;
|
|
24
28
|
};
|
|
25
29
|
export interface SliderProps extends SliderOwnProps, Omit<React.ComponentPropsWithoutRef<'input'>, keyof SliderOwnProps | 'type'> {
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
SOURCE CHIP COMPONENT
|
|
3
|
+
Numbered citation pill linking a claim to
|
|
4
|
+
its source. Anchor when href is set, plain
|
|
5
|
+
span otherwise.
|
|
6
|
+
============================================ */
|
|
7
|
+
|
|
8
|
+
.ds-source-chip {
|
|
9
|
+
/* Layout */
|
|
10
|
+
display: inline-flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
gap: var(--gap-xs); /* 4px */
|
|
13
|
+
|
|
14
|
+
/* Spacing */
|
|
15
|
+
padding: var(--padding-xxxs) var(--padding-sm); /* 2px 8px */
|
|
16
|
+
|
|
17
|
+
/* Shape — borderless pill on the secondary container */
|
|
18
|
+
border-radius: var(--radius-full);
|
|
19
|
+
background-color: var(--color-bg-container-secondary);
|
|
20
|
+
|
|
21
|
+
/* Typography */
|
|
22
|
+
font-family: var(--font-paragraph-sm-family);
|
|
23
|
+
font-size: var(--font-paragraph-sm-size);
|
|
24
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
25
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
26
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
27
|
+
color: var(--color-text-secondary);
|
|
28
|
+
|
|
29
|
+
/* The pill shape is the affordance — never an underline */
|
|
30
|
+
text-decoration: none;
|
|
31
|
+
cursor: default;
|
|
32
|
+
|
|
33
|
+
transition: background-color var(--motion-duration-fast) var(--motion-ease-standard),
|
|
34
|
+
color var(--motion-duration-fast) var(--motion-ease-standard);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* ============================================
|
|
38
|
+
INDEX — citation numeral in its own circle
|
|
39
|
+
============================================ */
|
|
40
|
+
|
|
41
|
+
.ds-source-chip__index {
|
|
42
|
+
display: inline-flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
justify-content: center;
|
|
45
|
+
flex-shrink: 0;
|
|
46
|
+
min-width: var(--icon-size-sm);
|
|
47
|
+
height: var(--icon-size-sm);
|
|
48
|
+
border-radius: var(--radius-full);
|
|
49
|
+
background-color: var(--color-bg-container-tertiary);
|
|
50
|
+
|
|
51
|
+
font-family: var(--font-paragraph-sm-em-family);
|
|
52
|
+
font-size: var(--font-paragraph-sm-em-size);
|
|
53
|
+
font-weight: var(--font-paragraph-sm-em-weight);
|
|
54
|
+
letter-spacing: var(--font-paragraph-sm-em-letter-spacing);
|
|
55
|
+
line-height: 1;
|
|
56
|
+
font-variant-numeric: tabular-nums;
|
|
57
|
+
color: var(--color-text-tertiary);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ============================================
|
|
61
|
+
ICON (leading, when no index)
|
|
62
|
+
============================================ */
|
|
63
|
+
|
|
64
|
+
.ds-source-chip__icon {
|
|
65
|
+
flex-shrink: 0;
|
|
66
|
+
--icon-size: var(--icon-size-sm);
|
|
67
|
+
line-height: 1;
|
|
68
|
+
color: var(--color-icon-primary);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* ============================================
|
|
72
|
+
TITLE — truncates with an ellipsis
|
|
73
|
+
============================================ */
|
|
74
|
+
|
|
75
|
+
.ds-source-chip__title {
|
|
76
|
+
max-width: 24ch;
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
white-space: nowrap;
|
|
79
|
+
text-overflow: ellipsis;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* ============================================
|
|
83
|
+
LINK (rendered as <a>)
|
|
84
|
+
============================================ */
|
|
85
|
+
|
|
86
|
+
.ds-source-chip--link {
|
|
87
|
+
cursor: pointer;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.ds-source-chip--link:hover {
|
|
91
|
+
background-color: var(--color-bg-container-tertiary);
|
|
92
|
+
color: var(--color-text-primary);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* ============================================
|
|
96
|
+
FOCUS
|
|
97
|
+
============================================ */
|
|
98
|
+
|
|
99
|
+
.ds-source-chip--link:focus-visible {
|
|
100
|
+
outline: 2px solid var(--color-action-primary-bg);
|
|
101
|
+
outline-offset: 2px;
|
|
102
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
/** Props owned by SourceChip itself — everything else falls through to the root element. */
|
|
3
|
+
type SourceChipOwnProps = {
|
|
4
|
+
/** The source name, e.g. "Design tokens quarterly". Truncates with an ellipsis when long. */
|
|
5
|
+
title: string;
|
|
6
|
+
/** Citation number, rendered as a leading numeral in its own small badge circle. */
|
|
7
|
+
index?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Leading icon — a Material Symbol name (string) or custom element (ReactNode).
|
|
10
|
+
* The icon and the index share the leading slot: when both are passed, `index` wins
|
|
11
|
+
* and the icon is not rendered.
|
|
12
|
+
*/
|
|
13
|
+
icon?: string | React.ReactNode;
|
|
14
|
+
/** Optional href — renders as an `<a>` instead of a `<span>`. */
|
|
15
|
+
href?: string;
|
|
16
|
+
/** Additional CSS classes */
|
|
17
|
+
className?: string;
|
|
18
|
+
};
|
|
19
|
+
export interface SourceChipProps extends SourceChipOwnProps, Omit<React.ComponentPropsWithoutRef<'a'>, keyof SourceChipOwnProps> {
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* SourceChip is the numbered citation pill linking a claim to its source.
|
|
23
|
+
* It renders inline after a sentence or in a sources row under an assistant
|
|
24
|
+
* chat message: a leading citation number (or icon) beside a truncating
|
|
25
|
+
* source title.
|
|
26
|
+
*
|
|
27
|
+
* Renders an `<a>` when `href` is supplied, a plain `<span>` otherwise.
|
|
28
|
+
* Forwards a ref to whichever element it renders, and spreads unrecognised
|
|
29
|
+
* props onto it — `target` and `rel` pass through as native anchor attributes.
|
|
30
|
+
*/
|
|
31
|
+
export declare const SourceChip: React.ForwardRefExoticComponent<SourceChipProps & React.RefAttributes<HTMLSpanElement | HTMLAnchorElement>>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import "./SourceChip.css";
|
|
4
|
+
import "../../fonts/material-symbols.css";
|
|
5
|
+
const SourceChip = React.forwardRef(
|
|
6
|
+
({ title, index, icon, href, className = "", ...rest }, ref) => {
|
|
7
|
+
const baseClass = "ds-source-chip";
|
|
8
|
+
const classes = [baseClass, href ? `${baseClass}--link` : "", className].filter(Boolean).join(" ");
|
|
9
|
+
const leading = index !== void 0 ? /* @__PURE__ */ jsx("span", { className: `${baseClass}__index`, children: index }) : icon ? /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon`, "aria-hidden": "true", children: typeof icon === "string" ? /* @__PURE__ */ jsx("span", { className: "material-symbols-rounded", children: icon }) : icon }) : null;
|
|
10
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
11
|
+
leading,
|
|
12
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__title`, children: title })
|
|
13
|
+
] });
|
|
14
|
+
if (href) {
|
|
15
|
+
return /* @__PURE__ */ jsx("a", { ...rest, ref, className: classes, href, children: content });
|
|
16
|
+
}
|
|
17
|
+
return /* @__PURE__ */ jsx(
|
|
18
|
+
"span",
|
|
19
|
+
{
|
|
20
|
+
...rest,
|
|
21
|
+
ref,
|
|
22
|
+
className: classes,
|
|
23
|
+
children: content
|
|
24
|
+
}
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
SourceChip.displayName = "SourceChip";
|
|
29
|
+
export {
|
|
30
|
+
SourceChip
|
|
31
|
+
};
|
package/components/Stat/Stat.css
CHANGED
|
@@ -66,11 +66,11 @@
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
.ds-stat__delta--up {
|
|
69
|
-
color: var(--color-
|
|
69
|
+
color: var(--color-core-accent-mint);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
.ds-stat__delta--down {
|
|
73
|
-
color: var(--color-
|
|
73
|
+
color: var(--color-core-accent-coral);
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
.ds-stat__delta--neutral {
|
|
@@ -23,7 +23,11 @@ type TextareaOwnProps = {
|
|
|
23
23
|
onValueChange?: (value: string) => void;
|
|
24
24
|
/** Additional CSS classes — applied to the wrapper, not the <textarea> */
|
|
25
25
|
className?: string;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Legacy accessible-name prop.
|
|
28
|
+
*
|
|
29
|
+
* @deprecated Pass the native `aria-label` attribute instead.
|
|
30
|
+
*/
|
|
27
31
|
ariaLabel?: string;
|
|
28
32
|
};
|
|
29
33
|
export interface TextareaProps extends TextareaOwnProps, Omit<React.ComponentPropsWithoutRef<'textarea'>, keyof TextareaOwnProps> {
|
|
@@ -35,6 +35,7 @@ export interface TimelineCompany {
|
|
|
35
35
|
}
|
|
36
36
|
/** Default variant — a flat sequence of steps/events with dot, badge, or icon markers. */
|
|
37
37
|
export interface TimelineDefaultProps {
|
|
38
|
+
/** Selects the flat step/event layout — the default when omitted */
|
|
38
39
|
variant?: 'default';
|
|
39
40
|
/** Ordered list of steps/events */
|
|
40
41
|
items: TimelineItem[];
|
|
@@ -47,6 +48,7 @@ export interface TimelineDefaultProps {
|
|
|
47
48
|
}
|
|
48
49
|
/** Company variant — grouped roles under a logo, for résumé/pipeline histories. */
|
|
49
50
|
export interface TimelineCompanyProps {
|
|
51
|
+
/** Selects the grouped layout: roles nested under a company logo */
|
|
50
52
|
variant: 'company';
|
|
51
53
|
/** Ordered list of company/tool entries */
|
|
52
54
|
items: TimelineCompany[];
|
|
@@ -23,9 +23,17 @@ type ToggleGroupOwnProps = {
|
|
|
23
23
|
onValueChange?: (value: string | string[]) => void;
|
|
24
24
|
/** Additional CSS classes */
|
|
25
25
|
className?: string;
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Legacy change handler, kept for backwards compatibility.
|
|
28
|
+
*
|
|
29
|
+
* @deprecated Use `onValueChange` instead.
|
|
30
|
+
*/
|
|
27
31
|
onChange?: (value: string | string[]) => void;
|
|
28
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Legacy accessible-name prop.
|
|
34
|
+
*
|
|
35
|
+
* @deprecated Pass the native `aria-label` attribute instead.
|
|
36
|
+
*/
|
|
29
37
|
ariaLabel?: string;
|
|
30
38
|
};
|
|
31
39
|
export interface ToggleGroupProps extends ToggleGroupOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof ToggleGroupOwnProps> {
|
|
@@ -13,9 +13,17 @@ type ToggleSwitchOwnProps = {
|
|
|
13
13
|
onCheckedChange?: (checked: boolean) => void;
|
|
14
14
|
/** Additional CSS classes */
|
|
15
15
|
className?: string;
|
|
16
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Legacy change handler, kept for backwards compatibility.
|
|
18
|
+
*
|
|
19
|
+
* @deprecated Use `onCheckedChange` instead.
|
|
20
|
+
*/
|
|
17
21
|
onChange?: (checked: boolean) => void;
|
|
18
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Legacy accessible-name prop.
|
|
24
|
+
*
|
|
25
|
+
* @deprecated Pass the native `aria-label` attribute instead.
|
|
26
|
+
*/
|
|
19
27
|
ariaLabel?: string;
|
|
20
28
|
};
|
|
21
29
|
export interface ToggleSwitchProps extends ToggleSwitchOwnProps, Omit<React.ComponentPropsWithoutRef<'button'>, keyof ToggleSwitchOwnProps | 'type'> {
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
TOOL CALL COMPONENT
|
|
3
|
+
One tool invocation: a skimmable header row
|
|
4
|
+
and, behind a disclosure, the arguments and
|
|
5
|
+
the result.
|
|
6
|
+
|
|
7
|
+
The container stays neutral — colour lives in
|
|
8
|
+
the indicator and the status word, so a long
|
|
9
|
+
run of calls reads as a list rather than a
|
|
10
|
+
wall of tinted cards. The two states a person
|
|
11
|
+
has to act on, pending and error, also take a
|
|
12
|
+
coloured border.
|
|
13
|
+
============================================ */
|
|
14
|
+
|
|
15
|
+
.ds-tool-call {
|
|
16
|
+
--ds-tool-call-color: var(--color-text-secondary);
|
|
17
|
+
--ds-tool-call-border: var(--color-bg-container-border);
|
|
18
|
+
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
width: 100%;
|
|
22
|
+
background-color: var(--color-bg-container-primary);
|
|
23
|
+
border: var(--border-xs) solid var(--ds-tool-call-border);
|
|
24
|
+
border-radius: var(--radius-md);
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* ============================================
|
|
29
|
+
HEADER
|
|
30
|
+
============================================ */
|
|
31
|
+
|
|
32
|
+
.ds-tool-call__header {
|
|
33
|
+
display: flex;
|
|
34
|
+
align-items: center;
|
|
35
|
+
gap: var(--gap-sm);
|
|
36
|
+
width: 100%;
|
|
37
|
+
padding: var(--padding-xs) var(--padding-sm-md);
|
|
38
|
+
background: none;
|
|
39
|
+
border: none;
|
|
40
|
+
text-align: left;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
transition: background-color var(--motion-duration-fast) var(--motion-ease-standard);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.ds-tool-call__header:hover {
|
|
46
|
+
background-color: var(--color-bg-container-secondary);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ds-tool-call__header:focus-visible {
|
|
50
|
+
outline: 2px solid var(--color-action-primary-bg);
|
|
51
|
+
outline-offset: -2px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* No panel to open — the row is a plain div and must not look pressable */
|
|
55
|
+
.ds-tool-call__header--static {
|
|
56
|
+
cursor: default;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ds-tool-call__header--static:hover {
|
|
60
|
+
background-color: transparent;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.ds-tool-call__indicator {
|
|
64
|
+
display: inline-flex;
|
|
65
|
+
align-items: center;
|
|
66
|
+
justify-content: center;
|
|
67
|
+
flex: none;
|
|
68
|
+
color: var(--ds-tool-call-color);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.ds-tool-call__indicator .material-symbols-rounded {
|
|
72
|
+
--icon-size: var(--icon-size-sm);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* The tool name is an identifier, so it takes the code stack —
|
|
76
|
+
the one place the system leaves Nunito Sans */
|
|
77
|
+
.ds-tool-call__name {
|
|
78
|
+
flex: none;
|
|
79
|
+
font-family: var(--font-family-code);
|
|
80
|
+
font-size: var(--font-paragraph-sm-size);
|
|
81
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
82
|
+
color: var(--color-text-primary);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.ds-tool-call__summary {
|
|
86
|
+
flex: 1 1 auto;
|
|
87
|
+
min-width: 0;
|
|
88
|
+
overflow: hidden;
|
|
89
|
+
text-overflow: ellipsis;
|
|
90
|
+
white-space: nowrap;
|
|
91
|
+
color: var(--color-text-tertiary);
|
|
92
|
+
font-family: var(--font-paragraph-sm-family);
|
|
93
|
+
font-size: var(--font-paragraph-sm-size);
|
|
94
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
95
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
96
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.ds-tool-call__status {
|
|
100
|
+
flex: none;
|
|
101
|
+
margin-left: auto;
|
|
102
|
+
color: var(--ds-tool-call-color);
|
|
103
|
+
font-family: var(--font-paragraph-sm-em-family);
|
|
104
|
+
font-size: var(--font-paragraph-sm-em-size);
|
|
105
|
+
font-weight: var(--font-paragraph-sm-em-weight);
|
|
106
|
+
line-height: var(--font-paragraph-sm-em-line-height);
|
|
107
|
+
letter-spacing: var(--font-paragraph-sm-em-letter-spacing);
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/* A summary already claims the free space; without one the status still
|
|
112
|
+
needs pushing to the right, which the auto margin above handles */
|
|
113
|
+
.ds-tool-call__summary ~ .ds-tool-call__status {
|
|
114
|
+
margin-left: 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.ds-tool-call__duration {
|
|
118
|
+
flex: none;
|
|
119
|
+
color: var(--color-text-tertiary);
|
|
120
|
+
font-family: var(--font-paragraph-sm-family);
|
|
121
|
+
font-size: var(--font-paragraph-sm-size);
|
|
122
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
123
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
124
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
125
|
+
font-variant-numeric: tabular-nums;
|
|
126
|
+
white-space: nowrap;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.ds-tool-call__chevron {
|
|
130
|
+
--icon-size: var(--icon-size-sm);
|
|
131
|
+
|
|
132
|
+
flex: none;
|
|
133
|
+
color: var(--color-icon-secondary);
|
|
134
|
+
transition: transform var(--motion-duration-slow) var(--motion-ease-standard);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.ds-tool-call--open .ds-tool-call__chevron {
|
|
138
|
+
transform: rotate(180deg);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* ============================================
|
|
142
|
+
STATUSES
|
|
143
|
+
============================================ */
|
|
144
|
+
|
|
145
|
+
.ds-tool-call--pending {
|
|
146
|
+
--ds-tool-call-color: var(--color-status-warning-text);
|
|
147
|
+
--ds-tool-call-border: var(--color-status-warning-border);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.ds-tool-call--running {
|
|
151
|
+
--ds-tool-call-color: var(--color-status-info-text);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.ds-tool-call--success {
|
|
155
|
+
--ds-tool-call-color: var(--color-status-positive-text);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.ds-tool-call--error {
|
|
159
|
+
--ds-tool-call-color: var(--color-status-error-text);
|
|
160
|
+
--ds-tool-call-border: var(--color-status-error-border);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/* ============================================
|
|
164
|
+
PANEL
|
|
165
|
+
============================================ */
|
|
166
|
+
|
|
167
|
+
.ds-tool-call__panel {
|
|
168
|
+
display: grid;
|
|
169
|
+
grid-template-rows: 0fr;
|
|
170
|
+
visibility: hidden;
|
|
171
|
+
transition:
|
|
172
|
+
grid-template-rows var(--motion-duration-slow) var(--motion-ease-standard),
|
|
173
|
+
visibility var(--motion-duration-slow) var(--motion-ease-standard);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.ds-tool-call--open .ds-tool-call__panel {
|
|
177
|
+
grid-template-rows: 1fr;
|
|
178
|
+
visibility: visible;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.ds-tool-call__content {
|
|
182
|
+
overflow: hidden;
|
|
183
|
+
min-height: 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.ds-tool-call--open .ds-tool-call__content {
|
|
187
|
+
padding: var(--padding-sm-md);
|
|
188
|
+
border-top: var(--border-xs) solid var(--color-divider);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.ds-tool-call__content > :first-child {
|
|
192
|
+
margin-top: 0;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.ds-tool-call__content > :last-child {
|
|
196
|
+
margin-bottom: 0;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* ============================================
|
|
200
|
+
ACTIONS
|
|
201
|
+
Outside the panel, so a call awaiting approval
|
|
202
|
+
can be answered without expanding it first.
|
|
203
|
+
============================================ */
|
|
204
|
+
|
|
205
|
+
.ds-tool-call__actions {
|
|
206
|
+
display: flex;
|
|
207
|
+
align-items: center;
|
|
208
|
+
justify-content: flex-end;
|
|
209
|
+
gap: var(--gap-sm);
|
|
210
|
+
padding: var(--padding-sm) var(--padding-sm-md);
|
|
211
|
+
border-top: var(--border-xs) solid var(--color-divider);
|
|
212
|
+
background-color: var(--color-bg-container-secondary);
|
|
213
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type ToolCallStatus = 'pending' | 'running' | 'success' | 'error';
|
|
3
|
+
/** Props owned by ToolCall itself — everything else falls through to the root element. */
|
|
4
|
+
type ToolCallOwnProps = {
|
|
5
|
+
/** The tool that was invoked, shown in monospace. */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Where the call has got to. Drives the colour, the indicator, and the default status text. */
|
|
8
|
+
status?: ToolCallStatus;
|
|
9
|
+
/** One line describing this particular call, e.g. the target path or query. */
|
|
10
|
+
summary?: string;
|
|
11
|
+
/** How long the call took, e.g. "1.2s". Free text, so callers keep their own formatting. */
|
|
12
|
+
duration?: string;
|
|
13
|
+
/** Override the status text shown beside the indicator. */
|
|
14
|
+
statusLabel?: string;
|
|
15
|
+
/** Open state for controlled use. Pair with `onOpenChange`. */
|
|
16
|
+
open?: boolean;
|
|
17
|
+
/** Open state for uncontrolled use. */
|
|
18
|
+
defaultOpen?: boolean;
|
|
19
|
+
/** Fires whenever the panel opens or closes. */
|
|
20
|
+
onOpenChange?: (open: boolean) => void;
|
|
21
|
+
/**
|
|
22
|
+
* Controls for a call awaiting a decision — allow, deny, always allow.
|
|
23
|
+
* Rendered outside the collapsible panel, so approving never requires
|
|
24
|
+
* expanding the call first.
|
|
25
|
+
*/
|
|
26
|
+
actions?: React.ReactNode;
|
|
27
|
+
/** Additional CSS classes */
|
|
28
|
+
className?: string;
|
|
29
|
+
/** The call's arguments and result. */
|
|
30
|
+
children?: React.ReactNode;
|
|
31
|
+
};
|
|
32
|
+
export interface ToolCallProps extends ToolCallOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof ToolCallOwnProps> {
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* ToolCall is the record of one tool invocation: what ran, how it went, how
|
|
36
|
+
* long it took, and — behind a disclosure — the arguments it was given and
|
|
37
|
+
* what it returned.
|
|
38
|
+
*
|
|
39
|
+
* A run is mostly a list of these, so the collapsed header carries everything
|
|
40
|
+
* needed to skim it and the body holds everything needed to audit it.
|
|
41
|
+
*/
|
|
42
|
+
export declare const ToolCall: React.ForwardRefExoticComponent<ToolCallProps & React.RefAttributes<HTMLDivElement>>;
|
|
43
|
+
export {};
|