@dorsk/tsumikit 0.77.0 → 0.78.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/components/layouts/AppShell.svelte +1 -0
- package/dist/components/layouts/NavBar.svelte +3 -0
- package/dist/components/molecules/Callout.svelte +5 -5
- package/dist/components/molecules/ChatBubble.svelte +4 -0
- package/dist/components/molecules/CodeBlock.svelte +7 -0
- package/dist/components/molecules/FilterInput.svelte +2 -1
- package/dist/components/molecules/StatusBar.svelte +2 -0
- package/dist/components/molecules/Truncate.svelte +21 -3
- package/dist/components/organisms/ConversationFeed.svelte +1 -0
- package/dist/components/organisms/FilterSearchBar.svelte +8 -2
- package/package.json +1 -1
|
@@ -90,19 +90,19 @@
|
|
|
90
90
|
gap: var(--sp-3);
|
|
91
91
|
padding: var(--sp-3);
|
|
92
92
|
}
|
|
93
|
-
:global(.callout-ok) {
|
|
93
|
+
:global(.card.callout-ok) {
|
|
94
94
|
--callout-tone: var(--ok);
|
|
95
95
|
}
|
|
96
|
-
:global(.callout-warn) {
|
|
96
|
+
:global(.card.callout-warn) {
|
|
97
97
|
--callout-tone: var(--warn);
|
|
98
98
|
}
|
|
99
|
-
:global(.callout-danger) {
|
|
99
|
+
:global(.card.callout-danger) {
|
|
100
100
|
--callout-tone: var(--danger);
|
|
101
101
|
}
|
|
102
|
-
:global(.callout-info) {
|
|
102
|
+
:global(.card.callout-info) {
|
|
103
103
|
--callout-tone: var(--info);
|
|
104
104
|
}
|
|
105
|
-
:global(.callout-accent) {
|
|
105
|
+
:global(.card.callout-accent) {
|
|
106
106
|
--callout-tone: var(--accent);
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -180,5 +180,9 @@
|
|
|
180
180
|
-webkit-line-clamp: var(--clamp);
|
|
181
181
|
line-clamp: var(--clamp);
|
|
182
182
|
overflow: hidden;
|
|
183
|
+
padding: calc(var(--focus-ring-width) + var(--focus-ring-offset));
|
|
184
|
+
padding-block-end: 0;
|
|
185
|
+
margin: calc(-1 * (var(--focus-ring-width) + var(--focus-ring-offset)));
|
|
186
|
+
margin-block-end: 0;
|
|
183
187
|
}
|
|
184
188
|
</style>
|
|
@@ -101,8 +101,15 @@
|
|
|
101
101
|
font-family: var(--font-mono);
|
|
102
102
|
color: var(--text-muted);
|
|
103
103
|
}
|
|
104
|
+
.cb-name {
|
|
105
|
+
min-width: 0;
|
|
106
|
+
overflow: hidden;
|
|
107
|
+
text-overflow: ellipsis;
|
|
108
|
+
white-space: nowrap;
|
|
109
|
+
}
|
|
104
110
|
.cb-body {
|
|
105
111
|
display: flex;
|
|
112
|
+
align-items: flex-start;
|
|
106
113
|
overflow: auto;
|
|
107
114
|
-webkit-overflow-scrolling: touch;
|
|
108
115
|
}
|
|
@@ -467,6 +467,7 @@
|
|
|
467
467
|
.fi__bar {
|
|
468
468
|
--fi-icon: var(--control-icon-md);
|
|
469
469
|
display: flex;
|
|
470
|
+
flex-wrap: wrap;
|
|
470
471
|
align-items: center;
|
|
471
472
|
gap: var(--sp-2);
|
|
472
473
|
padding: 0 var(--control-px-md);
|
|
@@ -522,7 +523,7 @@
|
|
|
522
523
|
position: relative;
|
|
523
524
|
display: flex;
|
|
524
525
|
flex: 1;
|
|
525
|
-
min-width:
|
|
526
|
+
min-width: min(100%, 6rem);
|
|
526
527
|
}
|
|
527
528
|
.fi__display {
|
|
528
529
|
position: absolute;
|
|
@@ -74,6 +74,8 @@
|
|
|
74
74
|
.status-label {
|
|
75
75
|
flex: 1;
|
|
76
76
|
min-width: 0;
|
|
77
|
+
padding-block: calc(var(--focus-ring-width) + var(--focus-ring-offset));
|
|
78
|
+
margin-block: calc(-1 * (var(--focus-ring-width) + var(--focus-ring-offset)));
|
|
77
79
|
overflow: hidden;
|
|
78
80
|
text-overflow: ellipsis;
|
|
79
81
|
white-space: nowrap;
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
// observed and the longest candidate that fits is shown (mode `path`
|
|
10
10
|
// abbreviates fish-style). `copyable` copies the full text on click.
|
|
11
11
|
import { copyToClipboard } from '../../clipboard';
|
|
12
|
+
import { untrack } from 'svelte';
|
|
12
13
|
import { pathCandidates, truncate, type TruncateMode } from '../../truncate';
|
|
13
14
|
import Tooltip from './Tooltip.svelte';
|
|
14
15
|
|
|
@@ -72,15 +73,18 @@
|
|
|
72
73
|
let probe = $state<HTMLSpanElement | null>(null);
|
|
73
74
|
let avail = $state(Number.POSITIVE_INFINITY);
|
|
74
75
|
let chPx = $state(8);
|
|
76
|
+
let cap = $state(Number.POSITIVE_INFINITY);
|
|
75
77
|
|
|
76
78
|
$effect(() => {
|
|
77
79
|
if (!fit || !rail) return;
|
|
78
80
|
const el = rail;
|
|
79
81
|
const measure = () => {
|
|
80
|
-
|
|
82
|
+
const w = el.clientWidth;
|
|
83
|
+
if (w > avail) cap = Number.POSITIVE_INFINITY;
|
|
84
|
+
avail = w;
|
|
81
85
|
if (probe) chPx = probe.getBoundingClientRect().width / 10 || chPx;
|
|
82
86
|
};
|
|
83
|
-
measure
|
|
87
|
+
untrack(measure);
|
|
84
88
|
const ro = new ResizeObserver(measure);
|
|
85
89
|
ro.observe(el);
|
|
86
90
|
return () => ro.disconnect();
|
|
@@ -88,7 +92,7 @@
|
|
|
88
92
|
|
|
89
93
|
const shown = $derived.by(() => {
|
|
90
94
|
if (fit) {
|
|
91
|
-
const budget = Math.max(0, avail - 1);
|
|
95
|
+
const budget = Math.max(0, Math.min(avail - 1, cap));
|
|
92
96
|
return candidates.find((c) => [...c].length * chPx <= budget) ?? candidates[candidates.length - 1];
|
|
93
97
|
}
|
|
94
98
|
if (max === undefined) return text;
|
|
@@ -96,6 +100,17 @@
|
|
|
96
100
|
});
|
|
97
101
|
const isTruncated = $derived(shown !== text);
|
|
98
102
|
|
|
103
|
+
// The per-character estimate can undershoot (glyph fallbacks, late fonts): cap the budget below the spilling candidate.
|
|
104
|
+
$effect(() => {
|
|
105
|
+
if (!fit || !rail || shown === candidates[candidates.length - 1]) return;
|
|
106
|
+
const el = rail;
|
|
107
|
+
const id = requestAnimationFrame(() => {
|
|
108
|
+
const over = el.scrollWidth - el.clientWidth;
|
|
109
|
+
if (over > 0) cap = Math.min(untrack(() => cap), [...shown].length * chPx - over);
|
|
110
|
+
});
|
|
111
|
+
return () => cancelAnimationFrame(id);
|
|
112
|
+
});
|
|
113
|
+
|
|
99
114
|
let status = $state('');
|
|
100
115
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
101
116
|
async function copy(e: MouseEvent) {
|
|
@@ -173,6 +188,9 @@
|
|
|
173
188
|
max-width: 100%;
|
|
174
189
|
overflow: hidden;
|
|
175
190
|
}
|
|
191
|
+
.rail .trunc:focus-visible {
|
|
192
|
+
outline-offset: var(--focus-ring-offset-inset);
|
|
193
|
+
}
|
|
176
194
|
.grow {
|
|
177
195
|
flex: 1 1 0;
|
|
178
196
|
}
|
|
@@ -97,14 +97,20 @@
|
|
|
97
97
|
{#if showChips && (chips.length || text)}
|
|
98
98
|
<div class="fsb__chips">
|
|
99
99
|
{#each chips as f (f.span[0])}
|
|
100
|
-
<Badge
|
|
100
|
+
<Badge
|
|
101
|
+
tone="info"
|
|
102
|
+
truncate
|
|
103
|
+
title="{labelFor(f.field)} {operatorById(f.op)?.label} {f.values.join(', ') || '∅'}"
|
|
104
|
+
removable
|
|
105
|
+
onremove={() => remove(f.span)}
|
|
106
|
+
>
|
|
101
107
|
<span class="fsb__chip-field">{labelFor(f.field)}</span>
|
|
102
108
|
<span class="fsb__chip-op">{operatorById(f.op)?.label}</span>
|
|
103
109
|
<span class="fsb__chip-val">{f.values.join(', ') || '∅'}</span>
|
|
104
110
|
</Badge>
|
|
105
111
|
{/each}
|
|
106
112
|
{#if text}
|
|
107
|
-
<Badge tone="neutral">
|
|
113
|
+
<Badge tone="neutral" truncate title="text {text}">
|
|
108
114
|
<span class="fsb__chip-op">text</span>
|
|
109
115
|
<span class="fsb__chip-val">{text}</span>
|
|
110
116
|
</Badge>
|
package/package.json
CHANGED