@artooi/ag-ui-web-component 0.48.0 → 0.49.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.
@@ -1 +1 @@
1
- {"version":3,"file":"chat_surface_tools.d.ts","sourceRoot":"","sources":["../../src/tools/chat_surface_tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,kFAAkF;AAClF,eAAO,MAAM,YAAY,YAAI,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,CAAU,CAAC;AAE9F,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,eAAe,IAAI,iBAAiB,CAAC;IACrC;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;IAC/E,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,EAAE,CA8GzE"}
1
+ {"version":3,"file":"chat_surface_tools.d.ts","sourceRoot":"","sources":["../../src/tools/chat_surface_tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,kFAAkF;AAClF,eAAO,MAAM,YAAY,YAAI,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,CAAU,CAAC;AAE9F,yCAAyC;AACzC,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,gDAAgD;IAChD,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;;;;;;OAOG;IACH,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KACzB,CAAC;CACH;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,UAAU,CAE/D;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC1B,eAAe,IAAI,iBAAiB,CAAC;IACrC;;;;;OAKG;IACH,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC;IAC/E,YAAY,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,UAAU,EAAE,CA4GzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"dock_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/dock_styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,EAAE,MAsFzB,CAAC"}
1
+ {"version":3,"file":"dock_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/dock_styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,WAAW,EAAE,MA0FzB,CAAC"}
@@ -62,6 +62,11 @@ export declare class PanelPlacement {
62
62
  * Drop the dragged size and its stored copy, so the placement's own size and
63
63
  * the host's tokens apply again. For a host entering a sized state of its
64
64
  * own, which a user's drag would otherwise outrank.
65
+ *
66
+ * A docked panel the user dragged off its dock goes back to it as well, and
67
+ * the stored spot with it: there the position is part of the same resting
68
+ * state the host is asking for. A corner panel keeps a dragged position, as
69
+ * it always has.
65
70
  */
66
71
  resetSize(): void;
67
72
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"panel_placement.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/panel_placement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAuGlD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACzD,kDAAkD;IAClD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,iDAAiD;IACjD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,uEAAuE;IACvE,QAAQ,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC1E;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;;IAGzB,YAAY,IAAI,EAAE,aAAa,EAE9B;IAED;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAOzC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAS5C;IAED,mFAAmF;IACnF,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAqBxC;IAED,sDAAsD;IACtD,WAAW,IAAI,IAAI,CAElB;IAED;;;;OAIG;IACH,SAAS,IAAI,IAAI,CAOhB;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAK,iBAAiC;IAqE/C;;;;;;OAMG;IACH,QAAQ,IAAI,OAAO,CAKlB;IAED,+EAA+E;IAC/E,eAAe,IAAI,iBAAiB,CAyBnC;IAED,oEAAoE;IACpE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CA2CjF;IA0HD,sEAAsE;IACtE,gBAAgB,IAAI,IAAI,CAYvB;IA0CD;;;;;;OAMG;IACH,gBAAgB,IAAI,IAAI,CAQvB;IAcD;;;;;;;;;OASG;IACH,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CAmBzD;IAsFD;;;;;;;;;;;;OAYG;IACH,qBAAqB,IAAI,IAAI,CAgD5B;IA8PD;;;;;OAKG;IACH,uBAAuB,IAAI,IAAI,CAmB9B;IAiCD;;;;OAIG;IACH,uBAAuB,IAAI,IAAI,CAU9B;CAuHF"}
1
+ {"version":3,"file":"panel_placement.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/panel_placement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACvF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAgHlD;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,OAAO,CAAC;IAClC,kEAAkE;IAClE,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,iCAAiC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,SAAS,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACzD,kDAAkD;IAClD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,iDAAiD;IACjD,QAAQ,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,uEAAuE;IACvE,QAAQ,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CAC1E;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;;IAGzB,YAAY,IAAI,EAAE,aAAa,EAE9B;IAED;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAOzC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAS5C;IAED,mFAAmF;IACnF,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAqBxC;IAED,sDAAsD;IACtD,WAAW,IAAI,IAAI,CAElB;IAED;;;;;;;;;OASG;IACH,SAAS,IAAI,IAAI,CAchB;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAK,iBAAiC;IA2F/C;;;;;;OAMG;IACH,QAAQ,IAAI,OAAO,CAKlB;IAED,+EAA+E;IAC/E,eAAe,IAAI,iBAAiB,CA+BnC;IAED,oEAAoE;IACpE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,GAAE;QAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,OAAO,CAmDjF;IAmID,sEAAsE;IACtE,gBAAgB,IAAI,IAAI,CAYvB;IA0CD;;;;;;OAMG;IACH,gBAAgB,IAAI,IAAI,CAQvB;IAiBD;;;;;;;;;OASG;IACH,QAAQ,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,GAAG,MAAM,CA8BzD;IA4LD;;;;;;;;;;;;OAYG;IACH,qBAAqB,IAAI,IAAI,CAgD5B;IAyQD;;;;;OAKG;IACH,uBAAuB,IAAI,IAAI,CA0B9B;IAiCD;;;;OAIG;IACH,uBAAuB,IAAI,IAAI,CAiB9B;CAgIF"}
@@ -37,10 +37,18 @@ export interface Surface {
37
37
  readonly collapseTo: CollapseTarget;
38
38
  /**
39
39
  * Whether a gesture may move the launcher. The rest have nowhere to put it:
40
- * the rail is a docked edge, `header` and `null` have no launcher, and a
41
- * full-bleed panel covers the screen it would be opening into.
40
+ * the rail is a docked edge, `header` and `null` have no launcher, a
41
+ * full-bleed panel covers the screen it would be opening into, and the bar
42
+ * and the host's own control are not a launcher at all.
42
43
  */
43
44
  readonly launcherDraggable: boolean;
45
+ /**
46
+ * Whether the header drag and `moveTo` may move the open panel. The same
47
+ * answer as {@link launcherDraggable} for every placement on its own; the two
48
+ * part under `collapse-to="bar"` and `"none"`, where a corner panel still
49
+ * moves like one but has no launcher left to drag.
50
+ */
51
+ readonly panelMovable: boolean;
44
52
  /**
45
53
  * Which axes the resize grips may change. A full-bleed layout is the whole
46
54
  * viewport by definition and cannot be resized; a docked panel owns its
@@ -69,10 +77,11 @@ export interface Surface {
69
77
  * state, never a placement's own shape: `bar` applies where the placement
70
78
  * collapses to `launcher`, so the sidebar keeps its rail and an embedded chat
71
79
  * its header bar, and `none` applies to every collapsible placement. Absent,
72
- * `auto` and any other value leave the placement as it was. A docked surface
73
- * cannot be moved -- the panel rises from the bar or the host's anchor, and a
74
- * position the user dragged would take it away from either -- so both turn
75
- * the launcher drag off, and with it the header drag and `moveTo`.
80
+ * `auto` and any other value leave the placement as it was. Both turn the
81
+ * launcher drag off, because there is no launcher left to drag, and keep the
82
+ * placement's own answer for moving the panel: a corner panel rises from the
83
+ * bar or the anchor until the user drags it somewhere else, and a placement
84
+ * that owns its position keeps owning it.
76
85
  */
77
86
  export declare function surfaceFor(placement: string | null, collapseTo?: string | null): Surface;
78
87
  //# sourceMappingURL=surface_for.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"surface_for.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/surface_for.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AA2DD;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO,CAS9F"}
1
+ {"version":3,"file":"surface_for.d.ts","sourceRoot":"","sources":["../../../src/ui/placement/surface_for.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;AAEpF;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;CACnC;AA2ED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO,CAS9F"}
@@ -1 +1 @@
1
- {"version":3,"file":"tool_group_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/progress/tool_group_styles.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,iBAAiB,EAAE,MAqP/B,CAAC"}
1
+ {"version":3,"file":"tool_group_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/progress/tool_group_styles.ts"],"names":[],"mappings":"AAmCA,eAAO,MAAM,iBAAiB,EAAE,MAsP/B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"token_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/shell/token_styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAE,MA8a1B,CAAC"}
1
+ {"version":3,"file":"token_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/shell/token_styles.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,EAAE,MA4c1B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"quiet_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/themes/quiet_styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,EAAE,MA8G1B,CAAC"}
1
+ {"version":3,"file":"quiet_styles.d.ts","sourceRoot":"","sources":["../../../src/ui/themes/quiet_styles.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,EAAE,MA8H1B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artooi/ag-ui-web-component",
3
- "version": "0.48.0",
3
+ "version": "0.49.0",
4
4
  "description": "Framework-free <ag-ui-chat> Web Component over the AG-UI protocol. Drop-in chat sidebar with a pluggable client-side tool registry, DOM driver primitives, animations, and destructive-action confirmation modal.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1128,7 +1128,8 @@ export class AgUiChat extends HTMLElement {
1128
1128
  return;
1129
1129
  }
1130
1130
  // collapse-to changes the surface the way placement does -- a docked panel
1131
- // cannot be moved, so the same handover applies -- and is live the same way.
1131
+ // has no launcher to drag, and keeps its own dragged spot apart from the
1132
+ // corner's, so the same handover applies -- and is live the same way.
1132
1133
  if (name === "placement" || name === "collapse-to") {
1133
1134
  // A placement owns the axes it fixes, so hand those back before anything
1134
1135
  // else: a size dragged under the previous placement would otherwise sit
@@ -2076,7 +2077,9 @@ export class AgUiChat extends HTMLElement {
2076
2077
  * `movable` folds two separate reasons into the one answer a caller needs:
2077
2078
  * a placement that places itself owns its position, and a panel that fills
2078
2079
  * the screen has nowhere to go. Reporting them apart would make every caller
2079
- * re-derive the same conjunction.
2080
+ * re-derive the same conjunction. A corner panel docked under
2081
+ * `collapse-to="bar"` or `"none"` is movable on a wide viewport, like the
2082
+ * corner panel it is.
2080
2083
  */
2081
2084
  describeSurface(): ChatSurfaceReport {
2082
2085
  return this.#placement.describeSurface();
@@ -2091,7 +2094,8 @@ export class AgUiChat extends HTMLElement {
2091
2094
  * the corner it opens from is re-picked, and switching placement hands
2092
2095
  * everything back. What it must not do is claim a move it did not make --
2093
2096
  * hence the boolean, and hence {@link describeSurface} existing so a caller
2094
- * can ask first.
2097
+ * can ask first. A docked panel moves too, within the room above its bar or
2098
+ * anchor, and remembers the spot as a header drag would.
2095
2099
  */
2096
2100
  moveTo(corner: ChatCorner, options: { readonly announce?: boolean } = {}): boolean {
2097
2101
  return this.#placement.moveTo(corner, options);
@@ -2100,6 +2104,9 @@ export class AgUiChat extends HTMLElement {
2100
2104
  /**
2101
2105
  * Drop a size the user dragged, and its stored copy, so the placement's
2102
2106
  * default and the host's `--ag-ui-width` / `--ag-ui-height` apply again.
2107
+ * Under `collapse-to="bar"` or `"none"` it also returns a panel the user
2108
+ * dragged off its dock to the dock, and forgets the stored spot; a corner
2109
+ * panel keeps a dragged position.
2103
2110
  */
2104
2111
  resetSize(): void {
2105
2112
  this.#placement.resetSize();
@@ -161,11 +161,9 @@ export function createChatSurfaceTools(surface: ChatSurface): ClientTool[] {
161
161
  moved: false,
162
162
  reason: report.fullBleed
163
163
  ? "the panel fills the screen, so there is nowhere to move it to"
164
- : report.collapseTo === "bar" || report.collapseTo === "none"
165
- ? "the panel is docked: it rises from the page's bottom bar and stays there"
166
- : report.draggable === false
167
- ? "this page has turned off moving the panel"
168
- : `the "${report.placement ?? ""}" placement owns the panel's position`,
164
+ : report.draggable === false
165
+ ? "this page has turned off moving the panel"
166
+ : `the "${report.placement ?? ""}" placement owns the panel's position`,
169
167
  suggestion: report.collapsible ? "minimise_chat" : null,
170
168
  };
171
169
  }
@@ -16,7 +16,11 @@ export const DOCK_STYLES: string = `
16
16
  The cap follows the token block's rule: what the host left free less the
17
17
  one gutter the anchored edge spends, so a panel grown to the cap runs from
18
18
  just above the bar to the far edge. A host therefore needs no inset to keep
19
- the panel off its bar; --ag-ui-inset still wins when set.
19
+ the panel off its bar; --ag-ui-inset still wins when set. A panel the user
20
+ dragged off its dock is written there inline, which is how the dragged spot
21
+ outranks every rule below, the anchor gap included; the element holds that
22
+ spot above the bar or the anchor itself, and drops it on a phone, where the
23
+ small-viewport block reads the same property first.
20
24
 
21
25
  These blocks restate tokens and nothing else, and sit ahead of the phone
22
26
  block at no more weight than it has, so on a phone the panel is the screen
@@ -50,6 +50,15 @@ const DOCK_RIGHT = "--_dock-right";
50
50
  /** Per-tab persistence key for a dragged launcher position. */
51
51
  const LAUNCHER_KEY = "ag-ui-chat:launcher";
52
52
 
53
+ /**
54
+ * Persistence key for where the user dragged a docked panel. Its own key, not
55
+ * the launcher's: a spot stored under the corner launcher describes another
56
+ * surface, and reading it here would open every panel away from the bar for a
57
+ * host that switched to the bar after its users had dragged their corner
58
+ * panels.
59
+ */
60
+ const DOCK_KEY = "ag-ui-chat:dock";
61
+
53
62
  /** A stored `{ left, top }` pair, or null for anything that is not one. */
54
63
  function asPoint(value: unknown): { readonly left: number; readonly top: number } | null {
55
64
  if (typeof value !== "object" || value === null) {
@@ -157,7 +166,7 @@ export class PanelPlacement {
157
166
  */
158
167
  enablePanelDrag(header: HTMLElement): void {
159
168
  enablePanelDrag(header, {
160
- enabled: () => !this.#host.collapsed() && this.#launcherDraggable(),
169
+ enabled: () => !this.#host.collapsed() && this.#canDragPanel(),
161
170
  rect: () => this.#host.element.getBoundingClientRect(),
162
171
  apply: (box, from) => this.#movePanel(box, from),
163
172
  commit: (box, from) => this.#commitPanel(box, from),
@@ -213,11 +222,23 @@ export class PanelPlacement {
213
222
  * Drop the dragged size and its stored copy, so the placement's own size and
214
223
  * the host's tokens apply again. For a host entering a sized state of its
215
224
  * own, which a user's drag would otherwise outrank.
225
+ *
226
+ * A docked panel the user dragged off its dock goes back to it as well, and
227
+ * the stored spot with it: there the position is part of the same resting
228
+ * state the host is asking for. A corner panel keeps a dragged position, as
229
+ * it always has.
216
230
  */
217
231
  resetSize(): void {
218
232
  this.#host.element.style.removeProperty(DRAG_WIDTH);
219
233
  this.#host.element.style.removeProperty(DRAG_HEIGHT);
220
234
  this.#host.clearPreference(SIZE_KEY);
235
+ if (this.#docked()) {
236
+ if (this.#dockPos !== null) {
237
+ this.#host.element.style.removeProperty("--ag-ui-inset");
238
+ }
239
+ this.#dockPos = null;
240
+ this.#storeDockPosition(null);
241
+ }
221
242
  // The anchor was measured against the dragged box; the resting one may
222
243
  // pin different edges.
223
244
  this.syncResizeAnchor();
@@ -250,6 +271,25 @@ export class PanelPlacement {
250
271
  */
251
272
  #panelPos: { readonly left: number; readonly top: number } | null = null;
252
273
 
274
+ /**
275
+ * Where the user dragged a docked panel, in viewport coordinates, or null
276
+ * while it stands on the bar or the anchor.
277
+ *
278
+ * Apart from the two corner positions above because it moves nothing else:
279
+ * a docked panel has no launcher to carry, and the corner it opens from is
280
+ * the dock's. Held as the user stated it and never as clamped, so a bar that
281
+ * grew, or a phone that took the panel full-bleed, gives the spot back
282
+ * unchanged once there is room for it again.
283
+ */
284
+ #dockPos: { readonly left: number; readonly top: number } | null = null;
285
+
286
+ /**
287
+ * The line a docked panel stays above, in viewport coordinates: the bar's
288
+ * top, or the anchor's. Infinite where neither is drawn. Measured by
289
+ * syncDock, which runs on every change either can make.
290
+ */
291
+ #dockTop = Number.POSITIVE_INFINITY;
292
+
253
293
  /**
254
294
  * The corner the panel opens away from, once this element is placing itself.
255
295
  * Null means the host's layout still decides, and the anchor is measured.
@@ -281,7 +321,10 @@ export class PanelPlacement {
281
321
  * rather than collapsed to nothing.
282
322
  */
283
323
  #withinViewport(box: PanelRect): PanelRect {
284
- const viewport = this.#viewport();
324
+ // A docked panel that moves has its room stop at the dock, so no grip
325
+ // pulls it over the bar it minimises to. A placement that owns its
326
+ // position keeps the bound it always had.
327
+ const viewport = this.#docked() && this.#panelMovable() ? this.#dockRoom() : this.#viewport();
285
328
  // The same bound a drag stops at, so a grip pulled to the edge and a panel
286
329
  // dragged to it come to rest on the same line. The inner Math.max/min pair
287
330
  // keeps an already-inverted box from turning inside out.
@@ -321,8 +364,14 @@ export class PanelPlacement {
321
364
  collapseTo: this.#surface().collapseTo,
322
365
  collapsed: this.#host.collapsed(),
323
366
  collapsible: this.#host.collapsible(),
324
- movable: this.#launcherDraggable() && !fullBleed,
325
- draggable: this.#launcherDraggable(),
367
+ movable: this.#panelMovable() && !fullBleed,
368
+ // Whether the page left moving on, which is not the same question as
369
+ // whether this panel moves: a docked sidebar's position is owned by its
370
+ // placement, and reporting that as the host having turned moving off is
371
+ // the sentence the move refusal would then get wrong.
372
+ draggable:
373
+ this.#host.element.getAttribute("data-launcher-drag") !== "false" &&
374
+ (this.#surface().launcherDraggable || this.#docked()),
326
375
  fullBleed,
327
376
  box: {
328
377
  left: Math.round(box.left),
@@ -341,7 +390,7 @@ export class PanelPlacement {
341
390
 
342
391
  /** The move behind `AgUiChat.moveTo`, whose doc is the contract. */
343
392
  moveTo(corner: ChatCorner, options: { readonly announce?: boolean } = {}): boolean {
344
- if (!this.#launcherDraggable()) {
393
+ if (!this.#panelMovable()) {
345
394
  return false;
346
395
  }
347
396
  const restore = options.announce === true ? this.#captureGeometry() : null;
@@ -351,23 +400,31 @@ export class PanelPlacement {
351
400
  return false;
352
401
  }
353
402
  const [edgeY, edgeX] = corner.split("-");
403
+ // A docked panel's bottom corners are above its dock, not on the bar.
404
+ const docked = this.#docked();
405
+ const room = docked ? this.#dockRoom() : viewport;
354
406
  // Every term is an absolute screen coordinate, because that is what the
355
407
  // clamps and the insets both speak. The usable box carries an origin, so
356
408
  // its near edge is `viewport.left`, not zero, and its far edge is
357
409
  // `viewport.left + viewport.width` -- a margin applied to the extents
358
410
  // alone would send the agent's own move under the chrome the host
359
411
  // reserved, which is the failure the usable box exists to prevent.
360
- const nearX = viewport.left + EDGE_MARGIN;
361
- const nearY = viewport.top + EDGE_MARGIN;
412
+ const nearX = room.left + EDGE_MARGIN;
413
+ const nearY = room.top + EDGE_MARGIN;
362
414
  const left =
363
- edgeX === "left"
364
- ? nearX
365
- : Math.max(nearX, viewport.left + viewport.width - EDGE_MARGIN - box.width);
415
+ edgeX === "left" ? nearX : Math.max(nearX, room.left + room.width - EDGE_MARGIN - box.width);
366
416
  const top =
367
- edgeY === "top"
368
- ? nearY
369
- : Math.max(nearY, viewport.top + viewport.height - EDGE_MARGIN - box.height);
417
+ edgeY === "top" ? nearY : Math.max(nearY, room.top + room.height - EDGE_MARGIN - box.height);
370
418
  const host = { left, top, right: left + box.width, bottom: top + box.height };
419
+ if (docked) {
420
+ this.#dockPos = { left, top };
421
+ this.#writeDockInset(host);
422
+ this.#storeDockPosition(this.#dockPos);
423
+ if (restore !== null) {
424
+ this.#host.announceSurfaceChange(this.#host.strings().chatMoved, restore);
425
+ }
426
+ return true;
427
+ }
371
428
  // Both axes measured, rather than one read twice: a host can restyle the
372
429
  // launcher as a pill, and squaring it here would put it off the corner.
373
430
  const launcherWidth = this.#host.launcher.offsetWidth;
@@ -401,6 +458,7 @@ export class PanelPlacement {
401
458
  const corner = this.#host.element.getAttribute("data-expand-corner");
402
459
  const launcherPos = this.#launcherPos;
403
460
  const panelPos = this.#panelPos;
461
+ const dockPos = this.#dockPos;
404
462
  const expandCorner = this.#expandCorner;
405
463
  return () => {
406
464
  this.#restoreProperty("--ag-ui-inset", inset);
@@ -412,7 +470,15 @@ export class PanelPlacement {
412
470
  }
413
471
  this.#launcherPos = launcherPos;
414
472
  this.#panelPos = panelPos;
473
+ this.#dockPos = dockPos;
415
474
  this.#expandCorner = expandCorner;
475
+ if (this.#docked()) {
476
+ // The dock's own record, and only that: the launcher's belongs to the
477
+ // corner surface and has nothing to undo here.
478
+ this.#storeDockPosition(dockPos);
479
+ this.syncResizeAnchor();
480
+ return;
481
+ }
416
482
  // Erased rather than rewritten when there was nothing to go back to.
417
483
  // #storeLauncherPosition returns early for a null position, which would
418
484
  // leave the move this is undoing sitting in storage -- and since that
@@ -583,7 +649,10 @@ export class PanelPlacement {
583
649
  return surfaceFor(element.getAttribute("placement"), element.getAttribute("collapse-to"));
584
650
  }
585
651
 
586
- /** Whether the panel rises from the bottom bar or the host's anchor. */
652
+ /**
653
+ * Whether the panel rises from the bottom bar or the host's anchor, until the
654
+ * user drags it somewhere else.
655
+ */
587
656
  #docked(): boolean {
588
657
  const target = this.#surface().collapseTo;
589
658
  return target === "bar" || target === "none";
@@ -617,9 +686,122 @@ export class PanelPlacement {
617
686
  element.style.removeProperty(DOCK_RIGHT);
618
687
  }
619
688
  element.toggleAttribute("data-dock-anchored", target === "none" && anchor !== null);
689
+ this.#dockTop =
690
+ target === "bar" && height > 0
691
+ ? bar.getBoundingClientRect().top
692
+ : target === "none" && anchor !== null
693
+ ? anchor.getBoundingClientRect().top
694
+ : Number.POSITIVE_INFINITY;
695
+ // Every change the dock can make passes through here -- the bar's height
696
+ // arrives by a ResizeObserver after the first restore, and a bar that grew
697
+ // since the drag would otherwise cover the panel's foot -- so the dragged
698
+ // spot is held against it here rather than only when it is restored.
699
+ this.#placeDocked();
620
700
  return height;
621
701
  }
622
702
 
703
+ /**
704
+ * The part of the usable viewport a docked panel may stand in: all of it
705
+ * above the dock's line. The bar is what it minimises to, and the anchor is
706
+ * the host's own way back, so a dragged panel never covers either.
707
+ */
708
+ #dockRoom(): ViewportBox {
709
+ const viewport = this.#viewport();
710
+ const bottom = Math.min(viewport.top + viewport.height, this.#dockTop);
711
+ return { ...viewport, height: Math.max(0, bottom - viewport.top) };
712
+ }
713
+
714
+ /**
715
+ * Put a docked panel back where the user dragged it, held inside its room.
716
+ *
717
+ * The inline inset comes off first, which is both how the panel's resting
718
+ * box is measured and what leaves a phone full-bleed: the small-viewport
719
+ * block reads the host's inset before its own, so a dragged spot written
720
+ * there would hold the panel off the screen's edges. The spot itself stays,
721
+ * for the next time there is room for it.
722
+ */
723
+ #placeDocked(): void {
724
+ if (!this.#docked() || !this.#panelMovable() || this.dragging()) {
725
+ return;
726
+ }
727
+ const at = this.#dockPos ?? this.#readDockPosition();
728
+ if (at === null) {
729
+ return;
730
+ }
731
+ this.#dockPos = at;
732
+ this.#host.element.style.removeProperty("--ag-ui-inset");
733
+ const rest = this.#host.element.getBoundingClientRect();
734
+ if (coversViewport(rest, this.#viewport())) {
735
+ return;
736
+ }
737
+ // Measured at the dock, so the inset below is written from the corner the
738
+ // dock holds still and a resize grows the panel away from it.
739
+ this.syncResizeAnchor();
740
+ this.#writeDockInset(
741
+ clampPanel(
742
+ { left: at.left, top: at.top, right: at.left + rest.width, bottom: at.top + rest.height },
743
+ this.#dockRoom(),
744
+ SCREEN_EDGE_MARGIN,
745
+ ),
746
+ );
747
+ }
748
+
749
+ /** Write the inset that stands a docked panel at `box`. */
750
+ #writeDockInset(box: PanelRect): void {
751
+ this.#host.element.style.setProperty(
752
+ "--ag-ui-inset",
753
+ insetFrom(this.#anchor, box, this.#screen()),
754
+ );
755
+ }
756
+
757
+ /** Remember a docked panel's dragged spot, or forget it for null. */
758
+ #storeDockPosition(at: { readonly left: number; readonly top: number } | null): void {
759
+ if (at === null) {
760
+ this.#host.clearPreference(DOCK_KEY);
761
+ return;
762
+ }
763
+ this.#host.writePreference(DOCK_KEY, JSON.stringify({ left: at.left, top: at.top }));
764
+ }
765
+
766
+ /** The stored spot of a docked panel, or null for none or anything corrupt. */
767
+ #readDockPosition(): { readonly left: number; readonly top: number } | null {
768
+ const raw = this.#host.readPreference(DOCK_KEY);
769
+ if (raw === null) {
770
+ return null;
771
+ }
772
+ try {
773
+ return asPoint(JSON.parse(raw));
774
+ } catch {
775
+ return null;
776
+ }
777
+ }
778
+
779
+ /**
780
+ * Whether the header drag and moveTo may move the open panel: the
781
+ * placement's answer, unless the host turned moving off.
782
+ */
783
+ #panelMovable(): boolean {
784
+ return (
785
+ this.#host.element.getAttribute("data-launcher-drag") !== "false" &&
786
+ this.#surface().panelMovable
787
+ );
788
+ }
789
+
790
+ /**
791
+ * Whether a header drag may start now. A docked panel on a phone is the
792
+ * screen, and a drag there would pull it off the edges it fills; a corner
793
+ * panel's header is left as it was.
794
+ */
795
+ #canDragPanel(): boolean {
796
+ if (!this.#panelMovable()) {
797
+ return false;
798
+ }
799
+ return (
800
+ !this.#docked() ||
801
+ !coversViewport(this.#host.element.getBoundingClientRect(), this.#viewport())
802
+ );
803
+ }
804
+
623
805
  /**
624
806
  * Whether this placement lets the launcher be dragged, read per interaction
625
807
  * because `placement` is a live attribute. `data-launcher-drag="false"` opts
@@ -863,6 +1045,13 @@ export class PanelPlacement {
863
1045
  * other still names the old one would move the launcher for no reason.
864
1046
  */
865
1047
  #movePanel(box: PanelRect, from: PanelRect): { held: PanelRect; launcher: LauncherBox | null } {
1048
+ if (this.#docked()) {
1049
+ // Inside the room above the dock, with nothing carried along.
1050
+ const held = clampPanel(box, this.#dockRoom(), SCREEN_EDGE_MARGIN);
1051
+ this.#dockPos = { left: held.left, top: held.top };
1052
+ this.#writeDockInset(held);
1053
+ return { held, launcher: null };
1054
+ }
866
1055
  if (!this.#launcherDraggable()) {
867
1056
  return { held: box, launcher: null };
868
1057
  }
@@ -936,6 +1125,10 @@ export class PanelPlacement {
936
1125
  // again. Recomputing it is how the two came apart: releasing the drag
937
1126
  // moved the bubble by the panel's whole travel a second time.
938
1127
  const { held, launcher } = this.#movePanel(box, from);
1128
+ if (this.#docked()) {
1129
+ this.#storeDockPosition({ left: held.left, top: held.top });
1130
+ return;
1131
+ }
939
1132
  if (launcher === null) {
940
1133
  return;
941
1134
  }
@@ -1026,6 +1219,13 @@ export class PanelPlacement {
1026
1219
  * unreachable -- it is the only way back to a collapsed conversation.
1027
1220
  */
1028
1221
  restoreLauncherPosition(): void {
1222
+ // Before the launcher's record is read at all: it belongs to the corner
1223
+ // surface, and seeding anything from it would put a spot dragged there on
1224
+ // a panel that should stand on its dock.
1225
+ if (this.#docked()) {
1226
+ this.#placeDocked();
1227
+ return;
1228
+ }
1029
1229
  const stored = this.#readLauncherPosition();
1030
1230
  const launcher = this.#launcherPos ?? stored;
1031
1231
  if (launcher === null) {
@@ -1083,6 +1283,13 @@ export class PanelPlacement {
1083
1283
  * the switch inline and pins a sidebar to wherever the floating launcher was.
1084
1284
  */
1085
1285
  releaseLauncherPosition(): void {
1286
+ // A dragged dock spot belongs to a docked panel that moves. Any other
1287
+ // surface hands it back; a docked one keeps it, and syncDock holds it
1288
+ // against the new dock.
1289
+ if (this.#dockPos !== null && !(this.#docked() && this.#panelMovable())) {
1290
+ this.#dockPos = null;
1291
+ this.#host.element.style.removeProperty("--ag-ui-inset");
1292
+ }
1086
1293
  if (this.#launcherDraggable()) {
1087
1294
  return;
1088
1295
  }
@@ -1110,11 +1317,12 @@ export class PanelPlacement {
1110
1317
  */
1111
1318
  #applyResize(grip: ResizeGrip, box: PanelRect): PanelRect {
1112
1319
  box = this.#withinViewport(box);
1113
- if (this.#docked()) {
1114
- // A docked panel keeps its resize but never its position: the edges it
1320
+ if (this.#docked() && this.#dockPos === null) {
1321
+ // A panel standing on its dock keeps it through a resize: the edges it
1115
1322
  // stands on are the bar's or the anchor's, and a grip on one of them
1116
1323
  // would write the position below and take the panel off its dock. So
1117
1324
  // the pinned edges stay where they are and only the free ones follow.
1325
+ // Once dragged off, it resizes like a corner panel, below.
1118
1326
  const now = this.#host.element.getBoundingClientRect();
1119
1327
  box = {
1120
1328
  left: grip.x === this.#anchor.x ? now.left : box.left,
@@ -1126,6 +1334,11 @@ export class PanelPlacement {
1126
1334
  return box;
1127
1335
  }
1128
1336
  this.#applySize({ width: box.right - box.left, height: box.bottom - box.top });
1337
+ if (this.#docked()) {
1338
+ // Any grip moves the top-left corner the spot is kept as, including one
1339
+ // on a free edge, which leaves the inset alone.
1340
+ this.#dockPos = { left: box.left, top: box.top };
1341
+ }
1129
1342
  if (grip.x !== this.#anchor.x && grip.y !== this.#anchor.y) {
1130
1343
  return box;
1131
1344
  }
@@ -1161,6 +1374,9 @@ export class PanelPlacement {
1161
1374
  const held = this.#applyResize(grip, box);
1162
1375
  this.#persistSize({ width: held.right - held.left, height: held.bottom - held.top });
1163
1376
  this.#storeLauncherPosition();
1377
+ if (this.#dockPos !== null) {
1378
+ this.#storeDockPosition(this.#dockPos);
1379
+ }
1164
1380
  // Re-stamp after the drag: a host whose layout changed underneath us would
1165
1381
  // otherwise keep the tab-reachable grip in the old corner, which reads as
1166
1382
  // the control being in the wrong place even though the drag was right.