verstak 0.24.269 → 0.24.271

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.
@@ -1,5 +1,6 @@
1
1
  import { ElCoords } from "./El.js";
2
2
  export declare function objectHasMember<T>(obj: any, member: string): obj is T;
3
+ export declare function clamp(value: number, min: number, max: number): number;
3
4
  export declare function emitLetters(n: number): string;
4
5
  export declare function parseElCoords(text: string, result: ElCoords): ElCoords;
5
6
  export declare function emitElCoords(value: ElCoords): string;
@@ -1,6 +1,9 @@
1
1
  export function objectHasMember(obj, member) {
2
2
  return obj === Object(obj) && !Array.isArray(obj) && member in obj;
3
3
  }
4
+ export function clamp(value, min, max) {
5
+ return Math.min(max, Math.max(min, value));
6
+ }
4
7
  export function emitLetters(n) {
5
8
  if (n < 0)
6
9
  throw new Error(`emitLetters: argument (${n}) should not be negative or zero`);
@@ -1,15 +1,29 @@
1
- import { RxNodeDecl, RxNode, Delegate } from "reactronic";
2
- import { El, ElArea } from "./El.js";
3
- import { HtmlElementDriver } from "./HtmlDriver.js";
1
+ import { RxNodeDecl, RxNodeDriver, RxNode, Delegate, MergedItem } from "reactronic";
2
+ import { CursorCommandDriver, El, ElArea } from "./El.js";
3
+ import { HtmlDriver } from "./HtmlDriver.js";
4
4
  export declare function Section<M = unknown>(declaration?: RxNodeDecl<El<HTMLElement, M>>, preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>>;
5
5
  export declare function Table<M = unknown, R = void>(declaration?: RxNodeDecl<El<HTMLElement, M>>, preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>>;
6
6
  export declare function row<T = void>(builder?: (element: void) => T, shiftCursorDown?: number): void;
7
+ export declare function Splitter<M = unknown, R = void>(declaration?: RxNodeDecl<El<HTMLElement, M>>, preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>>;
7
8
  export declare function rowBreak(shiftCursorDown?: number): void;
9
+ export declare function declareSplitter<T>(index: number, splitViewNode: RxNode<El<T>>): RxNode<El<HTMLElement>>;
8
10
  export declare function cursor(areaParams: ElArea): void;
9
11
  export declare function Note(content: string, formatted?: boolean, declaration?: RxNodeDecl<El<HTMLElement, void>>): RxNode<El<HTMLElement, void>>;
10
12
  export declare function Group<M = unknown, R = void>(declaration?: RxNodeDecl<El<HTMLElement, M>>, preset?: RxNodeDecl<El<HTMLElement, M>>): RxNode<El<HTMLElement, M>>;
11
13
  export declare function Handling<M = unknown>(onChange: Delegate<El<void, M>>): RxNode<El<void, M>>;
12
14
  export declare function SyntheticElement<M = unknown>(declaration?: RxNodeDecl<El<void, M>>, preset?: RxNodeDecl<El<void, M>>): RxNode<El<void, M>>;
13
- export declare class VerstakElementDriver<T extends HTMLElement> extends HtmlElementDriver<T> {
15
+ export declare class SectionDriver<T extends HTMLElement> extends HtmlDriver<T> {
14
16
  update(node: RxNode<El<T>>): void | Promise<void>;
17
+ child(ownerNode: RxNode<El<T, any>>, childDriver: RxNodeDriver<any>, childDeclaration?: RxNodeDecl<any> | undefined, childPreset?: RxNodeDecl<any> | undefined): MergedItem<RxNode> | undefined;
15
18
  }
19
+ export declare function isSplitViewPartition(childDriver: RxNodeDriver): boolean;
20
+ export declare const Drivers: {
21
+ section: SectionDriver<HTMLElement>;
22
+ table: HtmlDriver<HTMLElement, any>;
23
+ note: HtmlDriver<HTMLElement, any>;
24
+ group: HtmlDriver<HTMLElement, any>;
25
+ partition: HtmlDriver<HTMLElement, any>;
26
+ splitter: HtmlDriver<HTMLElement, any>;
27
+ cursor: CursorCommandDriver;
28
+ synthetic: RxNodeDriver<El<void, any>>;
29
+ };
@@ -1,6 +1,9 @@
1
- import { RxNode, Mode } from "reactronic";
2
- import { Constants, CursorCommandDriver, ElKind, ElDriver } from "./El.js";
3
- import { HtmlElementDriver } from "./HtmlDriver.js";
1
+ import { RxNode, Mode, unobs } from "reactronic";
2
+ import { Constants, CursorCommandDriver, ElKind, ElDriver, SplitView, ElLayoutInfo, InitialElLayoutInfo } from "./El.js";
3
+ import { getPrioritiesForEmptySpaceDistribution, getPrioritiesForSizeChanging, relayout, relayoutUsingSplitter } from "./SplitViewMath.js";
4
+ import { Axis, BodyFontSize, Dimension, toPx } from "./Sizes.js";
5
+ import { HtmlDriver } from "./HtmlDriver.js";
6
+ import { clamp } from "./ElUtils.js";
4
7
  export function Section(declaration, preset) {
5
8
  return RxNode.declare(Drivers.section, declaration, preset);
6
9
  }
@@ -11,8 +14,73 @@ export function row(builder, shiftCursorDown) {
11
14
  rowBreak(shiftCursorDown);
12
15
  builder === null || builder === void 0 ? void 0 : builder();
13
16
  }
17
+ export function Splitter(declaration, preset) {
18
+ return RxNode.declare(Drivers.splitter, declaration, preset);
19
+ }
14
20
  export function rowBreak(shiftCursorDown) {
15
- RxNode.declare(Drivers.partition);
21
+ RxNode.declare(Drivers.partition, {
22
+ onChange: el => {
23
+ const ownerEl = el.node.owner.element;
24
+ if (ownerEl.splitView !== undefined) {
25
+ el.style.display = "grid";
26
+ }
27
+ else {
28
+ }
29
+ },
30
+ });
31
+ }
32
+ export function declareSplitter(index, splitViewNode) {
33
+ const key = `splitter-${index}`;
34
+ return (Splitter({
35
+ key,
36
+ mode: Mode.independentUpdate,
37
+ onCreate: el => el.native.className = `splitter ${key}`,
38
+ onChange: b => {
39
+ const e = b.native;
40
+ const model = b.model;
41
+ const dataForSensor = e.dataForSensor;
42
+ dataForSensor.draggable = key;
43
+ dataForSensor.drag = key;
44
+ Handling(() => {
45
+ var _a, _b, _c, _d;
46
+ const pointer = e.sensors.pointer;
47
+ if (pointer.dragSource === key) {
48
+ if (pointer.dragStarted) {
49
+ if (pointer.draggingOver) {
50
+ pointer.dropAllowed = true;
51
+ const initialSizesPx = pointer.getData();
52
+ const deltaPx = Math.floor(splitViewNode.element.splitView === SplitView.horizontal
53
+ ? pointer.positionX - pointer.startX : pointer.positionY - pointer.startY);
54
+ const clonedSizesPx = [];
55
+ for (const item of initialSizesPx) {
56
+ clonedSizesPx.push({ node: item.node, sizePx: item.sizePx });
57
+ }
58
+ unobs(() => relayoutUsingSplitter(splitViewNode, deltaPx, index, clonedSizesPx));
59
+ if (pointer.dropped) {
60
+ (_a = model === null || model === void 0 ? void 0 : model.droppedAction) === null || _a === void 0 ? void 0 : _a.call(model, pointer);
61
+ }
62
+ }
63
+ else {
64
+ e.setAttribute("rx-dragging", "true");
65
+ const initialSizesPx = [];
66
+ for (const item of splitViewNode.children.items()) {
67
+ const child = item.instance;
68
+ if (isSplitViewPartition(child.driver)) {
69
+ const sizePx = (_c = (_b = child.element.layoutInfo) === null || _b === void 0 ? void 0 : _b.effectiveSizePx) !== null && _c !== void 0 ? _c : 0;
70
+ initialSizesPx.push({ node: child, sizePx });
71
+ }
72
+ }
73
+ pointer.setData(initialSizesPx);
74
+ }
75
+ if (pointer.dragFinished) {
76
+ (_d = model === null || model === void 0 ? void 0 : model.dragFinishedAction) === null || _d === void 0 ? void 0 : _d.call(model, pointer);
77
+ e.setAttribute("rx-dragging", "false");
78
+ }
79
+ }
80
+ }
81
+ });
82
+ },
83
+ }));
16
84
  }
17
85
  export function cursor(areaParams) {
18
86
  RxNode.declare(Drivers.cursor, {
@@ -28,7 +96,7 @@ export function Note(content, formatted, declaration) {
28
96
  el.native.innerHTML = content;
29
97
  else
30
98
  el.native.innerText = content;
31
- }
99
+ },
32
100
  });
33
101
  }
34
102
  export function Group(declaration, preset) {
@@ -40,20 +108,157 @@ export function Handling(onChange) {
40
108
  export function SyntheticElement(declaration, preset) {
41
109
  return RxNode.declare(Drivers.synthetic, declaration, preset);
42
110
  }
43
- export class VerstakElementDriver extends HtmlElementDriver {
111
+ export class SectionDriver extends HtmlDriver {
44
112
  update(node) {
45
- const element = node.element;
46
- if (element.kind === ElKind.section)
47
- rowBreak();
48
- return super.update(node);
113
+ rowBreak();
114
+ const result = super.update(node);
115
+ const el = node.element;
116
+ if (el.splitView !== undefined) {
117
+ Handling(h => {
118
+ var _a, _b;
119
+ const native = el.native;
120
+ const resize = native.sensors.resize;
121
+ for (const x of resize.resizedElements) {
122
+ if (el.layoutInfo === undefined)
123
+ el.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
124
+ const rect = x.contentRect;
125
+ const contentBoxPx = x.contentBoxSize[0];
126
+ const containerSizeXpx = contentBoxPx.inlineSize;
127
+ const containerSizeYpx = contentBoxPx.blockSize;
128
+ el.layoutInfo.offsetXpx = rect.left;
129
+ el.layoutInfo.offsetYpx = rect.top;
130
+ el.layoutInfo.contentSizeXpx = containerSizeXpx;
131
+ el.layoutInfo.contentSizeYpx = containerSizeYpx;
132
+ el.layoutInfo.borderSizeXpx = x.borderBoxSize[0].inlineSize;
133
+ el.layoutInfo.borderSizeYpx = x.borderBoxSize[0].blockSize;
134
+ const isHorizontal = el.splitView === SplitView.horizontal;
135
+ const wrapper = (_a = node.children.firstMergedItem()) === null || _a === void 0 ? void 0 : _a.instance;
136
+ if (wrapper !== undefined) {
137
+ const wrapperEl = wrapper.element;
138
+ el.layoutInfo.isConstrained = true;
139
+ if (isHorizontal)
140
+ wrapperEl.style.width = wrapperEl.style.maxWidth = `${containerSizeXpx}px`;
141
+ else
142
+ wrapperEl.style.height = wrapperEl.style.maxHeight = `${containerSizeYpx}px`;
143
+ }
144
+ }
145
+ if (h.node.stamp === 1) {
146
+ const isHorizontal = el.splitView === SplitView.horizontal;
147
+ const wrapper = (_b = node.children.firstMergedItem()) === null || _b === void 0 ? void 0 : _b.instance;
148
+ if (wrapper !== undefined) {
149
+ const wrapperEl = wrapper.element;
150
+ if (isHorizontal)
151
+ wrapperEl.style.width = wrapperEl.style.maxWidth = "0px";
152
+ else
153
+ wrapperEl.style.height = wrapperEl.style.maxHeight = "0px";
154
+ }
155
+ }
156
+ });
157
+ Handling(() => {
158
+ const native = el.native;
159
+ const isHorizontal = el.splitView === SplitView.horizontal;
160
+ if (el.layoutInfo === undefined)
161
+ el.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
162
+ if (el.layoutInfo.isConstrained) {
163
+ const surroundingXpx = el.layoutInfo.borderSizeXpx - el.layoutInfo.contentSizeXpx;
164
+ const surroundingYpx = el.layoutInfo.borderSizeYpx - el.layoutInfo.contentSizeYpx;
165
+ let i = 0;
166
+ const preferred = [];
167
+ const sizesPx = [];
168
+ for (const child of node.children.items()) {
169
+ const partEl = child.instance.element;
170
+ if (isSplitViewPartition(child.instance.driver) && partEl !== undefined) {
171
+ const size = isHorizontal ? partEl.width : partEl.height;
172
+ const options = {
173
+ axis: isHorizontal ? Axis.X : Axis.Y, lineSizePx: Dimension.lineSizePx, fontSizePx: BodyFontSize,
174
+ containerSizeXpx: native.scrollWidth - surroundingXpx, containerSizeYpx: native.scrollHeight - surroundingYpx,
175
+ };
176
+ const minPx = size.min ? toPx(Dimension.parse(size.min), options) : 0;
177
+ let maxPx = size.max ? toPx(Dimension.parse(size.max), options) : Number.POSITIVE_INFINITY;
178
+ maxPx = Math.max(minPx, maxPx);
179
+ if (partEl.layoutInfo === undefined)
180
+ partEl.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
181
+ if (isHorizontal)
182
+ partEl.widthPx = { minPx, maxPx };
183
+ else
184
+ partEl.heightPx = { minPx, maxPx };
185
+ const preferredUsed = isHorizontal ? partEl.preferredWidthUsed : partEl.preferredHeightUsed;
186
+ let preferredPx = 0;
187
+ if (!preferredUsed) {
188
+ preferredPx = size.preferred ? toPx(Dimension.parse(size.preferred), options) : 0;
189
+ if (preferredPx > 0) {
190
+ partEl.layoutInfo.effectiveSizePx = preferredPx;
191
+ preferred.push(i);
192
+ }
193
+ if (isHorizontal)
194
+ partEl.preferredWidthUsed = true;
195
+ else
196
+ partEl.preferredHeightUsed = true;
197
+ }
198
+ const sizePx = partEl.layoutInfo.effectiveSizePx = clamp(partEl.layoutInfo.effectiveSizePx, minPx, maxPx);
199
+ sizesPx.push({ node: child.instance, sizePx });
200
+ i++;
201
+ }
202
+ }
203
+ const priorities = preferred.length > 0
204
+ ? getPrioritiesForSizeChanging(isHorizontal, node.children, preferred)
205
+ : getPrioritiesForEmptySpaceDistribution(isHorizontal, node.children);
206
+ unobs(() => relayout(node, priorities.resizable, priorities.manuallyResizable, sizesPx));
207
+ }
208
+ });
209
+ }
210
+ return result;
49
211
  }
212
+ child(ownerNode, childDriver, childDeclaration, childPreset) {
213
+ var _a;
214
+ let result = undefined;
215
+ const el = ownerNode.element;
216
+ if (el.splitView !== undefined) {
217
+ if (isSplitViewPartition(childDriver)) {
218
+ let partCount = 0;
219
+ for (const child of ownerNode.children.items()) {
220
+ if (isSplitViewPartition(child.instance.driver))
221
+ partCount++;
222
+ }
223
+ const isHorizontal = el.splitView === SplitView.horizontal;
224
+ if (childDeclaration !== undefined) {
225
+ overrideOnCreate(childDeclaration, el => {
226
+ if (isHorizontal)
227
+ el.style.gridColumn = `${partCount + 1}`;
228
+ else
229
+ el.style.gridRow = `${partCount + 1}`;
230
+ });
231
+ }
232
+ if (partCount > 0)
233
+ declareSplitter(partCount - 1, ownerNode);
234
+ }
235
+ }
236
+ else {
237
+ if (childDriver.isPartition) {
238
+ const last = ownerNode.children.lastMergedItem();
239
+ if (((_a = last === null || last === void 0 ? void 0 : last.instance) === null || _a === void 0 ? void 0 : _a.driver) === childDriver)
240
+ result = last;
241
+ }
242
+ }
243
+ return result;
244
+ }
245
+ }
246
+ export function isSplitViewPartition(childDriver) {
247
+ return !childDriver.isPartition && childDriver !== Drivers.splitter && childDriver !== Drivers.synthetic;
248
+ }
249
+ function overrideOnCreate(declaration, func) {
250
+ const baseOnCreate = declaration.onCreate;
251
+ declaration.onCreate = baseOnCreate !== undefined
252
+ ? (el, base) => { baseOnCreate(el, base); func(el); }
253
+ : (el, base) => { base(); func(el); };
50
254
  }
51
- const Drivers = {
52
- section: new VerstakElementDriver(Constants.element, false, el => el.kind = ElKind.section),
53
- table: new VerstakElementDriver(Constants.element, false, el => el.kind = ElKind.table),
54
- note: new VerstakElementDriver(Constants.element, false, el => el.kind = ElKind.note),
55
- group: new VerstakElementDriver(Constants.group, false, el => el.kind = ElKind.group),
56
- partition: new VerstakElementDriver(Constants.partition, true, el => el.kind = ElKind.part),
255
+ export const Drivers = {
256
+ section: new SectionDriver(Constants.element, false, el => el.kind = ElKind.section),
257
+ table: new HtmlDriver(Constants.element, false, el => el.kind = ElKind.table),
258
+ note: new HtmlDriver(Constants.element, false, el => el.kind = ElKind.note),
259
+ group: new HtmlDriver(Constants.group, false, el => el.kind = ElKind.group),
260
+ partition: new HtmlDriver(Constants.partition, true, el => el.kind = ElKind.part),
261
+ splitter: new HtmlDriver(Constants.splitter, false, el => el.kind = ElKind.splitter),
57
262
  cursor: new CursorCommandDriver(),
58
263
  synthetic: new ElDriver("synthetic", false, el => el.kind = ElKind.group),
59
264
  };
@@ -3,4 +3,4 @@ import { FocusModel } from "./sensors/FocusSensor.js";
3
3
  import { ResizedElement } from "./sensors/ResizeSensor.js";
4
4
  export declare function OnClick(target: HTMLElement, action: (() => void) | ToggleRef | undefined, key?: string): void;
5
5
  export declare function OnResize(target: HTMLElement, action: ((element: ResizedElement) => void) | undefined, key?: string): void;
6
- export declare function OnFocus(target: HTMLElement, model: FocusModel, switchEditMode?: ((model?: FocusModel) => void) | undefined, key?: string): void;
6
+ export declare function OnFocus(target: HTMLElement, model: FocusModel, switchEditMode?: ((model: FocusModel) => void) | undefined, key?: string): void;
@@ -16,9 +16,9 @@ export declare class StaticDriver<T extends HTMLElement> extends WebDriver<T> {
16
16
  constructor(native: T, name: string, isRow: boolean, predefine?: SimpleDelegate<El<T>>);
17
17
  setNativeElement(node: RxNode<El<T>>): void;
18
18
  }
19
- export declare class HtmlElementDriver<T extends HTMLElement, M = any> extends WebDriver<T, M> {
19
+ export declare class HtmlDriver<T extends HTMLElement, M = any> extends WebDriver<T, M> {
20
20
  setNativeElement(node: RxNode<El<T, M>>): void;
21
21
  }
22
- export declare class SvgElementDriver<T extends SVGElement, M = any> extends WebDriver<T, M> {
22
+ export declare class SvgDriver<T extends SVGElement, M = any> extends WebDriver<T, M> {
23
23
  setNativeElement(node: RxNode<El<T, M>>): void;
24
24
  }
@@ -88,12 +88,12 @@ export class StaticDriver extends WebDriver {
88
88
  node.element.native = this.native;
89
89
  }
90
90
  }
91
- export class HtmlElementDriver extends WebDriver {
91
+ export class HtmlDriver extends WebDriver {
92
92
  setNativeElement(node) {
93
93
  node.element.native = document.createElement(node.driver.name);
94
94
  }
95
95
  }
96
- export class SvgElementDriver extends WebDriver {
96
+ export class SvgDriver extends WebDriver {
97
97
  setNativeElement(node) {
98
98
  node.element.native = document.createElementNS("http://www.w3.org/2000/svg", node.driver.name);
99
99
  }