@design.estate/dees-catalog 11.2.2 → 12.1.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/dist_bundle/bundle.js +1898 -1292
- package/dist_bundle/bundle.js.map +1 -1
- package/dist_ts_web/00_commitinfo_data.js +1 -1
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.d.ts +62 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.js +38 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.js +455 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-conversation-picker/index.js +2 -0
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.d.ts +39 -10
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.demo.js +81 -27
- package/dist_ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.js +327 -115
- package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.d.ts +22 -1
- package/dist_ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.js +42 -3
- package/dist_ts_web/elements/00group-harness/index.d.ts +1 -0
- package/dist_ts_web/elements/00group-harness/index.js +2 -1
- package/dist_ts_web/elements/00group-harness/interfaces.d.ts +35 -16
- package/package.json +1 -1
- package/readme.md +57 -23
- package/ts_web/00_commitinfo_data.ts +1 -1
- package/ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.demo.ts +46 -0
- package/ts_web/elements/00group-harness/dees-harness-conversation-picker/dees-harness-conversation-picker.ts +420 -0
- package/ts_web/elements/00group-harness/dees-harness-conversation-picker/index.ts +1 -0
- package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.demo.ts +94 -36
- package/ts_web/elements/00group-harness/dees-harness-session-list/dees-harness-session-list.ts +357 -120
- package/ts_web/elements/00group-harness/dees-terminal-view/dees-terminal-view.ts +42 -2
- package/ts_web/elements/00group-harness/index.ts +1 -0
- package/ts_web/elements/00group-harness/interfaces.ts +41 -16
|
@@ -93,6 +93,11 @@ export class DeesTerminalView extends DeesElement {
|
|
|
93
93
|
private pendingWriteBytes = 0;
|
|
94
94
|
private pendingWritesDropped = false;
|
|
95
95
|
private setupPromise: Promise<void> | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Set only by an explicit `focus()` that arrived before the terminal existed. Nothing else sets
|
|
98
|
+
* it, so a re-render, a write, or a resize can never move the caret into this element.
|
|
99
|
+
*/
|
|
100
|
+
private focusWhenReady = false;
|
|
96
101
|
private readyPending = true;
|
|
97
102
|
private readyResolve: () => void = () => undefined;
|
|
98
103
|
private readyReject: (reasonArg: unknown) => void = () => undefined;
|
|
@@ -302,8 +307,35 @@ export class DeesTerminalView extends DeesElement {
|
|
|
302
307
|
this.pendingWritesDropped = false;
|
|
303
308
|
}
|
|
304
309
|
|
|
305
|
-
|
|
306
|
-
|
|
310
|
+
/**
|
|
311
|
+
* Moves the caret into the terminal's input surface, so the next keystroke goes to the pty
|
|
312
|
+
* rather than to whatever the page focused last. This is the call a host makes when the user
|
|
313
|
+
* selects a terminal in a list.
|
|
314
|
+
*
|
|
315
|
+
* The terminal is created asynchronously — the xterm modules are loaded on first connection —
|
|
316
|
+
* so a call that arrives before it exists is remembered and applied once it is ready, exactly
|
|
317
|
+
* once. The same applies to an element that is focused while detached and then reattached: the
|
|
318
|
+
* pending request is dropped on disconnect, because by then the user's intent has expired, and
|
|
319
|
+
* a fresh `focus()` after the move is what a host should issue.
|
|
320
|
+
*
|
|
321
|
+
* Only this method arms that behaviour; re-renders, buffered output and background updates
|
|
322
|
+
* never steal focus.
|
|
323
|
+
*/
|
|
324
|
+
public focus(optionsArg?: FocusOptions): void {
|
|
325
|
+
const terminal = this.terminal;
|
|
326
|
+
if (terminal && this.isConnected) {
|
|
327
|
+
this.focusWhenReady = false;
|
|
328
|
+
terminal.focus();
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
// Preventing scroll is a hint for the eventual focus, not a reason to skip it.
|
|
332
|
+
void optionsArg;
|
|
333
|
+
this.focusWhenReady = true;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** True while an explicit `focus()` is waiting for the terminal to come up. */
|
|
337
|
+
public get focusPending(): boolean {
|
|
338
|
+
return this.focusWhenReady;
|
|
307
339
|
}
|
|
308
340
|
|
|
309
341
|
/** Current grid size, or undefined while no terminal is live. */
|
|
@@ -444,6 +476,11 @@ export class DeesTerminalView extends DeesElement {
|
|
|
444
476
|
this.refit();
|
|
445
477
|
this.resizeObserver = new ResizeObserver(() => this.refit());
|
|
446
478
|
this.resizeObserver.observe(host);
|
|
479
|
+
// An explicit focus() that arrived before the terminal existed is honoured now, once.
|
|
480
|
+
if (this.focusWhenReady) {
|
|
481
|
+
this.focusWhenReady = false;
|
|
482
|
+
terminal.focus();
|
|
483
|
+
}
|
|
447
484
|
this.readyResolve();
|
|
448
485
|
}
|
|
449
486
|
|
|
@@ -478,6 +515,9 @@ export class DeesTerminalView extends DeesElement {
|
|
|
478
515
|
// re-announce its grid and may retry a load that failed.
|
|
479
516
|
this.lastReportedSize = '';
|
|
480
517
|
this.setupPromise = undefined;
|
|
518
|
+
// A focus request belongs to the connection it was made in; a reattached element must not
|
|
519
|
+
// grab the caret from wherever the user moved it meanwhile.
|
|
520
|
+
this.focusWhenReady = false;
|
|
481
521
|
// Buffered output deliberately survives, so a replay that arrived while the
|
|
482
522
|
// element was detached still reaches the next connection.
|
|
483
523
|
if (this.readyPending) {
|
|
@@ -12,6 +12,7 @@ export * from './dees-harness-overflow-text.js';
|
|
|
12
12
|
export * from './dees-harness-chat/index.js';
|
|
13
13
|
export * from './dees-harness-composer/index.js';
|
|
14
14
|
export * from './dees-harness-content-blocks/index.js';
|
|
15
|
+
export * from './dees-harness-conversation-picker/index.js';
|
|
15
16
|
export * from './dees-harness-message/index.js';
|
|
16
17
|
export * from './dees-harness-permission-card/index.js';
|
|
17
18
|
export * from './dees-harness-question-card/index.js';
|
|
@@ -401,49 +401,66 @@ export interface IHarnessResourceMeta<TState extends string = string> {
|
|
|
401
401
|
}
|
|
402
402
|
|
|
403
403
|
/**
|
|
404
|
-
*
|
|
405
|
-
* other list item — a session or another resource such as a
|
|
404
|
+
* The controlled set of associations for one resource. A resource can be attached to several
|
|
405
|
+
* items at once, and a target is any other list item — a session or another resource such as a
|
|
406
|
+
* terminal. An empty array is an unattached resource.
|
|
406
407
|
*/
|
|
407
408
|
export interface IHarnessResourceAssociation {
|
|
408
409
|
resourceId: string;
|
|
409
|
-
|
|
410
|
+
targets: IHarnessSessionListItemRef[];
|
|
410
411
|
}
|
|
411
412
|
|
|
412
413
|
export interface IHarnessResourceEventDetail<TState extends string = string> {
|
|
413
414
|
resource: IHarnessResourceMeta<TState>;
|
|
414
|
-
/** The controlled association
|
|
415
|
-
|
|
415
|
+
/** The controlled association targets; empty when the resource is unattached. */
|
|
416
|
+
targets: IHarnessSessionListItemRef[];
|
|
416
417
|
}
|
|
417
418
|
|
|
418
419
|
/**
|
|
419
|
-
*
|
|
420
|
-
*
|
|
420
|
+
* Attaching is an explicit choice, never an accident of reordering: a drag only attaches when it
|
|
421
|
+
* is released on the centre of a row, and the edges of that same row stay positional. Keyboard
|
|
422
|
+
* moves are always positional; keyboard attaching goes through the host's menu.
|
|
421
423
|
*/
|
|
422
|
-
export type THarnessResourceAssociationInteractionSource = 'action' | 'keyboard';
|
|
424
|
+
export type THarnessResourceAssociationInteractionSource = 'action' | 'keyboard' | 'pointer';
|
|
423
425
|
|
|
424
|
-
|
|
426
|
+
/**
|
|
427
|
+
* A validated association request. `attach` adds the first target, `attach-additional` adds
|
|
428
|
+
* another one beside existing targets, `move` replaces one specific target, and `detach` removes
|
|
429
|
+
* one. `fromTarget` always names the attachment being replaced or removed, never the whole set.
|
|
430
|
+
*/
|
|
431
|
+
export type THarnessResourceAssociateDetail<TState extends string = string> =
|
|
425
432
|
| {
|
|
426
|
-
|
|
433
|
+
mode: 'attach';
|
|
427
434
|
resource: IHarnessResourceMeta<TState>;
|
|
428
435
|
fromTarget: null;
|
|
429
436
|
toTarget: IHarnessSessionListItemRef;
|
|
430
437
|
source: THarnessResourceAssociationInteractionSource;
|
|
431
438
|
}
|
|
432
439
|
| {
|
|
433
|
-
|
|
440
|
+
mode: 'attach-additional';
|
|
434
441
|
resource: IHarnessResourceMeta<TState>;
|
|
435
|
-
fromTarget:
|
|
436
|
-
toTarget:
|
|
442
|
+
fromTarget: null;
|
|
443
|
+
toTarget: IHarnessSessionListItemRef;
|
|
437
444
|
source: THarnessResourceAssociationInteractionSource;
|
|
438
445
|
}
|
|
439
446
|
| {
|
|
440
|
-
|
|
447
|
+
mode: 'move';
|
|
441
448
|
resource: IHarnessResourceMeta<TState>;
|
|
442
449
|
fromTarget: IHarnessSessionListItemRef;
|
|
443
450
|
toTarget: IHarnessSessionListItemRef;
|
|
444
451
|
source: THarnessResourceAssociationInteractionSource;
|
|
452
|
+
}
|
|
453
|
+
| {
|
|
454
|
+
mode: 'detach';
|
|
455
|
+
resource: IHarnessResourceMeta<TState>;
|
|
456
|
+
fromTarget: IHarnessSessionListItemRef;
|
|
457
|
+
toTarget: null;
|
|
458
|
+
source: THarnessResourceAssociationInteractionSource;
|
|
445
459
|
};
|
|
446
460
|
|
|
461
|
+
/** Explicit mode for `requestAssociation`; omitted lets the list infer it from the current set. */
|
|
462
|
+
export type THarnessResourceAssociateMode = THarnessResourceAssociateDetail['mode'];
|
|
463
|
+
|
|
447
464
|
export type THarnessResourceContextSource = 'pointer' | 'action' | 'keyboard';
|
|
448
465
|
|
|
449
466
|
/** Detail of `harness-resource-context`; the host owns the actual menu. */
|
|
@@ -453,8 +470,16 @@ export interface IHarnessResourceContextDetail<TState extends string = string>
|
|
|
453
470
|
clientY: number;
|
|
454
471
|
source: THarnessResourceContextSource;
|
|
455
472
|
originalEvent: MouseEvent | KeyboardEvent;
|
|
456
|
-
/**
|
|
457
|
-
|
|
473
|
+
/**
|
|
474
|
+
* Routes a host menu choice through the component's validated controlled request event. With no
|
|
475
|
+
* mode, an unattached resource attaches and a singly attached one moves; a resource with several
|
|
476
|
+
* attachments is refused, because only the host knows which attachment was meant.
|
|
477
|
+
*/
|
|
478
|
+
requestAssociation: (
|
|
479
|
+
toTarget: IHarnessSessionListItemRef | null,
|
|
480
|
+
mode?: THarnessResourceAssociateMode,
|
|
481
|
+
fromTarget?: IHarnessSessionListItemRef | null,
|
|
482
|
+
) => boolean;
|
|
458
483
|
/** Closes the external-menu disclosure state and restores focus to its invoking control. */
|
|
459
484
|
close: () => void;
|
|
460
485
|
}
|