@joewinke/jatui 0.38.6 → 0.39.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/CLAUDE.md +31 -0
- package/THIRD_PARTY_NOTICES.md +51 -0
- package/dist/components/BulkActionBar.svelte +32 -2
- package/dist/components/BulkActionBar.svelte.d.ts +5 -1
- package/dist/components/FloatingActionBar.svelte +102 -34
- package/dist/components/FloatingActionBar.svelte.d.ts +9 -0
- package/dist/components/MediaExplorer.svelte +249 -0
- package/dist/components/MediaExplorer.svelte.d.ts +37 -0
- package/dist/components/NotificationCenter.svelte +481 -0
- package/dist/components/NotificationCenter.svelte.d.ts +29 -0
- package/dist/components/SearchDropdown.svelte +54 -8
- package/dist/components/SearchDropdown.svelte.d.ts +12 -0
- package/dist/components/agent/AgentLog.svelte +217 -0
- package/dist/components/agent/AgentLog.svelte.d.ts +72 -0
- package/dist/components/agent/AgentLogRow.svelte +281 -0
- package/dist/components/agent/AgentLogRow.svelte.d.ts +21 -0
- package/dist/components/agent/AgentTaskList.svelte +607 -0
- package/dist/components/agent/AgentTaskList.svelte.d.ts +40 -0
- package/dist/components/agent/AgentThinking.svelte +280 -0
- package/dist/components/agent/AgentThinking.svelte.d.ts +22 -0
- package/dist/components/agent/ComposerGlow.svelte +265 -0
- package/dist/components/agent/ComposerGlow.svelte.d.ts +18 -0
- package/dist/components/agent/ContextMeter.svelte +277 -0
- package/dist/components/agent/ContextMeter.svelte.d.ts +21 -0
- package/dist/components/agent/Questionnaire.svelte +767 -0
- package/dist/components/agent/Questionnaire.svelte.d.ts +29 -0
- package/dist/components/agent/ShimmerText.svelte +100 -0
- package/dist/components/agent/ShimmerText.svelte.d.ts +19 -0
- package/dist/components/agent/StreamedText.svelte +135 -0
- package/dist/components/agent/StreamedText.svelte.d.ts +13 -0
- package/dist/components/agent/agentLog.d.ts +22 -0
- package/dist/components/agent/agentLog.js +26 -0
- package/dist/components/agent/agentTaskList.d.ts +90 -0
- package/dist/components/agent/agentTaskList.js +93 -0
- package/dist/components/agent/agentThinking.d.ts +46 -0
- package/dist/components/agent/agentThinking.js +78 -0
- package/dist/components/agent/contextMeter.d.ts +97 -0
- package/dist/components/agent/contextMeter.js +156 -0
- package/dist/components/agent/questionnaire.d.ts +104 -0
- package/dist/components/agent/questionnaire.js +225 -0
- package/dist/components/agent/revealCore.d.ts +74 -0
- package/dist/components/agent/revealCore.js +160 -0
- package/dist/components/agent/revealTicker.d.ts +34 -0
- package/dist/components/agent/revealTicker.js +73 -0
- package/dist/components/agent/streamedText.d.ts +28 -0
- package/dist/components/agent/streamedText.js +59 -0
- package/dist/components/messaging/MessageInput.svelte +34 -4
- package/dist/components/messaging/MessageInput.svelte.d.ts +7 -0
- package/dist/components/messaging/MessageItem.svelte +2 -2
- package/dist/components/notificationCenter.d.ts +65 -0
- package/dist/components/notificationCenter.js +110 -0
- package/dist/components/progress/Steps.svelte +269 -5
- package/dist/components/progress/Steps.svelte.d.ts +16 -1
- package/dist/components/progress/stepsSummary.d.ts +14 -0
- package/dist/components/progress/stepsSummary.js +32 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +29 -0
- package/dist/selection/clickSelection.d.ts +89 -0
- package/dist/selection/clickSelection.js +152 -0
- package/dist/selection/createClickSelection.d.ts +79 -0
- package/dist/selection/createClickSelection.js +134 -0
- package/package.json +3 -2
|
@@ -1,4 +1,24 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Steps — a numbered step track with an animated connector fill.
|
|
3
|
+
|
|
4
|
+
Opt-in extras (jatui-lltq9; none of them change the default output):
|
|
5
|
+
collapsible a summary header button ("3 steps left") that folds the
|
|
6
|
+
track away; the summary stays live while folded, and the
|
|
7
|
+
folded header also shows the active step's label + ring.
|
|
8
|
+
activeProgress 0–1 → a mini ProgressRing on the active step's node.
|
|
9
|
+
orientation 'vertical' stacks the steps (labels + descriptions beside
|
|
10
|
+
the nodes) — the shape for agent-progress / todo cards.
|
|
11
|
+
onFinished fires once, `completionDelay` ms after `current` passes the
|
|
12
|
+
last step (re-arms if `current` drops back), so a host can
|
|
13
|
+
hand the surface back to the agent's answer.
|
|
14
|
+
Drive `current` from real events; there is no time-simulated stepping.
|
|
15
|
+
-->
|
|
1
16
|
<script lang="ts">
|
|
17
|
+
import { untrack, type Snippet } from 'svelte';
|
|
18
|
+
import ProgressRing from './ProgressRing.svelte';
|
|
19
|
+
import { motionSlide } from '../../motion/transitions';
|
|
20
|
+
import { clampStepProgress, isStepsFinished, stepsSummary } from './stepsSummary';
|
|
21
|
+
|
|
2
22
|
interface Step {
|
|
3
23
|
label?: string;
|
|
4
24
|
description?: string;
|
|
@@ -10,6 +30,20 @@
|
|
|
10
30
|
color?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info';
|
|
11
31
|
size?: 'sm' | 'md' | 'lg';
|
|
12
32
|
class?: string;
|
|
33
|
+
/** Render a summary header button that folds the steps away. */
|
|
34
|
+
collapsible?: boolean;
|
|
35
|
+
/** Folded state (bindable). Only meaningful with `collapsible`. */
|
|
36
|
+
collapsed?: boolean;
|
|
37
|
+
/** Header copy. Default: "N steps left" / "All steps done". */
|
|
38
|
+
summary?: string | Snippet;
|
|
39
|
+
/** Layout. Default 'horizontal'. */
|
|
40
|
+
orientation?: 'horizontal' | 'vertical';
|
|
41
|
+
/** 0–1 progress of the active step → a mini ring on its node. */
|
|
42
|
+
activeProgress?: number;
|
|
43
|
+
/** Hold (ms) after the last step completes before `onFinished`. Default 0. */
|
|
44
|
+
completionDelay?: number;
|
|
45
|
+
/** Fired once after `current` passes the last step (+ `completionDelay`). */
|
|
46
|
+
onFinished?: () => void;
|
|
13
47
|
}
|
|
14
48
|
|
|
15
49
|
let {
|
|
@@ -17,7 +51,14 @@
|
|
|
17
51
|
current = 1,
|
|
18
52
|
color = 'primary',
|
|
19
53
|
size = 'md',
|
|
20
|
-
class: className = ''
|
|
54
|
+
class: className = '',
|
|
55
|
+
collapsible = false,
|
|
56
|
+
collapsed = $bindable(false),
|
|
57
|
+
summary,
|
|
58
|
+
orientation = 'horizontal',
|
|
59
|
+
activeProgress,
|
|
60
|
+
completionDelay = 0,
|
|
61
|
+
onFinished
|
|
21
62
|
}: Props = $props();
|
|
22
63
|
|
|
23
64
|
const normalized = $derived(
|
|
@@ -53,17 +94,45 @@
|
|
|
53
94
|
const nodePx = $derived(nodeSize[size]);
|
|
54
95
|
const fontSize: Record<NonNullable<Props['size']>, string> = { sm: '0.6875rem', md: '0.8125rem', lg: '1rem' };
|
|
55
96
|
const labelSize = $derived(fontSize[size]);
|
|
97
|
+
|
|
98
|
+
// ── Opt-in extras ────────────────────────────────────────────────────
|
|
99
|
+
const uid = $props.id();
|
|
100
|
+
const bodyId = `steps-body-${uid}`;
|
|
101
|
+
const vertical = $derived(orientation === 'vertical');
|
|
102
|
+
const finished = $derived(isStepsFinished(count, current));
|
|
103
|
+
const ringValue = $derived(
|
|
104
|
+
activeProgress == null ? null : Math.round(clampStepProgress(activeProgress) * 100)
|
|
105
|
+
);
|
|
106
|
+
const summaryText = $derived(typeof summary === 'string' ? summary : stepsSummary(count, current));
|
|
107
|
+
const activeLabel = $derived(finished ? undefined : normalized[current - 1]?.label);
|
|
108
|
+
|
|
109
|
+
// onFinished: once per "run" — re-arms when current drops back to a step.
|
|
110
|
+
let finishedFired = false;
|
|
111
|
+
$effect(() => {
|
|
112
|
+
if (!finished) {
|
|
113
|
+
finishedFired = false;
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (finishedFired) return;
|
|
117
|
+
const delay = Math.max(0, completionDelay);
|
|
118
|
+
const timer = setTimeout(() => {
|
|
119
|
+
finishedFired = true;
|
|
120
|
+
untrack(() => onFinished)?.();
|
|
121
|
+
}, delay);
|
|
122
|
+
return () => clearTimeout(timer);
|
|
123
|
+
});
|
|
56
124
|
</script>
|
|
57
125
|
|
|
126
|
+
{#snippet track()}
|
|
58
127
|
<div
|
|
59
|
-
class="steps-wrap {className}"
|
|
128
|
+
class="steps-wrap {collapsible ? '' : className}{vertical ? ' steps-wrap--vertical' : ''}"
|
|
60
129
|
role="list"
|
|
61
130
|
aria-label="Progress steps"
|
|
62
131
|
style="--fill:{fillColor};--fg:{fgColor};--node:{nodePx}px"
|
|
63
132
|
>
|
|
64
133
|
<!-- Connector track -->
|
|
65
134
|
<div class="steps-track" aria-hidden="true">
|
|
66
|
-
<div class="steps-track-fill" style="transform:scaleX({trackFill})"></div>
|
|
135
|
+
<div class="steps-track-fill" style="transform:{vertical ? 'scaleY' : 'scaleX'}({trackFill})"></div>
|
|
67
136
|
</div>
|
|
68
137
|
|
|
69
138
|
<!-- Step nodes -->
|
|
@@ -78,7 +147,7 @@
|
|
|
78
147
|
role="listitem"
|
|
79
148
|
aria-current={isActive ? 'step' : undefined}
|
|
80
149
|
>
|
|
81
|
-
<div class="step-node" style="font-size:{labelSize}">
|
|
150
|
+
<div class="step-node" class:step-node--ring={isActive && ringValue != null} style="font-size:{labelSize}">
|
|
82
151
|
{#if isComplete}
|
|
83
152
|
<!-- Check mark drawn in on complete -->
|
|
84
153
|
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="step-check" aria-hidden="true">
|
|
@@ -86,14 +155,71 @@
|
|
|
86
155
|
</svg>
|
|
87
156
|
{:else}
|
|
88
157
|
<span>{stepNum}</span>
|
|
158
|
+
{/if}{#if isActive && ringValue != null}
|
|
159
|
+
<span class="step-ring">
|
|
160
|
+
<ProgressRing
|
|
161
|
+
value={ringValue}
|
|
162
|
+
size={nodePx}
|
|
163
|
+
strokeWidth={size === 'sm' ? 2 : 3}
|
|
164
|
+
{color}
|
|
165
|
+
showValue={false}
|
|
166
|
+
label="{step.label ?? `Step ${stepNum}`} progress"
|
|
167
|
+
/>
|
|
168
|
+
</span>
|
|
89
169
|
{/if}
|
|
90
170
|
</div>
|
|
91
|
-
{#if
|
|
171
|
+
{#if vertical}
|
|
172
|
+
{#if step.label || step.description}
|
|
173
|
+
<span class="step-text">
|
|
174
|
+
{#if step.label}<span class="step-label" style="font-size:{labelSize}">{step.label}</span>{/if}
|
|
175
|
+
{#if step.description}<span class="step-desc">{step.description}</span>{/if}
|
|
176
|
+
</span>
|
|
177
|
+
{/if}
|
|
178
|
+
{:else if step.label}
|
|
92
179
|
<span class="step-label" style="font-size:{labelSize}">{step.label}</span>
|
|
93
180
|
{/if}
|
|
94
181
|
</div>
|
|
95
182
|
{/each}
|
|
96
183
|
</div>
|
|
184
|
+
{/snippet}
|
|
185
|
+
|
|
186
|
+
{#if collapsible}
|
|
187
|
+
<div class="steps-fold {className}" style="--fill:{fillColor}">
|
|
188
|
+
<button
|
|
189
|
+
type="button"
|
|
190
|
+
class="steps-fold-header"
|
|
191
|
+
aria-expanded={!collapsed}
|
|
192
|
+
aria-controls={bodyId}
|
|
193
|
+
onclick={() => (collapsed = !collapsed)}
|
|
194
|
+
>
|
|
195
|
+
<svg class="steps-fold-chevron" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
196
|
+
<polyline points="6,4 10,8 6,12" />
|
|
197
|
+
</svg>
|
|
198
|
+
<span class="steps-fold-summary">
|
|
199
|
+
{#if typeof summary === 'function'}{@render summary()}{:else}{summaryText}{/if}
|
|
200
|
+
</span>
|
|
201
|
+
{#if collapsed && activeLabel}
|
|
202
|
+
<span class="steps-fold-current">{activeLabel}</span>
|
|
203
|
+
{/if}
|
|
204
|
+
{#if collapsed && ringValue != null && !finished}
|
|
205
|
+
<span class="steps-fold-ring" aria-hidden="true">
|
|
206
|
+
<ProgressRing value={ringValue} size={16} strokeWidth={2} {color} showValue={false} />
|
|
207
|
+
</span>
|
|
208
|
+
{/if}
|
|
209
|
+
</button>
|
|
210
|
+
<!-- Live summary for assistive tech — the header text itself is not a live region. -->
|
|
211
|
+
<span class="sr-only" aria-live="polite">{summaryText}</span>
|
|
212
|
+
<div id={bodyId} class="steps-fold-body">
|
|
213
|
+
{#if !collapsed}
|
|
214
|
+
<div class="steps-fold-inner" transition:motionSlide>
|
|
215
|
+
{@render track()}
|
|
216
|
+
</div>
|
|
217
|
+
{/if}
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
{:else}
|
|
221
|
+
{@render track()}
|
|
222
|
+
{/if}
|
|
97
223
|
|
|
98
224
|
<style>
|
|
99
225
|
.steps-wrap {
|
|
@@ -136,6 +262,7 @@
|
|
|
136
262
|
}
|
|
137
263
|
|
|
138
264
|
.step-node {
|
|
265
|
+
position: relative;
|
|
139
266
|
width: var(--node);
|
|
140
267
|
height: var(--node);
|
|
141
268
|
border-radius: 9999px;
|
|
@@ -160,6 +287,18 @@
|
|
|
160
287
|
transform: scale(1.18);
|
|
161
288
|
}
|
|
162
289
|
|
|
290
|
+
/* Active node with a progress ring: the ring IS the border. */
|
|
291
|
+
.step--active .step-node--ring {
|
|
292
|
+
border-color: transparent;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.step-ring {
|
|
296
|
+
position: absolute;
|
|
297
|
+
inset: -2px;
|
|
298
|
+
display: flex;
|
|
299
|
+
pointer-events: none;
|
|
300
|
+
}
|
|
301
|
+
|
|
163
302
|
.step--complete .step-node {
|
|
164
303
|
background: var(--fill);
|
|
165
304
|
border-color: var(--fill);
|
|
@@ -184,6 +323,127 @@
|
|
|
184
323
|
color: var(--color-base-content);
|
|
185
324
|
}
|
|
186
325
|
|
|
326
|
+
/* ── Vertical orientation ─────────────────────────────────────────── */
|
|
327
|
+
.steps-wrap--vertical {
|
|
328
|
+
flex-direction: column;
|
|
329
|
+
align-items: stretch;
|
|
330
|
+
justify-content: flex-start;
|
|
331
|
+
gap: 0.875rem;
|
|
332
|
+
padding-top: 0;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
.steps-wrap--vertical .steps-track {
|
|
336
|
+
top: calc(var(--node) / 2);
|
|
337
|
+
bottom: calc(var(--node) / 2);
|
|
338
|
+
left: calc(var(--node) / 2);
|
|
339
|
+
right: auto;
|
|
340
|
+
width: 3px;
|
|
341
|
+
height: auto;
|
|
342
|
+
transform: translateX(-50%);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
.steps-wrap--vertical .steps-track-fill {
|
|
346
|
+
width: 100%;
|
|
347
|
+
transform-origin: top;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
.steps-wrap--vertical .step {
|
|
351
|
+
flex-direction: row;
|
|
352
|
+
align-items: flex-start;
|
|
353
|
+
gap: 0.75rem;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
.steps-wrap--vertical .step-node {
|
|
357
|
+
flex-shrink: 0;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
.step-text {
|
|
361
|
+
display: flex;
|
|
362
|
+
flex-direction: column;
|
|
363
|
+
gap: 0.125rem;
|
|
364
|
+
min-width: 0;
|
|
365
|
+
min-height: var(--node);
|
|
366
|
+
justify-content: center;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
.steps-wrap--vertical .step-label {
|
|
370
|
+
text-align: left;
|
|
371
|
+
max-width: none;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
.step-desc {
|
|
375
|
+
font-size: 0.75rem;
|
|
376
|
+
line-height: 1.3;
|
|
377
|
+
color: color-mix(in oklch, var(--color-base-content) 55%, transparent);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* ── Collapsible header ───────────────────────────────────────────── */
|
|
381
|
+
.steps-fold {
|
|
382
|
+
width: 100%;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
.steps-fold-header {
|
|
386
|
+
display: flex;
|
|
387
|
+
align-items: center;
|
|
388
|
+
gap: 0.5rem;
|
|
389
|
+
width: 100%;
|
|
390
|
+
min-height: 2.25rem;
|
|
391
|
+
padding: 0.375rem 0.5rem;
|
|
392
|
+
border-radius: var(--jatui-radius-field, var(--radius-field, 0.25rem));
|
|
393
|
+
font-size: 0.875rem;
|
|
394
|
+
font-weight: 600;
|
|
395
|
+
text-align: left;
|
|
396
|
+
color: var(--color-base-content);
|
|
397
|
+
background: transparent;
|
|
398
|
+
cursor: pointer;
|
|
399
|
+
transition: background var(--motion-fast, 150ms) var(--motion-glide);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
.steps-fold-header:hover {
|
|
403
|
+
background: color-mix(in oklch, var(--color-base-content) 6%, transparent);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
.steps-fold-header:focus-visible {
|
|
407
|
+
outline: 2px solid var(--fill);
|
|
408
|
+
outline-offset: 2px;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
.steps-fold-chevron {
|
|
412
|
+
width: 1rem;
|
|
413
|
+
height: 1rem;
|
|
414
|
+
flex-shrink: 0;
|
|
415
|
+
color: color-mix(in oklch, var(--color-base-content) 55%, transparent);
|
|
416
|
+
transform: rotate(90deg);
|
|
417
|
+
transition: transform var(--motion-fast, 150ms) var(--motion-glide);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
.steps-fold-header[aria-expanded='false'] .steps-fold-chevron {
|
|
421
|
+
transform: rotate(0deg);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.steps-fold-summary {
|
|
425
|
+
font-variant-numeric: tabular-nums;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.steps-fold-current {
|
|
429
|
+
min-width: 0;
|
|
430
|
+
overflow: hidden;
|
|
431
|
+
text-overflow: ellipsis;
|
|
432
|
+
white-space: nowrap;
|
|
433
|
+
font-weight: 400;
|
|
434
|
+
color: color-mix(in oklch, var(--color-base-content) 60%, transparent);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
.steps-fold-ring {
|
|
438
|
+
display: inline-flex;
|
|
439
|
+
margin-left: auto;
|
|
440
|
+
flex-shrink: 0;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
.steps-fold-inner {
|
|
444
|
+
padding: 0.5rem 0.25rem 0.25rem;
|
|
445
|
+
}
|
|
446
|
+
|
|
187
447
|
@media (prefers-reduced-motion: reduce) {
|
|
188
448
|
.steps-track-fill {
|
|
189
449
|
transition: none;
|
|
@@ -191,5 +451,9 @@
|
|
|
191
451
|
.step-node {
|
|
192
452
|
transition: none;
|
|
193
453
|
}
|
|
454
|
+
.steps-fold-chevron,
|
|
455
|
+
.steps-fold-header {
|
|
456
|
+
transition: none;
|
|
457
|
+
}
|
|
194
458
|
}
|
|
195
459
|
</style>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Snippet } from 'svelte';
|
|
1
2
|
interface Step {
|
|
2
3
|
label?: string;
|
|
3
4
|
description?: string;
|
|
@@ -8,7 +9,21 @@ interface Props {
|
|
|
8
9
|
color?: 'primary' | 'secondary' | 'accent' | 'success' | 'warning' | 'error' | 'info';
|
|
9
10
|
size?: 'sm' | 'md' | 'lg';
|
|
10
11
|
class?: string;
|
|
12
|
+
/** Render a summary header button that folds the steps away. */
|
|
13
|
+
collapsible?: boolean;
|
|
14
|
+
/** Folded state (bindable). Only meaningful with `collapsible`. */
|
|
15
|
+
collapsed?: boolean;
|
|
16
|
+
/** Header copy. Default: "N steps left" / "All steps done". */
|
|
17
|
+
summary?: string | Snippet;
|
|
18
|
+
/** Layout. Default 'horizontal'. */
|
|
19
|
+
orientation?: 'horizontal' | 'vertical';
|
|
20
|
+
/** 0–1 progress of the active step → a mini ring on its node. */
|
|
21
|
+
activeProgress?: number;
|
|
22
|
+
/** Hold (ms) after the last step completes before `onFinished`. Default 0. */
|
|
23
|
+
completionDelay?: number;
|
|
24
|
+
/** Fired once after `current` passes the last step (+ `completionDelay`). */
|
|
25
|
+
onFinished?: () => void;
|
|
11
26
|
}
|
|
12
|
-
declare const Steps: import("svelte").Component<Props, {}, "">;
|
|
27
|
+
declare const Steps: import("svelte").Component<Props, {}, "collapsed">;
|
|
13
28
|
type Steps = ReturnType<typeof Steps>;
|
|
14
29
|
export default Steps;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers behind Steps' collapsible summary header (jatui-lltq9).
|
|
3
|
+
*
|
|
4
|
+
* `current` is Steps' 1-based active step: steps before it are complete, the
|
|
5
|
+
* step at it is in progress, and `current > count` means every step is done.
|
|
6
|
+
*/
|
|
7
|
+
/** Steps still to finish, counting the active one. Never negative. */
|
|
8
|
+
export declare function stepsRemaining(count: number, current: number): number;
|
|
9
|
+
/** True once `current` has moved past the last step. */
|
|
10
|
+
export declare function isStepsFinished(count: number, current: number): boolean;
|
|
11
|
+
/** Default header copy: "3 steps left", "1 step left", "All steps done". */
|
|
12
|
+
export declare function stepsSummary(count: number, current: number): string;
|
|
13
|
+
/** Clamp an active-step progress fraction to 0–1 (non-finite → 0). */
|
|
14
|
+
export declare function clampStepProgress(value: number): number;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers behind Steps' collapsible summary header (jatui-lltq9).
|
|
3
|
+
*
|
|
4
|
+
* `current` is Steps' 1-based active step: steps before it are complete, the
|
|
5
|
+
* step at it is in progress, and `current > count` means every step is done.
|
|
6
|
+
*/
|
|
7
|
+
/** Steps still to finish, counting the active one. Never negative. */
|
|
8
|
+
export function stepsRemaining(count, current) {
|
|
9
|
+
if (!Number.isFinite(count) || count <= 0)
|
|
10
|
+
return 0;
|
|
11
|
+
const done = Math.max(0, Math.min(count, Math.floor(current) - 1));
|
|
12
|
+
return count - done;
|
|
13
|
+
}
|
|
14
|
+
/** True once `current` has moved past the last step. */
|
|
15
|
+
export function isStepsFinished(count, current) {
|
|
16
|
+
return count > 0 && current > count;
|
|
17
|
+
}
|
|
18
|
+
/** Default header copy: "3 steps left", "1 step left", "All steps done". */
|
|
19
|
+
export function stepsSummary(count, current) {
|
|
20
|
+
if (!Number.isFinite(count) || count <= 0)
|
|
21
|
+
return 'No steps';
|
|
22
|
+
const left = stepsRemaining(count, current);
|
|
23
|
+
if (left === 0)
|
|
24
|
+
return 'All steps done';
|
|
25
|
+
return `${left} ${left === 1 ? 'step' : 'steps'} left`;
|
|
26
|
+
}
|
|
27
|
+
/** Clamp an active-step progress fraction to 0–1 (non-finite → 0). */
|
|
28
|
+
export function clampStepProgress(value) {
|
|
29
|
+
if (!Number.isFinite(value))
|
|
30
|
+
return 0;
|
|
31
|
+
return value < 0 ? 0 : value > 1 ? 1 : value;
|
|
32
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -57,6 +57,10 @@ export { default as InlineEdit } from './components/InlineEdit.svelte';
|
|
|
57
57
|
export { default as FloatingActionBar } from './components/FloatingActionBar.svelte';
|
|
58
58
|
export { default as BulkActionBar } from './components/BulkActionBar.svelte';
|
|
59
59
|
export type { BulkAction, BulkActionGroup } from './components/BulkActionBar.svelte';
|
|
60
|
+
export { createClickSelection } from './selection/createClickSelection';
|
|
61
|
+
export type { ClickSelection, ClickSelectionOptions, ClickSelectionKeyOptions } from './selection/createClickSelection';
|
|
62
|
+
export { applyClick as applySelectionClick, extendTo as extendSelectionTo, rangeBetween as selectionRange, selectionKey, isAdditive as isAdditiveClick } from './selection/clickSelection';
|
|
63
|
+
export type { SelectionModifiers, SelectionState, SelectionKeyEvent, SelectionKeyAction, ArrowKey as SelectionArrowKey } from './selection/clickSelection';
|
|
60
64
|
export { default as HunkDiffView } from './components/HunkDiffView.svelte';
|
|
61
65
|
export { default as Tooltip } from './components/Tooltip.svelte';
|
|
62
66
|
export { default as PresenceStack } from './components/PresenceStack.svelte';
|
|
@@ -205,6 +209,8 @@ export type { AttentionEffect, AttentionOptions } from './actions/attention';
|
|
|
205
209
|
export { reveal, REVEAL_HIDDEN_CLASS, REVEAL_BASE_CLASS, REVEAL_OFF_SELECTOR, REVEAL_MAX_DELAY_SECONDS } from './actions/reveal';
|
|
206
210
|
export type { RevealOptions, RevealVariant } from './actions/reveal';
|
|
207
211
|
export { default as ThumbnailGrid } from './components/ThumbnailGrid.svelte';
|
|
212
|
+
export { default as MediaExplorer } from "./components/MediaExplorer.svelte";
|
|
213
|
+
export type { ExplorerSource } from "./components/MediaExplorer.svelte";
|
|
208
214
|
export type { ThumbnailItem } from './components/ThumbnailGrid.svelte';
|
|
209
215
|
export { floating, makeVirtualAnchor } from './actions/floating';
|
|
210
216
|
export type { FloatingOptions, Placement } from './actions/floating';
|
|
@@ -304,3 +310,31 @@ export { mergeReviewCounts, summarizeReview, reviewSentence, buildReviewFilters,
|
|
|
304
310
|
export type { ReviewTone, ReviewVerdictDef, ReviewCounts, ReviewRound, ReviewFilterChip, ReviewSummary, BuildFiltersInput } from './components/review/reviewSummary';
|
|
305
311
|
export { MEDIA_ZOOM_KEYS, mediaZoomHint } from './components/review/mediaZoom';
|
|
306
312
|
export type { MediaZoomState, MediaZoomView, MediaZoomFooterContext, MediaZoomAction, MediaZoomKeyDef, MediaZoomKeyContext } from './components/review/mediaZoom';
|
|
313
|
+
export { default as ShimmerText } from './components/agent/ShimmerText.svelte';
|
|
314
|
+
export { default as AgentThinking } from './components/agent/AgentThinking.svelte';
|
|
315
|
+
export { formatThinkingTime } from './components/agent/agentThinking';
|
|
316
|
+
export type { AgentThinkingVariant, AgentThinkingTone } from './components/agent/agentThinking';
|
|
317
|
+
export { default as AgentLog } from './components/agent/AgentLog.svelte';
|
|
318
|
+
export { default as AgentLogRow } from './components/agent/AgentLogRow.svelte';
|
|
319
|
+
export { createRevealTicker } from './components/agent/revealTicker';
|
|
320
|
+
export type { RevealTickerOptions, RevealTicker } from './components/agent/revealTicker';
|
|
321
|
+
export { RevealCore, revealDelay, DEFAULT_STEP_INTERVAL as REVEAL_STEP_INTERVAL, DEFAULT_START_DELAY as REVEAL_START_DELAY } from './components/agent/revealCore';
|
|
322
|
+
export type { RevealCoreOptions, RevealClock, RevealCoreHooks } from './components/agent/revealCore';
|
|
323
|
+
export { BRANCH_Y as AGENT_LOG_BRANCH_Y } from './components/agent/agentLog';
|
|
324
|
+
export { default as AgentTaskList } from './components/agent/AgentTaskList.svelte';
|
|
325
|
+
export { countUnits as countAgentTaskUnits, layoutTaskReveal, displayStatus as agentTaskDisplayStatus, isListComplete as isAgentTaskListComplete, foldedByPolicy as agentTaskFoldedByPolicy, sourceStack as agentSourceStack, sourceDomain as agentSourceDomain, sourceLabel as agentSourceLabel } from './components/agent/agentTaskList';
|
|
326
|
+
export type { AgentTask, AgentTaskStep, AgentTaskChip, AgentTaskSource, AgentTaskStatus, CollapsePolicy as AgentTaskCollapsePolicy, TaskReveal } from './components/agent/agentTaskList';
|
|
327
|
+
export { default as Questionnaire } from './components/agent/Questionnaire.svelte';
|
|
328
|
+
export { emptyAnswers as emptyQuestionnaireAnswers, normalizeAnswers as normalizeQuestionnaireAnswers, finalizeAnswers as finalizeQuestionnaireAnswers, isComplete as isQuestionnaireComplete, isAnswered as isQuestionAnswered, digitToRow as questionnaireDigitToRow } from './components/agent/questionnaire';
|
|
329
|
+
export type { QuestionnaireQuestion, QuestionnaireOption, QuestionnaireAnswer, QuestionnaireAnswers } from './components/agent/questionnaire';
|
|
330
|
+
export { default as ContextMeter } from './components/agent/ContextMeter.svelte';
|
|
331
|
+
export { computeContextMeter, buildBreakdown as buildContextBreakdown, formatCompact as formatCompactTokens, formatPercent as formatContextPercent, segmentColor as contextSegmentColor, meterValueText as contextMeterValueText } from './components/agent/contextMeter';
|
|
332
|
+
export type { ContextSegment, ContextGroup, ContextTone, ContextMeterModel, MeterSegment as ContextMeterSegment, BreakdownRow as ContextBreakdownRow } from './components/agent/contextMeter';
|
|
333
|
+
export { default as ComposerGlow } from './components/agent/ComposerGlow.svelte';
|
|
334
|
+
export { default as StreamedText } from './components/agent/StreamedText.svelte';
|
|
335
|
+
export { splitStreamedText } from './components/agent/streamedText';
|
|
336
|
+
export type { StreamedBlock, StreamedTextSplit } from './components/agent/streamedText';
|
|
337
|
+
export { stepsSummary, stepsRemaining, isStepsFinished, clampStepProgress } from './components/progress/stepsSummary';
|
|
338
|
+
export { default as NotificationCenter } from './components/NotificationCenter.svelte';
|
|
339
|
+
export { DEFAULT_NOTIFICATION_TABS, DATE_GROUP_LABELS as NOTIFICATION_DATE_GROUP_LABELS, dateGroupKey as notificationDateGroupKey, groupNotificationsByDate, toTimestampMs as notificationTimestampMs, isNotificationUnread, unreadIds as unreadNotificationIds, filterByTab as filterNotificationsByTab, tabCounts as notificationTabCounts, unreadSummary as notificationUnreadSummary } from './components/notificationCenter';
|
|
340
|
+
export type { NotificationItem, NotificationAction, NotificationTab, NotificationStatus, NotificationGroup, DateGroupKey as NotificationDateGroupKey } from './components/notificationCenter';
|
package/dist/index.js
CHANGED
|
@@ -93,6 +93,12 @@ export { default as SortDropdown } from './components/SortDropdown.svelte';
|
|
|
93
93
|
export { default as InlineEdit } from './components/InlineEdit.svelte';
|
|
94
94
|
export { default as FloatingActionBar } from './components/FloatingActionBar.svelte';
|
|
95
95
|
export { default as BulkActionBar } from './components/BulkActionBar.svelte';
|
|
96
|
+
// Click selection (qimg-x9ifp.1): the pointer-first multi-selection that feeds
|
|
97
|
+
// BulkActionBar — click / Ctrl-⌘ click / Shift click ranges, Shift+arrows,
|
|
98
|
+
// Ctrl/⌘ A, Esc. Pure rules in selection/clickSelection.ts (unit-tested), a
|
|
99
|
+
// reactive SvelteSet controller in createClickSelection.svelte.ts.
|
|
100
|
+
export { createClickSelection } from './selection/createClickSelection';
|
|
101
|
+
export { applyClick as applySelectionClick, extendTo as extendSelectionTo, rangeBetween as selectionRange, selectionKey, isAdditive as isAdditiveClick } from './selection/clickSelection';
|
|
96
102
|
export { default as HunkDiffView } from './components/HunkDiffView.svelte';
|
|
97
103
|
// Primitives — accessibility + form-editor scaffolding
|
|
98
104
|
export { default as Tooltip } from './components/Tooltip.svelte';
|
|
@@ -248,6 +254,7 @@ export { reveal, REVEAL_HIDDEN_CLASS, REVEAL_BASE_CLASS, REVEAL_OFF_SELECTOR, RE
|
|
|
248
254
|
// Thumbnail grid (jatui-m4uz3.3, chimaro port): generic {id,url,alt} strip
|
|
249
255
|
// with overflow counter, remove/add affordances and a cell snippet override.
|
|
250
256
|
export { default as ThumbnailGrid } from './components/ThumbnailGrid.svelte';
|
|
257
|
+
export { default as MediaExplorer } from "./components/MediaExplorer.svelte";
|
|
251
258
|
export { floating, makeVirtualAnchor } from './actions/floating';
|
|
252
259
|
export { glide } from './transitions/glide';
|
|
253
260
|
// View Transitions kit
|
|
@@ -355,3 +362,25 @@ export { default as MediaZoomLightbox } from './components/review/MediaZoomLight
|
|
|
355
362
|
export { reviewKeys, createReviewKeys, reviewKeyRows, resolveReviewKey, REVIEW_KEY_TABLE } from './actions/reviewKeys';
|
|
356
363
|
export { mergeReviewCounts, summarizeReview, reviewSentence, buildReviewFilters, orderRounds, formatRoundDate } from './components/review/reviewSummary';
|
|
357
364
|
export { MEDIA_ZOOM_KEYS, mediaZoomHint } from './components/review/mediaZoom';
|
|
365
|
+
// Agent surfaces (BoardUI wave 2 — jatui-lltq9). Free BoardUI items are MIT
|
|
366
|
+
// (THIRD_PARTY_NOTICES.md); Task List / Questionnaire / ContextMeter are clean-room.
|
|
367
|
+
export { default as ShimmerText } from './components/agent/ShimmerText.svelte';
|
|
368
|
+
export { default as AgentThinking } from './components/agent/AgentThinking.svelte';
|
|
369
|
+
export { formatThinkingTime } from './components/agent/agentThinking';
|
|
370
|
+
export { default as AgentLog } from './components/agent/AgentLog.svelte';
|
|
371
|
+
export { default as AgentLogRow } from './components/agent/AgentLogRow.svelte';
|
|
372
|
+
export { createRevealTicker } from './components/agent/revealTicker';
|
|
373
|
+
export { RevealCore, revealDelay, DEFAULT_STEP_INTERVAL as REVEAL_STEP_INTERVAL, DEFAULT_START_DELAY as REVEAL_START_DELAY } from './components/agent/revealCore';
|
|
374
|
+
export { BRANCH_Y as AGENT_LOG_BRANCH_Y } from './components/agent/agentLog';
|
|
375
|
+
export { default as AgentTaskList } from './components/agent/AgentTaskList.svelte';
|
|
376
|
+
export { countUnits as countAgentTaskUnits, layoutTaskReveal, displayStatus as agentTaskDisplayStatus, isListComplete as isAgentTaskListComplete, foldedByPolicy as agentTaskFoldedByPolicy, sourceStack as agentSourceStack, sourceDomain as agentSourceDomain, sourceLabel as agentSourceLabel } from './components/agent/agentTaskList';
|
|
377
|
+
export { default as Questionnaire } from './components/agent/Questionnaire.svelte';
|
|
378
|
+
export { emptyAnswers as emptyQuestionnaireAnswers, normalizeAnswers as normalizeQuestionnaireAnswers, finalizeAnswers as finalizeQuestionnaireAnswers, isComplete as isQuestionnaireComplete, isAnswered as isQuestionAnswered, digitToRow as questionnaireDigitToRow } from './components/agent/questionnaire';
|
|
379
|
+
export { default as ContextMeter } from './components/agent/ContextMeter.svelte';
|
|
380
|
+
export { computeContextMeter, buildBreakdown as buildContextBreakdown, formatCompact as formatCompactTokens, formatPercent as formatContextPercent, segmentColor as contextSegmentColor, meterValueText as contextMeterValueText } from './components/agent/contextMeter';
|
|
381
|
+
export { default as ComposerGlow } from './components/agent/ComposerGlow.svelte';
|
|
382
|
+
export { default as StreamedText } from './components/agent/StreamedText.svelte';
|
|
383
|
+
export { splitStreamedText } from './components/agent/streamedText';
|
|
384
|
+
export { stepsSummary, stepsRemaining, isStepsFinished, clampStepProgress } from './components/progress/stepsSummary';
|
|
385
|
+
export { default as NotificationCenter } from './components/NotificationCenter.svelte';
|
|
386
|
+
export { DEFAULT_NOTIFICATION_TABS, DATE_GROUP_LABELS as NOTIFICATION_DATE_GROUP_LABELS, dateGroupKey as notificationDateGroupKey, groupNotificationsByDate, toTimestampMs as notificationTimestampMs, isNotificationUnread, unreadIds as unreadNotificationIds, filterByTab as filterNotificationsByTab, tabCounts as notificationTabCounts, unreadSummary as notificationUnreadSummary } from './components/notificationCenter';
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pointer-first multi-selection: the desktop-standard click rules, as pure
|
|
3
|
+
* functions over a plain `Set` (a `SvelteSet` is a `Set`, so the reactive
|
|
4
|
+
* controller in `createClickSelection.svelte.ts` runs exactly this code).
|
|
5
|
+
*
|
|
6
|
+
* click select only this one; it becomes the anchor
|
|
7
|
+
* Ctrl/⌘ click toggle this one; it becomes the anchor
|
|
8
|
+
* Shift click select the range anchor..this, in the current id order
|
|
9
|
+
* (replaces the selection; the anchor stays put)
|
|
10
|
+
* Shift Ctrl/⌘ add the range anchor..this to the selection
|
|
11
|
+
* Shift arrows extend from the anchor (the caller says which id an
|
|
12
|
+
* arrow lands on, because only it knows the layout)
|
|
13
|
+
* Ctrl/⌘ A select every id
|
|
14
|
+
* Esc clear
|
|
15
|
+
*
|
|
16
|
+
* The selection is a set of ids, not of positions: re-sorting, filtering or
|
|
17
|
+
* live inserts keep it, and an id that is no longer in `ids` is simply not
|
|
18
|
+
* selected any more (`prune` drops it, the readers filter it out first).
|
|
19
|
+
*
|
|
20
|
+
* `head` is the moving end of the last range (the last id clicked or
|
|
21
|
+
* extended to), so Shift+arrows keep growing from where they left off.
|
|
22
|
+
*
|
|
23
|
+
* No DOM, no Svelte: unit-tested in tests/unit/clickSelection.test.ts.
|
|
24
|
+
*/
|
|
25
|
+
/** The modifier keys of a click (a MouseEvent or KeyboardEvent satisfies it). */
|
|
26
|
+
export interface SelectionModifiers {
|
|
27
|
+
shiftKey?: boolean;
|
|
28
|
+
ctrlKey?: boolean;
|
|
29
|
+
metaKey?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** What a selection is: the set, plus the fixed and the moving end of a range. */
|
|
32
|
+
export interface SelectionState<Id = string> {
|
|
33
|
+
selected: Set<Id>;
|
|
34
|
+
anchor: Id | null;
|
|
35
|
+
head: Id | null;
|
|
36
|
+
}
|
|
37
|
+
/** Ctrl on Linux/Windows, ⌘ on macOS: either counts as "toggle / add". */
|
|
38
|
+
export declare const isAdditive: (m: SelectionModifiers) => boolean;
|
|
39
|
+
/** The ids from `a` to `b` inclusive, in `ids` order (either direction). Empty when either is missing. */
|
|
40
|
+
export declare function rangeBetween<Id>(ids: readonly Id[], a: Id, b: Id): Id[];
|
|
41
|
+
/** Select only `id` and make it the anchor (a plain click, or a plain arrow move). */
|
|
42
|
+
export declare function selectOnly<Id>(s: SelectionState<Id>, id: Id): void;
|
|
43
|
+
/** Toggle `id` and make it the anchor (Ctrl/⌘ click). */
|
|
44
|
+
export declare function toggleOne<Id>(s: SelectionState<Id>, id: Id): void;
|
|
45
|
+
/**
|
|
46
|
+
* Select the range from the anchor to `id` (Shift click / Shift arrows).
|
|
47
|
+
* `additive` keeps what was selected and adds the range (Shift+Ctrl/⌘).
|
|
48
|
+
* With no usable anchor (none yet, or it vanished) it behaves as a plain
|
|
49
|
+
* click on `id` (or a toggle-on when additive).
|
|
50
|
+
*/
|
|
51
|
+
export declare function extendTo<Id>(s: SelectionState<Id>, ids: readonly Id[], id: Id, additive?: boolean): void;
|
|
52
|
+
/** Apply one click on `id` with its modifiers. Ids not in `ids` are ignored. */
|
|
53
|
+
export declare function applyClick<Id>(s: SelectionState<Id>, ids: readonly Id[], id: Id, m?: SelectionModifiers): void;
|
|
54
|
+
/** Select every id (Ctrl/⌘ A). The anchor stays if it is still there, else the first id. */
|
|
55
|
+
export declare function selectAll<Id>(s: SelectionState<Id>, ids: readonly Id[]): void;
|
|
56
|
+
/** Clear the selection and the range ends (Esc). */
|
|
57
|
+
export declare function clearSelection<Id>(s: SelectionState<Id>): void;
|
|
58
|
+
/** Drop selected ids that are no longer in `ids` (and an anchor or head that vanished). True when anything changed. */
|
|
59
|
+
export declare function prune<Id>(s: SelectionState<Id>, ids: readonly Id[]): boolean;
|
|
60
|
+
/** The selected ids that are still present, in `ids` order (what a range or a list shows). */
|
|
61
|
+
export declare const inOrder: <Id>(selected: ReadonlySet<Id>, ids: readonly Id[]) => Id[];
|
|
62
|
+
/** The selected ids that are still present, in the order they were selected (Set insertion order). */
|
|
63
|
+
export declare function inPickOrder<Id>(selected: ReadonlySet<Id>, ids: readonly Id[]): Id[];
|
|
64
|
+
/** The keyboard part of a keydown (a KeyboardEvent satisfies it). */
|
|
65
|
+
export interface SelectionKeyEvent extends SelectionModifiers {
|
|
66
|
+
key: string;
|
|
67
|
+
altKey?: boolean;
|
|
68
|
+
target?: EventTarget | null;
|
|
69
|
+
defaultPrevented?: boolean;
|
|
70
|
+
}
|
|
71
|
+
export declare const ARROW_KEYS: readonly ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"];
|
|
72
|
+
export type ArrowKey = (typeof ARROW_KEYS)[number];
|
|
73
|
+
/** What a selection key does, decided without touching anything. */
|
|
74
|
+
export type SelectionKeyAction = {
|
|
75
|
+
kind: 'selectAll';
|
|
76
|
+
} | {
|
|
77
|
+
kind: 'clear';
|
|
78
|
+
} | {
|
|
79
|
+
kind: 'extend';
|
|
80
|
+
key: ArrowKey;
|
|
81
|
+
additive: boolean;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Which selection key this is, if any: Ctrl/⌘ A (select all), Esc (clear,
|
|
85
|
+
* only while something is selected, so Esc keeps its other meanings when
|
|
86
|
+
* nothing is), Shift+arrows (extend; with Ctrl/⌘ too, add the range).
|
|
87
|
+
* Never while typing in a field, never with Alt, never when already handled.
|
|
88
|
+
*/
|
|
89
|
+
export declare function selectionKey(e: SelectionKeyEvent, hasSelection: boolean): SelectionKeyAction | null;
|