@vobs/ui 0.2.0 → 1.0.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/LICENSE +1 -1
- package/README.md +60 -0
- package/package.json +52 -102
- package/src/activity-rail.ts +125 -0
- package/src/alert.ts +65 -0
- package/src/assets/icons/alert-circle.svg +1 -0
- package/src/assets/icons/alert-triangle.svg +1 -0
- package/src/assets/icons/alert.d27e24.svg +1 -0
- package/src/assets/icons/alert.svg +1 -0
- package/src/assets/icons/apple.svg +1 -0
- package/src/assets/icons/arrow-down.svg +1 -0
- package/src/assets/icons/arrow-expand.svg +1 -0
- package/src/assets/icons/arrow-left.svg +1 -0
- package/src/assets/icons/arrow-minimize.svg +1 -0
- package/src/assets/icons/arrow-right-to-line.svg +1 -0
- package/src/assets/icons/arrow-right.svg +1 -0
- package/src/assets/icons/arrow-up-right.svg +1 -0
- package/src/assets/icons/arrow-up.0c0c0d.svg +1 -0
- package/src/assets/icons/arrow-up.svg +1 -0
- package/src/assets/icons/at.svg +1 -0
- package/src/assets/icons/atom.0c0c0d.svg +1 -0
- package/src/assets/icons/atom.svg +1 -0
- package/src/assets/icons/bar.svg +1 -0
- package/src/assets/icons/bell.svg +1 -0
- package/src/assets/icons/box.svg +1 -0
- package/src/assets/icons/bug.svg +1 -0
- package/src/assets/icons/calendar.svg +1 -0
- package/src/assets/icons/check-circle.33c192.svg +1 -0
- package/src/assets/icons/check-circle.svg +1 -0
- package/src/assets/icons/check.d1d3db.svg +1 -0
- package/src/assets/icons/check.svg +1 -0
- package/src/assets/icons/chevron-down.svg +1 -0
- package/src/assets/icons/chevron-right.svg +1 -0
- package/src/assets/icons/chevron-up.svg +1 -0
- package/src/assets/icons/circle.svg +1 -0
- package/src/assets/icons/clock.svg +1 -0
- package/src/assets/icons/cmd.svg +1 -0
- package/src/assets/icons/code.svg +1 -0
- package/src/assets/icons/columns.svg +1 -0
- package/src/assets/icons/copy.svg +1 -0
- package/src/assets/icons/cpu.svg +1 -0
- package/src/assets/icons/dashboard.0c0c0d.svg +1 -0
- package/src/assets/icons/dashboard.svg +1 -0
- package/src/assets/icons/dollar.svg +1 -0
- package/src/assets/icons/download.svg +1 -0
- package/src/assets/icons/edit.svg +1 -0
- package/src/assets/icons/extensions.svg +1 -0
- package/src/assets/icons/external.svg +1 -0
- package/src/assets/icons/eye.svg +1 -0
- package/src/assets/icons/file-text.svg +1 -0
- package/src/assets/icons/file.svg +1 -0
- package/src/assets/icons/files.svg +1 -0
- package/src/assets/icons/filter.svg +1 -0
- package/src/assets/icons/folder.svg +1 -0
- package/src/assets/icons/gear.svg +1 -0
- package/src/assets/icons/git.svg +1 -0
- package/src/assets/icons/github.svg +1 -0
- package/src/assets/icons/globe.svg +1 -0
- package/src/assets/icons/grid-2x2.svg +1 -0
- package/src/assets/icons/hash.svg +1 -0
- package/src/assets/icons/heart.svg +1 -0
- package/src/assets/icons/help.svg +1 -0
- package/src/assets/icons/home.svg +1 -0
- package/src/assets/icons/image.svg +1 -0
- package/src/assets/icons/info-circle.svg +1 -0
- package/src/assets/icons/info-square.svg +1 -0
- package/src/assets/icons/info.387bff.svg +1 -0
- package/src/assets/icons/info.svg +1 -0
- package/src/assets/icons/key.svg +1 -0
- package/src/assets/icons/layers.svg +1 -0
- package/src/assets/icons/layout.svg +1 -0
- package/src/assets/icons/link.svg +1 -0
- package/src/assets/icons/list.svg +1 -0
- package/src/assets/icons/lock.svg +1 -0
- package/src/assets/icons/log-out.svg +1 -0
- package/src/assets/icons/logo.svg +1 -0
- package/src/assets/icons/mail.svg +1 -0
- package/src/assets/icons/menu.svg +1 -0
- package/src/assets/icons/message-circle.svg +1 -0
- package/src/assets/icons/message-plus.svg +1 -0
- package/src/assets/icons/message-square.svg +1 -0
- package/src/assets/icons/mic.svg +1 -0
- package/src/assets/icons/minus.svg +1 -0
- package/src/assets/icons/moon.svg +1 -0
- package/src/assets/icons/more-h.svg +1 -0
- package/src/assets/icons/mouse.svg +1 -0
- package/src/assets/icons/palette.svg +1 -0
- package/src/assets/icons/panel-bottom.svg +1 -0
- package/src/assets/icons/pause.svg +1 -0
- package/src/assets/icons/play.svg +1 -0
- package/src/assets/icons/plug.svg +1 -0
- package/src/assets/icons/plus.0c0c0d.svg +1 -0
- package/src/assets/icons/plus.svg +1 -0
- package/src/assets/icons/refresh.svg +1 -0
- package/src/assets/icons/ruler.svg +1 -0
- package/src/assets/icons/scroll-text.svg +1 -0
- package/src/assets/icons/search-menu.svg +1 -0
- package/src/assets/icons/search.svg +1 -0
- package/src/assets/icons/send.0c0c0d.svg +1 -0
- package/src/assets/icons/send.svg +1 -0
- package/src/assets/icons/settings.0c0c0d.svg +1 -0
- package/src/assets/icons/settings.svg +1 -0
- package/src/assets/icons/shield.svg +1 -0
- package/src/assets/icons/sidebar-left.svg +1 -0
- package/src/assets/icons/sidebar-right.svg +1 -0
- package/src/assets/icons/sliders.svg +1 -0
- package/src/assets/icons/sparkles.32f08c.svg +1 -0
- package/src/assets/icons/sparkles.svg +1 -0
- package/src/assets/icons/square.svg +1 -0
- package/src/assets/icons/star.svg +1 -0
- package/src/assets/icons/sun.svg +1 -0
- package/src/assets/icons/terminal.svg +1 -0
- package/src/assets/icons/trash.svg +1 -0
- package/src/assets/icons/trending-down.svg +1 -0
- package/src/assets/icons/trending-up.svg +1 -0
- package/src/assets/icons/type.svg +1 -0
- package/src/assets/icons/upload.svg +1 -0
- package/src/assets/icons/user-circle.svg +1 -0
- package/src/assets/icons/user.svg +1 -0
- package/src/assets/icons/users.svg +1 -0
- package/src/assets/icons/wrench.svg +1 -0
- package/src/assets/icons/x-circle.svg +1 -0
- package/src/assets/icons/x.svg +1 -0
- package/src/assets/icons/zap.0c0c0d.svg +1 -0
- package/src/assets/icons/zap.svg +1 -0
- package/src/avatar.ts +64 -0
- package/src/button.ts +88 -0
- package/src/card.ts +59 -0
- package/src/chat-composer.ts +156 -0
- package/src/dialog.ts +127 -0
- package/src/drawer.ts +131 -0
- package/src/editor-tabs.ts +184 -0
- package/src/file-tree.ts +214 -0
- package/src/forms.ts +270 -0
- package/src/icon.ts +117 -0
- package/src/icons.js +165 -0
- package/src/index.test.ts +213 -0
- package/src/index.ts +94 -0
- package/src/kbd.ts +72 -0
- package/src/menu.ts +119 -0
- package/src/nav-list.ts +157 -0
- package/src/overlay.test.ts +66 -0
- package/src/overlay.ts +205 -0
- package/src/page-header.ts +97 -0
- package/src/pagination.ts +163 -0
- package/src/second-batch.test.ts +205 -0
- package/src/stat-card.ts +92 -0
- package/src/status-bar.ts +108 -0
- package/src/styles/base.css +240 -0
- package/src/styles/components.css +1234 -0
- package/{dist → src/styles}/styles.css +2 -0
- package/src/styles/toast.css +57 -0
- package/src/styles/tokens.css +438 -0
- package/src/styles/vui.css +47 -0
- package/src/table.ts +191 -0
- package/src/tabs.ts +100 -0
- package/src/tag.ts +33 -0
- package/src/third-batch.test.ts +137 -0
- package/src/toast.test.ts +55 -0
- package/src/toast.ts +79 -0
- package/src/types.ts +25 -0
- package/src/utils.ts +221 -0
- package/src/workbench-titlebar.ts +137 -0
- package/dist/app-shell-dom.d.ts +0 -24
- package/dist/app-shell-dom.js +0 -573
- package/dist/app-shell.d.ts +0 -199
- package/dist/app-shell.js +0 -370
- package/dist/base.css +0 -52
- package/dist/calendar-picker.d.ts +0 -45
- package/dist/calendar-picker.js +0 -217
- package/dist/calendar.d.ts +0 -95
- package/dist/calendar.js +0 -194
- package/dist/complex-inputs.d.ts +0 -300
- package/dist/complex-inputs.js +0 -862
- package/dist/components.css +0 -4568
- package/dist/data-display.d.ts +0 -1063
- package/dist/data-display.js +0 -2298
- package/dist/feedback.d.ts +0 -88
- package/dist/feedback.js +0 -281
- package/dist/forms.d.ts +0 -378
- package/dist/forms.js +0 -1015
- package/dist/icons-config.d.ts +0 -25
- package/dist/icons-config.js +0 -14
- package/dist/icons.d.ts +0 -41
- package/dist/icons.js +0 -185
- package/dist/index.d.ts +0 -27
- package/dist/index.js +0 -34
- package/dist/locale/en-US.d.ts +0 -31
- package/dist/locale/en-US.js +0 -20
- package/dist/locale/zh-CN.d.ts +0 -31
- package/dist/locale/zh-CN.js +0 -20
- package/dist/navigation.d.ts +0 -609
- package/dist/navigation.js +0 -1707
- package/dist/overlay.d.ts +0 -304
- package/dist/overlay.js +0 -969
- package/dist/primitives.d.ts +0 -268
- package/dist/primitives.js +0 -764
- package/dist/theme-data.d.ts +0 -363
- package/dist/theme-data.js +0 -374
- package/dist/theme.d.ts +0 -79
- package/dist/theme.js +0 -262
- package/dist/tokens.css +0 -449
- package/dist/tree.d.ts +0 -144
- package/dist/tree.js +0 -469
- package/dist/virtual-list.d.ts +0 -190
- package/dist/virtual-list.js +0 -521
- package/dist/workbench.d.ts +0 -136
- package/dist/workbench.js +0 -156
package/dist/virtual-list.js
DELETED
|
@@ -1,521 +0,0 @@
|
|
|
1
|
-
/** @license MIT
|
|
2
|
-
* Copyright (c) 2026 vobsjs
|
|
3
|
-
* @vobs/ui
|
|
4
|
-
*/
|
|
5
|
-
import { Virtualizer, elementScroll } from '@tanstack/virtual-core';
|
|
6
|
-
import { createUiDomPlan } from './primitives.js';
|
|
7
|
-
export function createFixedVirtualListPlans(options) {
|
|
8
|
-
const state = calculateFixedVirtualListState(options);
|
|
9
|
-
return withVirtualListDomPlans(options, state);
|
|
10
|
-
}
|
|
11
|
-
export function createDynamicVirtualListPlans(options) {
|
|
12
|
-
const state = calculateDynamicVirtualListState(options);
|
|
13
|
-
return withVirtualListDomPlans(options, state);
|
|
14
|
-
}
|
|
15
|
-
export function createVirtualListLayoutPlans(options) {
|
|
16
|
-
const state = calculateVirtualListLayoutState(options);
|
|
17
|
-
return {
|
|
18
|
-
...state,
|
|
19
|
-
root: createUiDomPlan('div', 'virtual-list', {
|
|
20
|
-
...(options.className === undefined ? {} : { className: options.className }),
|
|
21
|
-
attrs: {
|
|
22
|
-
id: options.id,
|
|
23
|
-
role: options.layout === 'grid' ? 'grid' : 'list',
|
|
24
|
-
'aria-label': options.ariaLabel,
|
|
25
|
-
style: `width: ${options.viewportWidth}px; height: ${options.viewportHeight}px;${styleSuffix(options.attrs?.style)}`,
|
|
26
|
-
...options.attrs,
|
|
27
|
-
'data-layout': state.layout,
|
|
28
|
-
'data-count': options.items.length,
|
|
29
|
-
'data-row-count': state.rowCount,
|
|
30
|
-
'data-column-count': state.columnCount,
|
|
31
|
-
'data-window-start': state.visibleStartIndex,
|
|
32
|
-
'data-window-end': state.visibleEndIndex,
|
|
33
|
-
'data-window-row-start': state.visibleRowStart,
|
|
34
|
-
'data-window-row-end': state.visibleRowEnd,
|
|
35
|
-
'data-window-column-start': state.visibleColumnStart,
|
|
36
|
-
'data-window-column-end': state.visibleColumnEnd,
|
|
37
|
-
'data-scroll-left': state.scrollLeft,
|
|
38
|
-
'data-scroll-top': state.scrollTop,
|
|
39
|
-
'data-total-width': state.totalWidth,
|
|
40
|
-
'data-total-height': state.totalHeight,
|
|
41
|
-
'data-layout-contract': 'true',
|
|
42
|
-
},
|
|
43
|
-
}),
|
|
44
|
-
spacer: createUiDomPlan('div', 'virtual-list-spacer', {
|
|
45
|
-
attrs: { style: `width: ${state.totalWidth}px; height: ${state.totalHeight}px;` },
|
|
46
|
-
}),
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
export function calculateVirtualListLayoutState(options) {
|
|
50
|
-
const itemWidth = positiveNumber(options.itemWidth, 'itemWidth');
|
|
51
|
-
const itemHeight = positiveNumber(options.itemHeight, 'itemHeight');
|
|
52
|
-
const count = options.items.length;
|
|
53
|
-
const viewportWidth = Math.max(0, options.viewportWidth);
|
|
54
|
-
const viewportHeight = Math.max(0, options.viewportHeight);
|
|
55
|
-
const overscan = options.overscan ?? 2;
|
|
56
|
-
const columnCount = options.layout === 'horizontal'
|
|
57
|
-
? count
|
|
58
|
-
: Math.max(1, Math.trunc(options.columnCount ?? Math.max(1, Math.floor(viewportWidth / itemWidth))));
|
|
59
|
-
const rowCount = count === 0 ? 0 : Math.ceil(count / Math.max(1, columnCount));
|
|
60
|
-
const totalWidth = options.layout === 'horizontal' ? count * itemWidth : columnCount * itemWidth;
|
|
61
|
-
const totalHeight = options.layout === 'horizontal' ? itemHeight : rowCount * itemHeight;
|
|
62
|
-
const scrollLeft = clamp(options.scrollLeft ?? 0, 0, Math.max(totalWidth - viewportWidth, 0));
|
|
63
|
-
const scrollTop = clamp(options.scrollTop ?? 0, 0, Math.max(totalHeight - viewportHeight, 0));
|
|
64
|
-
if (count === 0) {
|
|
65
|
-
return createLayoutState(options, rowCount, columnCount, totalWidth, totalHeight, scrollLeft, scrollTop, 0, -1, 0, -1, []);
|
|
66
|
-
}
|
|
67
|
-
const visibleColumnStart = Math.max(0, Math.floor(scrollLeft / itemWidth));
|
|
68
|
-
const visibleColumnEnd = Math.min(Math.max(0, columnCount - 1), Math.ceil((scrollLeft + viewportWidth) / itemWidth));
|
|
69
|
-
const visibleRowStart = Math.max(0, Math.floor(scrollTop / itemHeight));
|
|
70
|
-
const visibleRowEnd = Math.min(Math.max(0, rowCount - 1), Math.ceil((scrollTop + viewportHeight) / itemHeight));
|
|
71
|
-
const ssrCount = options.ssrFallbackCount;
|
|
72
|
-
const rowStart = ssrCount === undefined ? Math.max(0, visibleRowStart - overscan) : 0;
|
|
73
|
-
const rowEnd = ssrCount === undefined
|
|
74
|
-
? Math.min(rowCount - 1, visibleRowEnd + overscan)
|
|
75
|
-
: Math.min(rowCount - 1, Math.ceil(Math.max(0, ssrCount) / columnCount) - 1);
|
|
76
|
-
const columnStart = ssrCount === undefined ? Math.max(0, visibleColumnStart - overscan) : 0;
|
|
77
|
-
const columnEnd = ssrCount === undefined
|
|
78
|
-
? Math.min(columnCount - 1, visibleColumnEnd + overscan)
|
|
79
|
-
: columnCount - 1;
|
|
80
|
-
const items = layoutRangeItems(options, itemWidth, itemHeight, columnCount, rowStart, rowEnd, columnStart, columnEnd).slice(0, ssrCount === undefined ? undefined : Math.max(0, ssrCount));
|
|
81
|
-
const first = items[0];
|
|
82
|
-
const last = items.at(-1);
|
|
83
|
-
return createLayoutState(options, rowCount, columnCount, totalWidth, totalHeight, scrollLeft, scrollTop, first?.index ?? 0, last?.index ?? -1, visibleRowStart, visibleRowEnd, items, visibleColumnStart, visibleColumnEnd);
|
|
84
|
-
}
|
|
85
|
-
export function createVirtualListResizeMeasurementContract(options) {
|
|
86
|
-
const measuredKeys = options.items
|
|
87
|
-
.map((item, index) => ({
|
|
88
|
-
key: keyFor(options, index),
|
|
89
|
-
height: options.getMeasuredItemHeight?.(item, index),
|
|
90
|
-
}))
|
|
91
|
-
.filter((entry) => entry.height !== undefined && Number.isFinite(entry.height) && entry.height > 0)
|
|
92
|
-
.map((entry) => entry.key);
|
|
93
|
-
const measuringKeys = uniqueKeys(options.measuringIds ?? []);
|
|
94
|
-
const plans = createDynamicVirtualListPlans(options.getMeasuredItemHeight === undefined
|
|
95
|
-
? options
|
|
96
|
-
: {
|
|
97
|
-
...options,
|
|
98
|
-
getItemHeight: options.getMeasuredItemHeight,
|
|
99
|
-
});
|
|
100
|
-
const estimatedKeys = options.items
|
|
101
|
-
.map((_, index) => keyFor(options, index))
|
|
102
|
-
.filter((key) => !measuredKeys.includes(key));
|
|
103
|
-
return {
|
|
104
|
-
plans,
|
|
105
|
-
measuredKeys,
|
|
106
|
-
measuringKeys,
|
|
107
|
-
estimatedKeys,
|
|
108
|
-
attrs: {
|
|
109
|
-
'data-resize-measurement-contract': 'true',
|
|
110
|
-
'data-measured-count': measuredKeys.length,
|
|
111
|
-
'data-estimated-count': estimatedKeys.length,
|
|
112
|
-
'data-measuring-count': measuringKeys.length,
|
|
113
|
-
'data-measured-keys': measuredKeys.join(','),
|
|
114
|
-
'data-estimated-keys': estimatedKeys.join(','),
|
|
115
|
-
'data-measuring-keys': measuringKeys.join(','),
|
|
116
|
-
'data-total-size': plans.totalSize,
|
|
117
|
-
'data-viewport-height': options.viewportHeight,
|
|
118
|
-
'data-scroll-offset': plans.scrollOffset,
|
|
119
|
-
'aria-busy': measuringKeys.length > 0 ? 'true' : undefined,
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
export function createVirtualListAnchorStateContract(options) {
|
|
124
|
-
const itemHeight = positiveNumber(options.itemHeight, 'itemHeight');
|
|
125
|
-
const previousAnchorIndex = findItemIndexByKey(options.previousItems, options.anchorKey, options.getKey);
|
|
126
|
-
const nextAnchorIndex = findItemIndexByKey(options.nextItems, options.anchorKey, options.getKey);
|
|
127
|
-
const anchorOffset = Math.max(0, options.anchorOffset ?? 0);
|
|
128
|
-
const viewportHeight = Math.max(0, options.viewportHeight ?? 0);
|
|
129
|
-
const maxOffset = Math.max(options.nextItems.length * itemHeight - viewportHeight, 0);
|
|
130
|
-
const anchorOffsetTarget = nextAnchorIndex < 0 ? 0 : nextAnchorIndex * itemHeight + anchorOffset;
|
|
131
|
-
const scrollOffset = options.stickToEnd === true ? maxOffset : clamp(anchorOffsetTarget, 0, maxOffset);
|
|
132
|
-
const insertedBeforeCount = previousAnchorIndex < 0 || nextAnchorIndex < 0
|
|
133
|
-
? 0
|
|
134
|
-
: Math.max(0, nextAnchorIndex - previousAnchorIndex);
|
|
135
|
-
const state = nextAnchorIndex < 0 ? 'missing-anchor' : options.stickToEnd === true ? 'end' : 'preserved';
|
|
136
|
-
return {
|
|
137
|
-
scrollOffset,
|
|
138
|
-
previousAnchorIndex,
|
|
139
|
-
nextAnchorIndex,
|
|
140
|
-
insertedBeforeCount,
|
|
141
|
-
attrs: {
|
|
142
|
-
'data-anchor-contract': 'true',
|
|
143
|
-
'data-anchor-mode': options.mode ?? 'preserve',
|
|
144
|
-
'data-anchor-state': state,
|
|
145
|
-
'data-anchor-key': String(options.anchorKey),
|
|
146
|
-
'data-previous-anchor-index': previousAnchorIndex,
|
|
147
|
-
'data-next-anchor-index': nextAnchorIndex,
|
|
148
|
-
'data-inserted-before-count': insertedBeforeCount,
|
|
149
|
-
'data-scroll-offset': scrollOffset,
|
|
150
|
-
'data-stick-to-end': options.stickToEnd === true ? 'true' : undefined,
|
|
151
|
-
},
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
export function calculateFixedVirtualListState(options) {
|
|
155
|
-
const itemHeight = positiveNumber(options.itemHeight, 'itemHeight');
|
|
156
|
-
const count = options.items.length;
|
|
157
|
-
if (count === 0)
|
|
158
|
-
return createState(options, itemHeight, 0, 0, -1, []);
|
|
159
|
-
const viewportHeight = Math.max(0, options.viewportHeight);
|
|
160
|
-
const scrollOffset = clamp(options.scrollOffset ?? 0, 0, Math.max(count * itemHeight - viewportHeight, 0));
|
|
161
|
-
const visibleStart = Math.floor(scrollOffset / itemHeight);
|
|
162
|
-
const visibleEnd = Math.min(count - 1, Math.ceil((scrollOffset + viewportHeight) / itemHeight));
|
|
163
|
-
const ssrCount = options.ssrFallbackCount;
|
|
164
|
-
const fallbackEnd = ssrCount === undefined ? visibleEnd : Math.min(count - 1, Math.max(0, ssrCount) - 1);
|
|
165
|
-
const start = ssrCount === undefined ? Math.max(0, visibleStart - (options.overscan ?? 2)) : 0;
|
|
166
|
-
const end = ssrCount === undefined
|
|
167
|
-
? Math.min(count - 1, visibleEnd + (options.overscan ?? 2))
|
|
168
|
-
: fallbackEnd;
|
|
169
|
-
return createState(options, itemHeight, scrollOffset, visibleStart, visibleEnd, rangeItems(options, start, end));
|
|
170
|
-
}
|
|
171
|
-
export function calculateDynamicVirtualListState(options) {
|
|
172
|
-
const estimatedItemHeight = positiveNumber(options.estimatedItemHeight, 'estimatedItemHeight');
|
|
173
|
-
const count = options.items.length;
|
|
174
|
-
if (count === 0) {
|
|
175
|
-
return createDynamicState(options, 0, 0, 0, -1, 0, []);
|
|
176
|
-
}
|
|
177
|
-
const metrics = dynamicItemMetrics(options, estimatedItemHeight);
|
|
178
|
-
const totalSize = metrics.at(-1)?.end ?? 0;
|
|
179
|
-
const viewportHeight = Math.max(0, options.viewportHeight);
|
|
180
|
-
const scrollOffset = clamp(options.scrollOffset ?? 0, 0, Math.max(totalSize - viewportHeight, 0));
|
|
181
|
-
const visibleStart = firstDynamicIndexAfter(metrics, scrollOffset);
|
|
182
|
-
const visibleEnd = lastDynamicIndexBefore(metrics, scrollOffset + viewportHeight);
|
|
183
|
-
const ssrCount = options.ssrFallbackCount;
|
|
184
|
-
const fallbackEnd = ssrCount === undefined ? visibleEnd : Math.min(count - 1, Math.max(0, ssrCount) - 1);
|
|
185
|
-
const start = ssrCount === undefined ? Math.max(0, visibleStart - (options.overscan ?? 2)) : 0;
|
|
186
|
-
const end = ssrCount === undefined
|
|
187
|
-
? Math.min(count - 1, visibleEnd + (options.overscan ?? 2))
|
|
188
|
-
: fallbackEnd;
|
|
189
|
-
return createDynamicState(options, totalSize, scrollOffset, visibleStart, visibleEnd, metrics.filter((metric) => metric.measured).length, dynamicRangeItems(options, metrics, start, end));
|
|
190
|
-
}
|
|
191
|
-
export function createFixedVirtualListController(options) {
|
|
192
|
-
let current = normalizeControllerOptions(options);
|
|
193
|
-
let disposed = false;
|
|
194
|
-
const virtualizer = new Virtualizer({
|
|
195
|
-
count: current.items.length,
|
|
196
|
-
getScrollElement: current.getScrollElement,
|
|
197
|
-
estimateSize: () => current.itemHeight,
|
|
198
|
-
scrollToFn: elementScroll,
|
|
199
|
-
observeElementRect: (instance, callback) => {
|
|
200
|
-
const element = instance.scrollElement;
|
|
201
|
-
if (element === null)
|
|
202
|
-
return undefined;
|
|
203
|
-
callback({
|
|
204
|
-
width: element.clientWidth,
|
|
205
|
-
height: element.clientHeight || current.viewportHeight,
|
|
206
|
-
});
|
|
207
|
-
return undefined;
|
|
208
|
-
},
|
|
209
|
-
observeElementOffset: (instance, callback) => {
|
|
210
|
-
const element = instance.scrollElement;
|
|
211
|
-
if (element === null)
|
|
212
|
-
return undefined;
|
|
213
|
-
let frame = 0;
|
|
214
|
-
let first = true;
|
|
215
|
-
const readOffset = () => {
|
|
216
|
-
if (first && element.scrollTop === 0 && current.initialOffset > 0)
|
|
217
|
-
return current.initialOffset;
|
|
218
|
-
return element.scrollTop;
|
|
219
|
-
};
|
|
220
|
-
const emit = (scrolling) => {
|
|
221
|
-
if (frame !== 0)
|
|
222
|
-
return;
|
|
223
|
-
frame = requestFrame(() => {
|
|
224
|
-
frame = 0;
|
|
225
|
-
first = false;
|
|
226
|
-
callback(readOffset(), scrolling);
|
|
227
|
-
});
|
|
228
|
-
};
|
|
229
|
-
const onScroll = () => emit(true);
|
|
230
|
-
element.addEventListener('scroll', onScroll, { passive: true });
|
|
231
|
-
callback(readOffset(), false);
|
|
232
|
-
first = false;
|
|
233
|
-
return () => {
|
|
234
|
-
if (frame !== 0)
|
|
235
|
-
cancelFrame(frame);
|
|
236
|
-
element.removeEventListener('scroll', onScroll);
|
|
237
|
-
};
|
|
238
|
-
},
|
|
239
|
-
getItemKey: (index) => keyFor(current, index),
|
|
240
|
-
overscan: current.overscan,
|
|
241
|
-
initialOffset: current.initialOffset,
|
|
242
|
-
initialRect: { width: 0, height: current.viewportHeight },
|
|
243
|
-
anchorTo: 'start',
|
|
244
|
-
onChange: (instance, sync) => {
|
|
245
|
-
current.onChange?.(stateFromVirtualizer(current, instance), sync);
|
|
246
|
-
},
|
|
247
|
-
});
|
|
248
|
-
const cleanup = virtualizer._didMount();
|
|
249
|
-
virtualizer._willUpdate();
|
|
250
|
-
return {
|
|
251
|
-
read() {
|
|
252
|
-
return withVirtualListDomPlans(current, stateFromVirtualizer(current, virtualizer));
|
|
253
|
-
},
|
|
254
|
-
update(next) {
|
|
255
|
-
if (disposed)
|
|
256
|
-
return;
|
|
257
|
-
current = normalizeControllerOptions({ ...current, ...next });
|
|
258
|
-
virtualizer.setOptions({
|
|
259
|
-
...virtualizer.options,
|
|
260
|
-
count: current.items.length,
|
|
261
|
-
overscan: current.overscan,
|
|
262
|
-
});
|
|
263
|
-
virtualizer._willUpdate();
|
|
264
|
-
},
|
|
265
|
-
scrollToOffset(offset) {
|
|
266
|
-
if (!disposed)
|
|
267
|
-
virtualizer.scrollToOffset(offset);
|
|
268
|
-
},
|
|
269
|
-
scrollToIndex(index) {
|
|
270
|
-
if (!disposed)
|
|
271
|
-
virtualizer.scrollToIndex(index);
|
|
272
|
-
},
|
|
273
|
-
takeScrollState() {
|
|
274
|
-
const state = stateFromVirtualizer(current, virtualizer);
|
|
275
|
-
return {
|
|
276
|
-
scrollOffset: state.scrollOffset,
|
|
277
|
-
visibleStartIndex: state.visibleStartIndex,
|
|
278
|
-
visibleEndIndex: state.visibleEndIndex,
|
|
279
|
-
};
|
|
280
|
-
},
|
|
281
|
-
destroy() {
|
|
282
|
-
if (disposed)
|
|
283
|
-
return;
|
|
284
|
-
disposed = true;
|
|
285
|
-
cleanup();
|
|
286
|
-
},
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
function stateFromVirtualizer(options, virtualizer) {
|
|
290
|
-
const items = virtualizer
|
|
291
|
-
.getVirtualItems()
|
|
292
|
-
.map((virtualItem) => itemFromRange(options, virtualItem.index, virtualItem.start, virtualItem.size));
|
|
293
|
-
const first = items[0];
|
|
294
|
-
const last = items.at(-1);
|
|
295
|
-
return createState(options, options.itemHeight, virtualizer.scrollOffset ?? 0, first?.index ?? 0, last?.index ?? -1, items);
|
|
296
|
-
}
|
|
297
|
-
function withVirtualListDomPlans(options, state) {
|
|
298
|
-
return {
|
|
299
|
-
...state,
|
|
300
|
-
root: createUiDomPlan('div', 'virtual-list', {
|
|
301
|
-
...(options.className === undefined ? {} : { className: options.className }),
|
|
302
|
-
attrs: {
|
|
303
|
-
id: options.id,
|
|
304
|
-
role: 'list',
|
|
305
|
-
'aria-label': options.ariaLabel,
|
|
306
|
-
style: `height: ${options.viewportHeight}px;${styleSuffix(options.attrs?.style)}`,
|
|
307
|
-
...options.attrs,
|
|
308
|
-
'data-count': options.items.length,
|
|
309
|
-
'data-window-start': state.visibleStartIndex,
|
|
310
|
-
'data-window-end': state.visibleEndIndex,
|
|
311
|
-
'data-dynamic': 'estimatedItemHeight' in options ? 'true' : undefined,
|
|
312
|
-
'data-measured-count': 'measuredCount' in state ? state.measuredCount : undefined,
|
|
313
|
-
},
|
|
314
|
-
}),
|
|
315
|
-
spacer: createUiDomPlan('div', 'virtual-list-spacer', {
|
|
316
|
-
attrs: { style: `height: ${state.totalSize}px;` },
|
|
317
|
-
}),
|
|
318
|
-
};
|
|
319
|
-
}
|
|
320
|
-
function createState(options, itemHeight, scrollOffset, visibleStartIndex, visibleEndIndex, items) {
|
|
321
|
-
return {
|
|
322
|
-
totalSize: options.items.length * itemHeight,
|
|
323
|
-
scrollOffset,
|
|
324
|
-
visibleStartIndex,
|
|
325
|
-
visibleEndIndex,
|
|
326
|
-
items,
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
function rangeItems(options, startIndex, endIndex) {
|
|
330
|
-
const result = [];
|
|
331
|
-
for (let index = startIndex; index <= endIndex; index++) {
|
|
332
|
-
result.push(itemFromRange(options, index, index * options.itemHeight, options.itemHeight));
|
|
333
|
-
}
|
|
334
|
-
return result;
|
|
335
|
-
}
|
|
336
|
-
function itemFromRange(options, index, start, size) {
|
|
337
|
-
return {
|
|
338
|
-
key: keyFor(options, index),
|
|
339
|
-
index,
|
|
340
|
-
item: options.items[index],
|
|
341
|
-
start,
|
|
342
|
-
size,
|
|
343
|
-
end: start + size,
|
|
344
|
-
plan: createUiDomPlan('div', 'virtual-list-item', {
|
|
345
|
-
attrs: {
|
|
346
|
-
role: 'listitem',
|
|
347
|
-
'aria-posinset': index + 1,
|
|
348
|
-
'aria-setsize': options.items.length,
|
|
349
|
-
'data-index': index,
|
|
350
|
-
'data-key': String(keyFor(options, index)),
|
|
351
|
-
style: `height: ${size}px; transform: translateY(${start}px);`,
|
|
352
|
-
},
|
|
353
|
-
}),
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
function createDynamicState(options, totalSize, scrollOffset, visibleStartIndex, visibleEndIndex, measuredCount, items) {
|
|
357
|
-
return {
|
|
358
|
-
totalSize,
|
|
359
|
-
scrollOffset,
|
|
360
|
-
visibleStartIndex,
|
|
361
|
-
visibleEndIndex,
|
|
362
|
-
measuredCount,
|
|
363
|
-
items,
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
function dynamicRangeItems(options, metrics, startIndex, endIndex) {
|
|
367
|
-
const result = [];
|
|
368
|
-
for (let index = startIndex; index <= endIndex; index++) {
|
|
369
|
-
const metric = metrics[index];
|
|
370
|
-
if (metric === undefined)
|
|
371
|
-
continue;
|
|
372
|
-
result.push(dynamicItemFromMetric(options, index, metric));
|
|
373
|
-
}
|
|
374
|
-
return result;
|
|
375
|
-
}
|
|
376
|
-
function dynamicItemFromMetric(options, index, metric) {
|
|
377
|
-
return {
|
|
378
|
-
key: keyFor(options, index),
|
|
379
|
-
index,
|
|
380
|
-
item: options.items[index],
|
|
381
|
-
start: metric.start,
|
|
382
|
-
size: metric.size,
|
|
383
|
-
measured: metric.measured,
|
|
384
|
-
end: metric.end,
|
|
385
|
-
plan: createUiDomPlan('div', 'virtual-list-item', {
|
|
386
|
-
attrs: {
|
|
387
|
-
role: 'listitem',
|
|
388
|
-
'aria-posinset': index + 1,
|
|
389
|
-
'aria-setsize': options.items.length,
|
|
390
|
-
'data-index': index,
|
|
391
|
-
'data-key': String(keyFor(options, index)),
|
|
392
|
-
'data-measured': metric.measured ? 'true' : 'false',
|
|
393
|
-
style: `height: ${metric.size}px; transform: translateY(${metric.start}px);`,
|
|
394
|
-
},
|
|
395
|
-
}),
|
|
396
|
-
};
|
|
397
|
-
}
|
|
398
|
-
function dynamicItemMetrics(options, estimatedItemHeight) {
|
|
399
|
-
const metrics = [];
|
|
400
|
-
let start = 0;
|
|
401
|
-
for (let index = 0; index < options.items.length; index++) {
|
|
402
|
-
const measuredHeight = options.getItemHeight?.(options.items[index], index);
|
|
403
|
-
const measured = measuredHeight !== undefined && Number.isFinite(measuredHeight) && measuredHeight > 0;
|
|
404
|
-
const size = measured ? measuredHeight : estimatedItemHeight;
|
|
405
|
-
metrics.push({ start, size, measured, end: start + size });
|
|
406
|
-
start += size;
|
|
407
|
-
}
|
|
408
|
-
return metrics;
|
|
409
|
-
}
|
|
410
|
-
function createLayoutState(options, rowCount, columnCount, totalWidth, totalHeight, scrollLeft, scrollTop, visibleStartIndex, visibleEndIndex, visibleRowStart, visibleRowEnd, items, visibleColumnStart = 0, visibleColumnEnd = -1) {
|
|
411
|
-
return {
|
|
412
|
-
layout: options.layout,
|
|
413
|
-
rowCount,
|
|
414
|
-
columnCount,
|
|
415
|
-
totalWidth,
|
|
416
|
-
totalHeight,
|
|
417
|
-
scrollLeft,
|
|
418
|
-
scrollTop,
|
|
419
|
-
visibleStartIndex,
|
|
420
|
-
visibleEndIndex,
|
|
421
|
-
visibleRowStart,
|
|
422
|
-
visibleRowEnd,
|
|
423
|
-
visibleColumnStart,
|
|
424
|
-
visibleColumnEnd,
|
|
425
|
-
items,
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
function layoutRangeItems(options, itemWidth, itemHeight, columnCount, rowStart, rowEnd, columnStart, columnEnd) {
|
|
429
|
-
const result = [];
|
|
430
|
-
for (let rowIndex = rowStart; rowIndex <= rowEnd; rowIndex++) {
|
|
431
|
-
for (let columnIndex = columnStart; columnIndex <= columnEnd; columnIndex++) {
|
|
432
|
-
const index = rowIndex * columnCount + columnIndex;
|
|
433
|
-
if (index >= options.items.length)
|
|
434
|
-
continue;
|
|
435
|
-
result.push(layoutItemFromRange(options, index, rowIndex, columnIndex, itemWidth, itemHeight));
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return result;
|
|
439
|
-
}
|
|
440
|
-
function layoutItemFromRange(options, index, rowIndex, columnIndex, width, height) {
|
|
441
|
-
const x = columnIndex * width;
|
|
442
|
-
const y = rowIndex * height;
|
|
443
|
-
const key = keyFor(options, index);
|
|
444
|
-
return {
|
|
445
|
-
key,
|
|
446
|
-
index,
|
|
447
|
-
item: options.items[index],
|
|
448
|
-
rowIndex,
|
|
449
|
-
columnIndex,
|
|
450
|
-
x,
|
|
451
|
-
y,
|
|
452
|
-
width,
|
|
453
|
-
height,
|
|
454
|
-
plan: createUiDomPlan('div', 'virtual-list-item', {
|
|
455
|
-
attrs: {
|
|
456
|
-
role: options.layout === 'grid' ? 'gridcell' : 'listitem',
|
|
457
|
-
'aria-posinset': options.layout === 'horizontal' ? index + 1 : undefined,
|
|
458
|
-
'aria-setsize': options.layout === 'horizontal' ? options.items.length : undefined,
|
|
459
|
-
'aria-rowindex': options.layout === 'grid' ? rowIndex + 1 : undefined,
|
|
460
|
-
'aria-colindex': options.layout === 'grid' ? columnIndex + 1 : undefined,
|
|
461
|
-
'data-index': index,
|
|
462
|
-
'data-key': String(key),
|
|
463
|
-
'data-row-index': rowIndex,
|
|
464
|
-
'data-column-index': columnIndex,
|
|
465
|
-
style: `width: ${width}px; height: ${height}px; transform: translate(${x}px, ${y}px);`,
|
|
466
|
-
},
|
|
467
|
-
}),
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
function firstDynamicIndexAfter(metrics, offset) {
|
|
471
|
-
const index = metrics.findIndex((metric) => metric.end > offset);
|
|
472
|
-
return index === -1 ? Math.max(0, metrics.length - 1) : index;
|
|
473
|
-
}
|
|
474
|
-
function lastDynamicIndexBefore(metrics, offset) {
|
|
475
|
-
const index = metrics.findIndex((metric) => metric.start >= offset);
|
|
476
|
-
if (index === -1)
|
|
477
|
-
return metrics.length - 1;
|
|
478
|
-
return Math.max(0, index);
|
|
479
|
-
}
|
|
480
|
-
function normalizeControllerOptions(options) {
|
|
481
|
-
return {
|
|
482
|
-
...options,
|
|
483
|
-
itemHeight: positiveNumber(options.itemHeight, 'itemHeight'),
|
|
484
|
-
viewportHeight: options.viewportHeight ?? 0,
|
|
485
|
-
overscan: options.overscan ?? 2,
|
|
486
|
-
initialOffset: options.initialOffset ?? 0,
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
function keyFor(options, index) {
|
|
490
|
-
return options.getKey?.(options.items[index], index) ?? index;
|
|
491
|
-
}
|
|
492
|
-
function findItemIndexByKey(items, key, getKey) {
|
|
493
|
-
return items.findIndex((item, index) => (getKey?.(item, index) ?? index) === key);
|
|
494
|
-
}
|
|
495
|
-
function uniqueKeys(keys) {
|
|
496
|
-
return [...new Set(keys)];
|
|
497
|
-
}
|
|
498
|
-
function positiveNumber(value, name) {
|
|
499
|
-
if (!Number.isFinite(value) || value <= 0)
|
|
500
|
-
throw new Error(`${name} must be a positive number`);
|
|
501
|
-
return value;
|
|
502
|
-
}
|
|
503
|
-
function clamp(value, min, max) {
|
|
504
|
-
return Math.min(Math.max(value, min), max);
|
|
505
|
-
}
|
|
506
|
-
function requestFrame(callback) {
|
|
507
|
-
if (typeof requestAnimationFrame === 'function')
|
|
508
|
-
return requestAnimationFrame(callback);
|
|
509
|
-
return setTimeout(callback, 16);
|
|
510
|
-
}
|
|
511
|
-
function cancelFrame(frame) {
|
|
512
|
-
if (typeof cancelAnimationFrame === 'function')
|
|
513
|
-
cancelAnimationFrame(frame);
|
|
514
|
-
else
|
|
515
|
-
clearTimeout(frame);
|
|
516
|
-
}
|
|
517
|
-
function styleSuffix(value) {
|
|
518
|
-
if (typeof value !== 'string' || value.trim() === '')
|
|
519
|
-
return '';
|
|
520
|
-
return value.trim().endsWith(';') ? value.trim() : `${value.trim()};`;
|
|
521
|
-
}
|
package/dist/workbench.d.ts
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/** @license MIT
|
|
2
|
-
* Copyright (c) 2026 vobsjs
|
|
3
|
-
* @vobs/ui
|
|
4
|
-
*/
|
|
5
|
-
import { type UiAttributes, type UiDomPlan } from './primitives.js';
|
|
6
|
-
/**
|
|
7
|
-
* Workbench shell component plans — an IDE/workbench-style component family:
|
|
8
|
-
* rich status bar (status-bar), activity rail (activity-rail), workbench titlebar (workbench-titlebar), chat composer (chat-composer).
|
|
9
|
-
*
|
|
10
|
-
* Spec sources: UIStyle/preview/component-status-bar.html, component-activity-rail.html,
|
|
11
|
-
* component-workbench-titlebar.html, component-chat-composer.html (ds-* classes).
|
|
12
|
-
*
|
|
13
|
-
* Homogeneous with other plans components in the ui package: pure static DOM plans + derived state;
|
|
14
|
-
* text/icons are carried via data-label / data-icon and mapped by the app at render time — plans hold no DOM text fields.
|
|
15
|
-
*/
|
|
16
|
-
export type StatusDotTone = 'success' | 'warning' | 'error';
|
|
17
|
-
export interface StatusBarItemPlan extends UiDomPlan<'span'> {
|
|
18
|
-
readonly itemId: string;
|
|
19
|
-
/** Icon identifier (optional). */
|
|
20
|
-
readonly icon?: string;
|
|
21
|
-
/** Status dot tone (optional). */
|
|
22
|
-
readonly tone?: StatusDotTone;
|
|
23
|
-
/** Text. */
|
|
24
|
-
readonly label: string;
|
|
25
|
-
}
|
|
26
|
-
export interface StatusBarGroupPlan {
|
|
27
|
-
readonly groupId: string;
|
|
28
|
-
readonly items: readonly StatusBarItemPlan[];
|
|
29
|
-
}
|
|
30
|
-
export interface StatusBarPlans {
|
|
31
|
-
readonly root: UiDomPlan<'div'>;
|
|
32
|
-
readonly groups: readonly StatusBarGroupPlan[];
|
|
33
|
-
}
|
|
34
|
-
export interface StatusBarGroupInput {
|
|
35
|
-
readonly id: string;
|
|
36
|
-
readonly items: readonly {
|
|
37
|
-
readonly id: string;
|
|
38
|
-
readonly label: string;
|
|
39
|
-
readonly icon?: string;
|
|
40
|
-
readonly tone?: StatusDotTone;
|
|
41
|
-
}[];
|
|
42
|
-
}
|
|
43
|
-
export interface StatusBarPlanOptions {
|
|
44
|
-
readonly id: string;
|
|
45
|
-
readonly groups: readonly StatusBarGroupInput[];
|
|
46
|
-
readonly className?: string;
|
|
47
|
-
readonly attrs?: UiAttributes;
|
|
48
|
-
}
|
|
49
|
-
export declare function createStatusBarPlans(options: StatusBarPlanOptions): StatusBarPlans;
|
|
50
|
-
export type ActivityRailEntryKind = 'button' | 'divider' | 'spacer';
|
|
51
|
-
export interface ActivityRailButtonPlan extends UiDomPlan<'button'> {
|
|
52
|
-
readonly entryId: string;
|
|
53
|
-
readonly kind: 'button';
|
|
54
|
-
/** Icon identifier. */
|
|
55
|
-
readonly icon: string;
|
|
56
|
-
readonly active: boolean;
|
|
57
|
-
}
|
|
58
|
-
export interface ActivityRailDividerPlan extends UiDomPlan<'div'> {
|
|
59
|
-
readonly entryId: string;
|
|
60
|
-
readonly kind: 'divider';
|
|
61
|
-
}
|
|
62
|
-
export interface ActivityRailSpacerPlan extends UiDomPlan<'span'> {
|
|
63
|
-
readonly entryId: string;
|
|
64
|
-
readonly kind: 'spacer';
|
|
65
|
-
}
|
|
66
|
-
export type ActivityRailEntryPlan = ActivityRailButtonPlan | ActivityRailDividerPlan | ActivityRailSpacerPlan;
|
|
67
|
-
export interface ActivityRailEntryInput {
|
|
68
|
-
readonly id: string;
|
|
69
|
-
readonly kind: ActivityRailEntryKind;
|
|
70
|
-
/** Required when kind='button'. */
|
|
71
|
-
readonly icon?: string;
|
|
72
|
-
readonly active?: boolean;
|
|
73
|
-
readonly disabled?: boolean;
|
|
74
|
-
}
|
|
75
|
-
export interface ActivityRailPlans {
|
|
76
|
-
readonly root: UiDomPlan<'nav'>;
|
|
77
|
-
readonly entries: readonly ActivityRailEntryPlan[];
|
|
78
|
-
}
|
|
79
|
-
export interface ActivityRailPlanOptions {
|
|
80
|
-
readonly id: string;
|
|
81
|
-
readonly entries: readonly ActivityRailEntryInput[];
|
|
82
|
-
readonly className?: string;
|
|
83
|
-
readonly attrs?: UiAttributes;
|
|
84
|
-
}
|
|
85
|
-
export declare function createActivityRailPlans(options: ActivityRailPlanOptions): ActivityRailPlans;
|
|
86
|
-
export type TitlebarLightKind = 'close' | 'min' | 'max';
|
|
87
|
-
export interface WorkbenchTitlebarPlans {
|
|
88
|
-
readonly root: UiDomPlan<'div'>;
|
|
89
|
-
readonly left: UiDomPlan<'div'>;
|
|
90
|
-
/** Red/yellow/green window lights. */
|
|
91
|
-
readonly lights: readonly UiDomPlan<'span'>[];
|
|
92
|
-
readonly modeChip: UiDomPlan<'span'>;
|
|
93
|
-
readonly projectSelector: UiDomPlan<'button'>;
|
|
94
|
-
readonly right: UiDomPlan<'div'>;
|
|
95
|
-
/** Right-side icon buttons (data-icon identifier). */
|
|
96
|
-
readonly actions: readonly UiDomPlan<'button'>[];
|
|
97
|
-
}
|
|
98
|
-
export interface WorkbenchTitlebarPlanOptions {
|
|
99
|
-
readonly id: string;
|
|
100
|
-
/** Mode chip text (e.g. 'Agent Mode'). */
|
|
101
|
-
readonly mode?: string;
|
|
102
|
-
/** Project selector text. */
|
|
103
|
-
readonly project?: string;
|
|
104
|
-
/** Right-side action icon list. */
|
|
105
|
-
readonly actions?: readonly string[];
|
|
106
|
-
readonly className?: string;
|
|
107
|
-
readonly attrs?: UiAttributes;
|
|
108
|
-
}
|
|
109
|
-
export declare function createWorkbenchTitlebarPlans(options: WorkbenchTitlebarPlanOptions): WorkbenchTitlebarPlans;
|
|
110
|
-
export interface ChatComposerPlans {
|
|
111
|
-
readonly root: UiDomPlan<'div'>;
|
|
112
|
-
readonly input: UiDomPlan<'textarea'>;
|
|
113
|
-
readonly toolbar: UiDomPlan<'div'>;
|
|
114
|
-
readonly tools: UiDomPlan<'div'>;
|
|
115
|
-
/** Left-side tool buttons (data-icon identifier). */
|
|
116
|
-
readonly toolButtons: readonly UiDomPlan<'button'>[];
|
|
117
|
-
readonly modelSelector: UiDomPlan<'button'>;
|
|
118
|
-
readonly actions: UiDomPlan<'div'>;
|
|
119
|
-
/** Right-side action buttons (including send). */
|
|
120
|
-
readonly actionButtons: readonly UiDomPlan<'button'>[];
|
|
121
|
-
}
|
|
122
|
-
export interface ChatComposerPlanOptions {
|
|
123
|
-
readonly id: string;
|
|
124
|
-
/** Input placeholder. */
|
|
125
|
-
readonly placeholder?: string;
|
|
126
|
-
/** Left-side tool icon list. */
|
|
127
|
-
readonly tools?: readonly string[];
|
|
128
|
-
/** Model selector text. */
|
|
129
|
-
readonly model?: string;
|
|
130
|
-
/** Right-side action icon list (the send button is handled by the renderer via data-send). */
|
|
131
|
-
readonly actions?: readonly string[];
|
|
132
|
-
readonly disabled?: boolean;
|
|
133
|
-
readonly className?: string;
|
|
134
|
-
readonly attrs?: UiAttributes;
|
|
135
|
-
}
|
|
136
|
-
export declare function createChatComposerPlans(options: ChatComposerPlanOptions): ChatComposerPlans;
|