ionbase-ui 0.70.0 → 0.75.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/Chart.d.ts +95 -0
- package/dist/components/Chart.d.ts.map +1 -0
- package/dist/components/Chart.js +60 -0
- package/dist/components/Chart.js.map +1 -0
- package/dist/components/SettingRow.d.ts +54 -0
- package/dist/components/SettingRow.d.ts.map +1 -0
- package/dist/components/SettingRow.js +60 -0
- package/dist/components/SettingRow.js.map +1 -0
- package/dist/components/StatTile.d.ts +65 -0
- package/dist/components/StatTile.d.ts.map +1 -0
- package/dist/components/StatTile.js +54 -0
- package/dist/components/StatTile.js.map +1 -0
- package/dist/components/agent-run.d.ts +147 -0
- package/dist/components/agent-run.d.ts.map +1 -0
- package/dist/components/agent-run.js +250 -0
- package/dist/components/agent-run.js.map +1 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +16 -0
- package/dist/components/index.js.map +1 -1
- package/dist/components/use-agent-run.d.ts +65 -0
- package/dist/components/use-agent-run.d.ts.map +1 -0
- package/dist/components/use-agent-run.js +127 -0
- package/dist/components/use-agent-run.js.map +1 -0
- package/dist/figma-descriptions.json +88 -63
- package/dist/figma-map.json +236 -2
- package/dist/meta/ChartLegend.json +125 -0
- package/dist/meta/ChartTooltip.json +126 -0
- package/dist/meta/SettingRow.json +102 -0
- package/dist/meta/StatGroup.json +65 -0
- package/dist/meta/StatTile.json +163 -0
- package/dist/meta/components.json +595 -1
- package/dist/meta/contrast.json +613 -1
- package/dist/meta/index.json +64 -1
- package/dist/meta/patterns/AgentRun.json +14 -0
- package/dist/meta/patterns/HumanApproval.json +4 -0
- package/dist/meta/patterns/SettingsPanel.json +2 -1
- package/dist/meta/patterns/index.json +4 -1
- package/dist/styles/chart.css +275 -0
- package/dist/styles/index.css +3 -0
- package/dist/styles/setting-row.css +58 -0
- package/dist/styles/stat-tile.css +66 -0
- package/dist/styles/tokens/base.css +36 -8
- package/dist/styles/tokens/theme-dark.css +12 -0
- package/dist/tokens/index.d.ts +193 -40
- package/dist/tokens/index.d.ts.map +1 -1
- package/dist/tokens/index.js +157 -32
- package/dist/tokens/index.js.map +1 -1
- package/eslint-plugin/meta-data.js +9 -0
- package/eslint-plugin/rules/needs-accessible-name.js +14 -1
- package/llms.txt +19 -2
- package/package.json +1 -1
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Chart parts for charts drawn with visx.
|
|
4
|
+
*
|
|
5
|
+
* IonBase does not draw charts, and does not depend on visx. visx owns scales,
|
|
6
|
+
* shapes and layout; these own what a chart looks like and the two pieces
|
|
7
|
+
* every chart needs and no charting library supplies — a tooltip panel and a
|
|
8
|
+
* legend. See `styles/chart.css` for the classes, and why they are classes.
|
|
9
|
+
*/
|
|
10
|
+
/** Which of `--chart-1…8` a series takes. Series are coloured in order. */
|
|
11
|
+
export type ChartSeries = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;
|
|
12
|
+
/** The class that colours a series: its line, bar, area, points and swatch. */
|
|
13
|
+
export declare const chartSeriesClass: (series: ChartSeries) => string;
|
|
14
|
+
/**
|
|
15
|
+
* Spread onto visx `AxisLeft` / `AxisBottom` / `Axis`. Themes the axis line,
|
|
16
|
+
* tick marks and tick labels through `chart.css`, overriding the `#222` visx
|
|
17
|
+
* writes as attributes.
|
|
18
|
+
*
|
|
19
|
+
* <AxisBottom scale={x} top={h} {...chartAxisProps} />
|
|
20
|
+
*
|
|
21
|
+
* Passing your own `tickLabelProps` replaces this one — keep
|
|
22
|
+
* `className: 'ion-chart__tick'` in it.
|
|
23
|
+
*/
|
|
24
|
+
export declare const chartAxisProps: {
|
|
25
|
+
axisLineClassName: string;
|
|
26
|
+
tickClassName: string;
|
|
27
|
+
labelClassName: string;
|
|
28
|
+
tickLabelProps: {
|
|
29
|
+
className: string;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Spread onto visx `GridRows` / `GridColumns`. Gridlines take `border/subtle`,
|
|
34
|
+
* the quietest rule, so they sit behind the data rather than competing with it.
|
|
35
|
+
*/
|
|
36
|
+
export declare const chartGridProps: {
|
|
37
|
+
className: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Spread onto visx `Tooltip` / `TooltipWithBounds` / `TooltipInPortal`, with a
|
|
41
|
+
* `ChartTooltip` inside. visx then only positions it; the panel is ours.
|
|
42
|
+
*/
|
|
43
|
+
export declare const chartTooltipProps: {
|
|
44
|
+
unstyled: boolean;
|
|
45
|
+
applyPositionStyle: boolean;
|
|
46
|
+
};
|
|
47
|
+
export interface ChartTooltipRow {
|
|
48
|
+
/** The series or measure, e.g. "Success rate". */
|
|
49
|
+
label: React.ReactNode;
|
|
50
|
+
/** Already formatted — the tooltip cannot know the unit or precision. */
|
|
51
|
+
value: React.ReactNode;
|
|
52
|
+
/** Shows the series' swatch beside the label, matching the legend. */
|
|
53
|
+
series?: ChartSeries;
|
|
54
|
+
}
|
|
55
|
+
export interface ChartTooltipProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
56
|
+
/** What the pointer is over — usually the x value, e.g. a date. */
|
|
57
|
+
title?: React.ReactNode;
|
|
58
|
+
/** One row per series at that point. */
|
|
59
|
+
rows?: ChartTooltipRow[];
|
|
60
|
+
/** Free content after the rows, for anything that is not label/value. */
|
|
61
|
+
children?: React.ReactNode;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* ChartTooltip — the panel that shows the values under the pointer.
|
|
65
|
+
*
|
|
66
|
+
* Put it inside visx's Tooltip with `chartTooltipProps`, so visx places it and
|
|
67
|
+
* this draws it: raised, rimmed and shadowed like Popover and Toast.
|
|
68
|
+
*
|
|
69
|
+
* IT IS NOT THE ACCESSIBLE WAY TO THE DATA. It appears on hover, so a keyboard
|
|
70
|
+
* or screen-reader user never sees it. Every chart still needs a text summary
|
|
71
|
+
* and the values in a table (visually hidden is fine) — the tooltip is a
|
|
72
|
+
* convenience for pointer users, never the only route to a number.
|
|
73
|
+
*/
|
|
74
|
+
export declare const ChartTooltip: React.ForwardRefExoticComponent<ChartTooltipProps & React.RefAttributes<HTMLDivElement>>;
|
|
75
|
+
export type ChartLegendShape = 'square' | 'line';
|
|
76
|
+
export interface ChartLegendItem {
|
|
77
|
+
label: React.ReactNode;
|
|
78
|
+
series: ChartSeries;
|
|
79
|
+
}
|
|
80
|
+
export interface ChartLegendProps extends Omit<React.HTMLAttributes<HTMLUListElement>, 'children'> {
|
|
81
|
+
/** One per series, in the order the series are drawn. */
|
|
82
|
+
items: ChartLegendItem[];
|
|
83
|
+
/** `square` for bars and areas, `line` for line charts. */
|
|
84
|
+
shape?: ChartLegendShape;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* ChartLegend — which colour is which series.
|
|
88
|
+
*
|
|
89
|
+
* Colour alone never identifies a series (SC 1.4.1), so any chart with more
|
|
90
|
+
* than one series needs this, or direct labels on the lines. The swatch reads
|
|
91
|
+
* the same `--chart-<n>` as the series itself, through `chartSeriesClass`, so
|
|
92
|
+
* the two cannot drift apart.
|
|
93
|
+
*/
|
|
94
|
+
export declare const ChartLegend: React.ForwardRefExoticComponent<ChartLegendProps & React.RefAttributes<HTMLUListElement>>;
|
|
95
|
+
//# sourceMappingURL=Chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chart.d.ts","sourceRoot":"","sources":["../../src/components/Chart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAE1C;;;;;;;GAOG;AAEH,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAExD,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,GAAI,QAAQ,WAAW,WACtB,CAAC;AAE/B;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc;;;;;;;CAK1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc;;CAE1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB;;;CAG7B,CAAC;AAOF,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,yEAAyE;IACzE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,sEAAsE;IACtE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAC7C,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,OAAO,CACR;IACC,mEAAmE;IACnE,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,wCAAwC;IACxC,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,YAAY,0FA2BxB,CAAC;AAMF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC,EACtC,UAAU,CACX;IACC,yDAAyD;IACzD,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,2FAuBvB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
/** The class that colours a series: its line, bar, area, points and swatch. */
|
|
4
|
+
export const chartSeriesClass = (series) => `ion-chart-series-${series}`;
|
|
5
|
+
/**
|
|
6
|
+
* Spread onto visx `AxisLeft` / `AxisBottom` / `Axis`. Themes the axis line,
|
|
7
|
+
* tick marks and tick labels through `chart.css`, overriding the `#222` visx
|
|
8
|
+
* writes as attributes.
|
|
9
|
+
*
|
|
10
|
+
* <AxisBottom scale={x} top={h} {...chartAxisProps} />
|
|
11
|
+
*
|
|
12
|
+
* Passing your own `tickLabelProps` replaces this one — keep
|
|
13
|
+
* `className: 'ion-chart__tick'` in it.
|
|
14
|
+
*/
|
|
15
|
+
export const chartAxisProps = {
|
|
16
|
+
axisLineClassName: 'ion-chart__axis-line',
|
|
17
|
+
tickClassName: 'ion-chart__axis-tick',
|
|
18
|
+
labelClassName: 'ion-chart__axis-label',
|
|
19
|
+
tickLabelProps: { className: 'ion-chart__tick' },
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Spread onto visx `GridRows` / `GridColumns`. Gridlines take `border/subtle`,
|
|
23
|
+
* the quietest rule, so they sit behind the data rather than competing with it.
|
|
24
|
+
*/
|
|
25
|
+
export const chartGridProps = {
|
|
26
|
+
className: 'ion-chart__grid',
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Spread onto visx `Tooltip` / `TooltipWithBounds` / `TooltipInPortal`, with a
|
|
30
|
+
* `ChartTooltip` inside. visx then only positions it; the panel is ours.
|
|
31
|
+
*/
|
|
32
|
+
export const chartTooltipProps = {
|
|
33
|
+
unstyled: true,
|
|
34
|
+
applyPositionStyle: true,
|
|
35
|
+
};
|
|
36
|
+
const cx = (...c) => c.filter(Boolean).join(' ');
|
|
37
|
+
/**
|
|
38
|
+
* ChartTooltip — the panel that shows the values under the pointer.
|
|
39
|
+
*
|
|
40
|
+
* Put it inside visx's Tooltip with `chartTooltipProps`, so visx places it and
|
|
41
|
+
* this draws it: raised, rimmed and shadowed like Popover and Toast.
|
|
42
|
+
*
|
|
43
|
+
* IT IS NOT THE ACCESSIBLE WAY TO THE DATA. It appears on hover, so a keyboard
|
|
44
|
+
* or screen-reader user never sees it. Every chart still needs a text summary
|
|
45
|
+
* and the values in a table (visually hidden is fine) — the tooltip is a
|
|
46
|
+
* convenience for pointer users, never the only route to a number.
|
|
47
|
+
*/
|
|
48
|
+
export const ChartTooltip = forwardRef(({ title, rows, children, className, ...rest }, ref) => (_jsxs("div", { ...rest, ref: ref, className: cx('ion-chart-tooltip', className), children: [title != null && _jsx("div", { className: "ion-chart-tooltip__title", children: title }), rows && rows.length > 0 && (_jsx("dl", { className: "ion-chart-tooltip__rows", children: rows.map((row, i) => (_jsxs("div", { className: "ion-chart-tooltip__row", children: [_jsxs("dt", { className: cx('ion-chart-tooltip__label', row.series && chartSeriesClass(row.series)), children: [row.series && (_jsx("span", { className: "ion-chart-swatch", "aria-hidden": "true" })), row.label] }), _jsx("dd", { className: "ion-chart-tooltip__value", children: row.value })] }, i))) })), children] })));
|
|
49
|
+
ChartTooltip.displayName = 'ChartTooltip';
|
|
50
|
+
/**
|
|
51
|
+
* ChartLegend — which colour is which series.
|
|
52
|
+
*
|
|
53
|
+
* Colour alone never identifies a series (SC 1.4.1), so any chart with more
|
|
54
|
+
* than one series needs this, or direct labels on the lines. The swatch reads
|
|
55
|
+
* the same `--chart-<n>` as the series itself, through `chartSeriesClass`, so
|
|
56
|
+
* the two cannot drift apart.
|
|
57
|
+
*/
|
|
58
|
+
export const ChartLegend = forwardRef(({ items, shape = 'square', className, ...rest }, ref) => (_jsx("ul", { ...rest, ref: ref, className: cx('ion-chart-legend', className), children: items.map((item, i) => (_jsxs("li", { className: cx('ion-chart-legend__item', chartSeriesClass(item.series)), children: [_jsx("span", { className: cx('ion-chart-swatch', shape === 'line' && 'ion-chart-swatch--line'), "aria-hidden": "true" }), item.label] }, i))) })));
|
|
59
|
+
ChartLegend.displayName = 'ChartLegend';
|
|
60
|
+
//# sourceMappingURL=Chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Chart.js","sourceRoot":"","sources":["../../src/components/Chart.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAc1C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,MAAmB,EAAE,EAAE,CACtD,oBAAoB,MAAM,EAAE,CAAC;AAE/B;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,iBAAiB,EAAE,sBAAsB;IACzC,aAAa,EAAE,sBAAsB;IACrC,cAAc,EAAE,uBAAuB;IACvC,cAAc,EAAE,EAAE,SAAS,EAAE,iBAAiB,EAAE;CACjD,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,SAAS,EAAE,iBAAiB;CAC7B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,EAAE,IAAI;IACd,kBAAkB,EAAE,IAAI;CACzB,CAAC;AAEF,MAAM,EAAE,GAAG,CAAC,GAAG,CAAiC,EAAE,EAAE,CAClD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAyB9B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CACpC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACtD,kBAAS,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,mBAAmB,EAAE,SAAS,CAAC,aACnE,KAAK,IAAI,IAAI,IAAI,cAAK,SAAS,EAAC,0BAA0B,YAAE,KAAK,GAAO,EACxE,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAC1B,aAAI,SAAS,EAAC,yBAAyB,YACpC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CACpB,eAAa,SAAS,EAAC,wBAAwB,aAC7C,cACE,SAAS,EAAE,EAAE,CACX,0BAA0B,EAC1B,GAAG,CAAC,MAAM,IAAI,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,CAC3C,aAEA,GAAG,CAAC,MAAM,IAAI,CACb,eAAM,SAAS,EAAC,kBAAkB,iBAAa,MAAM,GAAG,CACzD,EACA,GAAG,CAAC,KAAK,IACP,EACL,aAAI,SAAS,EAAC,0BAA0B,YAAE,GAAG,CAAC,KAAK,GAAM,KAZjD,CAAC,CAaL,CACP,CAAC,GACC,CACN,EACA,QAAQ,IACL,CACP,CACF,CAAC;AAEF,YAAY,CAAC,WAAW,GAAG,cAAc,CAAC;AAqB1C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CACnC,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACxD,gBAAQ,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,kBAAkB,EAAE,SAAS,CAAC,YACjE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACtB,cAEE,SAAS,EAAE,EAAE,CACX,wBAAwB,EACxB,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAC9B,aAED,eACE,SAAS,EAAE,EAAE,CACX,kBAAkB,EAClB,KAAK,KAAK,MAAM,IAAI,wBAAwB,CAC7C,iBACW,MAAM,GAClB,EACD,IAAI,CAAC,KAAK,KAbN,CAAC,CAcH,CACN,CAAC,GACC,CACN,CACF,CAAC;AAEF,WAAW,CAAC,WAAW,GAAG,aAAa,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** The ids a control needs to be named and described by the row. */
|
|
3
|
+
export interface SettingRowIds {
|
|
4
|
+
labelId: string;
|
|
5
|
+
descriptionId?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SettingRowProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
8
|
+
/** The setting's name. It becomes the control's accessible name. */
|
|
9
|
+
label: React.ReactNode;
|
|
10
|
+
/** What the setting does, announced with the control. */
|
|
11
|
+
description?: React.ReactNode;
|
|
12
|
+
/**
|
|
13
|
+
* The control. Pass it as an element — `<Toggle />`, `<Select />`,
|
|
14
|
+
* `<Button />` — and the row names and describes it for you. Pass a
|
|
15
|
+
* function when the ids have to go somewhere other than the element's own
|
|
16
|
+
* props; it receives them.
|
|
17
|
+
*/
|
|
18
|
+
children: React.ReactElement<{
|
|
19
|
+
'aria-labelledby'?: string;
|
|
20
|
+
'aria-describedby'?: string;
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
}> | ((ids: SettingRowIds) => React.ReactNode);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* SettingRow — one setting: its name and what it does on the left, the control
|
|
26
|
+
* on the right. The row the SettingsPanel pattern is built from.
|
|
27
|
+
*
|
|
28
|
+
* THE WIRING IS THE POINT, NOT THE LAYOUT
|
|
29
|
+
*
|
|
30
|
+
* A label placed beside a Toggle looks labelled and is not: a screen reader
|
|
31
|
+
* announces "switch, off" and nothing else, and the description is never read
|
|
32
|
+
* at all. The pattern names this as its first a11y requirement, and the demo
|
|
33
|
+
* app's stand-in handed the ids to a render function — which still left the
|
|
34
|
+
* wiring as a step to remember. Here an element child is cloned with
|
|
35
|
+
* `aria-labelledby` and `aria-describedby` already set, so the row cannot be
|
|
36
|
+
* used without them. A value the caller passes explicitly wins, so an
|
|
37
|
+
* existing name is never overwritten.
|
|
38
|
+
*
|
|
39
|
+
* A CONTROL WITH ITS OWN TEXT KEEPS ITS OWN NAME
|
|
40
|
+
*
|
|
41
|
+
* A Button reading "Delete workspace…" must be announced by that text — WCAG
|
|
42
|
+
* 2.5.3 wants the visible words inside the accessible name, and a row label of
|
|
43
|
+
* "Danger zone" would replace them. So a child with children of its own is
|
|
44
|
+
* left named by them, and the row's label joins its description instead: the
|
|
45
|
+
* setting is still announced, just as context rather than as the name.
|
|
46
|
+
*
|
|
47
|
+
* The label is text rather than a `<label>` because the control may not be a
|
|
48
|
+
* form field, and a `<label>` pointing at a button is invalid.
|
|
49
|
+
*
|
|
50
|
+
* It stacks below 30rem of its OWN width, not the viewport's, so the same row
|
|
51
|
+
* works in a full page and in a narrow drawer.
|
|
52
|
+
*/
|
|
53
|
+
export declare const SettingRow: React.ForwardRefExoticComponent<SettingRowProps & React.RefAttributes<HTMLDivElement>>;
|
|
54
|
+
//# sourceMappingURL=SettingRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingRow.d.ts","sourceRoot":"","sources":["../../src/components/SettingRow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAE/E,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX;IACC,oEAAoE;IACpE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,yDAAyD;IACzD,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;;;OAKG;IACH,QAAQ,EACJ,KAAK,CAAC,YAAY,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;KAC5B,CAAC,GACF,CAAC,CAAC,GAAG,EAAE,aAAa,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,UAAU,wFAsDtB,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cloneElement, forwardRef, isValidElement, useId } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* SettingRow — one setting: its name and what it does on the left, the control
|
|
5
|
+
* on the right. The row the SettingsPanel pattern is built from.
|
|
6
|
+
*
|
|
7
|
+
* THE WIRING IS THE POINT, NOT THE LAYOUT
|
|
8
|
+
*
|
|
9
|
+
* A label placed beside a Toggle looks labelled and is not: a screen reader
|
|
10
|
+
* announces "switch, off" and nothing else, and the description is never read
|
|
11
|
+
* at all. The pattern names this as its first a11y requirement, and the demo
|
|
12
|
+
* app's stand-in handed the ids to a render function — which still left the
|
|
13
|
+
* wiring as a step to remember. Here an element child is cloned with
|
|
14
|
+
* `aria-labelledby` and `aria-describedby` already set, so the row cannot be
|
|
15
|
+
* used without them. A value the caller passes explicitly wins, so an
|
|
16
|
+
* existing name is never overwritten.
|
|
17
|
+
*
|
|
18
|
+
* A CONTROL WITH ITS OWN TEXT KEEPS ITS OWN NAME
|
|
19
|
+
*
|
|
20
|
+
* A Button reading "Delete workspace…" must be announced by that text — WCAG
|
|
21
|
+
* 2.5.3 wants the visible words inside the accessible name, and a row label of
|
|
22
|
+
* "Danger zone" would replace them. So a child with children of its own is
|
|
23
|
+
* left named by them, and the row's label joins its description instead: the
|
|
24
|
+
* setting is still announced, just as context rather than as the name.
|
|
25
|
+
*
|
|
26
|
+
* The label is text rather than a `<label>` because the control may not be a
|
|
27
|
+
* form field, and a `<label>` pointing at a button is invalid.
|
|
28
|
+
*
|
|
29
|
+
* It stacks below 30rem of its OWN width, not the viewport's, so the same row
|
|
30
|
+
* works in a full page and in a narrow drawer.
|
|
31
|
+
*/
|
|
32
|
+
export const SettingRow = forwardRef(({ label, description, children, className, id, ...rest }, ref) => {
|
|
33
|
+
const auto = useId();
|
|
34
|
+
const base = id ?? auto;
|
|
35
|
+
const labelId = `${base}-label`;
|
|
36
|
+
const descriptionId = description ? `${base}-description` : undefined;
|
|
37
|
+
let control;
|
|
38
|
+
if (typeof children === 'function') {
|
|
39
|
+
control = children({ labelId, descriptionId });
|
|
40
|
+
}
|
|
41
|
+
else if (isValidElement(children)) {
|
|
42
|
+
const props = children.props;
|
|
43
|
+
const namesItself = props.children != null && props.children !== false;
|
|
44
|
+
const describedBy = namesItself
|
|
45
|
+
? [labelId, descriptionId].filter(Boolean).join(' ')
|
|
46
|
+
: descriptionId;
|
|
47
|
+
control = cloneElement(children, {
|
|
48
|
+
'aria-labelledby': props['aria-labelledby'] ?? (namesItself ? undefined : labelId),
|
|
49
|
+
'aria-describedby': props['aria-describedby'] ?? describedBy,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
control = children;
|
|
54
|
+
}
|
|
55
|
+
return (_jsx("div", { ...rest, id: id, ref: ref, className: ['ion-setting-row', className || '']
|
|
56
|
+
.filter(Boolean)
|
|
57
|
+
.join(' '), children: _jsxs("div", { className: "ion-setting-row__inner", children: [_jsxs("div", { className: "ion-setting-row__text", children: [_jsx("span", { id: labelId, className: "ion-setting-row__label", children: label }), description && (_jsx("span", { id: descriptionId, className: "ion-setting-row__description", children: description }))] }), _jsx("div", { className: "ion-setting-row__control", children: control })] }) }));
|
|
58
|
+
});
|
|
59
|
+
SettingRow.displayName = 'SettingRow';
|
|
60
|
+
//# sourceMappingURL=SettingRow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingRow.js","sourceRoot":"","sources":["../../src/components/SettingRow.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AA+B/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAClC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE;IAChE,MAAM,IAAI,GAAG,KAAK,EAAE,CAAC;IACrB,MAAM,IAAI,GAAG,EAAE,IAAI,IAAI,CAAC;IACxB,MAAM,OAAO,GAAG,GAAG,IAAI,QAAQ,CAAC;IAChC,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;IAEtE,IAAI,OAAwB,CAAC;IAC7B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,GAAG,QAAQ,CAAC,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAItB,CAAC;QACF,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC;QACvE,MAAM,WAAW,GAAG,WAAW;YAC7B,CAAC,CAAC,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YACpD,CAAC,CAAC,aAAa,CAAC;QAClB,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE;YAC/B,iBAAiB,EACf,KAAK,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YACjE,kBAAkB,EAAE,KAAK,CAAC,kBAAkB,CAAC,IAAI,WAAW;SAC7D,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,QAAQ,CAAC;IACrB,CAAC;IAED,OAAO,CACL,iBACM,IAAI,EACR,EAAE,EAAE,EAAE,EACN,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,iBAAiB,EAAE,SAAS,IAAI,EAAE,CAAC;aAC5C,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,YAEZ,eAAK,SAAS,EAAC,wBAAwB,aACrC,eAAK,SAAS,EAAC,uBAAuB,aACpC,eAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,wBAAwB,YAClD,KAAK,GACD,EACN,WAAW,IAAI,CACd,eAAM,EAAE,EAAE,aAAa,EAAE,SAAS,EAAC,8BAA8B,YAC9D,WAAW,GACP,CACR,IACG,EACN,cAAK,SAAS,EAAC,0BAA0B,YAAE,OAAO,GAAO,IACrD,GACF,CACP,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,UAAU,CAAC,WAAW,GAAG,YAAY,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/** Which direction of change is good news. */
|
|
3
|
+
export type StatTileGoodWhen = 'up' | 'down' | 'neutral';
|
|
4
|
+
/** How `change` is expressed. */
|
|
5
|
+
export type StatTileChangeUnit = 'percent' | 'points';
|
|
6
|
+
export interface StatGroupProps extends React.HTMLAttributes<HTMLDListElement> {
|
|
7
|
+
/** StatTile elements. */
|
|
8
|
+
children?: React.ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export interface StatTileProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
11
|
+
/** What is being measured. Short: "Success rate", not a sentence. */
|
|
12
|
+
label: string;
|
|
13
|
+
/**
|
|
14
|
+
* The figure, already formatted — "1.2k", "96.2%", "38s". Formatting is the
|
|
15
|
+
* caller's: only it knows the locale, the precision and the unit.
|
|
16
|
+
*/
|
|
17
|
+
value: React.ReactNode;
|
|
18
|
+
/** Change against the comparison period. Omit when there is none. */
|
|
19
|
+
change?: number;
|
|
20
|
+
/**
|
|
21
|
+
* `percent` for a relative change; `points` for a metric that is already a
|
|
22
|
+
* percentage — 95% to 96% is +1 pt, and calling it +1.1% misreports it.
|
|
23
|
+
*/
|
|
24
|
+
changeUnit?: StatTileChangeUnit;
|
|
25
|
+
/**
|
|
26
|
+
* Which direction is good news. `down` for costs, durations and queues;
|
|
27
|
+
* `neutral` when a change is neither, so it is never coloured.
|
|
28
|
+
*/
|
|
29
|
+
goodWhen?: StatTileGoodWhen;
|
|
30
|
+
/** What `change` is measured against. */
|
|
31
|
+
comparison?: string;
|
|
32
|
+
/** Shows a placeholder for the value and change while data loads. */
|
|
33
|
+
isLoading?: boolean;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* StatGroup — a row of StatTiles.
|
|
37
|
+
*
|
|
38
|
+
* A `<dl>`: each tile is a term (the label) and its description (the figure),
|
|
39
|
+
* which is what a screen reader announces as a pair. The grid wraps on its own,
|
|
40
|
+
* so four tiles are one row on a desktop and two on a phone with no breakpoint
|
|
41
|
+
* in the caller's code.
|
|
42
|
+
*/
|
|
43
|
+
export declare const StatGroup: React.ForwardRefExoticComponent<StatGroupProps & React.RefAttributes<HTMLDListElement>>;
|
|
44
|
+
/**
|
|
45
|
+
* StatTile — one headline figure, and how it moved.
|
|
46
|
+
*
|
|
47
|
+
* Promoted from the demo app, where it was built for the Overview KPI row and
|
|
48
|
+
* survived three phases unchanged.
|
|
49
|
+
*
|
|
50
|
+
* GOOD AND BAD ARE NOT UP AND DOWN
|
|
51
|
+
*
|
|
52
|
+
* A rising median run time is bad news and a rising success rate is good, so
|
|
53
|
+
* the colour comes from `goodWhen` and the direction together — never from the
|
|
54
|
+
* sign alone. `neutral` never colours: a run count going up is not a verdict.
|
|
55
|
+
* The verdict is also spoken, as visually hidden text after the change, so it
|
|
56
|
+
* never rests on the badge's colour.
|
|
57
|
+
*
|
|
58
|
+
* The change is rounded BEFORE it is judged, so −0.04 reads "No change" rather
|
|
59
|
+
* than a red "−0.0%".
|
|
60
|
+
*
|
|
61
|
+
* It must sit inside a StatGroup: the tile renders a `<dt>` and a `<dd>`, which
|
|
62
|
+
* are only valid inside a `<dl>`.
|
|
63
|
+
*/
|
|
64
|
+
export declare const StatTile: React.ForwardRefExoticComponent<StatTileProps & React.RefAttributes<HTMLDivElement>>;
|
|
65
|
+
//# sourceMappingURL=StatTile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatTile.d.ts","sourceRoot":"","sources":["../../src/components/StatTile.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqB,MAAM,OAAO,CAAC;AAI1C,8CAA8C;AAC9C,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzD,iCAAiC;AACjC,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,cAAc,CAAC,gBAAgB,CAAC;IAC5E,yBAAyB;IACzB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,aAAc,SAAQ,IAAI,CACzC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EACpC,UAAU,CACX;IACC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC;;;OAGG;IACH,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA0BD;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,yFAUrB,CAAC;AAIF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,QAAQ,sFAsEpB,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from 'react';
|
|
3
|
+
import { Badge } from './Badge.js';
|
|
4
|
+
import { Skeleton } from './Skeleton.js';
|
|
5
|
+
const TrendUp = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "M22 7l-8.5 8.5-5-5L2 17M16 7h6v6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
6
|
+
const TrendDown = () => (_jsx("svg", { viewBox: "0 0 24 24", fill: "none", "aria-hidden": "true", focusable: "false", children: _jsx("path", { d: "M22 17l-8.5-8.5-5 5L2 7M16 17h6v-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }));
|
|
7
|
+
/**
|
|
8
|
+
* StatGroup — a row of StatTiles.
|
|
9
|
+
*
|
|
10
|
+
* A `<dl>`: each tile is a term (the label) and its description (the figure),
|
|
11
|
+
* which is what a screen reader announces as a pair. The grid wraps on its own,
|
|
12
|
+
* so four tiles are one row on a desktop and two on a phone with no breakpoint
|
|
13
|
+
* in the caller's code.
|
|
14
|
+
*/
|
|
15
|
+
export const StatGroup = forwardRef(({ className, children, ...rest }, ref) => (_jsx("dl", { ...rest, ref: ref, className: ['ion-stat-group', className || ''].filter(Boolean).join(' '), children: children })));
|
|
16
|
+
StatGroup.displayName = 'StatGroup';
|
|
17
|
+
/**
|
|
18
|
+
* StatTile — one headline figure, and how it moved.
|
|
19
|
+
*
|
|
20
|
+
* Promoted from the demo app, where it was built for the Overview KPI row and
|
|
21
|
+
* survived three phases unchanged.
|
|
22
|
+
*
|
|
23
|
+
* GOOD AND BAD ARE NOT UP AND DOWN
|
|
24
|
+
*
|
|
25
|
+
* A rising median run time is bad news and a rising success rate is good, so
|
|
26
|
+
* the colour comes from `goodWhen` and the direction together — never from the
|
|
27
|
+
* sign alone. `neutral` never colours: a run count going up is not a verdict.
|
|
28
|
+
* The verdict is also spoken, as visually hidden text after the change, so it
|
|
29
|
+
* never rests on the badge's colour.
|
|
30
|
+
*
|
|
31
|
+
* The change is rounded BEFORE it is judged, so −0.04 reads "No change" rather
|
|
32
|
+
* than a red "−0.0%".
|
|
33
|
+
*
|
|
34
|
+
* It must sit inside a StatGroup: the tile renders a `<dt>` and a `<dd>`, which
|
|
35
|
+
* are only valid inside a `<dl>`.
|
|
36
|
+
*/
|
|
37
|
+
export const StatTile = forwardRef(({ label, value, change, changeUnit = 'percent', goodWhen = 'up', comparison = 'vs previous period', isLoading = false, className, ...rest }, ref) => {
|
|
38
|
+
const rounded = change === undefined ? undefined : Number(change.toFixed(1));
|
|
39
|
+
let intent = 'neutral';
|
|
40
|
+
let icon;
|
|
41
|
+
let text = 'No change';
|
|
42
|
+
let verdict = '';
|
|
43
|
+
if (rounded) {
|
|
44
|
+
const up = rounded > 0;
|
|
45
|
+
const good = goodWhen === 'neutral' ? null : up === (goodWhen === 'up');
|
|
46
|
+
intent = good === null ? 'neutral' : good ? 'success' : 'error';
|
|
47
|
+
icon = up ? _jsx(TrendUp, {}) : _jsx(TrendDown, {});
|
|
48
|
+
text = `${up ? '+' : '−'}${Math.abs(rounded).toFixed(1)}${changeUnit === 'percent' ? '%' : ' pts'}`;
|
|
49
|
+
verdict = good === null ? '' : good ? ', better' : ', worse';
|
|
50
|
+
}
|
|
51
|
+
return (_jsxs("div", { ...rest, ref: ref, "aria-busy": isLoading || undefined, className: ['ion-stat-tile', className || ''].filter(Boolean).join(' '), children: [_jsx("dt", { className: "ion-stat-tile__label", children: label }), _jsx("dd", { className: "ion-stat-tile__body", children: isLoading ? (_jsx(Skeleton, { variant: "rect", width: "60%", height: "var(--type-h4-line-height)" })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "ion-stat-tile__value", children: value }), rounded !== undefined && (_jsxs("span", { className: "ion-stat-tile__change", children: [_jsx(Badge, { size: "sm", intent: intent, icon: icon, children: text }), verdict && (_jsx("span", { className: "ion-visually-hidden", children: verdict })), _jsx("span", { className: "ion-stat-tile__comparison", children: comparison })] }))] })) })] }));
|
|
52
|
+
});
|
|
53
|
+
StatTile.displayName = 'StatTile';
|
|
54
|
+
//# sourceMappingURL=StatTile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatTile.js","sourceRoot":"","sources":["../../src/components/StatTile.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent run state, as a reducer over events.
|
|
3
|
+
*
|
|
4
|
+
* AgentActivity, ApprovalGate, StreamingText and AgentStop each render one
|
|
5
|
+
* state well, and none of them knows about the others. What turns "the agent
|
|
6
|
+
* started step 3" into the right props on all four — one step active at a
|
|
7
|
+
* time, a stopped run keeping what it did, an unanswered approval never
|
|
8
|
+
* counting as a yes — was left to every product, and every product got a
|
|
9
|
+
* different edge wrong. This file is that logic, once.
|
|
10
|
+
*
|
|
11
|
+
* It is plain data in, plain data out: no React, no timers. The same events
|
|
12
|
+
* drive a live run (from a stream, a socket, a poll) and a recorded one
|
|
13
|
+
* (`replayAgentRun`), and `agentRunFrom` rebuilds a finished run for a history
|
|
14
|
+
* page without playing it. `useAgentRun` wraps it for components.
|
|
15
|
+
*
|
|
16
|
+
* Events are JSON-serialisable on purpose, so a recording can be stored as a
|
|
17
|
+
* run log and a backend can emit them as-is.
|
|
18
|
+
*/
|
|
19
|
+
/** Where a run is. The last four are ends; nothing changes a run after one. */
|
|
20
|
+
export type AgentRunPhase = 'idle' | 'running' | 'awaiting' | 'finished' | 'failed' | 'stopped' | 'expired';
|
|
21
|
+
/** The same five statuses AgentActivityStep and ToolCall take. */
|
|
22
|
+
export type AgentRunStepStatus = 'pending' | 'active' | 'done' | 'failed' | 'skipped';
|
|
23
|
+
export interface AgentRunStep {
|
|
24
|
+
id: string;
|
|
25
|
+
status: AgentRunStepStatus;
|
|
26
|
+
label?: string;
|
|
27
|
+
/** Why it failed, from `step-failed`. */
|
|
28
|
+
error?: string;
|
|
29
|
+
/** Whether it ever began. A planned step the run never reached is not in `log`. */
|
|
30
|
+
started: boolean;
|
|
31
|
+
}
|
|
32
|
+
export interface AgentRunApproval {
|
|
33
|
+
/** The step the approval belongs to. */
|
|
34
|
+
stepId: string;
|
|
35
|
+
status: 'pending' | 'approved' | 'rejected' | 'expired';
|
|
36
|
+
/** What happened, in words — ApprovalGate's `resolution`. */
|
|
37
|
+
resolution?: string;
|
|
38
|
+
/** A decision is on its way to the server. */
|
|
39
|
+
isSubmitting: boolean;
|
|
40
|
+
/** The decision did not arrive. The approval is still pending. */
|
|
41
|
+
error?: string;
|
|
42
|
+
}
|
|
43
|
+
export interface AgentRunState {
|
|
44
|
+
phase: AgentRunPhase;
|
|
45
|
+
/** Every step known so far, in the order it was planned or started. */
|
|
46
|
+
steps: AgentRunStep[];
|
|
47
|
+
/** The latest approval, or null if the run has not asked for one. */
|
|
48
|
+
approval: AgentRunApproval | null;
|
|
49
|
+
output: string;
|
|
50
|
+
isStreaming: boolean;
|
|
51
|
+
/** Stop was requested and the run has not confirmed it yet. */
|
|
52
|
+
isStopping: boolean;
|
|
53
|
+
/** From `run-failed`, when the failure is the run's and not one step's. */
|
|
54
|
+
error?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* What a run reports. A producer — a backend stream, a script, a recording —
|
|
58
|
+
* emits these; it never computes a status itself.
|
|
59
|
+
*/
|
|
60
|
+
export type AgentRunEvent =
|
|
61
|
+
/** Optionally with the plan, so later steps can be listed as not done. */
|
|
62
|
+
{
|
|
63
|
+
type: 'run-started';
|
|
64
|
+
steps?: {
|
|
65
|
+
id: string;
|
|
66
|
+
label?: string;
|
|
67
|
+
}[];
|
|
68
|
+
} | {
|
|
69
|
+
type: 'step-started';
|
|
70
|
+
id: string;
|
|
71
|
+
label?: string;
|
|
72
|
+
} | {
|
|
73
|
+
type: 'step-done';
|
|
74
|
+
id: string;
|
|
75
|
+
} | {
|
|
76
|
+
type: 'step-failed';
|
|
77
|
+
id: string;
|
|
78
|
+
error?: string;
|
|
79
|
+
} | {
|
|
80
|
+
type: 'step-skipped';
|
|
81
|
+
id: string;
|
|
82
|
+
} | {
|
|
83
|
+
type: 'approval-requested';
|
|
84
|
+
id: string;
|
|
85
|
+
} | {
|
|
86
|
+
type: 'approval-resolved';
|
|
87
|
+
id: string;
|
|
88
|
+
decision: 'approved' | 'rejected' | 'expired';
|
|
89
|
+
resolution?: string;
|
|
90
|
+
}
|
|
91
|
+
/** A chunk of output, appended. */
|
|
92
|
+
| {
|
|
93
|
+
type: 'output';
|
|
94
|
+
text: string;
|
|
95
|
+
} | {
|
|
96
|
+
type: 'output-done';
|
|
97
|
+
} | {
|
|
98
|
+
type: 'run-finished';
|
|
99
|
+
} | {
|
|
100
|
+
type: 'run-failed';
|
|
101
|
+
error?: string;
|
|
102
|
+
}
|
|
103
|
+
/** `resolution` explains an approval the stop left undecided. */
|
|
104
|
+
| {
|
|
105
|
+
type: 'run-stopped';
|
|
106
|
+
resolution?: string;
|
|
107
|
+
} | {
|
|
108
|
+
type: 'stop-requested';
|
|
109
|
+
} | {
|
|
110
|
+
type: 'stop-failed';
|
|
111
|
+
} | {
|
|
112
|
+
type: 'reset';
|
|
113
|
+
} | {
|
|
114
|
+
type: 'decision-submitted';
|
|
115
|
+
id: string;
|
|
116
|
+
} | {
|
|
117
|
+
type: 'decision-failed';
|
|
118
|
+
id: string;
|
|
119
|
+
error: string;
|
|
120
|
+
};
|
|
121
|
+
export declare const initialAgentRunState: AgentRunState;
|
|
122
|
+
/** Whether the run has reached an end — finished, failed, stopped or expired. */
|
|
123
|
+
export declare const agentRunHasEnded: (state: AgentRunState) => boolean;
|
|
124
|
+
/**
|
|
125
|
+
* The whole policy. Every rule here is one the AgentRun or HumanApproval
|
|
126
|
+
* pattern states; the comment says which.
|
|
127
|
+
*/
|
|
128
|
+
export declare function agentRunReducer(state: AgentRunState, event: AgentRunEvent): AgentRunState;
|
|
129
|
+
/** A finished run rebuilt from its events, without playing it — for a history page. */
|
|
130
|
+
export declare const agentRunFrom: (events: AgentRunEvent[]) => AgentRunState;
|
|
131
|
+
/** Steps that began, in order — what AgentActivity lists. Never planned-but-unreached ones. */
|
|
132
|
+
export declare const agentRunLog: (state: AgentRunState) => AgentRunStep[];
|
|
133
|
+
/** A recording: each event with the milliseconds to wait before it. */
|
|
134
|
+
export type AgentRunRecording = {
|
|
135
|
+
delay: number;
|
|
136
|
+
event: AgentRunEvent;
|
|
137
|
+
}[];
|
|
138
|
+
export interface ReplayAgentRunOptions {
|
|
139
|
+
/** 2 plays twice as fast. Default 1. */
|
|
140
|
+
speed?: number;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Plays a recording into `dispatch` on timers. Returns a function that cancels
|
|
144
|
+
* the rest — call it on unmount, or on stop before dispatching `run-stopped`.
|
|
145
|
+
*/
|
|
146
|
+
export declare function replayAgentRun(recording: AgentRunRecording, dispatch: (event: AgentRunEvent) => void, { speed }?: ReplayAgentRunOptions): () => void;
|
|
147
|
+
//# sourceMappingURL=agent-run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-run.d.ts","sourceRoot":"","sources":["../../src/components/agent-run.ts"],"names":[],"mappings":"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"}
|