@aparte/core 0.16.4 → 0.16.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/composer/aparte-composer-input.d.ts +8 -0
- package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
- package/dist/components/elicitation/aparte-elicitation.d.ts +1 -1
- package/dist/components/sidebar/aparte-sidebar.d.ts.map +1 -1
- package/dist/components/split/aparte-split.d.ts +5 -1
- package/dist/components/split/aparte-split.d.ts.map +1 -1
- package/dist/components/viewport/aparte-chat-viewport.d.ts +30 -0
- package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
- package/dist/custom-elements.json +5741 -5620
- package/dist/generated/element-attributes.d.ts +2 -0
- package/dist/generated/element-attributes.d.ts.map +1 -1
- package/dist/index.css +113 -42
- package/dist/index.js +122 -18
- package/dist/index.js.map +1 -1
- package/dist/types/element-attributes.d.ts +8 -2
- package/dist/types/element-attributes.d.ts.map +1 -1
- package/dist/utils/presence.d.ts +16 -0
- package/dist/utils/presence.d.ts.map +1 -0
- package/package.json +17 -3
|
@@ -200,6 +200,8 @@ export interface AparteSplitAttributes {
|
|
|
200
200
|
disabled?: boolean;
|
|
201
201
|
/** The seam's accessible name. Defaults to the locale's `splitHandleLabel`. */
|
|
202
202
|
label?: string;
|
|
203
|
+
/** Show one pane — the one `pane` names — whatever the width: the seam and the other pane are gone, as under the breakpoint. For a host that decides itself when a second pane exists (a preview with nothing to preview yet). `collapsed` is not this: it folds the primary pane to `--aparte-split-min` and keeps the seam. The CSS route, `.aparte-split--only-start` / `--only-end`, is the same state for a host that owns its breakpoints. */
|
|
204
|
+
single?: boolean;
|
|
203
205
|
/** Written BY the element while one pane is shown. Read-only; style against it. */
|
|
204
206
|
'data-stacked'?: boolean;
|
|
205
207
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"element-attributes.d.ts","sourceRoot":"","sources":["../../src/generated/element-attributes.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"element-attributes.d.ts","sourceRoot":"","sources":["../../src/generated/element-attributes.ts"],"names":[],"mappings":"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"}
|
package/dist/index.css
CHANGED
|
@@ -596,7 +596,11 @@ aparte-chat {
|
|
|
596
596
|
The eight text sizes were px and are rem now, like the rest of the typography:
|
|
597
597
|
identical at a 16px root, and following the reader's setting elsewhere. */
|
|
598
598
|
--aparte-message-gap: var(--aparte-space-6);
|
|
599
|
-
|
|
599
|
+
/* Split, because the action bar's offset below a message is computed from the
|
|
600
|
+
vertical half (#56) — a shorthand cannot be read by parts. */
|
|
601
|
+
--aparte-message-padding-block: var(--aparte-space-8);
|
|
602
|
+
--aparte-message-padding-inline: var(--aparte-space-6);
|
|
603
|
+
--aparte-message-padding: var(--aparte-message-padding-block) var(--aparte-message-padding-inline);
|
|
600
604
|
--aparte-message-content-padding: var(--aparte-space-5) var(--aparte-space-7);
|
|
601
605
|
--aparte-action-bar-gap: var(--aparte-space-2);
|
|
602
606
|
--aparte-branch-picker-gap: var(--aparte-space-2);
|
|
@@ -1030,6 +1034,10 @@ aparte-conversation-list {
|
|
|
1030
1034
|
* <button class="aparte-btn aparte-btn--surface">1 / 2</button>
|
|
1031
1035
|
* <button class="aparte-btn aparte-btn--surface">›</button>
|
|
1032
1036
|
* </div>
|
|
1037
|
+
* <div class="aparte-btn-group" role="group" aria-label="View">
|
|
1038
|
+
* <button class="aparte-btn aparte-btn--primary aparte-btn--outline" aria-pressed="true">Chat</button>
|
|
1039
|
+
* <button class="aparte-btn aparte-btn--primary aparte-btn--outline" aria-pressed="false">Preview</button>
|
|
1040
|
+
* </div>
|
|
1033
1041
|
*
|
|
1034
1042
|
* An intent on its own is a ghost — the quietest form, and the one a chat uses most.
|
|
1035
1043
|
* Add a fill when the button has to carry more weight.
|
|
@@ -1037,7 +1045,9 @@ aparte-conversation-list {
|
|
|
1037
1045
|
* `.aparte-btn-group` fuses adjacent buttons into ONE control: the inner corners
|
|
1038
1046
|
* drop, the shared borders overlap, and only the group's ends keep the radius. Give
|
|
1039
1047
|
* the wrapper `role="group"` and a name — visually one control, it should read as
|
|
1040
|
-
* one too.
|
|
1048
|
+
* one too. A SEGMENTED control is the same group with one segment selected: mark it
|
|
1049
|
+
* `aria-pressed="true"` (or `aria-selected="true"` under `role="tablist"`) and it is
|
|
1050
|
+
* painted solid in the group's intent, at rest — not only under the pointer.
|
|
1041
1051
|
*
|
|
1042
1052
|
* This layer is NEUTRAL: it is what a UI library offers, not a summary of what this
|
|
1043
1053
|
* repo happens to use. A variant nothing wears still ships, because the plugin that
|
|
@@ -1242,12 +1252,23 @@ aparte-conversation-list {
|
|
|
1242
1252
|
outline-offset: var(--aparte-btn-focus-offset);
|
|
1243
1253
|
}
|
|
1244
1254
|
|
|
1245
|
-
/* Toggled — a disclosure that is open, a toggle that is on. */
|
|
1255
|
+
/* Toggled — a disclosure that is open, a toggle that is on, a tab that is current. */
|
|
1246
1256
|
.aparte-btn[aria-expanded='true'],
|
|
1247
|
-
.aparte-btn[aria-pressed='true']
|
|
1257
|
+
.aparte-btn[aria-pressed='true'],
|
|
1258
|
+
.aparte-btn[aria-selected='true'] {
|
|
1248
1259
|
background: var(--aparte-btn-bg-toggled);
|
|
1249
1260
|
color: var(--aparte-btn-color-toggled);
|
|
1250
1261
|
}
|
|
1262
|
+
/* On a coloured fill the toggled wash must be DEEPER than the hover wash (22 %), or the
|
|
1263
|
+
pointer reads as the state and the state reads as nothing — measured on a dark
|
|
1264
|
+
`Chat | Preview` group, where `--aparte-btn-bg-toggled` (surface-2) sits a hair from
|
|
1265
|
+
surface-1 and the selected segment showed as an empty outline until hovered (#53). */
|
|
1266
|
+
.aparte-btn--outline[aria-pressed='true'],
|
|
1267
|
+
.aparte-btn--soft[aria-pressed='true'],
|
|
1268
|
+
.aparte-btn--outline[aria-selected='true'],
|
|
1269
|
+
.aparte-btn--soft[aria-selected='true'] {
|
|
1270
|
+
background: color-mix(in srgb, var(--aparte-btn-intent) 30%, transparent);
|
|
1271
|
+
}
|
|
1251
1272
|
|
|
1252
1273
|
/* Busy is NOT disabled: it stays focusable, and the app is what swaps the icon for a
|
|
1253
1274
|
spinner. Only the cursor changes here. */
|
|
@@ -1294,6 +1315,24 @@ aparte-conversation-list {
|
|
|
1294
1315
|
.aparte-btn-group > .aparte-btn:not(:first-child) { margin-inline-start: calc(var(--aparte-border-width) * -1); }
|
|
1295
1316
|
.aparte-btn-group > .aparte-btn:hover,
|
|
1296
1317
|
.aparte-btn-group > .aparte-btn:focus-visible { z-index: var(--aparte-z-raised); }
|
|
1318
|
+
/* The selected segment. Solid in the group's intent, whatever fill the segments wear:
|
|
1319
|
+
a segmented control has exactly one thing to say at rest, and a wash could not say
|
|
1320
|
+
it on dark (#53). `--surface` ignores the intent, so its groups select in neutral.
|
|
1321
|
+
Hover leaves it alone — the pointer must never be what makes selection legible. */
|
|
1322
|
+
.aparte-btn-group > .aparte-btn[aria-pressed='true'],
|
|
1323
|
+
.aparte-btn-group > .aparte-btn[aria-selected='true'],
|
|
1324
|
+
.aparte-btn-group > .aparte-btn[aria-current] {
|
|
1325
|
+
background: var(--aparte-btn-intent);
|
|
1326
|
+
border-color: var(--aparte-btn-intent);
|
|
1327
|
+
color: var(--aparte-btn-on-intent);
|
|
1328
|
+
z-index: var(--aparte-z-raised);
|
|
1329
|
+
}
|
|
1330
|
+
.aparte-btn-group > .aparte-btn[aria-pressed='true']:hover:not(:disabled),
|
|
1331
|
+
.aparte-btn-group > .aparte-btn[aria-selected='true']:hover:not(:disabled),
|
|
1332
|
+
.aparte-btn-group > .aparte-btn[aria-current]:hover:not(:disabled) {
|
|
1333
|
+
background: var(--aparte-btn-intent);
|
|
1334
|
+
filter: none;
|
|
1335
|
+
}
|
|
1297
1336
|
|
|
1298
1337
|
/* In forced-colors the UA repaints everything and drops backgrounds, so a solid button
|
|
1299
1338
|
loses the only thing marking it as the primary action. A border survives. */
|
|
@@ -4549,7 +4588,10 @@ aparte-chat-viewport[framework-managed] {
|
|
|
4549
4588
|
overscroll-behavior: contain;
|
|
4550
4589
|
display: flex;
|
|
4551
4590
|
flex-direction: column;
|
|
4552
|
-
gap
|
|
4591
|
+
/* No flex gap — each bubble carries the distance to the next as its own padding,
|
|
4592
|
+
inside its contained box, where an older message's action bar floats (#56;
|
|
4593
|
+
the rationale is on `.aparte-messages-wrapper` in bubble.css). */
|
|
4594
|
+
gap: 0;
|
|
4553
4595
|
padding: var(--aparte-viewport-padding);
|
|
4554
4596
|
/* No bottom padding: a sticky child is clamped to its parent's CONTENT box, so
|
|
4555
4597
|
clearance carried as padding held the scroll button `padding + spacer` above
|
|
@@ -4583,11 +4625,10 @@ aparte-chat-viewport.aparte-viewport--framework::after,
|
|
|
4583
4625
|
aparte-chat-viewport[framework-managed]::after {
|
|
4584
4626
|
content: '';
|
|
4585
4627
|
flex: 0 0 calc(var(--aparte-viewport-padding) + var(--aparte-fw-spacer, 0px) + var(--aparte-bottom-inset, 0px));
|
|
4586
|
-
/*
|
|
4587
|
-
the
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
margin-block-start: calc(var(--aparte-message-gap) * -1);
|
|
4628
|
+
/* The column has no `gap` any more (each bubble carries its own), so this item pays
|
|
4629
|
+
none — the negative margin that used to cancel it would now eat the last bubble's
|
|
4630
|
+
padding. (History: with a gap, an EMPTY transcript was 8px taller than its box and
|
|
4631
|
+
grew a scrollbar beside the welcome state.) */
|
|
4591
4632
|
}
|
|
4592
4633
|
|
|
4593
4634
|
aparte-chat-viewport.aparte-viewport--framework::-webkit-scrollbar {
|
|
@@ -4730,7 +4771,11 @@ aparte-chat[overlay-composer][center-empty][data-empty] > aparte-chat-viewport,
|
|
|
4730
4771
|
.aparte-messages-wrapper {
|
|
4731
4772
|
display: flex;
|
|
4732
4773
|
flex-direction: column;
|
|
4733
|
-
gap:
|
|
4774
|
+
/* No flex gap: the space between two turns is each bubble's own padding-block-end
|
|
4775
|
+
(below), so that it lies INSIDE the bubble's contained box — where the action
|
|
4776
|
+
bar of an older message floats (#56). A flex gap is outside every box, and the
|
|
4777
|
+
bubble's paint containment clipped anything placed there. */
|
|
4778
|
+
gap: 0;
|
|
4734
4779
|
padding: var(--aparte-viewport-padding);
|
|
4735
4780
|
}
|
|
4736
4781
|
|
|
@@ -4753,6 +4798,10 @@ aparte-chat-bubble {
|
|
|
4753
4798
|
contain: layout style paint;
|
|
4754
4799
|
content-visibility: auto;
|
|
4755
4800
|
contain-intrinsic-size: auto 320px;
|
|
4801
|
+
/* The distance to the next turn, carried by the bubble rather than by the list's
|
|
4802
|
+
`gap`, so it is part of this box: an older message's action bar floats over it
|
|
4803
|
+
(#56). Same token, same distance — nothing moved. */
|
|
4804
|
+
padding-block-end: var(--aparte-message-gap);
|
|
4756
4805
|
}
|
|
4757
4806
|
|
|
4758
4807
|
.aparte-message {
|
|
@@ -4799,6 +4848,9 @@ aparte-chat-bubble {
|
|
|
4799
4848
|
.aparte-body {
|
|
4800
4849
|
flex: 1;
|
|
4801
4850
|
min-width: 0;
|
|
4851
|
+
/* The containing block of a floating footer: the bar starts where the text starts
|
|
4852
|
+
and sits under it, whichever way the avatar column is laid out. */
|
|
4853
|
+
position: relative;
|
|
4802
4854
|
}
|
|
4803
4855
|
|
|
4804
4856
|
/* The message bubble — the surface fills ONLY the content (segments + text).
|
|
@@ -4866,11 +4918,22 @@ aparte-chat-bubble:last-of-type .aparte-message[data-role="assistant"]:not(.apar
|
|
|
4866
4918
|
* Measured (UI audit 2026-08-28, §8.3 #7): 103px between the text of one turn and the
|
|
4867
4919
|
* text of the next, and 34 of them were this footer — 28px of buttons nobody could
|
|
4868
4920
|
* see plus its margin, under EVERY message, so that the bar could appear on hover
|
|
4869
|
-
* without moving anything. The market floats it instead
|
|
4870
|
-
*
|
|
4871
|
-
*
|
|
4872
|
-
*
|
|
4873
|
-
*
|
|
4921
|
+
* without moving anything. The market floats it instead, BELOW the message, in the
|
|
4922
|
+
* space that already separates two turns: that is where ChatGPT and Claude put it,
|
|
4923
|
+
* and it takes no height because the space is already there.
|
|
4924
|
+
*
|
|
4925
|
+
* It floated top-right first (#56), over the header row's empty end, for one reason:
|
|
4926
|
+
* the bubble is a paint-containment boundary (`content-visibility`), and the space
|
|
4927
|
+
* between two bubbles was the list's flex `gap` — outside every box — so a bar
|
|
4928
|
+
* placed under the text was clipped. The gap is the bubble's own padding-block-end
|
|
4929
|
+
* now (see `aparte-chat-bubble` above), inside its box. The bar hangs from the
|
|
4930
|
+
* content column's bottom edge by `message padding-block + gap`: 16 + 12 = 28px at
|
|
4931
|
+
* the default density, 24 + 18 = 42px at the comfortable one, and the bar is 24px on
|
|
4932
|
+
* these messages — it overlaps padding, never text. The distance between turns is
|
|
4933
|
+
* what it was. A narrow container (responsive.css) shrinks the padding to 12 + 8 = 20:
|
|
4934
|
+
* 4px of the bar reach the last line's leading, under glyphs that do not descend that
|
|
4935
|
+
* far; and a narrow container is mostly a coarse pointer, where this block does not
|
|
4936
|
+
* apply.
|
|
4874
4937
|
*
|
|
4875
4938
|
* Three footers stay in the flow. The last assistant message: its bar is always on
|
|
4876
4939
|
* show, under the reply, where every chat puts it. A message whose branch picker is
|
|
@@ -4878,38 +4941,27 @@ aparte-chat-bubble:last-of-type .aparte-message[data-role="assistant"]:not(.apar
|
|
|
4878
4941
|
* picker must stay in view. And every message under a pointer that cannot hover, or
|
|
4879
4942
|
* that is coarse — `(hover: hover) and (pointer: fine)`, because the two features are
|
|
4880
4943
|
* independent and a TV remote reports both hover and coarse; responsive.css gives a
|
|
4881
|
-
* coarse pointer a 44px bar in the flow, and floated
|
|
4882
|
-
*
|
|
4883
|
-
*
|
|
4884
|
-
* The bar's place depends on the header row: 8px from the top, it fills the empty end
|
|
4885
|
-
* of the "Assistant · 12:34" line and clears the text by the header's height. A host
|
|
4886
|
-
* that hides `.aparte-header` moves that line away and should move the bar too
|
|
4887
|
-
* (`.aparte-footer { top: … }`), or keep it in the flow.
|
|
4944
|
+
* coarse pointer a 44px bar in the flow, and floated under the text a 44px bar would
|
|
4945
|
+
* cover the next turn.
|
|
4888
4946
|
*
|
|
4889
4947
|
* Invisible but NOT inert, on purpose. `opacity: 0` keeps the bar hit-testable, so a
|
|
4890
|
-
* drag-select started
|
|
4891
|
-
*
|
|
4892
|
-
*
|
|
4893
|
-
*
|
|
4894
|
-
*
|
|
4948
|
+
* drag-select started under a message begins on a button nobody sees — a review
|
|
4949
|
+
* flagged it, and `pointer-events: none` until `:hover` was tried. It made the bar
|
|
4950
|
+
* unreachable to anything that clicks without hovering first: Playwright (which
|
|
4951
|
+
* hit-tests the point before it moves the mouse — the header "intercepted" the edit
|
|
4952
|
+
* button on four projects), and with it voice control and switch access, which
|
|
4895
4953
|
* synthesise a click the same way. A control only a hover can enable is a control
|
|
4896
|
-
* some users cannot reach; a phantom button
|
|
4954
|
+
* some users cannot reach; a phantom button in the space between two turns is not. */
|
|
4897
4955
|
@media (hover: hover) and (pointer: fine) {
|
|
4898
4956
|
aparte-chat-bubble:not(:last-of-type) .aparte-message:not([data-branches]) .aparte-footer,
|
|
4899
4957
|
aparte-chat-bubble:last-of-type .aparte-message[data-role="user"]:not([data-branches]) .aparte-footer {
|
|
4900
4958
|
position: absolute;
|
|
4901
|
-
|
|
4902
|
-
inset-
|
|
4959
|
+
inset-inline-start: 0;
|
|
4960
|
+
inset-block-end: calc(-1 * (var(--aparte-message-padding-block) + var(--aparte-message-gap)));
|
|
4903
4961
|
margin: 0;
|
|
4904
4962
|
z-index: 1;
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
aparte-chat-bubble:not(:last-of-type) .aparte-message:not([data-branches]) .aparte-action-bar,
|
|
4908
|
-
aparte-chat-bubble:last-of-type .aparte-message[data-role="user"]:not([data-branches]) .aparte-action-bar {
|
|
4909
|
-
background: var(--aparte-surface-1);
|
|
4910
|
-
border: var(--aparte-border-width) solid var(--aparte-border);
|
|
4911
|
-
border-radius: var(--aparte-radius-md);
|
|
4912
|
-
box-shadow: var(--aparte-popover-shadow);
|
|
4963
|
+
/* Smaller than the last reply's 28px: this one lives in the padding. */
|
|
4964
|
+
--aparte-action-bar-btn-size: 24px;
|
|
4913
4965
|
}
|
|
4914
4966
|
}
|
|
4915
4967
|
|
|
@@ -5449,11 +5501,18 @@ aparte-composer-input .aparte-ci-editor {
|
|
|
5449
5501
|
caret-color: var(--aparte-text);
|
|
5450
5502
|
}
|
|
5451
5503
|
|
|
5452
|
-
/* Placeholder via CSS
|
|
5504
|
+
/* Placeholder via CSS. It never wraps: a `::before` counts in `scrollHeight`, and the
|
|
5505
|
+
auto-grow measured it once in a box that had no width yet — "Type a message…" folded
|
|
5506
|
+
over a dozen lines and the editor came up ~300 px tall while empty (#55). A
|
|
5507
|
+
placeholder longer than the box is clipped, which is what every native input does. */
|
|
5453
5508
|
aparte-composer-input .aparte-ci-editor:empty::before {
|
|
5454
5509
|
content: attr(data-placeholder);
|
|
5455
5510
|
color: var(--aparte-input-placeholder);
|
|
5456
5511
|
pointer-events: none;
|
|
5512
|
+
white-space: nowrap;
|
|
5513
|
+
overflow: hidden;
|
|
5514
|
+
text-overflow: ellipsis;
|
|
5515
|
+
display: block;
|
|
5457
5516
|
}
|
|
5458
5517
|
|
|
5459
5518
|
aparte-composer-input .aparte-ci-editor[aria-disabled="true"] {
|
|
@@ -6053,7 +6112,11 @@ details[open] > .aparte-tool-summary .aparte-tool-toggle { transform: rotate(180
|
|
|
6053
6112
|
}
|
|
6054
6113
|
|
|
6055
6114
|
.aparte-elic-message {
|
|
6056
|
-
margin
|
|
6115
|
+
/* The end margin is the room the corner "Skip" needs, from the same token the tab
|
|
6116
|
+
rail reserves — the button is absolutely positioned, so nothing in the flow knows
|
|
6117
|
+
it is there, and a long question printed its first line underneath it (#50). One
|
|
6118
|
+
token, because the button holds a word and the word changes width per locale. */
|
|
6119
|
+
margin: 0 var(--aparte-elic-dismiss-room) var(--aparte-space-3) var(--aparte-space-3);
|
|
6057
6120
|
font-size: var(--aparte-elic-message-size);
|
|
6058
6121
|
font-weight: var(--aparte-font-weight-semibold);
|
|
6059
6122
|
color: var(--aparte-text);
|
|
@@ -7262,6 +7325,7 @@ aparte-split[orientation='vertical'] .aparte-split__scrim,
|
|
|
7262
7325
|
Not "position: 100% and a zero-size handle": that leaves a focusable separator of
|
|
7263
7326
|
no width sitting in the tab order. */
|
|
7264
7327
|
aparte-split[data-stacked],
|
|
7328
|
+
aparte-split[single],
|
|
7265
7329
|
.aparte-split--only-start,
|
|
7266
7330
|
.aparte-split--only-end {
|
|
7267
7331
|
grid-template-columns: minmax(0, 1fr);
|
|
@@ -7269,17 +7333,23 @@ aparte-split[data-stacked],
|
|
|
7269
7333
|
}
|
|
7270
7334
|
|
|
7271
7335
|
aparte-split[data-stacked] > .aparte-split__handle,
|
|
7336
|
+
aparte-split[single] > .aparte-split__handle,
|
|
7272
7337
|
.aparte-split--only-start > .aparte-split__handle,
|
|
7273
7338
|
.aparte-split--only-end > .aparte-split__handle {
|
|
7274
7339
|
display: none;
|
|
7275
7340
|
}
|
|
7276
7341
|
|
|
7342
|
+
/* `single` is the host's word for the same state (#54): one pane, whatever the width,
|
|
7343
|
+
the one `pane` names. Same rules as the breakpoint's, so the element reads both the
|
|
7344
|
+
same way. */
|
|
7277
7345
|
aparte-split[data-stacked]:not([pane='end']) > :nth-child(3),
|
|
7346
|
+
aparte-split[single]:not([pane='end']) > :nth-child(3),
|
|
7278
7347
|
.aparte-split--only-start > :nth-child(3) {
|
|
7279
7348
|
display: none;
|
|
7280
7349
|
}
|
|
7281
7350
|
|
|
7282
7351
|
aparte-split[data-stacked][pane='end'] > :nth-child(1),
|
|
7352
|
+
aparte-split[single][pane='end'] > :nth-child(1),
|
|
7283
7353
|
.aparte-split--only-end > :nth-child(1) {
|
|
7284
7354
|
display: none;
|
|
7285
7355
|
}
|
|
@@ -7578,7 +7648,8 @@ aparte-split[disabled] > .aparte-split__handle:hover {
|
|
|
7578
7648
|
without container-query support keep the wide defaults. */
|
|
7579
7649
|
@container (max-width: 520px) {
|
|
7580
7650
|
.aparte-message {
|
|
7581
|
-
--aparte-message-padding: var(--aparte-space-6)
|
|
7651
|
+
--aparte-message-padding-block: var(--aparte-space-6);
|
|
7652
|
+
--aparte-message-padding-inline: var(--aparte-space-4);
|
|
7582
7653
|
--aparte-message-gap: var(--aparte-space-4);
|
|
7583
7654
|
}
|
|
7584
7655
|
|
package/dist/index.js
CHANGED
|
@@ -2311,6 +2311,24 @@ class AparteChatViewport extends HTMLElement {
|
|
|
2311
2311
|
/** How long after a scroll of ours we keep re-anchoring while the layout churns.
|
|
2312
2312
|
* Not `readonly`: a test shortens it to run past the window's end in a few frames. */
|
|
2313
2313
|
_settleWindowMs = 400;
|
|
2314
|
+
/**
|
|
2315
|
+
* Until when a smooth scroll of ours is in flight (#57). A user send glides to the
|
|
2316
|
+
* bottom with `scrollTo({ behavior: 'smooth' })`; the assistant placeholder and the
|
|
2317
|
+
* first tokens used to land INSIDE that glide through the streaming path — an instant
|
|
2318
|
+
* `scrollTop = scrollHeight` plus the settle chain — and an instant write cancels a
|
|
2319
|
+
* running smooth scroll in every engine. Measured before the fix: five instant writes
|
|
2320
|
+
* in the send's own frame (the spacer recalculation scrolls synchronously, the
|
|
2321
|
+
* mutation observer queues another), so there never was a glide to cut — the view
|
|
2322
|
+
* teleported. While this deadline is ahead, every bottom-pin RE-TARGETS the glide
|
|
2323
|
+
* (a second smooth `scrollTo` is continuous) instead of writing `scrollTop`; the
|
|
2324
|
+
* browser's `scrollend` closes it early where supported. Streaming is instant again
|
|
2325
|
+
* after that, as it must be to keep up with token bursts.
|
|
2326
|
+
*/
|
|
2327
|
+
_glideUntil = 0;
|
|
2328
|
+
/** The glide's budget when `scrollend` is not there to close it: Chromium's smooth scroll over a viewport takes ~300–500 ms. */
|
|
2329
|
+
_glideWindowMs = 450;
|
|
2330
|
+
/** Armed with each glide: when the window closes, a view still short of the bottom is pinned. */
|
|
2331
|
+
_glideSettleTimer = null;
|
|
2314
2332
|
/** Deadline of the settle in flight (0 = none). Pushed forward, never stacked. */
|
|
2315
2333
|
_settleUntil = 0;
|
|
2316
2334
|
_settleRafId = null;
|
|
@@ -2347,6 +2365,7 @@ class AparteChatViewport extends HTMLElement {
|
|
|
2347
2365
|
constructor() {
|
|
2348
2366
|
super();
|
|
2349
2367
|
this._handleScroll = this._handleScroll.bind(this);
|
|
2368
|
+
this._handleScrollEnd = this._handleScrollEnd.bind(this);
|
|
2350
2369
|
}
|
|
2351
2370
|
connectedCallback() {
|
|
2352
2371
|
if (this.hasAttribute("framework-managed")) this._frameworkManagedDOM = true;
|
|
@@ -2727,9 +2746,12 @@ class AparteChatViewport extends HTMLElement {
|
|
|
2727
2746
|
}
|
|
2728
2747
|
this._pruneRenderedBubbles();
|
|
2729
2748
|
this._syncBusy();
|
|
2730
|
-
this._recalculateSpacer();
|
|
2731
2749
|
if (message.role === "user") {
|
|
2732
2750
|
this._isAutoScrollEnabled = true;
|
|
2751
|
+
this._smoothScrollToBottom();
|
|
2752
|
+
}
|
|
2753
|
+
this._recalculateSpacer();
|
|
2754
|
+
if (message.role === "user") {
|
|
2733
2755
|
requestAnimationFrame(() => {
|
|
2734
2756
|
if (this._isAutoScrollEnabled) this._smoothScrollToBottom();
|
|
2735
2757
|
});
|
|
@@ -3081,16 +3103,9 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3081
3103
|
}
|
|
3082
3104
|
_autoScroll() {
|
|
3083
3105
|
if (this._isAutoScrollEnabled) {
|
|
3084
|
-
|
|
3085
|
-
this.
|
|
3086
|
-
|
|
3087
|
-
if (this._isAutoScrollEnabled) this._smoothScrollToBottom();
|
|
3088
|
-
});
|
|
3089
|
-
} else {
|
|
3090
|
-
requestAnimationFrame(() => {
|
|
3091
|
-
if (this._isAutoScrollEnabled) this._scrollToBottom();
|
|
3092
|
-
});
|
|
3093
|
-
}
|
|
3106
|
+
requestAnimationFrame(() => {
|
|
3107
|
+
if (this._isAutoScrollEnabled) this._scrollToBottom();
|
|
3108
|
+
});
|
|
3094
3109
|
}
|
|
3095
3110
|
this._pruneRenderedBubbles();
|
|
3096
3111
|
}
|
|
@@ -3234,6 +3249,14 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3234
3249
|
if (!inGutter) return;
|
|
3235
3250
|
}
|
|
3236
3251
|
this._readerInputAt = performance.now();
|
|
3252
|
+
if (this._gliding() && this._container) {
|
|
3253
|
+
this._glideUntil = 0;
|
|
3254
|
+
if (e.type === "wheel" || e.type === "touchmove") {
|
|
3255
|
+
this._ownScrollAt = performance.now();
|
|
3256
|
+
const here = this._container.scrollTop;
|
|
3257
|
+
this._container.scrollTop = here;
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3237
3260
|
};
|
|
3238
3261
|
_onBranchNavigate = (e) => {
|
|
3239
3262
|
const evt = e;
|
|
@@ -3242,6 +3265,7 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3242
3265
|
};
|
|
3243
3266
|
_setupEventListeners() {
|
|
3244
3267
|
this._container?.addEventListener("scroll", this._handleScroll, { passive: true });
|
|
3268
|
+
this._container?.addEventListener("scrollend", this._handleScrollEnd, { passive: true });
|
|
3245
3269
|
for (const type of ["wheel", "touchmove", "pointerdown", "keydown"]) {
|
|
3246
3270
|
this._container?.addEventListener(type, this._noteReaderInput, { passive: true });
|
|
3247
3271
|
}
|
|
@@ -3275,8 +3299,16 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3275
3299
|
this._overlayObserver.observe(this._overlayRoot, { childList: true });
|
|
3276
3300
|
this._updateOverlayInset();
|
|
3277
3301
|
}
|
|
3278
|
-
this._mutationObserver = new MutationObserver(() => {
|
|
3302
|
+
this._mutationObserver = new MutationObserver((mutations) => {
|
|
3279
3303
|
if (this._frameworkManagedDOM) this._keepScrollButtonLast();
|
|
3304
|
+
if (this._isAutoScrollEnabled && !this._gliding()) {
|
|
3305
|
+
const added = mutations.flatMap((m2) => Array.from(m2.addedNodes)).filter((n2) => n2 instanceof Element && n2.tagName === "APARTE-CHAT-BUBBLE");
|
|
3306
|
+
const only = added.length === 1 ? added[0] : void 0;
|
|
3307
|
+
if (only && only.getAttribute("data-role") === "user" && only.parentElement) {
|
|
3308
|
+
const bubbles = only.parentElement.querySelectorAll("aparte-chat-bubble");
|
|
3309
|
+
if (bubbles[bubbles.length - 1] === only) this._smoothScrollOnce = true;
|
|
3310
|
+
}
|
|
3311
|
+
}
|
|
3280
3312
|
if (this._isAutoScrollEnabled) {
|
|
3281
3313
|
requestAnimationFrame(() => {
|
|
3282
3314
|
if (this._isAutoScrollEnabled) this._scrollToBottom();
|
|
@@ -3352,10 +3384,41 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3352
3384
|
}
|
|
3353
3385
|
_scrollToBottom() {
|
|
3354
3386
|
if (!this._container) return;
|
|
3387
|
+
if (this._smoothScrollOnce) {
|
|
3388
|
+
this._smoothScrollOnce = false;
|
|
3389
|
+
this._smoothScrollToBottom();
|
|
3390
|
+
return;
|
|
3391
|
+
}
|
|
3392
|
+
if (this._gliding()) {
|
|
3393
|
+
this._retargetGlide();
|
|
3394
|
+
return;
|
|
3395
|
+
}
|
|
3355
3396
|
this._ownScrollAt = performance.now();
|
|
3356
3397
|
this._container.scrollTop = this._container.scrollHeight;
|
|
3357
3398
|
this._settleAtBottom();
|
|
3358
3399
|
}
|
|
3400
|
+
_gliding() {
|
|
3401
|
+
return performance.now() < this._glideUntil;
|
|
3402
|
+
}
|
|
3403
|
+
/** A second smooth `scrollTo` is continuous where an instant write is a cut. */
|
|
3404
|
+
_retargetGlide() {
|
|
3405
|
+
if (!this._container) return;
|
|
3406
|
+
this._ownScrollAt = performance.now();
|
|
3407
|
+
this._container.scrollTo({ top: this._container.scrollHeight, behavior: "smooth" });
|
|
3408
|
+
}
|
|
3409
|
+
/**
|
|
3410
|
+
* The browser says a scroll came to rest — the glide is over ONLY if it rested at the
|
|
3411
|
+
* bottom. WebKit fires `scrollend` when a smooth scroll is REPLACED by another (our own
|
|
3412
|
+
* re-target), 45–60 ms into the glide and hundreds of pixels short; taken at its word,
|
|
3413
|
+
* that closed the window and the next pin was the cut this guard exists to prevent
|
|
3414
|
+
* (react-webkit and vanilla-webkit, 2 of 2). Short of the bottom, the budget keeps
|
|
3415
|
+
* bounding the window.
|
|
3416
|
+
*/
|
|
3417
|
+
_handleScrollEnd() {
|
|
3418
|
+
if (!this._container) return;
|
|
3419
|
+
const max = this._container.scrollHeight - this._container.clientHeight;
|
|
3420
|
+
if (max - this._container.scrollTop <= 1) this._glideUntil = 0;
|
|
3421
|
+
}
|
|
3359
3422
|
/**
|
|
3360
3423
|
* Confirm over the next few frames that we actually reached the bottom.
|
|
3361
3424
|
*
|
|
@@ -3401,7 +3464,7 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3401
3464
|
return;
|
|
3402
3465
|
}
|
|
3403
3466
|
const max = this._container.scrollHeight - this._container.clientHeight;
|
|
3404
|
-
if (max - this._container.scrollTop > 1) {
|
|
3467
|
+
if (max - this._container.scrollTop > 1 && !this._gliding()) {
|
|
3405
3468
|
this._ownScrollAt = performance.now();
|
|
3406
3469
|
this._container.scrollTop = max;
|
|
3407
3470
|
}
|
|
@@ -3414,7 +3477,15 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3414
3477
|
if (!this._container) return;
|
|
3415
3478
|
this._ownScrollAt = performance.now();
|
|
3416
3479
|
if (typeof this._container.scrollTo === "function" && !this._prefersReducedMotion()) {
|
|
3480
|
+
this._glideUntil = performance.now() + this._glideWindowMs;
|
|
3417
3481
|
this._container.scrollTo({ top: this._container.scrollHeight, behavior: "smooth" });
|
|
3482
|
+
if (this._glideSettleTimer !== null) clearTimeout(this._glideSettleTimer);
|
|
3483
|
+
this._glideSettleTimer = setTimeout(() => {
|
|
3484
|
+
this._glideSettleTimer = null;
|
|
3485
|
+
if (!this._container || !this._isAutoScrollEnabled || this._gliding()) return;
|
|
3486
|
+
const max = this._container.scrollHeight - this._container.clientHeight;
|
|
3487
|
+
if (max - this._container.scrollTop > 1) this._scrollToBottom();
|
|
3488
|
+
}, this._glideWindowMs + 16);
|
|
3418
3489
|
} else {
|
|
3419
3490
|
this._container.scrollTop = this._container.scrollHeight;
|
|
3420
3491
|
}
|
|
@@ -3530,6 +3601,11 @@ class AparteChatViewport extends HTMLElement {
|
|
|
3530
3601
|
}
|
|
3531
3602
|
_cleanup() {
|
|
3532
3603
|
this._container?.removeEventListener("scroll", this._handleScroll);
|
|
3604
|
+
this._container?.removeEventListener("scrollend", this._handleScrollEnd);
|
|
3605
|
+
if (this._glideSettleTimer !== null) {
|
|
3606
|
+
clearTimeout(this._glideSettleTimer);
|
|
3607
|
+
this._glideSettleTimer = null;
|
|
3608
|
+
}
|
|
3533
3609
|
for (const type of ["wheel", "touchmove", "pointerdown", "keydown"]) {
|
|
3534
3610
|
this._container?.removeEventListener(type, this._noteReaderInput);
|
|
3535
3611
|
}
|
|
@@ -4041,6 +4117,14 @@ class AparteComposerInput extends HTMLElement {
|
|
|
4041
4117
|
_editor = null;
|
|
4042
4118
|
_maxHeight = 200;
|
|
4043
4119
|
_minHeight = 44;
|
|
4120
|
+
/**
|
|
4121
|
+
* Re-measures the editor when its WIDTH changes (#55). The three fixed instants
|
|
4122
|
+
* (connect, next frame, fonts.ready) all miss the same case: a box not yet laid
|
|
4123
|
+
* out — the placeholder wraps in a 0 px column, `scrollHeight` reads ~300 px, and
|
|
4124
|
+
* that became the inline height until the first keystroke. Width is the variable
|
|
4125
|
+
* none of them watched.
|
|
4126
|
+
*/
|
|
4127
|
+
_resizeObserver = null;
|
|
4044
4128
|
_unsubscribes = [];
|
|
4045
4129
|
// Bound handlers
|
|
4046
4130
|
_onInput = this._handleInput.bind(this);
|
|
@@ -4061,6 +4145,10 @@ class AparteComposerInput extends HTMLElement {
|
|
|
4061
4145
|
this._editor?.addEventListener("paste", this._onPaste);
|
|
4062
4146
|
this._connectToRoot();
|
|
4063
4147
|
this._scheduleInitialReflow();
|
|
4148
|
+
if (this._editor && typeof ResizeObserver === "function") {
|
|
4149
|
+
this._resizeObserver = new ResizeObserver(() => this._adjustHeight());
|
|
4150
|
+
this._resizeObserver.observe(this._editor);
|
|
4151
|
+
}
|
|
4064
4152
|
this._unsubscribes.push(subscribeConfigChange(this, () => this._updatePlaceholder()));
|
|
4065
4153
|
}
|
|
4066
4154
|
disconnectedCallback() {
|
|
@@ -4069,6 +4157,8 @@ class AparteComposerInput extends HTMLElement {
|
|
|
4069
4157
|
this._editor?.removeEventListener("focus", this._onFocus);
|
|
4070
4158
|
this._editor?.removeEventListener("blur", this._onBlur);
|
|
4071
4159
|
this._editor?.removeEventListener("paste", this._onPaste);
|
|
4160
|
+
this._resizeObserver?.disconnect();
|
|
4161
|
+
this._resizeObserver = null;
|
|
4072
4162
|
this._unsubscribes.forEach((fn) => fn());
|
|
4073
4163
|
this._unsubscribes = [];
|
|
4074
4164
|
}
|
|
@@ -5824,6 +5914,9 @@ class AparteScrollRail extends HTMLElement {
|
|
|
5824
5914
|
if (!customElements.get("aparte-scroll-rail")) {
|
|
5825
5915
|
customElements.define("aparte-scroll-rail", AparteScrollRail);
|
|
5826
5916
|
}
|
|
5917
|
+
function presenceOn(value) {
|
|
5918
|
+
return value === "" ? true : Boolean(value);
|
|
5919
|
+
}
|
|
5827
5920
|
const DRAWER_QUERY = "(max-width: 48rem)";
|
|
5828
5921
|
class AparteSidebar extends HTMLElement {
|
|
5829
5922
|
static get observedAttributes() {
|
|
@@ -5873,7 +5966,7 @@ class AparteSidebar extends HTMLElement {
|
|
|
5873
5966
|
return this.hasAttribute("collapsed");
|
|
5874
5967
|
}
|
|
5875
5968
|
set collapsed(value) {
|
|
5876
|
-
this.toggleAttribute("collapsed", value);
|
|
5969
|
+
this.toggleAttribute("collapsed", presenceOn(value));
|
|
5877
5970
|
}
|
|
5878
5971
|
/** True while the window is under the breakpoint and the sidebar is a drawer. */
|
|
5879
5972
|
get drawer() {
|
|
@@ -6133,7 +6226,7 @@ function toPercent(raw, fallback) {
|
|
|
6133
6226
|
}
|
|
6134
6227
|
class AparteSplit extends HTMLElement {
|
|
6135
6228
|
static get observedAttributes() {
|
|
6136
|
-
return ["position", "orientation", "primary", "collapsed", "breakpoint", "pane", "disabled", "label"];
|
|
6229
|
+
return ["position", "orientation", "primary", "collapsed", "breakpoint", "pane", "disabled", "label", "single"];
|
|
6137
6230
|
}
|
|
6138
6231
|
_handle = null;
|
|
6139
6232
|
_scrim = null;
|
|
@@ -6217,7 +6310,7 @@ class AparteSplit extends HTMLElement {
|
|
|
6217
6310
|
return this.hasAttribute("collapsed");
|
|
6218
6311
|
}
|
|
6219
6312
|
set collapsed(value) {
|
|
6220
|
-
this.toggleAttribute("collapsed", value);
|
|
6313
|
+
this.toggleAttribute("collapsed", presenceOn(value));
|
|
6221
6314
|
}
|
|
6222
6315
|
/** Which pane is shown while the split is stacked. */
|
|
6223
6316
|
get pane() {
|
|
@@ -6231,7 +6324,7 @@ class AparteSplit extends HTMLElement {
|
|
|
6231
6324
|
return this.hasAttribute("disabled");
|
|
6232
6325
|
}
|
|
6233
6326
|
set disabled(value) {
|
|
6234
|
-
this.toggleAttribute("disabled", value);
|
|
6327
|
+
this.toggleAttribute("disabled", presenceOn(value));
|
|
6235
6328
|
}
|
|
6236
6329
|
/**
|
|
6237
6330
|
* True while the split is showing one pane. Read-only.
|
|
@@ -6244,7 +6337,14 @@ class AparteSplit extends HTMLElement {
|
|
|
6244
6337
|
* alone would measure a one-track grid and commit `position="100"`.
|
|
6245
6338
|
*/
|
|
6246
6339
|
get stacked() {
|
|
6247
|
-
return this.hasAttribute("data-stacked") || this.classList.contains("aparte-split--only-start") || this.classList.contains("aparte-split--only-end");
|
|
6340
|
+
return this.hasAttribute("data-stacked") || this.hasAttribute("single") || this.classList.contains("aparte-split--only-start") || this.classList.contains("aparte-split--only-end");
|
|
6341
|
+
}
|
|
6342
|
+
/** One pane on demand, whatever the width (#54). Reflected. */
|
|
6343
|
+
get single() {
|
|
6344
|
+
return this.hasAttribute("single");
|
|
6345
|
+
}
|
|
6346
|
+
set single(value) {
|
|
6347
|
+
this.toggleAttribute("single", presenceOn(value));
|
|
6248
6348
|
}
|
|
6249
6349
|
// ─── Public API ───────────────────────────────────────────────────────
|
|
6250
6350
|
/** Fold the primary pane to its minimum, remembering the size it had. */
|
|
@@ -6375,6 +6475,10 @@ class AparteSplit extends HTMLElement {
|
|
|
6375
6475
|
if (this.disabled && this._dragging) this._endDrag("pointer", this._dragStartPercent);
|
|
6376
6476
|
this._stampHandle();
|
|
6377
6477
|
return;
|
|
6478
|
+
case "single":
|
|
6479
|
+
if (this.single && this._dragging) this._endDrag("pointer", this._dragStartPercent);
|
|
6480
|
+
this._stampHandle();
|
|
6481
|
+
return;
|
|
6378
6482
|
case "breakpoint":
|
|
6379
6483
|
this._watchBreakpoint();
|
|
6380
6484
|
return;
|