@aparte/core 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -7
- package/dist/components/bubble/aparte-chat-bubble.d.ts +18 -0
- package/dist/components/bubble/aparte-chat-bubble.d.ts.map +1 -1
- package/dist/components/chat/aparte-chat.d.ts +17 -0
- package/dist/components/chat/aparte-chat.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-add-attachment.d.ts +11 -0
- package/dist/components/composer/aparte-composer-add-attachment.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-attachments.d.ts +14 -0
- package/dist/components/composer/aparte-composer-attachments.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-cancel.d.ts +11 -0
- package/dist/components/composer/aparte-composer-cancel.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-input.d.ts +10 -0
- package/dist/components/composer/aparte-composer-input.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-send.d.ts +10 -0
- package/dist/components/composer/aparte-composer-send.d.ts.map +1 -1
- package/dist/components/composer/aparte-composer-toolbar.d.ts +53 -0
- package/dist/components/composer/aparte-composer-toolbar.d.ts.map +1 -0
- package/dist/components/composer/aparte-composer.d.ts +13 -0
- package/dist/components/composer/aparte-composer.d.ts.map +1 -1
- package/dist/components/composer/index.d.ts +1 -0
- package/dist/components/composer/index.d.ts.map +1 -1
- package/dist/components/conversation-list/aparte-conversation-list.d.ts +22 -1
- package/dist/components/conversation-list/aparte-conversation-list.d.ts.map +1 -1
- package/dist/components/elicitation/aparte-elicitation.d.ts +15 -0
- package/dist/components/elicitation/aparte-elicitation.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/status/aparte-chat-status.d.ts +6 -0
- package/dist/components/status/aparte-chat-status.d.ts.map +1 -1
- package/dist/components/viewport/aparte-chat-viewport.d.ts +16 -0
- package/dist/components/viewport/aparte-chat-viewport.d.ts.map +1 -1
- package/dist/custom-elements.json +3769 -3552
- package/dist/index.css +11 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +121 -2
- package/dist/index.js.map +1 -1
- package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts +5 -0
- package/dist/primitives/progress-spinner/aparte-progress-spinner.d.ts.map +1 -1
- package/dist/primitives/select/aparte-optgroup.d.ts +11 -0
- package/dist/primitives/select/aparte-optgroup.d.ts.map +1 -1
- package/dist/primitives/select/aparte-option.d.ts +6 -0
- package/dist/primitives/select/aparte-option.d.ts.map +1 -1
- package/dist/primitives/select/aparte-select.d.ts +23 -0
- package/dist/primitives/select/aparte-select.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -2059,7 +2059,12 @@ aparte-composer.is-dragover:not(:has(.aparte-composer-shell)) {
|
|
|
2059
2059
|
justify-content: center;
|
|
2060
2060
|
}
|
|
2061
2061
|
|
|
2062
|
-
/*
|
|
2062
|
+
/* The composer's bottom row (mode picker, model selector, token counter…).
|
|
2063
|
+
`aparte-composer-toolbar` is the element consumers write — one name for vanilla and
|
|
2064
|
+
every wrapper. `.aparte-composer-footer` is the class the same row used to be built
|
|
2065
|
+
with, kept so markup that predates the element keeps its styling instead of silently
|
|
2066
|
+
rendering as a bare div. Removable at 1.0. */
|
|
2067
|
+
aparte-composer-toolbar,
|
|
2063
2068
|
.aparte-composer-footer {
|
|
2064
2069
|
display: flex;
|
|
2065
2070
|
align-items: center;
|
|
@@ -2068,6 +2073,11 @@ aparte-composer.is-dragover:not(:has(.aparte-composer-shell)) {
|
|
|
2068
2073
|
border-top: var(--aparte-border-width, 1px) solid var(--aparte-border);
|
|
2069
2074
|
}
|
|
2070
2075
|
|
|
2076
|
+
/* A row with nothing in it must not draw its separator. The element reflects
|
|
2077
|
+
`data-empty` itself (see aparte-composer-toolbar.ts) because `:empty` is defeated by
|
|
2078
|
+
the whitespace text node an indented template leaves behind; the legacy class keeps
|
|
2079
|
+
`:empty`, which is all it ever had. */
|
|
2080
|
+
aparte-composer-toolbar[data-empty],
|
|
2071
2081
|
.aparte-composer-footer:empty {
|
|
2072
2082
|
display: none;
|
|
2073
2083
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ export { AparteChatBubble, populateBubbleFromMessage } from './components/index.
|
|
|
26
26
|
export type { SyncableBubble } from './components/index.js';
|
|
27
27
|
export { AparteChatStatus } from './components/index.js';
|
|
28
28
|
export { AparteChatViewport } from './components/index.js';
|
|
29
|
-
export { AparteComposer, AparteComposerInput, AparteComposerSend, AparteComposerCancel, AparteComposerAttachments, AparteComposerAddAttachment, AparteComposerAction } from './components/index.js';
|
|
29
|
+
export { AparteComposer, AparteComposerInput, AparteComposerSend, AparteComposerCancel, AparteComposerAttachments, AparteComposerAddAttachment, AparteComposerAction, AparteComposerToolbar } from './components/index.js';
|
|
30
30
|
export type { AparteComposerEventMap, AparteComposerEventType, AparteComposerState, AparteComposerChangeEventDetail } from './components/index.js';
|
|
31
31
|
export { AparteConversationList } from './components/index.js';
|
|
32
32
|
export type { AparteConversationListItem, AparteConversationSelectDetail, AparteConversationDeleteDetail } from './components/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,qBAAqB,CAAC;AAC7B,OAAO,gCAAgC,CAAC;AACxC,OAAO,oDAAoD,CAAC;AAG5D,OAAO,sBAAsB,CAAC;AAG9B,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,KAAK,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAGzI,YAAY,EACR,gBAAgB,EAChB,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,yBAAyB,EACzB,sBAAsB,EACtB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EAErB,gBAAgB,EAChB,aAAa,EACb,2BAA2B,EAC3B,4BAA4B,EAC5B,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,4BAA4B,EAC5B,4BAA4B,EAC5B,4BAA4B,EAC5B,iBAAiB,EACjB,+BAA+B,EAC/B,4BAA4B,EAC5B,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,8BAA8B,EAC9B,8BAA8B,EAC9B,8BAA8B,EAC9B,6BAA6B,EAE7B,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EAEX,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,wBAAwB,EACxB,+BAA+B,EAC/B,sBAAsB,EAEtB,uBAAuB,EAC1B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EACH,uBAAuB,EACvB,yBAAyB,EACzB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EAC3B,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACpF,YAAY,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -312,8 +312,23 @@ class AparteSelect extends HTMLElement {
|
|
|
312
312
|
_setupMutationObserver() {
|
|
313
313
|
this._observer = new MutationObserver(() => {
|
|
314
314
|
this._updateDropdownContent();
|
|
315
|
+
this._restoreActive();
|
|
315
316
|
});
|
|
316
|
-
this._observer.observe(this, { childList: true });
|
|
317
|
+
this._observer.observe(this, { childList: true, subtree: true });
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Put the roving highlight back after the options changed underneath it.
|
|
321
|
+
*
|
|
322
|
+
* `data-active` lives on an option ELEMENT, so replacing the list throws it
|
|
323
|
+
* away while `_activeIndex` still claims a position: the highlight disappeared,
|
|
324
|
+
* `aria-activedescendant` kept pointing at an id no longer in the document, and
|
|
325
|
+
* the next ArrowDown moved from the stale index — skipping an option. Only when
|
|
326
|
+
* open and only when a position was held, so a refresh never invents one.
|
|
327
|
+
*/
|
|
328
|
+
_restoreActive() {
|
|
329
|
+
if (!this._isOpen || this._activeIndex < 0) return;
|
|
330
|
+
if (this.querySelector("aparte-option[data-active]")) return;
|
|
331
|
+
this._setActive(this._activeIndex);
|
|
317
332
|
}
|
|
318
333
|
_updateDropdownContent() {
|
|
319
334
|
if (!this._trigger || !this.contains(this._trigger)) {
|
|
@@ -335,9 +350,10 @@ class AparteSelect extends HTMLElement {
|
|
|
335
350
|
optionsContainer.appendChild(child);
|
|
336
351
|
});
|
|
337
352
|
if (this.isConnected) {
|
|
338
|
-
this._observer?.observe(this, { childList: true });
|
|
353
|
+
this._observer?.observe(this, { childList: true, subtree: true });
|
|
339
354
|
}
|
|
340
355
|
this._updateTriggerLabel();
|
|
356
|
+
this._restoreActive();
|
|
341
357
|
}
|
|
342
358
|
_setupEventListeners() {
|
|
343
359
|
this._trigger?.addEventListener("click", () => this._toggle());
|
|
@@ -772,7 +788,23 @@ class AparteChatBubble extends HTMLElement {
|
|
|
772
788
|
const detail = e2.detail;
|
|
773
789
|
if (detail?.config && detail.config !== this._cfg) return;
|
|
774
790
|
this._updateActionBar();
|
|
791
|
+
this._updateName();
|
|
792
|
+
this._updateLocalizedLabels();
|
|
793
|
+
this._updateWaiting();
|
|
775
794
|
};
|
|
795
|
+
/**
|
|
796
|
+
* Re-apply the locale strings written straight into the markup by `_render()` —
|
|
797
|
+
* the accessible names a screen reader reads, which nothing else refreshes.
|
|
798
|
+
*/
|
|
799
|
+
_updateLocalizedLabels() {
|
|
800
|
+
const locale = this._cfg.getLocale();
|
|
801
|
+
const set = (selector, label) => {
|
|
802
|
+
this.querySelector(selector)?.setAttribute("aria-label", label);
|
|
803
|
+
};
|
|
804
|
+
set(".aparte-branch-prev", locale.previousResponse ?? "Previous response");
|
|
805
|
+
set(".aparte-branch-next", locale.nextResponse ?? "Next response");
|
|
806
|
+
set(".aparte-action-bar", locale.messageActions ?? "Message actions");
|
|
807
|
+
}
|
|
776
808
|
/**
|
|
777
809
|
* Config governing this bubble: the instance config of the nearest
|
|
778
810
|
* `[data-aparte-host]` boundary, else the global singleton. Resolved live
|
|
@@ -1797,8 +1829,28 @@ class AparteChatViewport extends HTMLElement {
|
|
|
1797
1829
|
this._setupObservers();
|
|
1798
1830
|
this._boundResetHandler = () => this.clearAll();
|
|
1799
1831
|
window.addEventListener("aparte-reset", this._boundResetHandler);
|
|
1832
|
+
window.addEventListener("aparte-config-change", this._onConfigChange);
|
|
1833
|
+
}
|
|
1834
|
+
/**
|
|
1835
|
+
* A locale switch changes the reading direction, and `dir` was applied once at
|
|
1836
|
+
* render — so a chat already on screen never flipped to RTL until a reload.
|
|
1837
|
+
* Only OUR config: an instance-scoped change elsewhere must not touch us.
|
|
1838
|
+
*/
|
|
1839
|
+
_onConfigChange = (e2) => {
|
|
1840
|
+
const detail = e2.detail;
|
|
1841
|
+
if (detail?.config && detail.config !== resolveConfig(this)) return;
|
|
1842
|
+
this._applyDirection();
|
|
1843
|
+
};
|
|
1844
|
+
/** Mirror `locale.direction` onto the scroll container. */
|
|
1845
|
+
_applyDirection() {
|
|
1846
|
+
const container = this.querySelector(".aparte-viewport-container");
|
|
1847
|
+
if (!container) return;
|
|
1848
|
+
const direction = resolveConfig(this).getLocale().direction;
|
|
1849
|
+
if (direction) container.setAttribute("dir", direction);
|
|
1850
|
+
else container.removeAttribute("dir");
|
|
1800
1851
|
}
|
|
1801
1852
|
disconnectedCallback() {
|
|
1853
|
+
window.removeEventListener("aparte-config-change", this._onConfigChange);
|
|
1802
1854
|
if (this._boundResetHandler) {
|
|
1803
1855
|
window.removeEventListener("aparte-reset", this._boundResetHandler);
|
|
1804
1856
|
this._boundResetHandler = null;
|
|
@@ -2697,7 +2749,25 @@ class AparteComposer extends HTMLElement {
|
|
|
2697
2749
|
_modelGated = false;
|
|
2698
2750
|
_onConfigChange = () => {
|
|
2699
2751
|
this._evaluateModelGate();
|
|
2752
|
+
this._applyDirection();
|
|
2700
2753
|
};
|
|
2754
|
+
/**
|
|
2755
|
+
* Mirror `locale.direction` onto ourselves, so everything inside — input, buttons,
|
|
2756
|
+
* the toolbar row and whatever the consumer put in it — inherits it.
|
|
2757
|
+
*
|
|
2758
|
+
* The direction used to stop at the transcript: only the viewport applied `dir`, so
|
|
2759
|
+
* an RTL locale flipped the conversation and left the composer left-to-right. It is
|
|
2760
|
+
* also what makes the toolbar's placement idiom real: `margin-inline-start: auto` in
|
|
2761
|
+
* a subtree that inherits no direction is just `margin-left`.
|
|
2762
|
+
*
|
|
2763
|
+
* One attribute on the host rather than a stamp per child: inheritance is the
|
|
2764
|
+
* mechanism, so nothing needs to know about the consumer's markup.
|
|
2765
|
+
*/
|
|
2766
|
+
_applyDirection() {
|
|
2767
|
+
const direction = (this._cfg ?? resolveConfig(this)).getLocale().direction;
|
|
2768
|
+
if (direction) this.setAttribute("dir", direction);
|
|
2769
|
+
else this.removeAttribute("dir");
|
|
2770
|
+
}
|
|
2701
2771
|
static get observedAttributes() {
|
|
2702
2772
|
return ["placeholder", "disabled", "target"];
|
|
2703
2773
|
}
|
|
@@ -2709,6 +2779,7 @@ class AparteComposer extends HTMLElement {
|
|
|
2709
2779
|
this._cfg = resolveConfig(this);
|
|
2710
2780
|
this._configUnsub = this._cfg.subscribe(this._onConfigChange);
|
|
2711
2781
|
this._evaluateModelGate();
|
|
2782
|
+
this._applyDirection();
|
|
2712
2783
|
}
|
|
2713
2784
|
disconnectedCallback() {
|
|
2714
2785
|
window.removeEventListener("aparte-message-start", this._onMessageStart);
|
|
@@ -3594,6 +3665,39 @@ class AparteComposerAction extends HTMLElement {
|
|
|
3594
3665
|
if (!customElements.get("aparte-composer-action")) {
|
|
3595
3666
|
customElements.define("aparte-composer-action", AparteComposerAction);
|
|
3596
3667
|
}
|
|
3668
|
+
class AparteComposerToolbar extends HTMLElement {
|
|
3669
|
+
_observer = null;
|
|
3670
|
+
connectedCallback() {
|
|
3671
|
+
this._syncEmpty();
|
|
3672
|
+
this._observer ??= new MutationObserver(() => this._syncEmpty());
|
|
3673
|
+
this._observer.observe(this, { childList: true });
|
|
3674
|
+
}
|
|
3675
|
+
disconnectedCallback() {
|
|
3676
|
+
this._observer?.disconnect();
|
|
3677
|
+
this._observer = null;
|
|
3678
|
+
}
|
|
3679
|
+
/**
|
|
3680
|
+
* Reflect `data-empty` from the presence of an ELEMENT child.
|
|
3681
|
+
*
|
|
3682
|
+
* Not `:empty` in CSS: that selector does not match an element holding a whitespace
|
|
3683
|
+
* text node, so a template that indents its content keeps the row — separator,
|
|
3684
|
+
* padding and all — while it looks empty to the user. Every framework template
|
|
3685
|
+
* indents. An empty row must not draw its own separator (the same rule as an empty
|
|
3686
|
+
* bubble action bar).
|
|
3687
|
+
*
|
|
3688
|
+
* Non-whitespace TEXT counts as content, not just an element child: a hand-written
|
|
3689
|
+
* row holding a bare token count (`<aparte-composer-toolbar>1 240 tokens</…>`) is
|
|
3690
|
+
* not empty, and hiding it would be a twenty-minute mystery for whoever wrote it.
|
|
3691
|
+
*/
|
|
3692
|
+
_syncEmpty() {
|
|
3693
|
+
const hasContent = Boolean(this.firstElementChild) || this.textContent?.trim() !== "";
|
|
3694
|
+
if (hasContent) this.removeAttribute("data-empty");
|
|
3695
|
+
else this.setAttribute("data-empty", "");
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
if (!customElements.get("aparte-composer-toolbar")) {
|
|
3699
|
+
customElements.define("aparte-composer-toolbar", AparteComposerToolbar);
|
|
3700
|
+
}
|
|
3597
3701
|
class AparteConversationList extends HTMLElement {
|
|
3598
3702
|
_conversations = [];
|
|
3599
3703
|
_activeId = null;
|
|
@@ -3609,6 +3713,10 @@ class AparteConversationList extends HTMLElement {
|
|
|
3609
3713
|
this.setAttribute("role", "navigation");
|
|
3610
3714
|
}
|
|
3611
3715
|
this._render();
|
|
3716
|
+
window.addEventListener("aparte-config-change", this._onConfigChange);
|
|
3717
|
+
}
|
|
3718
|
+
disconnectedCallback() {
|
|
3719
|
+
window.removeEventListener("aparte-config-change", this._onConfigChange);
|
|
3612
3720
|
}
|
|
3613
3721
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
3614
3722
|
if (oldValue === newValue) return;
|
|
@@ -3617,6 +3725,16 @@ class AparteConversationList extends HTMLElement {
|
|
|
3617
3725
|
this._updateActiveState();
|
|
3618
3726
|
}
|
|
3619
3727
|
}
|
|
3728
|
+
/**
|
|
3729
|
+
* Re-render on a locale switch: every row's title fallback and both button
|
|
3730
|
+
* labels come from the locale, so without this the list stayed in the previous
|
|
3731
|
+
* language until something else happened to re-render it. Only OUR config.
|
|
3732
|
+
*/
|
|
3733
|
+
_onConfigChange = (e2) => {
|
|
3734
|
+
const detail = e2.detail;
|
|
3735
|
+
if (detail?.config && detail.config !== resolveConfig(this)) return;
|
|
3736
|
+
this._render();
|
|
3737
|
+
};
|
|
3620
3738
|
// ─── Public API ───────────────────────────────────────────────────────
|
|
3621
3739
|
/** Set the list of conversations to display. Triggers a re-render. */
|
|
3622
3740
|
set conversations(items) {
|
|
@@ -3865,6 +3983,7 @@ export {
|
|
|
3865
3983
|
AparteComposerCancel,
|
|
3866
3984
|
AparteComposerInput,
|
|
3867
3985
|
AparteComposerSend,
|
|
3986
|
+
AparteComposerToolbar,
|
|
3868
3987
|
AparteConfig,
|
|
3869
3988
|
e as AparteConfigClass,
|
|
3870
3989
|
f as AparteConversationController,
|