@tuidom/elements 0.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/body/bodyElement.d.ts +33 -0
- package/dist/body/bodyElement.js +87 -0
- package/dist/button/buttonElement.d.ts +18 -0
- package/dist/button/buttonElement.js +68 -0
- package/dist/completionlist/completionDetailsElement.d.ts +49 -0
- package/dist/completionlist/completionDetailsElement.js +165 -0
- package/dist/completionlist/completionItemKindIcon.d.ts +2 -0
- package/dist/completionlist/completionItemKindIcon.js +43 -0
- package/dist/completionlist/completionListElement.d.ts +102 -0
- package/dist/completionlist/completionListElement.js +309 -0
- package/dist/completionlist/completionWidgetElement.d.ts +41 -0
- package/dist/completionlist/completionWidgetElement.js +102 -0
- package/dist/contextview/contextMenuController.d.ts +23 -0
- package/dist/contextview/contextMenuController.js +75 -0
- package/dist/contextview/overlayHostElement.d.ts +23 -0
- package/dist/contextview/overlayHostElement.js +47 -0
- package/dist/editorgroup/editorTabItemElement.d.ts +41 -0
- package/dist/editorgroup/editorTabItemElement.js +186 -0
- package/dist/editorgroup/editorTabStripElement.d.ts +33 -0
- package/dist/editorgroup/editorTabStripElement.js +118 -0
- package/dist/editorpart/editorPartElement.d.ts +95 -0
- package/dist/editorpart/editorPartElement.js +285 -0
- package/dist/inputbox/inputElement.d.ts +34 -0
- package/dist/inputbox/inputElement.js +207 -0
- package/dist/inputbox/inputState.d.ts +69 -0
- package/dist/inputbox/inputState.js +326 -0
- package/dist/layout/boxContainerElement.d.ts +27 -0
- package/dist/layout/boxContainerElement.js +121 -0
- package/dist/layout/boxElement.d.ts +4 -0
- package/dist/layout/boxElement.js +30 -0
- package/dist/layout/fillerElement.d.ts +12 -0
- package/dist/layout/fillerElement.js +16 -0
- package/dist/layout/fitContentElement.d.ts +18 -0
- package/dist/layout/fitContentElement.js +46 -0
- package/dist/layout/hFlexElement.d.ts +26 -0
- package/dist/layout/hFlexElement.js +134 -0
- package/dist/layout/paddingContainerElement.d.ts +30 -0
- package/dist/layout/paddingContainerElement.js +88 -0
- package/dist/layout/sizedBoxElement.d.ts +30 -0
- package/dist/layout/sizedBoxElement.js +74 -0
- package/dist/layout/vFlexElement.d.ts +32 -0
- package/dist/layout/vFlexElement.js +136 -0
- package/dist/layout/vStackElement.d.ts +18 -0
- package/dist/layout/vStackElement.js +74 -0
- package/dist/list/listViewElement.d.ts +232 -0
- package/dist/list/listViewElement.js +944 -0
- package/dist/menu/menuBarElement.d.ts +47 -0
- package/dist/menu/menuBarElement.js +285 -0
- package/dist/menu/menuBarItemElement.d.ts +20 -0
- package/dist/menu/menuBarItemElement.js +68 -0
- package/dist/menu/popupMenuElement.d.ts +81 -0
- package/dist/menu/popupMenuElement.js +318 -0
- package/dist/menu/popupMenuItemElement.d.ts +24 -0
- package/dist/menu/popupMenuItemElement.js +89 -0
- package/dist/panel/panelContainerElement.d.ts +64 -0
- package/dist/panel/panelContainerElement.js +219 -0
- package/dist/quickpick/quickPickElement.d.ts +161 -0
- package/dist/quickpick/quickPickElement.js +561 -0
- package/dist/sash/sashElement.d.ts +30 -0
- package/dist/sash/sashElement.js +78 -0
- package/dist/scrollbar/iScrollable.d.ts +8 -0
- package/dist/scrollbar/iScrollable.js +1 -0
- package/dist/scrollbar/scrollBarRenderer.d.ts +36 -0
- package/dist/scrollbar/scrollBarRenderer.js +76 -0
- package/dist/scrollbar/scrollContainerElement.d.ts +39 -0
- package/dist/scrollbar/scrollContainerElement.js +91 -0
- package/dist/scrollbar/scrollViewport.d.ts +28 -0
- package/dist/scrollbar/scrollViewport.js +65 -0
- package/dist/scrollbar/scrollableElement.d.ts +22 -0
- package/dist/scrollbar/scrollableElement.js +42 -0
- package/dist/selectbox/selectBoxElement.d.ts +48 -0
- package/dist/selectbox/selectBoxElement.js +161 -0
- package/dist/terminal/encodeKeyForPty.d.ts +3 -0
- package/dist/terminal/encodeKeyForPty.js +56 -0
- package/dist/terminal/terminalViewElement.d.ts +17 -0
- package/dist/terminal/terminalViewElement.js +172 -0
- package/dist/text/textBlockElement.d.ts +13 -0
- package/dist/text/textBlockElement.js +35 -0
- package/dist/text/textLabelElement.d.ts +28 -0
- package/dist/text/textLabelElement.js +77 -0
- package/dist/titledpanel/titledPanelElement.d.ts +14 -0
- package/dist/titledpanel/titledPanelElement.js +40 -0
- package/dist/tree/iTreeDataProvider.d.ts +19 -0
- package/dist/tree/iTreeDataProvider.js +1 -0
- package/dist/tree/treeViewElement.d.ts +116 -0
- package/dist/tree/treeViewElement.js +748 -0
- package/dist/workbenchlayout/workbenchLayoutElement.d.ts +60 -0
- package/dist/workbenchlayout/workbenchLayoutElement.js +203 -0
- package/package.json +33 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { BoxConstraints, Point, Size } from "@tuidom/core/common/geometryPromitives";
|
|
2
|
+
import type { TUIEventBase } from "@tuidom/core/dom/events/tuiEventBase";
|
|
3
|
+
import type { StyleResolutionContext } from "@tuidom/core/dom/styles/tuiStyle";
|
|
4
|
+
import type { RenderContext } from "@tuidom/core/dom/tuiElement";
|
|
5
|
+
import { TUIElement } from "@tuidom/core/dom/tuiElement";
|
|
6
|
+
import { ScrollableElement, type ScrollViewportInfo } from "../scrollbar/scrollableElement.js";
|
|
7
|
+
/**
|
|
8
|
+
* Состояние «строка под указателем ИЛИ под курсором сфокусированного списка» —
|
|
9
|
+
* то, что в вебе назвали бы «строка в фокусе внимания». Ставится на обёртку
|
|
10
|
+
* строки, поэтому потомкам доступно селектором `in:rowActive` и методом
|
|
11
|
+
* {@link TUIElement.hasStyleStateWithin} — так строка раскрывает свои
|
|
12
|
+
* инлайн-кнопки, ничего не зная про список.
|
|
13
|
+
*
|
|
14
|
+
* Почему не `hover`: диспатчер мыши ставит hover на ВСЮ цепочку target→root, а
|
|
15
|
+
* строки презентационные — target'ом всегда оказывается сам список. То есть
|
|
16
|
+
* `in:hover` у потомка строки был бы истиной для всех строк разом, стоит мыши
|
|
17
|
+
* оказаться где угодно над списком.
|
|
18
|
+
*/
|
|
19
|
+
export declare const LIST_ROW_ACTIVE_STATE = "rowActive";
|
|
20
|
+
export interface IListRowOptions {
|
|
21
|
+
/** Родительская строка; глубина/отступ выводятся из цепочки родителей. */
|
|
22
|
+
readonly parentId?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Текст для typeahead-поиска; строки без label быстрый поиск пропускает.
|
|
25
|
+
* Сам typeahead выключается опцией конструктора `typeahead: false`.
|
|
26
|
+
*/
|
|
27
|
+
readonly label?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Виртуализирующий список: настоящие TUIElement-дети высотой ровно 1 строка.
|
|
31
|
+
*
|
|
32
|
+
* Потребитель императивно собирает произвольные строки-элементы и добавляет их
|
|
33
|
+
* через {@link appendRow}; контейнер прячет внутри виртуализацию (layout и render
|
|
34
|
+
* получают только строки видимого окна), иерархию со сворачиванием (`parentId` +
|
|
35
|
+
* {@link setCollapsed}), скрытие ({@link setRowHidden}) и общие механики списка:
|
|
36
|
+
* курсор, множественный выбор, клавиатуру, hover, typeahead и сигнал контекстного
|
|
37
|
+
* меню. У каждой строки обязан быть непустой `element.id` — без него appendRow
|
|
38
|
+
* бросает ошибку.
|
|
39
|
+
*
|
|
40
|
+
* Контракт строк: строки — презентационные. Хит-тест всегда возвращает сам
|
|
41
|
+
* контейнер, поэтому строки не получают mouse-событий и фокуса; вся семантика
|
|
42
|
+
* клика/клавиатуры принадлежит списку. Единственное исключение — делегация
|
|
43
|
+
* левого клика без модификаторов: контейнер ре-диспатчит click/dblclick в
|
|
44
|
+
* поддерево видимой строки, и если чей-то listener вызвал `preventDefault()`,
|
|
45
|
+
* клик считается потреблённым — курсор, выделение и активация не трогаются.
|
|
46
|
+
* Так строка может нести инлайн-кнопки (обычные элементы с click-listener'ом),
|
|
47
|
+
* не зная ничего про список. Фокуса такая кнопка не берёт (строки вне Tab-обхода),
|
|
48
|
+
* поэтому «строка в фокусе внимания» выражена состоянием
|
|
49
|
+
* {@link LIST_ROW_ACTIVE_STATE} на обёртке строки — по нему кнопка решает,
|
|
50
|
+
* показываться ли ей. Выделение и hover рисуются пост-оверлеем
|
|
51
|
+
* поверх отрендеренной строки: перекрашиваются только ячейки, чьи цвета совпадают
|
|
52
|
+
* с унаследованными fg/bg контейнера, так что собственные цвета строки (подсветка
|
|
53
|
+
* совпадения, приглушённый номер) выделение переживают. Строка, явно выставившая
|
|
54
|
+
* цвет, равный унаследованному, неотличима от ненастроенной и тоже будет
|
|
55
|
+
* перекрашена — это осознанное ограничение механизма.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ListViewElement extends ScrollableElement {
|
|
58
|
+
private readonly indentSize;
|
|
59
|
+
private readonly typeaheadEnabled;
|
|
60
|
+
private rowById;
|
|
61
|
+
/** Дети по родителю в порядке добавления; ключ null — верхний уровень. */
|
|
62
|
+
private childIds;
|
|
63
|
+
private collapsedIds;
|
|
64
|
+
/** Ленивая DFS-проекция видимых строк; null = требуется пересборка. */
|
|
65
|
+
private visibleRows;
|
|
66
|
+
private visibleIndexById;
|
|
67
|
+
private hasCollapsibleRows;
|
|
68
|
+
/**
|
|
69
|
+
* Окно строк, реально разложенное последним performLayout. Делегация кликов
|
|
70
|
+
* (см. {@link delegateToRowChild}) доверяет позициям детей только внутри него:
|
|
71
|
+
* скролл или пересборка проекции между кадрами делают layout недействительным
|
|
72
|
+
* (-1), и незалейаученные строки с ленивыми позициями (0,0)/80×24 не ловят
|
|
73
|
+
* чужие клики.
|
|
74
|
+
*/
|
|
75
|
+
private lastLayoutScrollTop;
|
|
76
|
+
private lastLayoutViewportHeight;
|
|
77
|
+
private cursorIndex;
|
|
78
|
+
private anchorIndex;
|
|
79
|
+
private selectedIds;
|
|
80
|
+
private hoveredIndex;
|
|
81
|
+
/** Курсор, запомненный по id на время грязной проекции (restoreSelection дерева). */
|
|
82
|
+
private pendingCursorId;
|
|
83
|
+
private pendingCursorIndex;
|
|
84
|
+
private typeaheadBuffer;
|
|
85
|
+
private typeaheadTimer;
|
|
86
|
+
onSelect: ((element: TUIElement) => void) | null;
|
|
87
|
+
onActivate: ((element: TUIElement) => void) | null;
|
|
88
|
+
onCollapsedChanged: ((element: TUIElement, collapsed: boolean) => void) | null;
|
|
89
|
+
onContextMenu: ((element: TUIElement, screenX: number, screenY: number) => void) | null;
|
|
90
|
+
constructor(options?: {
|
|
91
|
+
indentSize?: number;
|
|
92
|
+
typeahead?: boolean;
|
|
93
|
+
});
|
|
94
|
+
appendRow(element: TUIElement, options?: IListRowOptions): void;
|
|
95
|
+
clear(): void;
|
|
96
|
+
get rowCount(): number;
|
|
97
|
+
setCollapsed(id: string, collapsed: boolean): void;
|
|
98
|
+
toggleCollapsed(id: string): void;
|
|
99
|
+
isCollapsed(id: string): boolean;
|
|
100
|
+
/** Снимок свёрнутых строк — восстановление состояния после полной пересборки. */
|
|
101
|
+
getCollapsedIds(): readonly string[];
|
|
102
|
+
/**
|
|
103
|
+
* Есть ли в видимой проекции развёрнутая строка с детьми — семантика
|
|
104
|
+
* VS Code `viewHasSomeCollapsibleResult` (тумблер Collapse All/Expand All).
|
|
105
|
+
*/
|
|
106
|
+
hasVisibleExpandedRow(): boolean;
|
|
107
|
+
setRowHidden(id: string, hidden: boolean): void;
|
|
108
|
+
getCursorElement(): TUIElement | null;
|
|
109
|
+
/**
|
|
110
|
+
* Все выбранные строки. Если множественный выбор пуст, возвращает строку под
|
|
111
|
+
* курсором (в виде массива из одного элемента). Порядок — как в списке.
|
|
112
|
+
*/
|
|
113
|
+
getSelectedElements(): TUIElement[];
|
|
114
|
+
/** Ставит курсор на строку, раскрывая свёрнутых предков, и проматывает к ней. */
|
|
115
|
+
setCursorTo(id: string): void;
|
|
116
|
+
focusPageDown(): void;
|
|
117
|
+
focusPageUp(): void;
|
|
118
|
+
focusFirst(): void;
|
|
119
|
+
focusLast(): void;
|
|
120
|
+
get contentHeight(): number;
|
|
121
|
+
get contentWidth(): number;
|
|
122
|
+
/**
|
|
123
|
+
* Строки презентационные: в хит-тест не спускаемся — вся семантика мыши
|
|
124
|
+
* живёт в контейнере (и закуленные строки с непосчитанным layout не крадут
|
|
125
|
+
* хиты у чужих углов экрана).
|
|
126
|
+
*/
|
|
127
|
+
protected hitTestChildren(_point: Point): TUIElement | null;
|
|
128
|
+
/** Строки не участвуют в Tab-обходе — фокусируется только сам список. */
|
|
129
|
+
getDepthFirstFocusableOrder(): TUIElement[];
|
|
130
|
+
/**
|
|
131
|
+
* Damage-обход не заходит в строки: их тысячи, офскрин-хосты держат
|
|
132
|
+
* протухшие layout-позиции (виртуализация), а любая смена состояния списка
|
|
133
|
+
* (скролл, курсор, данные) метит сам список — повреждается rect вьюпорта.
|
|
134
|
+
*/
|
|
135
|
+
protected get paintsSubtreeAtomically(): boolean;
|
|
136
|
+
protected performLayout(constraints: BoxConstraints): Size;
|
|
137
|
+
/**
|
|
138
|
+
* Строки, которые были в окне прошлого layout и выпали из нынешнего, несут
|
|
139
|
+
* устаревшую геометрию (прежняя ширина/позиция). Помечаем их
|
|
140
|
+
* layout-грязными — тем же флагом, с которым живут ни разу не разложенные
|
|
141
|
+
* строки: он и вернёт им честный layout при въезде в окно, и выведет их
|
|
142
|
+
* из-под геометрических проверок `validateTree`.
|
|
143
|
+
*
|
|
144
|
+
* Окно умеет не только ехать, но и **сжиматься** — например, когда
|
|
145
|
+
* `ScrollBarDecorator` спрашивает `contentWidth` у ещё не разложенного
|
|
146
|
+
* списка: ленивый layout проходит по дефолтным 80×24, а следующий за ним
|
|
147
|
+
* настоящий кладёт лишь пару видимых строк. Без этой уборки хвост остался
|
|
148
|
+
* бы «чистым» с шириной 80 внутри 28-колоночного списка.
|
|
149
|
+
*
|
|
150
|
+
* Цена — O(окна), а не O(N): переcборка проекции сюда не попадает (там
|
|
151
|
+
* строки и так новые, а `lastLayoutScrollTop` сброшен в -1).
|
|
152
|
+
*/
|
|
153
|
+
private invalidateRowsLeavingWindow;
|
|
154
|
+
/**
|
|
155
|
+
* Стилевой проход виртуализирован, как layout/render/hitTest: резолвится
|
|
156
|
+
* только видимое окно строк, O(вьюпорта) вместо O(N) на кадр. Офскрин-
|
|
157
|
+
* строки остаются style-dirty до въезда в окно (см. performLayout).
|
|
158
|
+
*/
|
|
159
|
+
protected performChildrenStyleResolution(context: StyleResolutionContext): void;
|
|
160
|
+
inspectState(): Record<string, unknown>;
|
|
161
|
+
protected performDefaultAction(event: TUIEventBase): void;
|
|
162
|
+
/**
|
|
163
|
+
* Единый вход контекстного меню: от мыши — строка под кликом (мультивыбор по
|
|
164
|
+
* выбранной строке не сбрасывается), от клавиатуры — строка курсора с якорем
|
|
165
|
+
* на её глобальной позиции. Виджет только сигналит {@link onContextMenu} —
|
|
166
|
+
* сборка и показ меню на стороне владельца.
|
|
167
|
+
*/
|
|
168
|
+
private handleContextMenu;
|
|
169
|
+
protected renderViewport(context: RenderContext, viewport: ScrollViewportInfo): void;
|
|
170
|
+
private ensureProjection;
|
|
171
|
+
/**
|
|
172
|
+
* Инкрементальное дополнение живой проекции при appendRow: стрим результатов
|
|
173
|
+
* (SearchPerformance.md, случай 6) не платит полную пересборку O(N) на кадр.
|
|
174
|
+
* Быстрые случаи: строка под невидимым/свёрнутым родителем — проекция не
|
|
175
|
+
* меняется вовсе; строка в хвосте проекции (последний топ-левел или новый
|
|
176
|
+
* последний ребёнок раскрытой группы, чьё поддерево замыкает проекцию) —
|
|
177
|
+
* push в конец: индексы существующих строк стабильны, курсор, выделение и
|
|
178
|
+
* якорь Shift-диапазона не трогаются (полная пересборка якорь сбрасывает —
|
|
179
|
+
* инкрементальный append его сохраняет). Остальное (вставка в середину) —
|
|
180
|
+
* фоллбек на полную инвалидацию.
|
|
181
|
+
*/
|
|
182
|
+
private appendToProjection;
|
|
183
|
+
/**
|
|
184
|
+
* Замыкает ли поддерево строки текущую проекцию: последняя видимая строка —
|
|
185
|
+
* она сама или её потомок (walk по цепочке родителей, O(глубины)). Именно
|
|
186
|
+
* тогда новый последний ребёнок строки встаёт в самый хвост проекции.
|
|
187
|
+
*/
|
|
188
|
+
private isProjectionTail;
|
|
189
|
+
private invalidateProjection;
|
|
190
|
+
private rowIdAt;
|
|
191
|
+
private requireRow;
|
|
192
|
+
private rowHasChildren;
|
|
193
|
+
private rowContentX;
|
|
194
|
+
private setSelectedIndex;
|
|
195
|
+
/** Двигает курсор и расширяет множественный выбор диапазоном от якоря (Shift+стрелки). */
|
|
196
|
+
private extendSelectionTo;
|
|
197
|
+
private selectRange;
|
|
198
|
+
/** Переключает выбор одной строки (Ctrl/Cmd+клик), не сбрасывая остальное. */
|
|
199
|
+
private toggleSelectionAt;
|
|
200
|
+
private applyCursor;
|
|
201
|
+
private ensureVisible;
|
|
202
|
+
private handleKeypress;
|
|
203
|
+
/**
|
|
204
|
+
* Быстрый поиск по набору: печатаешь символы — курсор перепрыгивает к первой строке,
|
|
205
|
+
* чей label начинается с набранной последовательности. Повтор одного и того же
|
|
206
|
+
* символа циклически перебирает совпадения; набор из разных символов уточняет
|
|
207
|
+
* префикс, начиная с текущей строки. Буфер копится, пока не выйдет тайм-аут.
|
|
208
|
+
*/
|
|
209
|
+
private handleTypeahead;
|
|
210
|
+
private restartTypeaheadTimer;
|
|
211
|
+
private jumpToTypeaheadMatch;
|
|
212
|
+
private handleExpandOrMoveToChild;
|
|
213
|
+
private handleCollapseOrMoveToParent;
|
|
214
|
+
private activateCursorRow;
|
|
215
|
+
private toggleCursorRow;
|
|
216
|
+
/**
|
|
217
|
+
* Ре-диспатчит click/dblclick в поддерево видимой строки; true = ребёнок
|
|
218
|
+
* потребил событие (какой-то listener вызвал `preventDefault()`).
|
|
219
|
+
*
|
|
220
|
+
* Хит-тест идёт от элемента строки, так что результат по построению лежит в её
|
|
221
|
+
* поддереве. Доверять позициям детей можно только строкам, разложенным последним
|
|
222
|
+
* performLayout на своих местах: скролл или пересборка проекции между кадрами
|
|
223
|
+
* инвалидируют окно, и делегация отключается до следующего кадра — иначе
|
|
224
|
+
* незалейаученная строка с ленивыми (0,0)/80×24 поймала бы чужой клик.
|
|
225
|
+
*/
|
|
226
|
+
private delegateToRowChild;
|
|
227
|
+
private handleClick;
|
|
228
|
+
private handleDblClick;
|
|
229
|
+
private handleMouseMove;
|
|
230
|
+
private handleMouseLeave;
|
|
231
|
+
private handleWheel;
|
|
232
|
+
}
|