@artooi/ag-ui-web-component 0.33.0 → 0.34.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/CHANGELOG.md +95 -1
- package/README.md +47 -3
- package/dist/ag-ui-web-component.bundle.js +119 -47
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/index.js +449 -100
- package/dist/index.js.map +4 -4
- package/dist/ui/chart_block.d.ts +18 -0
- package/dist/ui/chart_block.d.ts.map +1 -1
- package/dist/ui/clamp_panel.d.ts +13 -0
- package/dist/ui/clamp_panel.d.ts.map +1 -0
- package/dist/ui/launcher_placement.d.ts.map +1 -1
- package/dist/ui/panel_drag.d.ts +40 -0
- package/dist/ui/panel_drag.d.ts.map +1 -0
- package/dist/ui/place_widget.d.ts +23 -0
- package/dist/ui/place_widget.d.ts.map +1 -0
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/constants.ts +8 -0
- package/src/core/ag_ui_chat.ts +207 -9
- package/src/ui/chart_block.ts +222 -57
- package/src/ui/clamp_panel.ts +24 -0
- package/src/ui/launcher_placement.ts +18 -54
- package/src/ui/panel_drag.ts +134 -0
- package/src/ui/place_widget.ts +56 -0
- package/src/ui/styles.ts +75 -3
- package/src/version.ts +1 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ExpandCorner, Extent, LauncherBox } from "./launcher_placement.js";
|
|
2
|
+
import type { PanelRect } from "./resize_handle.js";
|
|
3
|
+
|
|
4
|
+
/** Where to put the host box, and where the launcher sits inside it. */
|
|
5
|
+
export interface WidgetInsets {
|
|
6
|
+
/** An `inset` shorthand for the host box. */
|
|
7
|
+
readonly hostInset: string;
|
|
8
|
+
/** An `inset` shorthand for the launcher, relative to the host box. */
|
|
9
|
+
readonly launcherInset: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Express a panel and its launcher, both already positioned, as the two
|
|
14
|
+
* `inset` shorthands the element writes.
|
|
15
|
+
*
|
|
16
|
+
* Both are measured from the **same** corner, which is what stops a later
|
|
17
|
+
* resize from dragging the launcher: the pinned corner is the one edge a
|
|
18
|
+
* resize cannot move. Which corner that is says nothing about where either box
|
|
19
|
+
* ends up -- the positions are absolute and arrive decided -- so re-picking it
|
|
20
|
+
* moves nothing, and the launcher may sit outside its own host box. Nothing
|
|
21
|
+
* clips it there, and that is what lets a launcher be flush to a screen corner
|
|
22
|
+
* while the panel it opens keeps its margin.
|
|
23
|
+
*/
|
|
24
|
+
export function placeWidget(
|
|
25
|
+
host: PanelRect,
|
|
26
|
+
launcher: LauncherBox,
|
|
27
|
+
corner: ExpandCorner,
|
|
28
|
+
viewport: Extent,
|
|
29
|
+
): WidgetInsets {
|
|
30
|
+
return {
|
|
31
|
+
hostInset: inset({
|
|
32
|
+
top: corner.y === "top" ? host.top : null,
|
|
33
|
+
right: corner.x === "right" ? viewport.width - host.right : null,
|
|
34
|
+
bottom: corner.y === "bottom" ? viewport.height - host.bottom : null,
|
|
35
|
+
left: corner.x === "left" ? host.left : null,
|
|
36
|
+
}),
|
|
37
|
+
launcherInset: inset({
|
|
38
|
+
top: corner.y === "top" ? launcher.top - host.top : null,
|
|
39
|
+
right: corner.x === "right" ? host.right - (launcher.left + launcher.width) : null,
|
|
40
|
+
bottom: corner.y === "bottom" ? host.bottom - (launcher.top + launcher.height) : null,
|
|
41
|
+
left: corner.x === "left" ? launcher.left - host.left : null,
|
|
42
|
+
}),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** An `inset` shorthand; a null side is `auto`, so the opposite one pins it. */
|
|
47
|
+
function inset(sides: {
|
|
48
|
+
top: number | null;
|
|
49
|
+
right: number | null;
|
|
50
|
+
bottom: number | null;
|
|
51
|
+
left: number | null;
|
|
52
|
+
}): string {
|
|
53
|
+
const side = (value: number | null): string =>
|
|
54
|
+
value === null ? "auto" : `${Math.round(value)}px`;
|
|
55
|
+
return `${side(sides.top)} ${side(sides.right)} ${side(sides.bottom)} ${side(sides.left)}`;
|
|
56
|
+
}
|
package/src/ui/styles.ts
CHANGED
|
@@ -109,6 +109,11 @@ export const STYLES = `
|
|
|
109
109
|
--_glyph-size: var(--ag-ui-glyph-size, 18px);
|
|
110
110
|
--_glyph-stroke: var(--ag-ui-glyph-stroke, 1.75);
|
|
111
111
|
|
|
112
|
+
/* How wide a chart is allowed to get. A cap rather than a width: below it
|
|
113
|
+
the chart fills its column, and above it a wider panel is just a wider
|
|
114
|
+
panel. */
|
|
115
|
+
--_chart-max-width: var(--ag-ui-chart-max-width, 480px);
|
|
116
|
+
|
|
112
117
|
/* Unread badge on the launcher. */
|
|
113
118
|
--_badge-bg: var(--ag-ui-badge-bg, var(--_danger));
|
|
114
119
|
--_badge-fg: var(--ag-ui-badge-fg, #ffffff);
|
|
@@ -499,6 +504,41 @@ export const STYLES = `
|
|
|
499
504
|
color: var(--_header-fg);
|
|
500
505
|
}
|
|
501
506
|
|
|
507
|
+
/* The header is the panel's title bar: on the placements that let the widget
|
|
508
|
+
be moved it drags the whole thing, matching the launcher's own drag. The
|
|
509
|
+
selector lists those placements rather than asking JS to stamp an attribute,
|
|
510
|
+
because a cursor that appears one frame late reads as a control that only
|
|
511
|
+
sometimes exists. touch-action keeps a finger drag here moving the panel
|
|
512
|
+
instead of scrolling the page behind it. */
|
|
513
|
+
:host(:not([placement])) .header,
|
|
514
|
+
:host([placement=""]) .header,
|
|
515
|
+
:host([placement="floating"]) .header,
|
|
516
|
+
:host([placement="bottom-left"]) .header {
|
|
517
|
+
cursor: move;
|
|
518
|
+
touch-action: none;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
/* A host that turned the drag off keeps a header that says so. */
|
|
522
|
+
:host([data-launcher-drag="false"]) .header {
|
|
523
|
+
cursor: auto;
|
|
524
|
+
touch-action: auto;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* :host is carried for the specificity, not the scope: the placement rules
|
|
528
|
+
above are a host selector plus a class plus an attribute, and a bare
|
|
529
|
+
.header[data-dragging] loses to them -- silently, because the drag still
|
|
530
|
+
works and only the cursor is wrong. */
|
|
531
|
+
:host .header[data-dragging] {
|
|
532
|
+
cursor: grabbing;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/* The cursor inherits, so a control a host slots into the header would show
|
|
536
|
+
the drag cursor over something the drag deliberately ignores. Named to
|
|
537
|
+
match the controls panel_drag steps aside for. */
|
|
538
|
+
.header ::slotted(:is(button, a, input, select, textarea)) {
|
|
539
|
+
cursor: pointer;
|
|
540
|
+
}
|
|
541
|
+
|
|
502
542
|
.header-title {
|
|
503
543
|
flex: 1;
|
|
504
544
|
min-width: 0;
|
|
@@ -808,7 +848,22 @@ export const STYLES = `
|
|
|
808
848
|
border-radius: var(--_msg-radius);
|
|
809
849
|
line-height: 1.4;
|
|
810
850
|
white-space: pre-wrap;
|
|
811
|
-
word-break
|
|
851
|
+
/* overflow-wrap, not word-break, and the difference is the whole reason a
|
|
852
|
+
markdown table used to be unreadable.
|
|
853
|
+
|
|
854
|
+
Both stop one long unbroken token blowing out the bubble, which is all this
|
|
855
|
+
is for. But word-break: break-word is the legacy spelling of "break
|
|
856
|
+
anywhere", and breaking anywhere drops the *min-content* width of every
|
|
857
|
+
descendant to one character. A table's column algorithm takes min-content
|
|
858
|
+
as an input, so the table always fitted max-width: 100%, the overflow-x:
|
|
859
|
+
auto below it never had anything to scroll, and the columns absorbed the
|
|
860
|
+
pressure by rendering one letter per line instead. A seven-column header
|
|
861
|
+
came out 162px tall.
|
|
862
|
+
|
|
863
|
+
overflow-wrap: break-word breaks a word only when it would otherwise
|
|
864
|
+
overflow its line, and leaves min-content alone -- so the bubble is still
|
|
865
|
+
protected and the table is free to be wider than the panel and scroll. */
|
|
866
|
+
overflow-wrap: break-word;
|
|
812
867
|
}
|
|
813
868
|
|
|
814
869
|
/* ── Incoming-text animations (data-text-animation) ─────────────────────── */
|
|
@@ -1967,13 +2022,30 @@ export const STYLES = `
|
|
|
1967
2022
|
* values, and the axis furniture inherits currentColor at low opacity so it
|
|
1968
2023
|
* reads correctly in either theme without a second palette.
|
|
1969
2024
|
*/
|
|
2025
|
+
/* A chart is sized like a message, not like a panel: it takes the width it
|
|
2026
|
+
needs and stops, rather than stretching into whatever room the transcript
|
|
2027
|
+
has. A message bubble caps at 80% for the same reason -- widening the panel
|
|
2028
|
+
should not resize what is already in it. The cap is a token so a host with a
|
|
2029
|
+
wide panel and a real reason can raise it; the default is the width this
|
|
2030
|
+
renderer has always drawn at. Below the cap the block still fills its column,
|
|
2031
|
+
which is what a narrow panel needs. */
|
|
1970
2032
|
.chart-block {
|
|
1971
|
-
align-self:
|
|
1972
|
-
|
|
2033
|
+
align-self: flex-start;
|
|
2034
|
+
width: 100%;
|
|
2035
|
+
max-width: var(--_chart-max-width);
|
|
1973
2036
|
margin: 6px 0;
|
|
1974
2037
|
color: var(--_fg);
|
|
1975
2038
|
}
|
|
1976
2039
|
|
|
2040
|
+
/* The drawing fills the block's width and carries its own height in the
|
|
2041
|
+
viewBox, so it is laid out rather than magnified: block display keeps the
|
|
2042
|
+
inline baseline gap from adding a stripe under every chart. */
|
|
2043
|
+
.chart-block svg {
|
|
2044
|
+
display: block;
|
|
2045
|
+
width: 100%;
|
|
2046
|
+
height: auto;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
1977
2049
|
.chart-title {
|
|
1978
2050
|
margin-bottom: 2px;
|
|
1979
2051
|
font-size: 0.85em;
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION: string = "0.
|
|
1
|
+
export const VERSION: string = "0.34.0";
|