verstak 0.24.270 → 0.24.272

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.
Files changed (28) hide show
  1. package/build/dist/source/html/El.d.ts +56 -25
  2. package/build/dist/source/html/El.js +197 -117
  3. package/build/dist/source/html/ElUtils.d.ts +14 -0
  4. package/build/dist/source/html/ElUtils.js +38 -9
  5. package/build/dist/source/html/Elements.js +124 -68
  6. package/build/dist/source/html/Handlers.d.ts +1 -1
  7. package/build/dist/source/html/Handlers.js +2 -0
  8. package/build/dist/source/html/SplitViewMath.d.ts +15 -6
  9. package/build/dist/source/html/SplitViewMath.js +195 -128
  10. package/build/dist/source/html/api.d.ts +1 -0
  11. package/build/dist/source/html/api.js +1 -0
  12. package/build/dist/source/html/sensors/BasePointerSensor.d.ts +1 -2
  13. package/build/dist/source/html/sensors/BasePointerSensor.js +2 -2
  14. package/build/dist/source/html/sensors/ButtonSensor.d.ts +1 -2
  15. package/build/dist/source/html/sensors/ButtonSensor.js +2 -2
  16. package/build/dist/source/html/sensors/DataForSensor.d.ts +1 -0
  17. package/build/dist/source/html/sensors/DataForSensor.js +3 -3
  18. package/build/dist/source/html/sensors/FocusSensor.js +1 -1
  19. package/build/dist/source/html/sensors/HtmlDragSensor.d.ts +1 -2
  20. package/build/dist/source/html/sensors/HtmlDragSensor.js +2 -2
  21. package/build/dist/source/html/sensors/HtmlElementSensor.d.ts +1 -2
  22. package/build/dist/source/html/sensors/HtmlElementSensor.js +1 -6
  23. package/build/dist/source/html/sensors/HtmlSensors.js +3 -3
  24. package/build/dist/source/html/sensors/KeyboardSensor.d.ts +1 -0
  25. package/build/dist/source/html/sensors/KeyboardSensor.js +5 -0
  26. package/build/dist/source/html/sensors/PointerSensor.d.ts +1 -2
  27. package/build/dist/source/html/sensors/PointerSensor.js +2 -2
  28. package/package.json +1 -1
@@ -1,9 +1,8 @@
1
- import { RxNode, Mode } from "reactronic";
2
- import { Constants, CursorCommandDriver, ElKind, ElDriver, SplitView, ElLayoutInfo, InitialElLayoutInfo } from "./El.js";
3
- import { getPrioritiesForEmptySpaceDistribution, relayout, relayoutUsingSplitter } from "./SplitViewMath.js";
1
+ import { RxNode, Mode, unobs } from "reactronic";
2
+ import { Constants, CursorCommandDriver, ElKind, ElDriver, Direction, ElLayoutInfo, InitialElLayoutInfo } from "./El.js";
3
+ import { getPrioritiesForEmptySpaceDistribution, getPrioritiesForSizeChanging, relayout, relayoutUsingSplitter } from "./SplitViewMath.js";
4
4
  import { Axis, BodyFontSize, Dimension, toPx } from "./Sizes.js";
5
5
  import { HtmlDriver } from "./HtmlDriver.js";
6
- import { OnResize } from "./Handlers.js";
7
6
  import { clamp } from "./ElUtils.js";
8
7
  export function Section(declaration, preset) {
9
8
  return RxNode.declare(Drivers.section, declaration, preset);
@@ -35,6 +34,7 @@ export function declareSplitter(index, splitViewNode) {
35
34
  return (Splitter({
36
35
  key,
37
36
  mode: Mode.independentUpdate,
37
+ onCreate: el => el.native.className = `splitter ${key}`,
38
38
  onChange: b => {
39
39
  const e = b.native;
40
40
  const model = b.model;
@@ -49,13 +49,13 @@ export function declareSplitter(index, splitViewNode) {
49
49
  if (pointer.draggingOver) {
50
50
  pointer.dropAllowed = true;
51
51
  const initialSizesPx = pointer.getData();
52
- const deltaPx = Math.floor(splitViewNode.element.splitView === SplitView.horizontal
52
+ const deltaPx = Math.floor(splitViewNode.element.splitView === Direction.horizontal
53
53
  ? pointer.positionX - pointer.startX : pointer.positionY - pointer.startY);
54
54
  const clonedSizesPx = [];
55
55
  for (const item of initialSizesPx) {
56
56
  clonedSizesPx.push({ node: item.node, sizePx: item.sizePx });
57
57
  }
58
- relayoutUsingSplitter(splitViewNode, deltaPx, index, clonedSizesPx);
58
+ unobs(() => relayoutUsingSplitter(splitViewNode, deltaPx, index, clonedSizesPx));
59
59
  if (pointer.dropped) {
60
60
  (_a = model === null || model === void 0 ? void 0 : model.droppedAction) === null || _a === void 0 ? void 0 : _a.call(model, pointer);
61
61
  }
@@ -70,7 +70,6 @@ export function declareSplitter(index, splitViewNode) {
70
70
  initialSizesPx.push({ node: child, sizePx });
71
71
  }
72
72
  }
73
- console.log("initial", initialSizesPx.map(x => x.sizePx).join(", "));
74
73
  pointer.setData(initialSizesPx);
75
74
  }
76
75
  if (pointer.dragFinished) {
@@ -114,55 +113,103 @@ export class SectionDriver extends HtmlDriver {
114
113
  rowBreak();
115
114
  const result = super.update(node);
116
115
  const el = node.element;
117
- if (el.splitView !== undefined) {
118
- const native = el.native;
119
- OnResize(native, x => {
120
- var _a;
121
- if (el.layoutInfo === undefined)
122
- el.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
123
- const rect = x.contentRect;
124
- const contentBoxPx = x.contentBoxSize[0];
125
- const containerSizeXpx = contentBoxPx.inlineSize;
126
- const containerSizeYpx = contentBoxPx.blockSize;
127
- el.layoutInfo.offsetXpx = rect.left;
128
- el.layoutInfo.offsetYpx = rect.top;
129
- el.layoutInfo.containerSizeXpx = containerSizeXpx;
130
- el.layoutInfo.containerSizeYpx = containerSizeYpx;
131
- const isHorizontal = el.splitView === SplitView.horizontal;
132
- const wrapper = (_a = node.children.firstMergedItem()) === null || _a === void 0 ? void 0 : _a.instance;
133
- if (wrapper !== undefined) {
134
- const wrapperEl = wrapper.element;
135
- if (isHorizontal)
136
- wrapperEl.style.width = wrapperEl.style.maxWidth = `${containerSizeXpx}px`;
137
- else {
138
- wrapperEl.style.height = wrapperEl.style.maxHeight = `${containerSizeYpx}px`;
116
+ if (el.sealed !== undefined) {
117
+ Handling(h => {
118
+ var _a, _b;
119
+ const native = el.native;
120
+ const resize = native.sensors.resize;
121
+ const isHorizontal = el.sealed === Direction.horizontal;
122
+ for (const x of resize.resizedElements) {
123
+ if (el.layoutInfo === undefined)
124
+ el.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
125
+ const rect = x.contentRect;
126
+ const contentBoxPx = x.contentBoxSize[0];
127
+ const containerSizeXpx = contentBoxPx.inlineSize;
128
+ const containerSizeYpx = contentBoxPx.blockSize;
129
+ el.layoutInfo.offsetXpx = rect.left;
130
+ el.layoutInfo.offsetYpx = rect.top;
131
+ el.layoutInfo.contentSizeXpx = containerSizeXpx;
132
+ el.layoutInfo.contentSizeYpx = containerSizeYpx;
133
+ el.layoutInfo.borderSizeXpx = x.borderBoxSize[0].inlineSize;
134
+ el.layoutInfo.borderSizeYpx = x.borderBoxSize[0].blockSize;
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`;
139
143
  }
140
144
  }
141
- const surroundingXpx = x.borderBoxSize[0].inlineSize - containerSizeXpx;
142
- const surroundingYpx = x.borderBoxSize[0].blockSize - containerSizeYpx;
143
- const sizesPx = [];
144
- for (const child of node.children.items()) {
145
- const partEl = child.instance.element;
146
- if (isSplitViewPartition(child.instance.driver) && partEl !== undefined) {
147
- const size = isHorizontal ? partEl.width : partEl.height;
148
- const options = {
149
- axis: isHorizontal ? Axis.X : Axis.Y, lineSizePx: Dimension.lineSizePx, fontSizePx: BodyFontSize,
150
- containerSizeXpx: native.scrollWidth - surroundingXpx, containerSizeYpx: native.scrollHeight - surroundingYpx,
151
- };
152
- const minPx = size.min ? toPx(Dimension.parse(size.min), options) : 0;
153
- let maxPx = size.max ? toPx(Dimension.parse(size.max), options) : Number.POSITIVE_INFINITY;
154
- maxPx = Math.max(minPx, maxPx);
155
- if (partEl.layoutInfo === undefined)
156
- partEl.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
145
+ if (h.node.stamp === 1) {
146
+ const wrapper = (_b = node.children.firstMergedItem()) === null || _b === void 0 ? void 0 : _b.instance;
147
+ if (wrapper !== undefined) {
148
+ const wrapperEl = wrapper.element;
157
149
  if (isHorizontal)
158
- partEl.widthPx = { minPx, maxPx };
150
+ wrapperEl.style.width = wrapperEl.style.maxWidth = "0px";
159
151
  else
160
- partEl.heightPx = { minPx, maxPx };
161
- const sizePx = partEl.layoutInfo.effectiveSizePx = clamp(partEl.layoutInfo.effectiveSizePx, minPx, maxPx);
162
- sizesPx.push({ node: child.instance, sizePx });
152
+ wrapperEl.style.height = wrapperEl.style.maxHeight = "0px";
163
153
  }
164
154
  }
165
- relayout(node, getPrioritiesForEmptySpaceDistribution(node.children), sizesPx);
155
+ });
156
+ }
157
+ if (el.splitView !== undefined) {
158
+ SyntheticElement({
159
+ mode: Mode.independentUpdate,
160
+ triggers: { count: el.node.stamp },
161
+ onChange: () => {
162
+ const native = el.native;
163
+ const isHorizontal = el.splitView === Direction.horizontal;
164
+ if (el.layoutInfo === undefined)
165
+ el.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
166
+ if (el.layoutInfo.isConstrained) {
167
+ const surroundingXpx = el.layoutInfo.borderSizeXpx - el.layoutInfo.contentSizeXpx;
168
+ const surroundingYpx = el.layoutInfo.borderSizeYpx - el.layoutInfo.contentSizeYpx;
169
+ let i = 0;
170
+ const preferred = [];
171
+ const sizesPx = [];
172
+ for (const child of node.children.items()) {
173
+ const partEl = child.instance.element;
174
+ if (isSplitViewPartition(child.instance.driver) && partEl !== undefined) {
175
+ const size = isHorizontal ? partEl.width : partEl.height;
176
+ const options = {
177
+ axis: isHorizontal ? Axis.X : Axis.Y, lineSizePx: BodyFontSize, fontSizePx: BodyFontSize,
178
+ containerSizeXpx: native.scrollWidth - surroundingXpx, containerSizeYpx: native.scrollHeight - surroundingYpx,
179
+ };
180
+ const minPx = size.min ? toPx(Dimension.parse(size.min), options) : 0;
181
+ let maxPx = size.max ? toPx(Dimension.parse(size.max), options) : Number.POSITIVE_INFINITY;
182
+ maxPx = Math.max(minPx, maxPx);
183
+ if (partEl.layoutInfo === undefined)
184
+ partEl.layoutInfo = new ElLayoutInfo(InitialElLayoutInfo);
185
+ if (isHorizontal)
186
+ partEl.widthPx = { minPx, maxPx };
187
+ else
188
+ partEl.heightPx = { minPx, maxPx };
189
+ const preferredUsed = isHorizontal ? partEl.preferredWidthUsed : partEl.preferredHeightUsed;
190
+ let preferredPx = 0;
191
+ if (!preferredUsed) {
192
+ preferredPx = size.preferred ? toPx(Dimension.parse(size.preferred), options) : 0;
193
+ if (preferredPx > 0) {
194
+ partEl.layoutInfo.effectiveSizePx = preferredPx;
195
+ preferred.push(i);
196
+ }
197
+ if (isHorizontal)
198
+ partEl.preferredWidthUsed = true;
199
+ else
200
+ partEl.preferredHeightUsed = true;
201
+ }
202
+ const sizePx = partEl.layoutInfo.effectiveSizePx = clamp(partEl.layoutInfo.effectiveSizePx, minPx, maxPx);
203
+ sizesPx.push({ node: child.instance, sizePx });
204
+ i++;
205
+ }
206
+ }
207
+ const priorities = preferred.length > 0
208
+ ? getPrioritiesForSizeChanging(isHorizontal, node.children, preferred)
209
+ : getPrioritiesForEmptySpaceDistribution(isHorizontal, node.children);
210
+ unobs(() => relayout(node, priorities.resizable, priorities.manuallyResizable, sizesPx));
211
+ }
212
+ },
166
213
  });
167
214
  }
168
215
  return result;
@@ -171,25 +218,28 @@ export class SectionDriver extends HtmlDriver {
171
218
  var _a;
172
219
  let result = undefined;
173
220
  const el = ownerNode.element;
174
- if (el.splitView !== undefined && isSplitViewPartition(childDriver)) {
175
- let partCount = 0;
176
- for (const child of ownerNode.children.items()) {
177
- if (isSplitViewPartition(child.instance.driver))
178
- partCount++;
179
- }
180
- const isHorizontal = el.splitView === SplitView.horizontal;
181
- if (childDeclaration !== undefined) {
182
- const onCreate = childDeclaration.onCreate;
183
- childDeclaration.onCreate = (el, basis) => {
184
- onCreate === null || onCreate === void 0 ? void 0 : onCreate(el, basis);
185
- if (isHorizontal)
186
- el.style.gridColumn = `${partCount + 1}`;
187
- else
188
- el.style.gridRow = `${partCount + 1}`;
189
- };
221
+ if (el.splitView !== undefined) {
222
+ if (isSplitViewPartition(childDriver)) {
223
+ let partCount = 0;
224
+ for (const child of ownerNode.children.items()) {
225
+ if (isSplitViewPartition(child.instance.driver))
226
+ partCount++;
227
+ }
228
+ const isHorizontal = el.splitView === Direction.horizontal;
229
+ if (childDeclaration !== undefined) {
230
+ if (childDeclaration.triggers === undefined)
231
+ childDeclaration.triggers = {};
232
+ Object.defineProperty(childDeclaration.triggers, "index", { value: partCount });
233
+ overrideMethod(childDeclaration, "onChange", el => {
234
+ if (isHorizontal)
235
+ el.style.gridColumn = `${partCount + 1}`;
236
+ else
237
+ el.style.gridRow = `${partCount + 1}`;
238
+ });
239
+ }
240
+ if (partCount > 0)
241
+ declareSplitter(partCount - 1, ownerNode);
190
242
  }
191
- if (partCount > 0)
192
- declareSplitter(partCount - 1, ownerNode);
193
243
  }
194
244
  else {
195
245
  if (childDriver.isPartition) {
@@ -204,6 +254,12 @@ export class SectionDriver extends HtmlDriver {
204
254
  export function isSplitViewPartition(childDriver) {
205
255
  return !childDriver.isPartition && childDriver !== Drivers.splitter && childDriver !== Drivers.synthetic;
206
256
  }
257
+ function overrideMethod(declaration, method, func) {
258
+ const baseOnChange = declaration[method];
259
+ declaration[method] = baseOnChange !== undefined
260
+ ? (el, base) => { baseOnChange(el, base); func(el); }
261
+ : (el, base) => { base(); func(el); };
262
+ }
207
263
  export const Drivers = {
208
264
  section: new SectionDriver(Constants.element, false, el => el.kind = ElKind.section),
209
265
  table: new HtmlDriver(Constants.element, false, el => el.kind = ElKind.table),
@@ -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;
@@ -44,6 +44,8 @@ export function OnFocus(target, model, switchEditMode = undefined, key) {
44
44
  el.node.configureReactronic({ throttling: 0 });
45
45
  },
46
46
  onChange: el => {
47
+ if (switchEditMode === undefined && !target.hasAttribute("tabindex"))
48
+ console.warn(`"${key !== null && key !== void 0 ? key : "noname"}" element must have "tabindex" attribute set in order to be focusable`);
47
49
  if (switchEditMode !== undefined) {
48
50
  switchEditMode(model);
49
51
  }
@@ -1,18 +1,27 @@
1
- import { MergeList, MergedItem, RxNode } from "reactronic";
1
+ import { MergeList, RxNode } from "reactronic";
2
2
  import { ElImpl } from "./El.js";
3
+ export declare function equal(a: number, b: number): boolean;
4
+ export declare function less(a: number, b: number): boolean;
5
+ export declare function greater(a: number, b: number): boolean;
3
6
  export declare function relayoutUsingSplitter(splitViewNode: RxNode<ElImpl>, deltaPx: number, index: number, initialSizesPx: Array<{
4
7
  node: RxNode<ElImpl>;
5
8
  sizePx: number;
6
9
  }>, priorities?: ReadonlyArray<number>): void;
7
- export declare function relayout(splitViewNode: RxNode<ElImpl>, priorities: ReadonlyArray<number>, sizesPx: Array<{
10
+ export declare function relayout(splitViewNode: RxNode<ElImpl>, priorities: ReadonlyArray<number>, manuallyResizablePriorities: ReadonlyArray<number>, sizesPx: Array<{
8
11
  node: RxNode<ElImpl>;
9
12
  sizePx: number;
10
13
  }>): void;
11
- export declare function resizeUsingDelta(splitViewNode: RxNode<ElImpl>, containerSizePx: number, deltaPx: number, index: number, priorities: ReadonlyArray<number>, sizesPx: Array<{
14
+ export declare function resizeUsingDelta(splitViewNode: RxNode<ElImpl>, deltaPx: number, index: number, priorities: ReadonlyArray<number>, sizesPx: Array<{
12
15
  node: RxNode<ElImpl>;
13
16
  sizePx: number;
14
- }>, force?: boolean): void;
17
+ }>, force?: boolean): number;
15
18
  export declare function layout(splitViewNode: RxNode<ElImpl>): void;
16
19
  export declare function getPrioritiesForSplitter(index: number, size: number): ReadonlyArray<number>;
17
- export declare function getPrioritiesForSizeChanging(item: MergedItem<any>, children: MergeList<RxNode>): ReadonlyArray<number>;
18
- export declare function getPrioritiesForEmptySpaceDistribution(children: MergeList<RxNode>): ReadonlyArray<number>;
20
+ export declare function getPrioritiesForSizeChanging(isHorizontal: boolean, children: MergeList<RxNode>, indexes: Array<number>): {
21
+ resizable: ReadonlyArray<number>;
22
+ manuallyResizable: ReadonlyArray<number>;
23
+ };
24
+ export declare function getPrioritiesForEmptySpaceDistribution(isHorizontal: boolean, children: MergeList<RxNode>): {
25
+ resizable: ReadonlyArray<number>;
26
+ manuallyResizable: ReadonlyArray<number>;
27
+ };