@nebularstreams/libmui 2.0.2 → 2.0.3

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.
@@ -0,0 +1,46 @@
1
+
2
+ .flexcol {
3
+ flex-direction: column;
4
+ display: flex
5
+ }
6
+
7
+ .flexrow {
8
+ flex-direction: row;
9
+ display: flex
10
+ }
11
+
12
+ .grows {
13
+ flex-grow: 1;
14
+ }
15
+
16
+ .noshrink {
17
+ flex-shrink: 0;
18
+ }
19
+
20
+ .h-100 {
21
+ height: -webkit-fill-available;
22
+ }
23
+
24
+ .w-100 {
25
+ width: -webkit-fill-available;
26
+ }
27
+
28
+ .relative {
29
+ position: relative;
30
+ }
31
+
32
+ .absolute {
33
+ position: absolute;
34
+ }
35
+
36
+ .unitheight {
37
+ height: 2.54rem;
38
+ }
39
+
40
+ .pad-2 {
41
+ padding: 0.5rem;
42
+ }
43
+
44
+ .scaff-bottom {
45
+ border-bottom: solid 1px var(--border-color);
46
+ }
package/src/index.js ADDED
@@ -0,0 +1,34 @@
1
+ import m from "mithril";
2
+
3
+ import {Button, ButtonNew, Icon, Empty, Selector} from "./widgets/Basic";
4
+ import CardieWidget from "./widgets/CardieWidget";
5
+ import InputWidget from "./widgets/InputWidget";
6
+ import NoticeWidget from "./widgets/NoticeWidget";
7
+ import SwitchWidget from "./widgets/SwitchWidget";
8
+ import * as OverflowUtils from "./widgets/OverflowUtils";
9
+ import {clearModal, popupMessage} from "./util/widgets";
10
+ import Separator from "./widgets/Separator";
11
+ import RangeWidget from "./widgets/RangeWidget";
12
+ import startApp from "./app/app"
13
+ import defineWidget from "./util/widgets.utils";
14
+
15
+ import "./style.js"
16
+
17
+ export {
18
+ Button,
19
+ ButtonNew,
20
+ CardieWidget,
21
+ Empty,
22
+ Icon,
23
+ InputWidget,
24
+ NoticeWidget,
25
+ OverflowUtils,
26
+ RangeWidget,
27
+ Selector,
28
+ SwitchWidget,
29
+ Separator,
30
+ clearModal,
31
+ popupMessage,
32
+ startApp,
33
+ defineWidget
34
+ }
package/src/style.js ADDED
@@ -0,0 +1,9 @@
1
+ import "./css/body.css"
2
+ import "./css/flex.css"
3
+ import "./css/cardie.css"
4
+ import "./css/b-root.css"
5
+ import "./css/b-root-bootstrap.css"
6
+ import "./css/b-root-bootstrap-ext.css"
7
+ import "./css/b-root-semantic-flex.css"
8
+ import "./css/b-root-semantic-size.css"
9
+ import "./css/a-measures.css"
@@ -0,0 +1,28 @@
1
+ import {ConfirmPromise} from "./widgets.core";
2
+
3
+ function confirm(text, onAction, onCancel = undefined, optionYes = "YES", optionNo = "NO") {
4
+ ConfirmPromise(null, text, [optionNo, optionYes], onCancel)
5
+ .then(({idx}) => {
6
+ if (idx) onAction(idx); else if (onCancel) onCancel();
7
+ })
8
+ .catch(() => {
9
+ if (onCancel) onCancel();
10
+ });
11
+ }
12
+
13
+ function confirmPromise(text, options = ["NO", "YES"], cancelError = "cancelled") {
14
+
15
+ return new Promise((resolve, reject) => {
16
+ ConfirmPromise(null, text, options, () => reject(new Error(cancelError)))
17
+ .then(({idx}) => {
18
+ if (idx) {
19
+ resolve(idx);
20
+ } else {
21
+ reject(new Error(cancelError));
22
+ }
23
+ });
24
+ });
25
+
26
+ }
27
+
28
+ export {confirm, confirmPromise};
@@ -0,0 +1,443 @@
1
+ import m from "mithril";
2
+
3
+
4
+ ///////////////////////////////////////////////
5
+ // Mithril Range
6
+ // (c) 2017-2018 by Mike Linkovich
7
+ // https://github.com/spacejack/mithril-range
8
+ // License: MIT
9
+ ///////////////////////////////////////////////
10
+ const
11
+
12
+ NONE = 0,
13
+ MOUSE = 1,
14
+ TOUCH = 2,
15
+
16
+ // So we aren't triggered by echoed mouse events (some mobile browsers)
17
+ DEVICE_DELAY = 350,
18
+
19
+ isIOS = !!navigator.userAgent.match(/iPhone|iPad|iPod/i);
20
+
21
+ // This is some unbelievable stone-age nonsense.
22
+ // Workaround for webkit bug where event.preventDefault
23
+ // within touchmove handler fails to prevent scrolling.
24
+
25
+ let
26
+ iOSHackApplied = false;
27
+
28
+ /** Clamp number to range */
29
+ function clamp(n, min, max) {
30
+ return Math.min(Math.max(n, min), max);
31
+ }
32
+
33
+ function applyIOSHack() {
34
+ // Only apply this hack if iOS, haven't yet applied it,
35
+ // and only if a component is actually created
36
+ if (!isIOS || iOSHackApplied) {
37
+ return;
38
+ }
39
+ window.addEventListener("touchmove", function () {
40
+ });
41
+ iOSHackApplied = true;
42
+ }
43
+
44
+ export function quantize(val, min, max, step) {
45
+ if (max - min <= 0) {
46
+ return min;
47
+ }
48
+ if (step <= 0) {
49
+ return clamp(val, min, max);
50
+ }
51
+ const
52
+ steps = Math.ceil((max - min) / step),
53
+ v = min + Math.round(steps * (val - min) / (max - min)) * step;
54
+ return clamp(v, min, max);
55
+ }
56
+
57
+
58
+ /** Range Component */
59
+ function MithrilRange() {
60
+ let
61
+ elHit,
62
+ elBar,
63
+ elBar0,
64
+ elBar1,
65
+ elHandle,
66
+ rcBar,
67
+ device = NONE,
68
+ pressed = false,
69
+
70
+ useAbsolute = false,
71
+ factorCoarse = 4,
72
+ factorFine = 1,
73
+ absolute,
74
+ lastRead,
75
+
76
+ // Attrs we need to cache
77
+ min = 0,
78
+ max = 10,
79
+ value = 0,
80
+ startValue = 0,
81
+ step = 1,
82
+ orientation = "horizontal",
83
+ onchange,
84
+ ondrag;
85
+
86
+ // App handlers
87
+ function onPressAbsolute(x, y) {
88
+ startValue = value;
89
+ pressed = absolute = true;
90
+ rcBar = elBar.getBoundingClientRect();
91
+ const val = moveHandleAbsolute(x, y);
92
+ if (val !== value) {
93
+ value = val;
94
+ if (ondrag && ondrag(value) !== false) {
95
+ m.redraw();
96
+ }
97
+ }
98
+ }
99
+
100
+ function onPressDelta(x, y, e, isTouch) {
101
+ startValue = value;
102
+ pressed = true;
103
+ absolute = false;
104
+ rcBar = elBar.getBoundingClientRect();
105
+ lastRead = (orientation === "vertical") ? y : x;
106
+ if (!isTouch) e.target.requestPointerLock();
107
+ }
108
+
109
+ function moveHandleAbsolute(x, y) {
110
+
111
+ let
112
+ barLength,
113
+ delta;
114
+
115
+ if (orientation === "vertical") {
116
+
117
+ barLength = rcBar.bottom - rcBar.top;
118
+ delta = rcBar.bottom - y;
119
+
120
+ } else {
121
+ barLength = rcBar.right - rcBar.left;
122
+ delta = x - rcBar.left;
123
+ }
124
+
125
+ delta = clamp(delta, 0, barLength);
126
+ const val = quantize((delta / barLength) * (max - min) + min, min, max, step);
127
+ setStyles(val);
128
+ return val;
129
+ }
130
+
131
+ function moveHandleDelta(x, y, event) {
132
+
133
+ const
134
+ factor = event.shiftKey
135
+ ? factorCoarse
136
+ : (event.metaKey || event.ctrlKey)
137
+ ? 4 * factorCoarse
138
+ : factorFine;
139
+
140
+ let
141
+ delta;
142
+
143
+ if (orientation === "vertical") {
144
+ delta = event.movementY || 0;
145
+ } else {
146
+ delta = event.movementX || 0;
147
+ }
148
+
149
+ let newVal;
150
+ let s = step > 0 ? step : (max - min) / 100;
151
+
152
+ if (delta < 0) {
153
+ newVal = Math.max(value + s * factor * delta, min);
154
+ } else if (delta > 0) { // right/up
155
+ newVal = Math.min(value + s * factor * delta, max);
156
+ } else {
157
+ return value;
158
+ }
159
+
160
+ newVal = quantize(newVal, min, max, step);
161
+
162
+ setStyles(newVal);
163
+ return newVal;
164
+
165
+ }
166
+
167
+ function onPress(x, y, event) {
168
+ return useAbsolute
169
+ ? onPressAbsolute(x, y, event)
170
+ : onPressDelta(x, y, event);
171
+ }
172
+
173
+ function moveHandle(x, y, event) {
174
+ return absolute
175
+ ? moveHandleAbsolute(x, y, event)
176
+ : moveHandleDelta(x, y, event);
177
+ }
178
+
179
+ // Event handlers
180
+ function onMouseDown(e) {
181
+ if (device === TOUCH) {
182
+ return;
183
+ }
184
+ device = MOUSE;
185
+ if (e.button !== 0) {
186
+ return;
187
+ }
188
+ window.addEventListener("mousemove", onMouseMove);
189
+ window.addEventListener("mouseup", onMouseUp);
190
+ onPress(e.clientX, e.clientY, e);
191
+ }
192
+
193
+ function onMouseMove(e) {
194
+ e.preventDefault();
195
+ onMove(e.clientX, e.clientY, e);
196
+ }
197
+
198
+ function onMouseUp(e) {
199
+ window.removeEventListener("mousemove", onMouseMove);
200
+ window.removeEventListener("mouseup", onMouseUp);
201
+ onRelease(e.clientX, e.clientY, e);
202
+ }
203
+
204
+ function onTouchStart(e) {
205
+ if (device === MOUSE) {
206
+ return;
207
+ }
208
+ elHit.addEventListener("touchmove", onTouchMove);
209
+ elHit.addEventListener("touchend", onTouchEnd);
210
+ const t = e.changedTouches[0];
211
+ onPress(t.clientX, t.clientY, e, true);
212
+ }
213
+
214
+ function onTouchMove(e) {
215
+ e.preventDefault();
216
+ const t = e.changedTouches[0];
217
+ onMove(t.clientX, t.clientY, e);
218
+ }
219
+
220
+ function onTouchEnd(e) {
221
+ elHit.removeEventListener("touchmove", onTouchMove);
222
+ elHit.removeEventListener("touchend", onTouchEnd);
223
+ const t = e.changedTouches[0];
224
+ onRelease(t.clientX, t.clientY, t);
225
+ }
226
+
227
+ function onKeyDown(e) {
228
+
229
+ const k = e.keyCode;
230
+ let newVal;
231
+
232
+ if (k === 33) { // pgup
233
+ e.preventDefault();
234
+ let s = Math.max((max - min) / 10, step);
235
+ if (s <= 0) {
236
+ s = 1;
237
+ }
238
+ newVal = quantize(value + s, min, max, step);
239
+ } else if (k === 34) { // pgdown
240
+ e.preventDefault();
241
+ let s = Math.max((max - min) / 10, step);
242
+ if (s <= 0) {
243
+ s = 1;
244
+ }
245
+ newVal = quantize(value - s, min, max, step);
246
+ } else if (k === 35) { // end
247
+ e.preventDefault();
248
+ newVal = max;
249
+ } else if (k === 36) { // home
250
+ e.preventDefault();
251
+ newVal = min;
252
+ } else if (k === 37 || k === 40) { // left/down
253
+ e.preventDefault();
254
+ let s = (step > 0 ? step : (max - min) / 10) * (e.shiftKey ? 0.25 : (e.ctrlKey || e.metaKey) ? 4 : 1);
255
+ newVal = Math.max(value - s, min);
256
+ } else if (k === 38 || k === 39) { // right/up
257
+ e.preventDefault();
258
+ let s = (step > 0 ? step : (max - min) / 10) * (e.shiftKey ? 0.25 : (e.ctrlKey || e.metaKey) ? 4 : 1);
259
+ newVal = Math.min(value + s, max);
260
+ } else if (k === 48) { // 0
261
+ newVal = (max + min) / 2;
262
+ }
263
+ if (typeof newVal !== "number" || newVal === value) {
264
+ return; // no change to make
265
+ }
266
+ value = newVal;
267
+ setStyles(value);
268
+ if (onchange && onchange(value) !== false) {
269
+ m.redraw();
270
+ }
271
+ }
272
+
273
+ function onMove(x, y, event) {
274
+ if (!pressed) {
275
+ return;
276
+ }
277
+
278
+ const val = moveHandle(x, y, event);
279
+ if (val !== value) {
280
+ value = val;
281
+ if (ondrag && ondrag(value) !== false) {
282
+ m.redraw();
283
+ }
284
+ }
285
+ }
286
+
287
+ function onRelease(x, y, e) {
288
+
289
+ if (!pressed) {
290
+ return;
291
+ }
292
+
293
+ pressed = false;
294
+ value = moveHandle(x, y, e);
295
+
296
+ if (onchange && onchange(value) !== false) {
297
+ m.redraw();
298
+ }
299
+
300
+ /*
301
+ if (value !== startValue) {
302
+ if (onchange && onchange(value) !== false) {
303
+ m.redraw();
304
+ }
305
+ }
306
+ */
307
+
308
+ if (!absolute) document.exitPointerLock();
309
+
310
+ setTimeout(function () {
311
+ if (!pressed) {
312
+ device = NONE;
313
+ }
314
+ }, DEVICE_DELAY);
315
+ }
316
+
317
+ /** Compute handle position style */
318
+ function positionStyle(val) {
319
+ let s = (val - min) / (max - min);
320
+ if (orientation === "vertical") {
321
+ s = 1.0 - s;
322
+ }
323
+ return String(100 * s) + "%";
324
+ }
325
+
326
+ /** Set styles for movable parts */
327
+ function setStyles(value) {
328
+ const
329
+ ps = positionStyle(value),
330
+ rps = positionStyle(max - value + min);
331
+
332
+ if (orientation === "vertical") {
333
+ elHandle.style.top = ps;
334
+ elBar0.style.height = ps;
335
+ elBar1.style.height = rps;
336
+ } else {
337
+ elHandle.style.left = ps;
338
+ elBar0.style.width = rps;
339
+ elBar1.style.width = ps;
340
+ }
341
+ }
342
+
343
+ /** Some attrs need to be cached (and updated) so that they are current in event handlers */
344
+ function updateAttrs(attrs) {
345
+ min = attrs.min;
346
+ max = attrs.max;
347
+ step = (typeof attrs.step === "number" && !Number.isNaN(attrs.step))
348
+ ? clamp(attrs.step, 0, max - min) : 1;
349
+ orientation = attrs.orientation === "vertical" ? "vertical" : "horizontal";
350
+ onchange = attrs.onchange;
351
+ ondrag = attrs.ondrag;
352
+ if (typeof attrs.value === "number") {
353
+ value = clamp(attrs.value, min, max);
354
+ }
355
+ useAbsolute = !attrs.relative;
356
+ factorCoarse = (attrs.factor && attrs.factor[0]) || 4;
357
+ factorFine = (attrs.factor && attrs.factor[1]) || 1;
358
+
359
+ }
360
+
361
+ /** Return mithril component hooks object */
362
+ return {
363
+ oncreate: ({attrs, dom}) => {
364
+ applyIOSHack();
365
+ updateAttrs(attrs);
366
+ elHit = dom;
367
+ elBar = elHit.querySelector(".mithril-range-bar");
368
+ elBar0 = elBar.querySelector(".mithril-range-bar-0");
369
+ elBar1 = elBar.querySelector(".mithril-range-bar-1");
370
+ elHandle = elBar.querySelector(".mithril-range-handle");
371
+ elHit.addEventListener("mousedown", onMouseDown);
372
+ elHit.addEventListener("touchstart", onTouchStart);
373
+ elHit.addEventListener("keydown", onKeyDown);
374
+ },
375
+ onremove: function () {
376
+ window.removeEventListener("mousemove", onMouseMove);
377
+ window.removeEventListener("mouseup", onMouseUp);
378
+ elHit.removeEventListener("mousedown", onMouseDown);
379
+ elHit.removeEventListener("touchstart", onTouchStart);
380
+ elHit.removeEventListener("touchmove", onTouchMove);
381
+ elHit.removeEventListener("touchend", onTouchEnd);
382
+ elHit.removeEventListener("keydown", onKeyDown);
383
+ },
384
+ view: function ({attrs, children}) {
385
+
386
+ updateAttrs(attrs);
387
+ value = quantize(value, min, max, step);
388
+ const a = {
389
+ class: "mithril-range nokey" + (attrs.relative ? " isrelative " : " ") + (value === 0 ? "atzero" : value < 0 ? "belowzero" : "overzero") + (attrs.class != null ? " " + attrs.class : ""),
390
+ tabIndex: "0",
391
+ role: "slider",
392
+ "aria-valuemin": String(min),
393
+ "aria-valuemax": String(max),
394
+ "aria-valuenow": String(value),
395
+ "aria-orientation": orientation
396
+ };
397
+ if (attrs.id) {
398
+ a.id = attrs.id;
399
+ }
400
+ // noinspection JSUnresolvedVariable
401
+ if (attrs.ariaLabelledby) {
402
+ a["aria-labelledby"] = attrs.ariaLabelledby;
403
+ }
404
+ if (attrs.disabled) {
405
+ a.style = {pointerEvents: "none"};
406
+ a["aria-disabled"] = "true";
407
+ }
408
+ const
409
+ ps = positionStyle(value),
410
+ rps = positionStyle(max - value + min);
411
+ let
412
+ handleStyle,
413
+ bar0Style,
414
+ bar1Style;
415
+
416
+ if (orientation === "vertical") {
417
+ handleStyle = {top: ps};
418
+ bar0Style = {height: ps};
419
+ bar1Style = {height: rps};
420
+ } else {
421
+ handleStyle = {left: ps};
422
+ bar0Style = {width: rps};
423
+ bar1Style = {width: ps};
424
+ }
425
+ return m("div", a, m("div", {class: "mithril-range-bar nokey"}, m("div", {
426
+ class: "mithril-range-bar-0 nokey",
427
+ style: bar0Style
428
+ }), m("div", {
429
+ class: "mithril-range-bar-1 nokey",
430
+ style: bar1Style
431
+ }), m("div", {
432
+ class: "mithril-range-handle nokey",
433
+ style: handleStyle
434
+ }, children)), !!attrs.name && m("input", {
435
+ type: "hidden",
436
+ name: attrs.name,
437
+ value: String(value)
438
+ }));
439
+ }
440
+ };
441
+ }
442
+
443
+ export default MithrilRange;
@@ -0,0 +1,8 @@
1
+ const
2
+ ENABLE_SCLONE = true, // atm SLOWER than JSON
3
+ softClone = (o) => JSON.parse(JSON.stringify(o)),
4
+ clone = window.structuredClone && ENABLE_SCLONE
5
+ ? window.structuredClone
6
+ : softClone;
7
+
8
+ export default clone;