@aparte/core 0.15.1 → 0.16.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.
Files changed (138) hide show
  1. package/dist/client/aparte-client.d.ts +53 -51
  2. package/dist/client/aparte-client.d.ts.map +1 -1
  3. package/dist/client/lifecycle-events.d.ts +0 -12
  4. package/dist/client/lifecycle-events.d.ts.map +1 -1
  5. package/dist/client/stream-adapter.d.ts +2 -12
  6. package/dist/client/stream-adapter.d.ts.map +1 -1
  7. package/dist/components/bubble/aparte-chat-bubble.d.ts +45 -1
  8. package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
  9. package/dist/components/composer/aparte-composer-attachments.d.ts +0 -1
  10. package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
  11. package/dist/components/composer/aparte-composer-send.d.ts +11 -11
  12. package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
  13. package/dist/components/composer/aparte-composer.d.ts +20 -11
  14. package/dist/components/composer/aparte-composer.d.ts.map +1 -1
  15. package/dist/components/context/aparte-context.d.ts +31 -8
  16. package/dist/components/context/aparte-context.d.ts.map +1 -1
  17. package/dist/components/conversation-list/aparte-conversation-list.d.ts +93 -36
  18. package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
  19. package/dist/components/conversation-list/index.d.ts +1 -1
  20. package/dist/components/conversation-list/index.d.ts.map +1 -1
  21. package/dist/components/elicitation/aparte-elicitation.d.ts +19 -1
  22. package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
  23. package/dist/components/index.d.ts +7 -1
  24. package/dist/components/index.d.ts.map +1 -1
  25. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts +105 -0
  26. package/dist/components/scroll-rail/aparte-scroll-rail.d.ts.map +1 -0
  27. package/dist/components/scroll-rail/index.d.ts +3 -0
  28. package/dist/components/scroll-rail/index.d.ts.map +1 -0
  29. package/dist/components/sidebar/aparte-sidebar.d.ts +186 -0
  30. package/dist/components/sidebar/aparte-sidebar.d.ts.map +1 -0
  31. package/dist/components/sidebar/index.d.ts +3 -0
  32. package/dist/components/sidebar/index.d.ts.map +1 -0
  33. package/dist/components/split/aparte-split.d.ts +354 -0
  34. package/dist/components/split/aparte-split.d.ts.map +1 -0
  35. package/dist/components/split/geometry.d.ts +65 -0
  36. package/dist/components/split/geometry.d.ts.map +1 -0
  37. package/dist/components/split/index.d.ts +3 -0
  38. package/dist/components/split/index.d.ts.map +1 -0
  39. package/dist/components/suggestions/aparte-suggestions.d.ts +7 -1
  40. package/dist/components/suggestions/aparte-suggestions.d.ts.map +1 -1
  41. package/dist/components/viewport/aparte-chat-viewport.d.ts +52 -2
  42. package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
  43. package/dist/config/aparte-config.d.ts +95 -33
  44. package/dist/config/aparte-config.d.ts.map +1 -1
  45. package/dist/config/icon-provider.d.ts +6 -0
  46. package/dist/config/icon-provider.d.ts.map +1 -1
  47. package/dist/config/index.d.ts +2 -2
  48. package/dist/config/index.d.ts.map +1 -1
  49. package/dist/config/locale.d.ts +140 -27
  50. package/dist/config/locale.d.ts.map +1 -1
  51. package/dist/config/sanitize.d.ts +9 -0
  52. package/dist/config/sanitize.d.ts.map +1 -1
  53. package/dist/conversations/conversation-controller.d.ts +13 -1
  54. package/dist/conversations/conversation-controller.d.ts.map +1 -1
  55. package/dist/conversations/conversation-manager.d.ts +9 -0
  56. package/dist/conversations/conversation-manager.d.ts.map +1 -1
  57. package/dist/custom-elements.json +9219 -6730
  58. package/dist/{is-awaiting-reply-BZ_iJ3s3.js → dialog-triggers-CVCxqKg3.js} +718 -1182
  59. package/dist/dialog-triggers-CVCxqKg3.js.map +1 -0
  60. package/dist/elicitation/approval-panel.d.ts +1 -1
  61. package/dist/elicitation/approval-panel.d.ts.map +1 -1
  62. package/dist/elicitation/panel.d.ts +24 -16
  63. package/dist/elicitation/panel.d.ts.map +1 -1
  64. package/dist/elicitation/types.d.ts +31 -0
  65. package/dist/elicitation/types.d.ts.map +1 -1
  66. package/dist/generated/element-attributes.d.ts +47 -1
  67. package/dist/generated/element-attributes.d.ts.map +1 -1
  68. package/dist/{glyphs-B3BZ2TIb.js → glyphs-DQTeOj4w.js} +22 -13
  69. package/dist/{glyphs-B3BZ2TIb.js.map → glyphs-DQTeOj4w.js.map} +1 -1
  70. package/dist/host/aparte-chat-host.d.ts +10 -2
  71. package/dist/host/aparte-chat-host.d.ts.map +1 -1
  72. package/dist/icons/extended.d.ts +4 -2
  73. package/dist/icons/extended.d.ts.map +1 -1
  74. package/dist/icons/glyphs.d.ts +9 -0
  75. package/dist/icons/glyphs.d.ts.map +1 -1
  76. package/dist/icons.js +16 -15
  77. package/dist/icons.js.map +1 -1
  78. package/dist/index.css +1217 -396
  79. package/dist/index.d.ts +26 -15
  80. package/dist/index.d.ts.map +1 -1
  81. package/dist/index.js +2097 -295
  82. package/dist/index.js.map +1 -1
  83. package/dist/index.node.d.ts +21 -5
  84. package/dist/index.node.d.ts.map +1 -1
  85. package/dist/index.node.js +39 -34
  86. package/dist/index.node.js.map +1 -1
  87. package/dist/interop/dialog-triggers.d.ts +27 -0
  88. package/dist/interop/dialog-triggers.d.ts.map +1 -0
  89. package/dist/interop/element-props.d.ts +16 -8
  90. package/dist/interop/element-props.d.ts.map +1 -1
  91. package/dist/parsers/aparte-stream-parser.d.ts +52 -22
  92. package/dist/parsers/aparte-stream-parser.d.ts.map +1 -1
  93. package/dist/parsers/index.d.ts +1 -1
  94. package/dist/parsers/index.d.ts.map +1 -1
  95. package/dist/primitives/select/aparte-select.d.ts.map +1 -1
  96. package/dist/renderers/segment-renderers.d.ts.map +1 -1
  97. package/dist/renderers/segments/code.d.ts.map +1 -1
  98. package/dist/renderers/segments/tool-call.d.ts.map +1 -1
  99. package/dist/runtime/message-repository.d.ts.map +1 -1
  100. package/dist/transport/backend-handler.d.ts.map +1 -1
  101. package/dist/transport/backend-transport.d.ts +6 -1
  102. package/dist/transport/backend-transport.d.ts.map +1 -1
  103. package/dist/types/chat.d.ts +8 -14
  104. package/dist/types/chat.d.ts.map +1 -1
  105. package/dist/types/element-map.d.ts +54 -4
  106. package/dist/types/element-map.d.ts.map +1 -1
  107. package/dist/types/event-map.d.ts +16 -10
  108. package/dist/types/event-map.d.ts.map +1 -1
  109. package/dist/types/events.d.ts +59 -117
  110. package/dist/types/events.d.ts.map +1 -1
  111. package/dist/types/imperative-api.d.ts +3 -1
  112. package/dist/types/imperative-api.d.ts.map +1 -1
  113. package/dist/types/index.d.ts +5 -4
  114. package/dist/types/index.d.ts.map +1 -1
  115. package/dist/types/models.d.ts +11 -31
  116. package/dist/types/models.d.ts.map +1 -1
  117. package/dist/types/segments.d.ts +11 -47
  118. package/dist/types/segments.d.ts.map +1 -1
  119. package/dist/types/stream-blocks.d.ts +57 -0
  120. package/dist/types/stream-blocks.d.ts.map +1 -0
  121. package/dist/types/tools.d.ts +57 -0
  122. package/dist/types/tools.d.ts.map +1 -1
  123. package/dist/utils/copy-text.d.ts +24 -0
  124. package/dist/utils/copy-text.d.ts.map +1 -0
  125. package/dist/utils/css-escape.d.ts +5 -0
  126. package/dist/utils/css-escape.d.ts.map +1 -1
  127. package/dist/utils/tool-input.d.ts +20 -0
  128. package/dist/utils/tool-input.d.ts.map +1 -0
  129. package/package.json +10 -3
  130. package/dist/is-awaiting-reply-BZ_iJ3s3.js.map +0 -1
  131. package/dist/renderers/segments/artifact/binary-file.d.ts +0 -45
  132. package/dist/renderers/segments/artifact/binary-file.d.ts.map +0 -1
  133. package/dist/renderers/segments/artifact/card.d.ts +0 -3
  134. package/dist/renderers/segments/artifact/card.d.ts.map +0 -1
  135. package/dist/renderers/segments/artifact/preview-document.d.ts +0 -27
  136. package/dist/renderers/segments/artifact/preview-document.d.ts.map +0 -1
  137. package/dist/renderers/segments/artifact/shared.d.ts +0 -29
  138. package/dist/renderers/segments/artifact/shared.d.ts.map +0 -1
@@ -1,9 +1,12 @@
1
1
  export interface AparteConversationListItem {
2
2
  id: string;
3
3
  title: string;
4
+ /** Drives the date groups. A list where no item carries one renders flat. */
4
5
  updatedAt?: number;
5
- /** When set, the item renders the unarchive action instead of archive. */
6
+ /** When set, the row is italic and its menu offers unarchive instead of archive. */
6
7
  archivedAt?: number;
8
+ /** When set, the row sits in the "Pinned" group first, and its menu offers unpin. */
9
+ pinnedAt?: number;
7
10
  }
8
11
  export interface AparteConversationSelectDetail {
9
12
  id: string;
@@ -14,10 +17,27 @@ export interface AparteConversationDeleteDetail {
14
17
  export interface AparteConversationArchiveDetail {
15
18
  id: string;
16
19
  }
20
+ export interface AparteConversationPinDetail {
21
+ id: string;
22
+ }
23
+ export interface AparteConversationRenameDetail {
24
+ id: string;
25
+ /** The new title, trimmed and non-empty — an unchanged or emptied title fires nothing. */
26
+ title: string;
27
+ }
17
28
  /**
18
29
  * Conversation-history sidebar — a framework-agnostic web component. The host sets
19
30
  * the `conversations` JS property and the `active-id` attribute; this renders the
20
- * list and fires the user's intent, never acting on it itself.
31
+ * rows and fires the user's intent, never acting on it itself.
32
+ *
33
+ * A row is two real buttons: the title, which selects, and a `⋯` that opens the row's
34
+ * menu — rename, pin or unpin, archive or unarchive, delete. Every item fires an event
35
+ * and stops; the one exception is delete, which asks first, inline in the menu,
36
+ * because it is the one action the host cannot undo. Rename swaps the title for an
37
+ * input: Enter or leaving the field commits, Escape cancels, and an unchanged or
38
+ * emptied title fires nothing. The rows are grouped by date — Pinned, Today,
39
+ * Yesterday, Previous 7 days, Previous 30 days, then one heading per month — as soon
40
+ * as any item carries `updatedAt`; set `no-groups` to render them flat.
21
41
  *
22
42
  * Children are not a composition point: `_render()` assigns `innerHTML` from the
23
43
  * `conversations` array, so any light-DOM child a host writes inside the element is
@@ -25,29 +45,33 @@ export interface AparteConversationArchiveDetail {
25
45
  * enough to trigger one. Compose around the element, not inside it: it renders rows
26
46
  * and nothing else, with no header, no new-conversation button and no search field.
27
47
  *
28
- * What it is not: a store. Clicking a row selects nothing, and the two row actions
29
- * delete and archive nothing — the four events carry an id and stop. A row's text
30
- * comes from the array, so it changes when the host assigns `conversations` again;
31
- * the exception is an empty title, which falls back to the locale's new-chat label
32
- * and therefore follows a locale switch. An archived item is still rendered (it gains
33
- * `aparte-conv-item--archived` and swaps its action's icon and event name); filtering
34
- * archived conversations out of the list is the host's decision, not this element's.
35
- * The asymmetry between the two inputs is deliberate: `active-id` is an attribute
36
- * because moving the selection patches the rendered rows in place, while
37
- * `conversations` is a JS property because it is structured data an attribute cannot
38
- * carry, and setting it re-renders the whole list.
48
+ * What it is not: a store. Selecting, renaming, pinning, archiving and deleting all
49
+ * leave the array untouched — the events carry an id (and, for rename, the title) and
50
+ * stop. A row's text comes from the array, so it changes when the host assigns
51
+ * `conversations` again; the exception is an empty title, which falls back to the
52
+ * locale's new-chat label and therefore follows a locale switch. An archived item is
53
+ * still rendered (it gains `aparte-conv-item--archived`); filtering archived
54
+ * conversations out of the list is the host's decision, not this element's. The
55
+ * asymmetry between the two inputs is deliberate: `active-id` is an attribute because
56
+ * moving the selection patches the rendered rows in place, while `conversations` is a
57
+ * JS property because it is structured data an attribute cannot carry, and setting it
58
+ * re-renders the whole list.
39
59
  *
40
60
  * @element aparte-conversation-list
41
61
  * @attr {string} active-id - The id of the conversation to render as selected.
62
+ * @attr {boolean} no-groups - Render the rows flat, in host order, with no date headings.
42
63
  *
43
- * @fires {CustomEvent<AparteConversationSelectDetail>} aparte-select-conversation - A row was activated; the host loads that conversation.
44
- * @fires {CustomEvent<AparteConversationDeleteDetail>} aparte-delete-conversation - The delete action was pressed. Nothing is removed here.
45
- * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-archive-conversation - The archive action was pressed on a live conversation.
46
- * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-unarchive-conversation - The same action on an already-archived one; same detail shape, opposite intent.
64
+ * @fires {CustomEvent<AparteConversationSelectDetail>} aparte-select-conversation - A row's title was activated; the host loads that conversation.
65
+ * @fires {CustomEvent<AparteConversationRenameDetail>} aparte-rename-conversation - A rename was committed with a new, non-empty title. Nothing is renamed here.
66
+ * @fires {CustomEvent<AparteConversationPinDetail>} aparte-pin-conversation - The pin item was chosen on an unpinned row.
67
+ * @fires {CustomEvent<AparteConversationPinDetail>} aparte-unpin-conversation - The same item on a pinned row; same detail shape, opposite intent.
68
+ * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-archive-conversation - The archive item was chosen on a live conversation.
69
+ * @fires {CustomEvent<AparteConversationArchiveDetail>} aparte-unarchive-conversation - The same item on an already-archived one; same detail shape, opposite intent.
70
+ * @fires {CustomEvent<AparteConversationDeleteDetail>} aparte-delete-conversation - The delete was confirmed. Nothing is removed here.
47
71
  *
48
- * @cssprop [--aparte-conv-list-gap=2px] - Vertical gap between rows. The element itself is the flex column, so this is its `gap`.
49
- * @cssprop [--aparte-conv-item-padding=7px 10px] - Padding of a row.
50
- * @cssprop [--aparte-conv-item-gap=6px] - Gap between a row's title and its two action buttons.
72
+ * @cssprop [--aparte-conv-list-gap=2px] - Vertical gap between rows, and between a group's heading and its rows.
73
+ * @cssprop [--aparte-conv-item-padding=7px 10px] - Padding of a row's title button.
74
+ * @cssprop [--aparte-conv-item-gap=6px] - Gap between a row's title and its `⋯` button.
51
75
  * @cssprop [--aparte-conv-item-radius=var(--aparte-radius-md)] - Corner radius of a row.
52
76
  * @cssprop [--aparte-conv-item-font-size=0.8125rem] - Font size of a row's title.
53
77
  * @cssprop [--aparte-conv-item-color=var(--aparte-text-muted)] - Title colour of an inactive row.
@@ -55,15 +79,7 @@ export interface AparteConversationArchiveDetail {
55
79
  * @cssprop [--aparte-conv-item-bg-active=var(--aparte-surface-3)] - Background of the row matching `active-id`.
56
80
  * @cssprop [--aparte-conv-item-color-active=var(--aparte-text)] - Title colour of the active row.
57
81
  * @cssprop [--aparte-conv-item-font-weight-active=var(--aparte-font-weight-medium, 500)] - Title weight of the active row.
58
- * @cssprop [--aparte-conv-action-btn-size=20px] - Square size of both action buttons. Under `(pointer: coarse)` the stylesheet redeclares it as 28px on the buttons themselves, so a value set on the element does not reach them there; the buttons also stay visible instead of appearing on hover.
59
- * @cssprop [--aparte-conv-delete-color=var(--aparte-text-muted)] - Icon colour of the delete button.
60
- * @cssprop [--aparte-conv-delete-bg-hover=var(--aparte-error)] - Delete button background on hover.
61
- * @cssprop [--aparte-conv-delete-color-hover=var(--aparte-text-inverse)] - Delete button icon colour on hover.
62
- * @cssprop [--aparte-conv-delete-radius=var(--aparte-radius-sm)] - Corner radius of the delete button.
63
- * @cssprop [--aparte-conv-archive-color=var(--aparte-text-muted)] - Icon colour of the archive/unarchive button.
64
- * @cssprop [--aparte-conv-archive-bg-hover=var(--aparte-surface-4, var(--aparte-surface-3))] - Archive button background on hover. Core declares no `--aparte-surface-4`, so unset it resolves to `--aparte-surface-3`.
65
- * @cssprop [--aparte-conv-archive-color-hover=var(--aparte-text)] - Archive button icon colour on hover.
66
- * @cssprop [--aparte-conv-archive-radius=var(--aparte-radius-sm)] - Corner radius of the archive button.
82
+ * @cssprop [--aparte-conv-action-btn-size=20px] - Square size of the `⋯` button. Under `(pointer: coarse)` the stylesheet redeclares it as 28px on the button itself, so a value set on the element does not reach it there; the button also stays visible instead of appearing on hover.
67
83
  *
68
84
  * @example
69
85
  * <!-- It stores nothing and fetches nothing: an empty tag renders the empty state, and
@@ -71,9 +87,12 @@ export interface AparteConversationArchiveDetail {
71
87
  * <aparte-conversation-list active-id="c1" style="max-width: 20rem"></aparte-conversation-list>
72
88
  *
73
89
  * <script>
90
+ * const day = 864e5;
74
91
  * document.querySelector('aparte-conversation-list').conversations = [
92
+ * { id: 'c0', title: 'Release checklist', updatedAt: Date.now() - 3 * day, pinnedAt: Date.now() },
75
93
  * { id: 'c1', title: 'Deploy checklist', updatedAt: Date.now() },
76
- * { id: 'c2', title: 'Rename the segment types', updatedAt: Date.now() - 864e5 },
94
+ * { id: 'c2', title: 'Rename the segment types', updatedAt: Date.now() - day },
95
+ * { id: 'c3', title: 'Tokens, not selectors', updatedAt: Date.now() - 4 * day },
77
96
  * ];
78
97
  * </script>
79
98
  *
@@ -87,31 +106,69 @@ export interface AparteConversationArchiveDetail {
87
106
  * list.setAttribute('active-id', 'c1');
88
107
  *
89
108
  * list.addEventListener('aparte-select-conversation', (e) => load(e.detail.id));
90
- * list.addEventListener('aparte-delete-conversation', (e) => remove(e.detail.id));
109
+ * list.addEventListener('aparte-rename-conversation', (e) => manager.updateTitle(e.detail.id, e.detail.title));
110
+ * list.addEventListener('aparte-pin-conversation', (e) => manager.pin(e.detail.id));
111
+ * list.addEventListener('aparte-delete-conversation', (e) => manager.delete(e.detail.id));
91
112
  */
92
113
  export declare class AparteConversationList extends HTMLElement {
93
114
  private _conversations;
94
115
  private _activeId;
116
+ private _open;
117
+ private _renaming;
95
118
  static get observedAttributes(): string[];
96
119
  connectedCallback(): void;
97
120
  disconnectedCallback(): void;
98
121
  attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
99
122
  /**
100
- * Re-render on a locale switch: every row's title fallback and both button
101
- * labels come from the locale, so without this the list stayed in the previous
102
- * language until something else happened to re-render it. Only OUR config.
123
+ * Re-render on a locale switch: every row's title fallback, the `⋯` button's name
124
+ * and the group headings come from the locale, so without this the list stayed in
125
+ * the previous language until something else happened to re-render it. Only OUR
126
+ * config.
103
127
  */
104
128
  private _onConfigChange;
105
129
  /** Set the list of conversations to display. Triggers a re-render. */
106
130
  set conversations(items: AparteConversationListItem[]);
107
131
  get conversations(): AparteConversationListItem[];
108
132
  private _render;
133
+ private _t;
134
+ /**
135
+ * Pinned first, then the calendar buckets every chat product uses, then a heading
136
+ * per month (newest first), then whatever carries no date. Flat when nothing is
137
+ * dated or the host asked for `no-groups`: a heading over the only group would say
138
+ * nothing.
139
+ */
140
+ private _groups;
141
+ private _renderGroup;
109
142
  private _renderItem;
110
- private _bindEvents;
143
+ private _menuMarkup;
144
+ private _confirmMarkup;
145
+ private _openMenu;
146
+ /**
147
+ * Fixed, below the button's end edge, flipped above it when the viewport ends
148
+ * first. Fixed rather than absolute because a sidebar scrolls: an absolute menu on
149
+ * the last rows would be clipped by the list's own overflow. No anchoring library —
150
+ * the menu closes on any scroll or resize, which is what makes the arithmetic
151
+ * safe to do once.
152
+ */
153
+ private _placeMenu;
154
+ private _closeMenu;
155
+ private _onDocumentPointerDown;
156
+ private _onWindowScroll;
157
+ private _onFocusOut;
158
+ private _onMenuAction;
159
+ private _menuFocusables;
160
+ private _onMenuKeydown;
161
+ private _startRename;
162
+ /**
163
+ * One exit for the three ways out (Enter, Escape, leaving the field), guarded so
164
+ * the blur a removal causes cannot commit a second time. The row is re-rendered
165
+ * from the array either way: the list shows data, and the host's re-assignment is
166
+ * what makes the new title appear.
167
+ */
168
+ private _finishRename;
111
169
  private _onClick;
112
170
  private _onKeydown;
113
171
  /** Update active class without full re-render (perf optimisation). */
114
172
  private _updateActiveState;
115
- private _esc;
116
173
  }
117
174
  //# sourceMappingURL=aparte-conversation-list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-conversation-list.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/aparte-conversation-list.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,0BAA0B;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,+BAA+B;IAC5C,EAAE,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,qBAAa,sBAAuB,SAAQ,WAAW;IACnD,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,SAAS,CAAuB;IAExC,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAID,iBAAiB,IAAI,IAAI;IAWzB,oBAAoB,IAAI,IAAI;IAI5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAQ9F;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAIrB;IAIF,sEAAsE;IACtE,IAAI,aAAa,CAAC,KAAK,EAAE,0BAA0B,EAAE,EAGpD;IAED,IAAI,aAAa,IAAI,0BAA0B,EAAE,CAEhD;IAID,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,WAAW;IA8CnB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,QAAQ,CAkCd;IAEF,OAAO,CAAC,UAAU,CAoBhB;IAEF,sEAAsE;IACtE,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,IAAI;CAQf"}
1
+ {"version":3,"file":"aparte-conversation-list.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/aparte-conversation-list.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,0BAA0B;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,+BAA+B;IAC5C,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,2BAA2B;IACxC,EAAE,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,8BAA8B;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;CACjB;AA6BD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoFG;AACH,qBAAa,sBAAuB,SAAQ,WAAW;IACnD,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,SAAS,CAAuE;IAExF,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAID,iBAAiB,IAAI,IAAI;IAczB,oBAAoB,IAAI,IAAI;IAQ5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAU9F;;;;;OAKG;IACH,OAAO,CAAC,eAAe,CAIrB;IAIF,sEAAsE;IACtE,IAAI,aAAa,CAAC,KAAK,EAAE,0BAA0B,EAAE,EAGpD;IAED,IAAI,aAAa,IAAI,0BAA0B,EAAE,CAEhD;IAID,OAAO,CAAC,OAAO;IAOf,OAAO,CAAC,EAAE;IAKV;;;;;OAKG;IACH,OAAO,CAAC,OAAO;IA6Cf,OAAO,CAAC,YAAY;IAapB,OAAO,CAAC,WAAW;IAoCnB,OAAO,CAAC,WAAW;IAkBnB,OAAO,CAAC,cAAc;IActB,OAAO,CAAC,SAAS;IAoBjB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,sBAAsB,CAO5B;IAEF,OAAO,CAAC,eAAe,CAErB;IAEF,OAAO,CAAC,WAAW,CAQjB;IAEF,OAAO,CAAC,aAAa;IA8DrB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,YAAY;IAgBpB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,QAAQ,CA2Bd;IAEF,OAAO,CAAC,UAAU,CAYhB;IAEF,sEAAsE;IACtE,OAAO,CAAC,kBAAkB;CAQ7B"}
@@ -1,2 +1,2 @@
1
- export { AparteConversationList, type AparteConversationListItem, type AparteConversationSelectDetail, type AparteConversationDeleteDetail, type AparteConversationArchiveDetail, } from './aparte-conversation-list.js';
1
+ export { AparteConversationList, type AparteConversationListItem, type AparteConversationSelectDetail, type AparteConversationDeleteDetail, type AparteConversationArchiveDetail, type AparteConversationPinDetail, type AparteConversationRenameDetail, } from './aparte-conversation-list.js';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,GACvC,MAAM,+BAA+B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/conversation-list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,sBAAsB,EACtB,KAAK,0BAA0B,EAC/B,KAAK,8BAA8B,EACnC,KAAK,8BAA8B,EACnC,KAAK,+BAA+B,EACpC,KAAK,2BAA2B,EAChC,KAAK,8BAA8B,GACtC,MAAM,+BAA+B,CAAC"}
@@ -79,11 +79,13 @@ import type { AparteConfig } from '../../config/aparte-config.js';
79
79
  * @cssprop [--aparte-approval-option-size=0.85rem] - Font size of an approval option button.
80
80
  * @cssprop [--aparte-approval-option-padding=8px 10px] - Padding of an approval option button.
81
81
  * @cssprop [--aparte-approval-option-radius=8px] - Corner radius of an approval option button.
82
+ * @cssprop [--aparte-approval-args-max-height=8.5rem] - Height cap of the arguments block before it scrolls.
83
+ * @cssprop [--aparte-approval-args-size=var(--aparte-font-size-sm)] - Font size of the arguments block.
82
84
  *
83
85
  * @example
84
86
  * <!-- Renders nothing by itself: it registers as the presenter for its subtree, so a
85
87
  * tool handler calling requestUserInput() gets its panel mounted in the composer. -->
86
- * <aparte-chat>
88
+ * <aparte-chat style="height: 20rem">
87
89
  * <aparte-chat-viewport></aparte-chat-viewport>
88
90
  * <aparte-elicitation></aparte-elicitation>
89
91
  * <aparte-composer>
@@ -93,6 +95,22 @@ import type { AparteConfig } from '../../config/aparte-config.js';
93
95
  * </div>
94
96
  * </aparte-composer>
95
97
  * </aparte-chat>
98
+ *
99
+ * <script>
100
+ * // `aparte` is the `@aparte/core` module the frame exposes; in your app this line is
101
+ * // `import { requestUserInput } from '@aparte/core'`. A tool handler asks; the panel
102
+ * // mounts in the composer of the chat whose presenter this element is.
103
+ * aparte.requestUserInput({
104
+ * message: 'Which environment should I deploy to?',
105
+ * schema: {
106
+ * type: 'enum',
107
+ * options: [
108
+ * { value: 'staging', label: 'Staging', recommended: true },
109
+ * { value: 'prod', label: 'Production', description: 'Live traffic' },
110
+ * ],
111
+ * },
112
+ * });
113
+ * </script>
96
114
  */
97
115
  export declare class AparteElicitation extends HTMLElement implements AparteConfigAware {
98
116
  private _pending;
@@ -1 +1 @@
1
- {"version":3,"file":"aparte-elicitation.d.ts","sourceRoot":"","sources":["../../../src/components/elicitation/aparte-elicitation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgC,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,qBAAa,iBAAkB,SAAQ,WAAY,YAAW,iBAAiB;IAC3E,OAAO,CAAC,QAAQ,CAAwB;IACxC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,kBAAkB,CAA6B;IAEvD,iBAAiB,IAAI,IAAI;IAiBzB;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAQrE,oBAAoB,IAAI,IAAI;IAY5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,QAAQ,CA0Md;IAEF,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;CAwBvB"}
1
+ {"version":3,"file":"aparte-elicitation.d.ts","sourceRoot":"","sources":["../../../src/components/elicitation/aparte-elicitation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAgC,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAiClE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyFG;AACH,qBAAa,iBAAkB,SAAQ,WAAY,YAAW,iBAAiB;IAC3E,OAAO,CAAC,QAAQ,CAAwB;IACxC;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,UAAU,CAKhB;IAEF,OAAO,CAAC,kBAAkB,CAA6B;IAEvD,iBAAiB,IAAI,IAAI;IAiBzB;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAQrE,oBAAoB,IAAI,IAAI;IAY5B;;;;;;;OAOG;IACH,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,QAAQ,CAoMd;IAEF,OAAO,CAAC,cAAc;IAItB;;;;;;;;;OASG;IACH,OAAO,CAAC,gBAAgB;IAWxB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,YAAY;CAwBvB"}
@@ -6,9 +6,15 @@ export { AparteChatViewport } from './viewport/index.js';
6
6
  export { AparteComposer, AparteComposerInput, AparteComposerSend, AparteComposerCancel, AparteComposerAttachments, AparteComposerAddAttachment, AparteComposerAction, AparteComposerToolbar } from './composer/index.js';
7
7
  export type { AparteComposerEventMap, AparteComposerEventType, AparteComposerState, AparteComposerChangeEventDetail, AparteComposerPanelMode, AparteActionClickEventDetail } from './composer/index.js';
8
8
  export { AparteConversationList } from './conversation-list/index.js';
9
- export type { AparteConversationListItem, AparteConversationSelectDetail, AparteConversationDeleteDetail, AparteConversationArchiveDetail } from './conversation-list/index.js';
9
+ export type { AparteConversationListItem, AparteConversationSelectDetail, AparteConversationDeleteDetail, AparteConversationArchiveDetail, AparteConversationPinDetail, AparteConversationRenameDetail } from './conversation-list/index.js';
10
10
  export { AparteSuggestions } from './suggestions/index.js';
11
11
  export type { AparteSuggestion, AparteSuggestionEventDetail } from './suggestions/index.js';
12
12
  export { AparteContext } from './context/index.js';
13
13
  export type { AparteContextLevel, AparteContextThresholdEventDetail } from './context/index.js';
14
+ export { AparteScrollRail } from './scroll-rail/index.js';
15
+ export type { AparteScrollRailJumpDetail, AparteScrollRailEvery } from './scroll-rail/index.js';
16
+ export { AparteSidebar } from './sidebar/index.js';
17
+ export type { AparteSidebarToggleDetail } from './sidebar/index.js';
18
+ export { AparteSplit } from './split/index.js';
19
+ export type { AparteSplitResizeDetail } from './split/index.js';
14
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACzN,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAGxM,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AAGhL,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AACzN,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,+BAA+B,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAGxM,OAAO,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AACtE,YAAY,EAAE,0BAA0B,EAAE,8BAA8B,EAAE,8BAA8B,EAAE,+BAA+B,EAAE,2BAA2B,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAG7O,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAG5F,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,kBAAkB,EAAE,iCAAiC,EAAE,MAAM,oBAAoB,CAAC;AAGhG,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,YAAY,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAGhG,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,105 @@
1
+ /** Detail of `aparte-scroll-rail-jump`: the message a tick points at. */
2
+ export interface AparteScrollRailJumpDetail {
3
+ messageId: string;
4
+ }
5
+ /** What a tick is drawn for: one per user turn (the default), or one per message. */
6
+ export type AparteScrollRailEvery = 'user' | 'message';
7
+ /**
8
+ * A rail of ticks beside the transcript — one per turn — that shows where you are in a
9
+ * long conversation and jumps back to any message on a click.
10
+ *
11
+ * The thing every long chat is missing and no product ships natively: the scrollbar says
12
+ * how far down you are, not which question you are under. This is the minimap of a code
13
+ * editor reduced to its ticks, the search marks of a browser's scrollbar, the scrollspy
14
+ * of a documentation site — the same ancestry, applied to turns. A tick per USER message
15
+ * by default, because a user's turns are the questions and a rail with a tick per reply
16
+ * is unreadable on a long thread; `every="message"` marks each one.
17
+ *
18
+ * It owns nothing of the transcript: the viewport keeps its scroll, the bubbles keep
19
+ * their markup, and the rail only READS them — which bubbles exist (a mutation observer
20
+ * on the chat), which one is under the reader (an intersection observer on the scroll
21
+ * surface, never scroll arithmetic), and the first few words of each for the tick's
22
+ * name. A click is a `scrollIntoView` on the bubble, announced first by a cancelable
23
+ * `aparte-scroll-rail-jump` so a host that pages history in can load it before the
24
+ * jump. Honoured by core alone, so it is live by default (ratified decision #8, tier a).
25
+ *
26
+ * Place it as a direct child of `<aparte-chat>` (or the wrapper's `[data-aparte-chat]`
27
+ * host): the stylesheet floats it on the transcript's end edge, vertically centred, and
28
+ * hides it under a coarse pointer, where a 2px tick is not a target. Under two ticks it
29
+ * renders nothing — a rail with one mark says nothing.
30
+ *
31
+ * @element aparte-scroll-rail
32
+ *
33
+ * @attr {string} target - The id of the `<aparte-chat>` to follow, when the element is not inside it.
34
+ * @attr {string} every - `user` (default): one tick per user turn. `message`: one per message.
35
+ * @attr {boolean} data-empty - Reflected BY the element while it has fewer than two ticks. Read-only.
36
+ *
37
+ * @fires {CustomEvent<AparteScrollRailJumpDetail>} aparte-scroll-rail-jump - A tick was activated. Bubbles, cancelable: `preventDefault()` leaves the transcript where it is.
38
+ *
39
+ * @cssprop [--aparte-scroll-rail-width=20px] - The rail's column, the ticks right-aligned in it.
40
+ * @cssprop [--aparte-scroll-rail-tick-size=14px] - Length of a tick; the current one is 1.6× that.
41
+ * @cssprop [--aparte-scroll-rail-tick-thickness=2px] - Thickness of a tick.
42
+ * @cssprop [--aparte-scroll-rail-gap=8px] - Space between ticks.
43
+ *
44
+ * @example
45
+ * <aparte-chat style="height: 18rem">
46
+ * <aparte-chat-viewport>
47
+ * <aparte-chat-bubble message-id="u1" data-role="user" content="What is a web component?"></aparte-chat-bubble>
48
+ * <aparte-chat-bubble message-id="a1" data-role="assistant" name="Assistant" content="A custom element: a tag the browser upgrades to a class you wrote. It carries its own markup, behaviour and, if you want, its own styles — and it works in any framework, or none, because it is the platform's own component model."></aparte-chat-bubble>
49
+ * <aparte-chat-bubble message-id="u2" data-role="user" content="And a light-DOM one?"></aparte-chat-bubble>
50
+ * <aparte-chat-bubble message-id="a2" data-role="assistant" name="Assistant" content="One that renders its children into the page rather than into a shadow root, so the page's CSS reaches inside it. aparté is light DOM on purpose: a theme is a stylesheet, not an API."></aparte-chat-bubble>
51
+ * <aparte-chat-bubble message-id="u3" data-role="user" content="Which one is this rail?"></aparte-chat-bubble>
52
+ * <aparte-chat-bubble message-id="a3" data-role="assistant" name="Assistant" content="Light DOM, like everything else here. Its ticks are plain buttons in a list; scroll the transcript and watch the current one move."></aparte-chat-bubble>
53
+ * </aparte-chat-viewport>
54
+ * <aparte-scroll-rail></aparte-scroll-rail>
55
+ * <aparte-composer></aparte-composer>
56
+ * </aparte-chat>
57
+ */
58
+ export declare class AparteScrollRail extends HTMLElement {
59
+ static get observedAttributes(): string[];
60
+ private _host;
61
+ private _mutations;
62
+ private _intersections;
63
+ private _rebuildQueued;
64
+ private _currentId;
65
+ /** Visible ratio per message id, from the intersection observer. */
66
+ private _visible;
67
+ private _onConfigChange;
68
+ /** The id of the message the rail currently marks, or `null`. */
69
+ get currentMessageId(): string | null;
70
+ connectedCallback(): void;
71
+ disconnectedCallback(): void;
72
+ attributeChangedCallback(name: string): void;
73
+ /** The chat this rail follows: `target`, else the host above it — the gauge's rule. */
74
+ private _findHost;
75
+ private _attach;
76
+ private _detach;
77
+ /** Coalesce a burst of mutations (a streaming reply is one per token) into one rebuild. */
78
+ private _queueRebuild;
79
+ private _viewport;
80
+ /** The element that scrolls: the vanilla container, or the viewport itself under a wrapper. */
81
+ private _scrollSurface;
82
+ private _bubbles;
83
+ /** The first words of a message, for the tick's name. An excerpt, never a summary. */
84
+ private _excerpt;
85
+ private _tickLabel;
86
+ private _rebuild;
87
+ /**
88
+ * Which tick is current is read, not computed: the scroll surface is the root, and
89
+ * the bubble with the largest visible share of a reading band near the top wins.
90
+ * Scroll arithmetic was the alternative, and every scroll-position rule in the
91
+ * viewport carries a regression note — this one has none to carry.
92
+ */
93
+ private _observe;
94
+ private _pickCurrent;
95
+ private _setCurrent;
96
+ private _onClick;
97
+ /** The ticks are buttons; the arrows walk them, as in any toolbar. */
98
+ private _onKeydown;
99
+ /**
100
+ * Scroll the transcript to a message. Announced first, cancelable; then a
101
+ * `scrollIntoView` on the bubble, smooth unless the reader prefers reduced motion.
102
+ */
103
+ jumpTo(messageId: string): void;
104
+ }
105
+ //# sourceMappingURL=aparte-scroll-rail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aparte-scroll-rail.d.ts","sourceRoot":"","sources":["../../../src/components/scroll-rail/aparte-scroll-rail.ts"],"names":[],"mappings":"AAGA,yEAAyE;AACzE,MAAM,WAAW,0BAA0B;IACvC,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,CAAC;AAIvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;IAC7C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,KAAK,CAA4B;IACzC,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,cAAc,CAAqC;IAC3D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,UAAU,CAAuB;IACzC,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAA6B;IAE7C,OAAO,CAAC,eAAe,CAA+B;IAEtD,iEAAiE;IACjE,IAAI,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEpC;IAED,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAO5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ5C,uFAAuF;IACvF,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,OAAO;IAiBf,OAAO,CAAC,OAAO;IASf,2FAA2F;IAC3F,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,SAAS;IAIjB,+FAA+F;IAC/F,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,QAAQ;IAUhB,sFAAsF;IACtF,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,UAAU;IASlB,OAAO,CAAC,QAAQ;IAwChB;;;;;OAKG;IACH,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,QAAQ,CAMd;IAEF,sEAAsE;IACtE,OAAO,CAAC,UAAU,CAWhB;IAEF;;;OAGG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;CAelC"}
@@ -0,0 +1,3 @@
1
+ export { AparteScrollRail } from './aparte-scroll-rail.js';
2
+ export type { AparteScrollRailJumpDetail, AparteScrollRailEvery } from './aparte-scroll-rail.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/scroll-rail/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,186 @@
1
+ /** Detail of `aparte-sidebar-toggle`: the state just entered. */
2
+ export interface AparteSidebarToggleDetail {
3
+ collapsed: boolean;
4
+ /** True while the sidebar is a drawer — the window is under the breakpoint. */
5
+ drawer: boolean;
6
+ }
7
+ /**
8
+ * The column beside the chat — conversations, a new-chat button, a search field, an
9
+ * account row — as an element, because it has behaviour: it collapses, it becomes a
10
+ * drawer on a narrow window, and its search field filters the conversation list.
11
+ *
12
+ * What it does NOT own is its content. Children are yours, in the order you want them:
13
+ * a `.aparte-sidebar__header`, a `.aparte-sidebar__search`, a `.aparte-sidebar__body`
14
+ * holding the `<aparte-conversation-list>`, a `.aparte-sidebar__footer`. The
15
+ * stylesheet lays those out and draws nothing you did not put there — the recipe
16
+ * (`.aparte-sidebar`, in `styles/shell/sidebar.css`) is the look, this element is
17
+ * the three behaviours.
18
+ *
19
+ * **Collapse.** `collapsed` is an attribute, reflected, so the host can set it, read
20
+ * it and persist it. Any element carrying `data-aparte-sidebar-toggle` anywhere on
21
+ * the page toggles the nearest sidebar (or the one whose id the attribute names), so
22
+ * a hamburger in the header needs no script. `aparte-sidebar-toggle` fires on every
23
+ * change, whoever caused it.
24
+ *
25
+ * **Drawer.** Under 48rem of window the sidebar leaves the flow and slides over the
26
+ * page (`data-drawer`, set by the element from a media query); open, it draws a
27
+ * scrim, moves the focus to its first focusable child, closes on Escape from anywhere
28
+ * on the page or on a click outside, and hands the focus back to the control that
29
+ * opened it. Nothing here is a portal: the drawer is the same element in the same
30
+ * place, positioned fixed, which is all a sidebar needs and what a dialog would not
31
+ * get away with. Collapsed — folded as a column or slid off as a drawer — it carries
32
+ * `inert` and `aria-hidden`, so nothing invisible keeps a tab stop.
33
+ *
34
+ * **Search.** An input carrying `data-aparte-sidebar-search` filters the conversation
35
+ * list below it by title as the user types — rows that do not match are hidden, and a
36
+ * date group with nothing left hides with them. Client-side, on the titles the list
37
+ * already has: an index over message bodies is the storage adapter's business.
38
+ *
39
+ * @element aparte-sidebar
40
+ *
41
+ * @attr {boolean} collapsed - Hidden (in the flow) or closed (as a drawer). Reflected; set it to start closed.
42
+ * @attr {string} breakpoint - The window width under which the sidebar becomes a drawer: a length (default `48rem`), or `none` for a column that never does.
43
+ * @attr {boolean} data-drawer - Reflected BY the element while the window is under 48rem. Read-only.
44
+ *
45
+ * @fires {CustomEvent<AparteSidebarToggleDetail>} aparte-sidebar-toggle - The sidebar opened or closed, by a toggle, by Escape, by a click on the scrim or by `collapsed` being set. Bubbles.
46
+ *
47
+ * @cssprop [--aparte-sidebar-width=260px] - Width of the column, and of the drawer.
48
+ * @cssprop [--aparte-sidebar-bg=var(--aparte-surface-2)] - Its ground.
49
+ *
50
+ * @example
51
+ * <!-- The sidebar alone, as a column: its header, a search field that filters the list,
52
+ * the list, a footer. The shell it sits in — header, chat — is the app-shell guide's.
53
+ * breakpoint="none" keeps it a column at any width; without it, under 48rem of
54
+ * window it becomes a drawer behind a [data-aparte-sidebar-toggle] control. -->
55
+ * <aparte-sidebar breakpoint="none" style="height: 22rem">
56
+ * <div class="aparte-sidebar__header">
57
+ * <span class="aparte-sidebar__brand">aparté</span>
58
+ * <button class="aparte-btn aparte-btn--icon aparte-btn--sm" type="button" aria-label="New chat">
59
+ * <aparte-icon name="edit"></aparte-icon>
60
+ * </button>
61
+ * </div>
62
+ * <div class="aparte-sidebar__search aparte-field-group">
63
+ * <input class="aparte-field aparte-field--sm" type="search" placeholder="Search conversations" data-aparte-sidebar-search>
64
+ * </div>
65
+ * <div class="aparte-sidebar__body">
66
+ * <aparte-conversation-list active-id="c1"></aparte-conversation-list>
67
+ * </div>
68
+ * <div class="aparte-sidebar__footer">
69
+ * <span class="aparte-avatar aparte-avatar--sm">P</span> Paul
70
+ * </div>
71
+ * </aparte-sidebar>
72
+ * <script>
73
+ * const day = 864e5;
74
+ * document.querySelector('aparte-conversation-list').conversations = [
75
+ * { id: 'c1', title: 'Deploy checklist', updatedAt: Date.now() },
76
+ * { id: 'c2', title: 'Rename the segment types', updatedAt: Date.now() - day },
77
+ * { id: 'c3', title: 'Tokens, not selectors', updatedAt: Date.now() - 4 * day },
78
+ * { id: 'c4', title: 'The first release', updatedAt: Date.now() - 60 * day },
79
+ * ];
80
+ * </script>
81
+ */
82
+ export declare class AparteSidebar extends HTMLElement {
83
+ static get observedAttributes(): string[];
84
+ private _media;
85
+ private _scrim;
86
+ /** The control that last opened the drawer, to hand the focus back to. */
87
+ private _opener;
88
+ private _lastCollapsed;
89
+ /**
90
+ * `connectedCallback` has run and the element knows what its markup asked for.
91
+ *
92
+ * Not `isConnected`: during an UPGRADE the element is already in the document, so
93
+ * `attributeChangedCallback` fires for every authored attribute — connected, and
94
+ * before `connectedCallback` — which is the ordinary case for a server-rendered
95
+ * `<aparte-sidebar collapsed>` upgraded when the module loads. Announcing there
96
+ * tells the host its sidebar just closed when all that happened is that the markup
97
+ * was read, and says `drawer: false` because the media query has not run yet.
98
+ */
99
+ private _ready;
100
+ /**
101
+ * The host (or the markup) asked for the column to be folded, so widening the
102
+ * window must not unfold it. Only a collapse taken OUTSIDE the drawer state counts:
103
+ * dismissing an overlay says nothing about what a wide window should show.
104
+ */
105
+ private _closedByHost;
106
+ /**
107
+ * `_closedByHost` has been taken from the markup once. A re-parent runs
108
+ * `connectedCallback` again, and by then `collapsed` may be the BREAKPOINT's own
109
+ * write — a drawer closes itself on the way in — so reading it back a second time
110
+ * records the element's own doing as the host's word and the column never reopens.
111
+ * Like `_initialCaptured` on `<aparte-split>`, it must survive the move.
112
+ */
113
+ private _hostIntentSeeded;
114
+ /** Raised around `_applyDrawer`'s own writes, so the breakpoint is never read as a host's intent. */
115
+ private _auto;
116
+ /**
117
+ * The element wrote `inert`/`aria-hidden` and may take them back. A host that inerts
118
+ * the sidebar behind its own modal wrote them itself, and `_syncHidden` runs on every
119
+ * breakpoint re-evaluation: without this it would un-inert the page behind the overlay.
120
+ * Same convention as `_relabel`, which leaves a host-authored `aria-label` alone.
121
+ */
122
+ private _ownHidden;
123
+ /** Whether the sidebar is collapsed (hidden in the flow, or closed as a drawer). */
124
+ get collapsed(): boolean;
125
+ set collapsed(value: boolean);
126
+ /** True while the window is under the breakpoint and the sidebar is a drawer. */
127
+ get drawer(): boolean;
128
+ connectedCallback(): void;
129
+ /**
130
+ * The drawer's media query, from the `breakpoint` attribute: a length (`48rem`, the
131
+ * default, or `640px`), or `none` for a column that never becomes a drawer — which
132
+ * a narrow host that has room for it wants, and a documentation frame needs.
133
+ */
134
+ private _watchBreakpoint;
135
+ disconnectedCallback(): void;
136
+ attributeChangedCallback(name: string): void;
137
+ /** Open the sidebar. `opener` is the control to hand the focus back to when it closes. */
138
+ open(opener?: HTMLElement): void;
139
+ close(): void;
140
+ toggle(opener?: HTMLElement): void;
141
+ private _onMediaChange;
142
+ /**
143
+ * Entering the drawer state closes the sidebar: a narrow window that opens on an
144
+ * overlay covering the chat is the wrong first screen. Leaving it reopens, since
145
+ * a wide window has room for the column — unless the host had collapsed it before.
146
+ */
147
+ private _applyDrawer;
148
+ /**
149
+ * A collapsed sidebar is invisible — folded to nothing in the flow, slid off the
150
+ * screen as a drawer — so it must not keep its tab stops or its place in the
151
+ * accessibility tree. `inert` covers focus and the pointer, `aria-hidden` covers
152
+ * the readers that predate it; a browser without `inert` still gets the second.
153
+ *
154
+ * It removes only what it wrote. Both are standard global attributes a host sets
155
+ * itself — inerting the sidebar behind its own modal is the ordinary pattern — and
156
+ * this runs on every breakpoint re-evaluation, so clearing them unconditionally lets
157
+ * an unrelated resize re-expose the page under an overlay. Same convention as
158
+ * `_relabel`, which leaves a host-authored `aria-label` alone.
159
+ *
160
+ * Neither is declared `@attr`, and `data-drawer` is not the precedent: a `@attr` on a
161
+ * STANDARD name displaces the wrappers' own prop for it — React's JSX props are
162
+ * `Omit<HTMLAttributes, keyof T>`, so declaring `inert` here would retype
163
+ * `<aparte-sidebar inert={busy}>` out of existence. The class docblock says it in prose.
164
+ */
165
+ private _syncHidden;
166
+ /**
167
+ * The drawer covers the page, so the focus has to follow it in — otherwise the next
168
+ * Tab walks the transcript under the overlay. The host owns the children, so this
169
+ * takes the first thing that can hold focus and leaves the rest alone; a drawer with
170
+ * nothing focusable in it keeps the focus where it was, which is the honest outcome.
171
+ */
172
+ private _focusFirst;
173
+ private _syncScrim;
174
+ private _onKeydown;
175
+ /** A `[data-aparte-sidebar-toggle]` anywhere toggles this sidebar — no script in the host. */
176
+ private _onDocumentClick;
177
+ private _onInput;
178
+ /**
179
+ * Hide the conversation rows whose title does not contain `query`, and the date
180
+ * groups left empty. Case- and accent-insensitive. An empty query shows everything.
181
+ */
182
+ filter(query: string): void;
183
+ private _onConfigChange;
184
+ private _relabel;
185
+ }
186
+ //# sourceMappingURL=aparte-sidebar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aparte-sidebar.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/aparte-sidebar.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,WAAW,yBAAyB;IACtC,SAAS,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,MAAM,EAAE,OAAO,CAAC;CACnB;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC1C,MAAM,KAAK,kBAAkB,IAAI,MAAM,EAAE,CAExC;IAED,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,MAAM,CAA4B;IAC1C,0EAA0E;IAC1E,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,cAAc,CAAwB;IAE9C;;;;;;;;;OASG;IACH,OAAO,CAAC,MAAM,CAAS;IAEvB;;;;OAIG;IACH,OAAO,CAAC,aAAa,CAAS;IAE9B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB,CAAS;IAElC,qGAAqG;IACrG,OAAO,CAAC,KAAK,CAAS;IAEtB;;;;;OAKG;IACH,OAAO,CAAC,UAAU,CAAS;IAE3B,oFAAoF;IACpF,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,OAAO,EAE3B;IAED,iFAAiF;IACjF,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,iBAAiB,IAAI,IAAI;IAyBzB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAexB,oBAAoB,IAAI,IAAI;IAU5B,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA8B5C,0FAA0F;IAC1F,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI;IAKhC,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,IAAI;IAOlC,OAAO,CAAC,cAAc,CAAkE;IAExF;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAcpB;;;;;;;;;;;;;;;;OAgBG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,UAAU,CAKhB;IAEF,8FAA8F;IAC9F,OAAO,CAAC,gBAAgB,CAUtB;IAIF,OAAO,CAAC,QAAQ,CAId;IAEF;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAe3B,OAAO,CAAC,eAAe,CAA+B;IAEtD,OAAO,CAAC,QAAQ;CAMnB"}
@@ -0,0 +1,3 @@
1
+ export { AparteSidebar } from './aparte-sidebar.js';
2
+ export type { AparteSidebarToggleDetail } from './aparte-sidebar.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/sidebar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC"}