@thi.ng/hdom-components 5.1.80 → 5.1.82
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/CHANGELOG.md +1 -1
- package/button-group.js +28 -42
- package/button.js +27 -43
- package/canvas.js +36 -72
- package/dropdown.js +16 -10
- package/fps-counter.js +46 -49
- package/link.js +18 -14
- package/notification.js +11 -26
- package/package.json +12 -10
- package/pager.js +52 -81
- package/sparkline.js +51 -48
- package/title.js +17 -30
- package/toggle.js +88 -88
- package/utils/merge-attribs.js +10 -17
package/CHANGELOG.md
CHANGED
package/button-group.js
CHANGED
|
@@ -1,47 +1,33 @@
|
|
|
1
1
|
import { mergeAttribs } from "./utils/merge-attribs.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* - hdom context object (unused)
|
|
8
|
-
* - partial {@link ButtonGroupArgs} object (extra attribs, disabled flag)
|
|
9
|
-
* - button group items (varargs)
|
|
10
|
-
*
|
|
11
|
-
* Any `attribs` provided as arg via {@link ButtonGroupArgs} are merged with
|
|
12
|
-
* the default options provided to the HOF. If `disabled` is true, ALL
|
|
13
|
-
* buttons in the group will be disabled, regardless of their individual
|
|
14
|
-
* settings. The group can have any number of elements, given as
|
|
15
|
-
* varargs.
|
|
16
|
-
*
|
|
17
|
-
* @param opts -
|
|
18
|
-
*/
|
|
19
|
-
export const buttonGroup = (opts) => (_, args, ...buttons) => [
|
|
20
|
-
"div",
|
|
21
|
-
mergeAttribs(opts.attribs, args.attribs),
|
|
22
|
-
...groupBody(opts, args.disabled, buttons),
|
|
2
|
+
const buttonGroup = (opts) => (_, args, ...buttons) => [
|
|
3
|
+
"div",
|
|
4
|
+
mergeAttribs(opts.attribs, args.attribs),
|
|
5
|
+
...groupBody(opts, args.disabled, buttons)
|
|
23
6
|
];
|
|
24
7
|
const groupBody = (opts, disabled, buttons) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
8
|
+
switch (buttons.length) {
|
|
9
|
+
case 0:
|
|
10
|
+
return [];
|
|
11
|
+
case 1:
|
|
12
|
+
return [bt(opts.inner || opts.first, disabled, buttons[0])];
|
|
13
|
+
case 2:
|
|
14
|
+
return [
|
|
15
|
+
bt(opts.first, disabled, buttons[0]),
|
|
16
|
+
bt(opts.last || opts.first, disabled, buttons[1])
|
|
17
|
+
];
|
|
18
|
+
default: {
|
|
19
|
+
const res = [bt(opts.first, disabled, buttons[0])];
|
|
20
|
+
const el = opts.inner || opts.first;
|
|
21
|
+
const n = buttons.length - 1;
|
|
22
|
+
for (let i = 1; i < n; i++) {
|
|
23
|
+
res[i] = bt(el, disabled, buttons[i]);
|
|
24
|
+
}
|
|
25
|
+
res[n] = bt(opts.last || opts.first, disabled, buttons[n]);
|
|
26
|
+
return res;
|
|
45
27
|
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const bt = (el, disabled, bt2) => disabled ? [el, { ...bt2[0], disabled: true }, ...bt2.slice(1)] : [el, ...bt2];
|
|
31
|
+
export {
|
|
32
|
+
buttonGroup
|
|
46
33
|
};
|
|
47
|
-
const bt = (el, disabled, bt) => disabled ? [el, { ...bt[0], disabled: true }, ...bt.slice(1)] : [el, ...bt];
|
package/button.js
CHANGED
|
@@ -1,45 +1,29 @@
|
|
|
1
1
|
import { mergeAttribs } from "./utils/merge-attribs.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
{
|
|
30
|
-
...mergeAttribs(opts.attribsDisabled, args.attribs),
|
|
31
|
-
disabled: true,
|
|
32
|
-
},
|
|
33
|
-
...body,
|
|
34
|
-
]
|
|
35
|
-
: [
|
|
36
|
-
opts.tag,
|
|
37
|
-
{
|
|
38
|
-
...mergeAttribs(opts.attribs, args.attribs),
|
|
39
|
-
onclick: opts.preventDefault
|
|
40
|
-
? (e) => (e.preventDefault(), args.onclick(e))
|
|
41
|
-
: args.onclick,
|
|
42
|
-
},
|
|
43
|
-
...body,
|
|
44
|
-
];
|
|
2
|
+
const button = (opts) => {
|
|
3
|
+
opts = {
|
|
4
|
+
tag: "a",
|
|
5
|
+
tagDisabled: "span",
|
|
6
|
+
preventDefault: true,
|
|
7
|
+
attribs: {},
|
|
8
|
+
...opts
|
|
9
|
+
};
|
|
10
|
+
!opts.attribs.role && (opts.attribs.role = "button");
|
|
11
|
+
return (_, args, ...body) => args.disabled ? [
|
|
12
|
+
opts.tagDisabled,
|
|
13
|
+
{
|
|
14
|
+
...mergeAttribs(opts.attribsDisabled, args.attribs),
|
|
15
|
+
disabled: true
|
|
16
|
+
},
|
|
17
|
+
...body
|
|
18
|
+
] : [
|
|
19
|
+
opts.tag,
|
|
20
|
+
{
|
|
21
|
+
...mergeAttribs(opts.attribs, args.attribs),
|
|
22
|
+
onclick: opts.preventDefault ? (e) => (e.preventDefault(), args.onclick(e)) : args.onclick
|
|
23
|
+
},
|
|
24
|
+
...body
|
|
25
|
+
];
|
|
26
|
+
};
|
|
27
|
+
export {
|
|
28
|
+
button
|
|
45
29
|
};
|
package/canvas.js
CHANGED
|
@@ -1,75 +1,39 @@
|
|
|
1
1
|
import { adaptDPI } from "@thi.ng/adapt-dpi";
|
|
2
|
-
/**
|
|
3
|
-
* Configurable canvas component. Used as common base for {@link canvasWebGL}
|
|
4
|
-
* and {@link canvas2D} wrappers.
|
|
5
|
-
*
|
|
6
|
-
* @param type - canvas context type
|
|
7
|
-
* @param handlers - user handlers
|
|
8
|
-
* @param opts - canvas context creation options
|
|
9
|
-
*/
|
|
10
2
|
const _canvas = (type, handlers, opts) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
3
|
+
let el;
|
|
4
|
+
let ctx;
|
|
5
|
+
let frame = 0;
|
|
6
|
+
let time = 0;
|
|
7
|
+
return {
|
|
8
|
+
init(_el, hctx, ...args) {
|
|
9
|
+
el = _el;
|
|
10
|
+
adaptDPI(el, el.width, el.height);
|
|
11
|
+
ctx = el.getContext(type, opts);
|
|
12
|
+
time = Date.now();
|
|
13
|
+
handlers.init && handlers.init(el, ctx, hctx, ...args);
|
|
14
|
+
handlers.update && handlers.update(el, ctx, hctx, time, frame++, ...args);
|
|
15
|
+
},
|
|
16
|
+
render(hctx, ...args) {
|
|
17
|
+
ctx && handlers.update && handlers.update(
|
|
18
|
+
el,
|
|
19
|
+
ctx,
|
|
20
|
+
hctx,
|
|
21
|
+
Date.now() - time,
|
|
22
|
+
frame++,
|
|
23
|
+
...args
|
|
24
|
+
);
|
|
25
|
+
return ["canvas", args[0]];
|
|
26
|
+
},
|
|
27
|
+
release(hctx, ...args) {
|
|
28
|
+
handlers.release && handlers.release(el, ctx, hctx, ...args);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
const canvasWebGL = (handlers, opts) => _canvas("webgl", handlers, opts);
|
|
33
|
+
const canvasWebGL2 = (handlers, opts) => _canvas("webgl2", handlers, opts);
|
|
34
|
+
const canvas2D = (handlers, opts) => _canvas("2d", handlers, opts);
|
|
35
|
+
export {
|
|
36
|
+
canvas2D,
|
|
37
|
+
canvasWebGL,
|
|
38
|
+
canvasWebGL2
|
|
35
39
|
};
|
|
36
|
-
/**
|
|
37
|
-
* Higher order WebGL canvas component delegating to user provided
|
|
38
|
-
* handlers.
|
|
39
|
-
*
|
|
40
|
-
* @remarks
|
|
41
|
-
* Since this is an higher order component, if used within a non-static
|
|
42
|
-
* parent component, this function itself cannot be directly inlined
|
|
43
|
-
* into hdom tree and must be initialized prior/outside, however the
|
|
44
|
-
* returned component can be used as normal.
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* ```ts
|
|
48
|
-
* const glcanvas = canvasWebGL({
|
|
49
|
-
* render(canv, gl, hctx, time, frame, ...args) {
|
|
50
|
-
* const col = 0.5 + 0.5 * Math.sin(time);
|
|
51
|
-
* gl.clearColor(col, col, col, 1);
|
|
52
|
-
* }
|
|
53
|
-
* });
|
|
54
|
-
* ...
|
|
55
|
-
* [glcanvas, {id: "foo", width: 640, height: 480}]
|
|
56
|
-
* ```
|
|
57
|
-
*
|
|
58
|
-
* @param handlers - user provided handlers
|
|
59
|
-
* @param opts - canvas context creation options
|
|
60
|
-
*/
|
|
61
|
-
export const canvasWebGL = (handlers, opts) => _canvas("webgl", handlers, opts);
|
|
62
|
-
/**
|
|
63
|
-
* Same as {@link canvasWebGL} but targets WebGL2.
|
|
64
|
-
*
|
|
65
|
-
* @param handlers - user provided handlers
|
|
66
|
-
* @param opts - canvas context creation options
|
|
67
|
-
*/
|
|
68
|
-
export const canvasWebGL2 = (handlers, opts) => _canvas("webgl2", handlers, opts);
|
|
69
|
-
/**
|
|
70
|
-
* Similar to {@link canvasWebGL}, but targets default 2D drawing context.
|
|
71
|
-
*
|
|
72
|
-
* @param handlers - user provided handlers
|
|
73
|
-
* @param glopts - canvas context creation options
|
|
74
|
-
*/
|
|
75
|
-
export const canvas2D = (handlers, opts) => _canvas("2d", handlers, opts);
|
package/dropdown.js
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
const option = ([value, label, disabled], sel) => [
|
|
2
|
+
"option",
|
|
3
|
+
{ value, disabled: !!disabled, selected: value === sel },
|
|
4
|
+
label
|
|
5
5
|
];
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const optgroup = (attribs, options, sel) => [
|
|
7
|
+
"optgroup",
|
|
8
|
+
{ ...attribs, label: attribs.label || "--" },
|
|
9
|
+
...options.map((o) => option(o, sel))
|
|
10
10
|
];
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const dropdown = (_, attribs, options, sel) => ["select", attribs, ...options.map((o) => option(o, sel))];
|
|
12
|
+
const groupedDropdown = (_, attribs, groups, sel) => ["select", attribs, ...groups.map((o) => optgroup(o[0], o[1], sel))];
|
|
13
|
+
export {
|
|
14
|
+
dropdown,
|
|
15
|
+
groupedDropdown,
|
|
16
|
+
optgroup,
|
|
17
|
+
option
|
|
18
|
+
};
|
package/fps-counter.js
CHANGED
|
@@ -1,53 +1,50 @@
|
|
|
1
1
|
import { sma } from "@thi.ng/transducers-stats/sma";
|
|
2
2
|
import { step } from "@thi.ng/transducers/step";
|
|
3
3
|
import { sparkline } from "./sparkline.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
];
|
|
51
|
-
},
|
|
52
|
-
};
|
|
4
|
+
const fpsCounter = (_opts) => {
|
|
5
|
+
const opts = {
|
|
6
|
+
history: 25,
|
|
7
|
+
smooth: 5,
|
|
8
|
+
labelPeriod: 250,
|
|
9
|
+
sparkline: {},
|
|
10
|
+
..._opts
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
init() {
|
|
14
|
+
this.last = Date.now();
|
|
15
|
+
this.lastLabel = this.last;
|
|
16
|
+
this.buffer = [];
|
|
17
|
+
this.ma = step(sma(opts.smooth));
|
|
18
|
+
},
|
|
19
|
+
render() {
|
|
20
|
+
const t = Date.now();
|
|
21
|
+
const fps = 1e3 / (t - this.last);
|
|
22
|
+
this.last = t;
|
|
23
|
+
if (!this.buffer)
|
|
24
|
+
return ["div"];
|
|
25
|
+
const smoothFps = this.ma(fps);
|
|
26
|
+
if (!smoothFps)
|
|
27
|
+
return ["div"];
|
|
28
|
+
this.buffer.push(smoothFps);
|
|
29
|
+
this.buffer.length > opts.history && this.buffer.shift();
|
|
30
|
+
const updateLabel = t - this.lastLabel > opts.labelPeriod;
|
|
31
|
+
updateLabel && (this.lastLabel = t);
|
|
32
|
+
return [
|
|
33
|
+
"div",
|
|
34
|
+
[
|
|
35
|
+
sparkline,
|
|
36
|
+
{ min: 0, max: 65, ...opts.sparkline },
|
|
37
|
+
this.buffer
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
"span",
|
|
41
|
+
{ __skip: !updateLabel },
|
|
42
|
+
smoothFps ? smoothFps.toFixed(2) + " fps" : ""
|
|
43
|
+
]
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
fpsCounter
|
|
53
50
|
};
|
package/link.js
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { isString } from "@thi.ng/checks/is-string";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
const link = (attribs, body) => [
|
|
3
|
+
"a",
|
|
4
|
+
isString(attribs) ? { href: attribs } : attribs,
|
|
5
|
+
body
|
|
6
6
|
];
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
15
|
-
...attribs,
|
|
7
|
+
const appLink = (_, attribs, onclick, body) => [
|
|
8
|
+
"a",
|
|
9
|
+
{
|
|
10
|
+
href: "#",
|
|
11
|
+
onclick: (e) => {
|
|
12
|
+
e.preventDefault();
|
|
13
|
+
onclick(e);
|
|
16
14
|
},
|
|
17
|
-
|
|
15
|
+
...attribs
|
|
16
|
+
},
|
|
17
|
+
body
|
|
18
18
|
];
|
|
19
|
+
export {
|
|
20
|
+
appLink,
|
|
21
|
+
link
|
|
22
|
+
};
|
package/notification.js
CHANGED
|
@@ -1,28 +1,13 @@
|
|
|
1
1
|
import { appLink } from "./link.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* consists of multiple elements then they will need to be wrapped in a
|
|
14
|
-
* container element.
|
|
15
|
-
*
|
|
16
|
-
* @param opts -
|
|
17
|
-
*/
|
|
18
|
-
export const notification = (opts = {}) => {
|
|
19
|
-
return (_, args, body) => [
|
|
20
|
-
"div",
|
|
21
|
-
{ ...opts.attribs, ...args.attribs },
|
|
22
|
-
opts.icon,
|
|
23
|
-
body,
|
|
24
|
-
opts.close && args.onclose
|
|
25
|
-
? [appLink, opts.attribsClose, args.onclose, opts.close]
|
|
26
|
-
: undefined,
|
|
27
|
-
];
|
|
2
|
+
const notification = (opts = {}) => {
|
|
3
|
+
return (_, args, body) => [
|
|
4
|
+
"div",
|
|
5
|
+
{ ...opts.attribs, ...args.attribs },
|
|
6
|
+
opts.icon,
|
|
7
|
+
body,
|
|
8
|
+
opts.close && args.onclose ? [appLink, opts.attribsClose, args.onclose, opts.close] : void 0
|
|
9
|
+
];
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
notification
|
|
28
13
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/hdom-components",
|
|
3
|
-
"version": "5.1.
|
|
3
|
+
"version": "5.1.82",
|
|
4
4
|
"description": "Raw, skinnable UI & SVG components for @thi.ng/hdom",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -24,7 +24,9 @@
|
|
|
24
24
|
"author": "Karsten Schmidt (https://thi.ng)",
|
|
25
25
|
"license": "Apache-2.0",
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "yarn
|
|
27
|
+
"build": "yarn build:esbuild && yarn build:decl",
|
|
28
|
+
"build:decl": "tsc --declaration --emitDeclarationOnly",
|
|
29
|
+
"build:esbuild": "esbuild --format=esm --platform=neutral --target=es2022 --tsconfig=tsconfig.json --outdir=. src/**/*.ts",
|
|
28
30
|
"clean": "rimraf --glob '*.js' '*.d.ts' '*.map' doc utils",
|
|
29
31
|
"doc": "typedoc --excludePrivate --excludeInternal --out doc src/index.ts",
|
|
30
32
|
"doc:ae": "mkdir -p .ae/doc .ae/temp && api-extractor run --local --verbose",
|
|
@@ -33,16 +35,16 @@
|
|
|
33
35
|
"test": "bun test"
|
|
34
36
|
},
|
|
35
37
|
"dependencies": {
|
|
36
|
-
"@thi.ng/adapt-dpi": "^2.2.
|
|
37
|
-
"@thi.ng/api": "^8.9.
|
|
38
|
-
"@thi.ng/checks": "^3.4.
|
|
39
|
-
"@thi.ng/math": "^5.7.
|
|
40
|
-
"@thi.ng/transducers": "^8.8.
|
|
41
|
-
"@thi.ng/transducers-stats": "^2.1.
|
|
38
|
+
"@thi.ng/adapt-dpi": "^2.2.28",
|
|
39
|
+
"@thi.ng/api": "^8.9.12",
|
|
40
|
+
"@thi.ng/checks": "^3.4.12",
|
|
41
|
+
"@thi.ng/math": "^5.7.7",
|
|
42
|
+
"@thi.ng/transducers": "^8.8.15",
|
|
43
|
+
"@thi.ng/transducers-stats": "^2.1.82"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
46
|
"@microsoft/api-extractor": "^7.38.3",
|
|
45
|
-
"
|
|
47
|
+
"esbuild": "^0.19.8",
|
|
46
48
|
"rimraf": "^5.0.5",
|
|
47
49
|
"tools": "^0.0.1",
|
|
48
50
|
"typedoc": "^0.25.4",
|
|
@@ -109,5 +111,5 @@
|
|
|
109
111
|
"status": "beta",
|
|
110
112
|
"year": 2018
|
|
111
113
|
},
|
|
112
|
-
"gitHead": "
|
|
114
|
+
"gitHead": "5e7bafedfc3d53bc131469a28de31dd8e5b4a3ff\n"
|
|
113
115
|
}
|
package/pager.js
CHANGED
|
@@ -1,86 +1,57 @@
|
|
|
1
1
|
import { map } from "@thi.ng/transducers/map";
|
|
2
2
|
import { range } from "@thi.ng/transducers/range";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*
|
|
45
|
-
* @param opts -
|
|
46
|
-
*/
|
|
47
|
-
export const pager = (_opts) => {
|
|
48
|
-
const opts = {
|
|
49
|
-
navStep: 1,
|
|
50
|
-
labelFirst: "<<",
|
|
51
|
-
labelPrev: "<",
|
|
52
|
-
labelNext: ">",
|
|
53
|
-
labelLast: ">>",
|
|
54
|
-
..._opts,
|
|
55
|
-
};
|
|
56
|
-
return (_, id, num, pageLen = 10, maxBts = 5) => {
|
|
57
|
-
const bt = opts.button;
|
|
58
|
-
const step = opts.navStep;
|
|
59
|
-
const maxID = Math.floor(Math.max(0, num - 1) / pageLen);
|
|
60
|
-
id = Math.max(Math.min(id, maxID), 0);
|
|
61
|
-
return [
|
|
62
|
-
opts.root,
|
|
63
|
-
[
|
|
64
|
-
opts.groupPrev,
|
|
65
|
-
bt(0, id, maxID, opts.labelFirst, !id),
|
|
66
|
-
bt(Math.max(id - step, 0), id, maxID, opts.labelPrev, !id),
|
|
67
|
-
],
|
|
68
|
-
[
|
|
69
|
-
opts.groupPages,
|
|
70
|
-
map((i) => bt(i, id, maxID, i + 1, i === id), pageRange(id, maxID, maxBts)),
|
|
71
|
-
],
|
|
72
|
-
[
|
|
73
|
-
opts.groupNext,
|
|
74
|
-
bt(Math.min(id + step, maxID), id, maxID, opts.labelNext, id >= maxID),
|
|
75
|
-
bt(maxID, id, maxID, opts.labelLast, id >= maxID),
|
|
76
|
-
],
|
|
77
|
-
];
|
|
78
|
-
};
|
|
3
|
+
const pager = (_opts) => {
|
|
4
|
+
const opts = {
|
|
5
|
+
navStep: 1,
|
|
6
|
+
labelFirst: "<<",
|
|
7
|
+
labelPrev: "<",
|
|
8
|
+
labelNext: ">",
|
|
9
|
+
labelLast: ">>",
|
|
10
|
+
..._opts
|
|
11
|
+
};
|
|
12
|
+
return (_, id, num, pageLen = 10, maxBts = 5) => {
|
|
13
|
+
const bt = opts.button;
|
|
14
|
+
const step = opts.navStep;
|
|
15
|
+
const maxID = Math.floor(Math.max(0, num - 1) / pageLen);
|
|
16
|
+
id = Math.max(Math.min(id, maxID), 0);
|
|
17
|
+
return [
|
|
18
|
+
opts.root,
|
|
19
|
+
[
|
|
20
|
+
opts.groupPrev,
|
|
21
|
+
bt(0, id, maxID, opts.labelFirst, !id),
|
|
22
|
+
bt(Math.max(id - step, 0), id, maxID, opts.labelPrev, !id)
|
|
23
|
+
],
|
|
24
|
+
[
|
|
25
|
+
opts.groupPages,
|
|
26
|
+
map(
|
|
27
|
+
(i) => bt(i, id, maxID, i + 1, i === id),
|
|
28
|
+
pageRange(id, maxID, maxBts)
|
|
29
|
+
)
|
|
30
|
+
],
|
|
31
|
+
[
|
|
32
|
+
opts.groupNext,
|
|
33
|
+
bt(
|
|
34
|
+
Math.min(id + step, maxID),
|
|
35
|
+
id,
|
|
36
|
+
maxID,
|
|
37
|
+
opts.labelNext,
|
|
38
|
+
id >= maxID
|
|
39
|
+
),
|
|
40
|
+
bt(maxID, id, maxID, opts.labelLast, id >= maxID)
|
|
41
|
+
]
|
|
42
|
+
];
|
|
43
|
+
};
|
|
79
44
|
};
|
|
80
45
|
const pageRange = (id, maxID, maxBt) => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
46
|
+
if (maxID > maxBt - 1) {
|
|
47
|
+
const from = Math.max(
|
|
48
|
+
Math.min(id - (maxBt >> 1), maxID - maxBt + 1),
|
|
49
|
+
0
|
|
50
|
+
);
|
|
51
|
+
return range(from, from + maxBt);
|
|
52
|
+
}
|
|
53
|
+
return range(0, maxID + 1);
|
|
54
|
+
};
|
|
55
|
+
export {
|
|
56
|
+
pager
|
|
86
57
|
};
|
package/sparkline.js
CHANGED
|
@@ -1,52 +1,55 @@
|
|
|
1
1
|
import { fitClamped } from "@thi.ng/math/fit";
|
|
2
2
|
import { mapIndexed } from "@thi.ng/transducers/map-indexed";
|
|
3
3
|
import { str } from "@thi.ng/transducers/str";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
4
|
+
const sparkline = (_, _opts, vals) => {
|
|
5
|
+
const opts = {
|
|
6
|
+
min: 0,
|
|
7
|
+
max: 100,
|
|
8
|
+
width: 50,
|
|
9
|
+
height: 16,
|
|
10
|
+
col: "red",
|
|
11
|
+
r: 1.5,
|
|
12
|
+
..._opts
|
|
13
|
+
};
|
|
14
|
+
const n = vals.length;
|
|
15
|
+
const s = opts.width / n;
|
|
16
|
+
const r = opts.r;
|
|
17
|
+
const h = opts.height - r;
|
|
18
|
+
return [
|
|
19
|
+
"svg",
|
|
20
|
+
{
|
|
21
|
+
width: opts.width + 2 * r,
|
|
22
|
+
height: opts.height,
|
|
23
|
+
stroke: opts.col,
|
|
24
|
+
fill: "none"
|
|
25
|
+
},
|
|
26
|
+
[
|
|
27
|
+
"polyline",
|
|
28
|
+
{
|
|
29
|
+
points: str(
|
|
30
|
+
",",
|
|
31
|
+
mapIndexed(
|
|
32
|
+
(i, y) => [
|
|
33
|
+
i * s | 0,
|
|
34
|
+
fitClamped(y, opts.min, opts.max, h, r) | 0
|
|
35
|
+
],
|
|
36
|
+
0,
|
|
37
|
+
vals
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
[
|
|
43
|
+
"circle",
|
|
44
|
+
{
|
|
45
|
+
cx: (n - 1) * s | 0,
|
|
46
|
+
cy: fitClamped(vals[n - 1], opts.min, opts.max, h, r) | 0,
|
|
47
|
+
r,
|
|
48
|
+
fill: opts.col
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
];
|
|
52
|
+
};
|
|
53
|
+
export {
|
|
54
|
+
sparkline
|
|
52
55
|
};
|
package/title.js
CHANGED
|
@@ -1,31 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const opts = {
|
|
19
|
-
element: "h1",
|
|
20
|
-
attribs: {},
|
|
21
|
-
subElement: "small",
|
|
22
|
-
subAttribs: {},
|
|
23
|
-
..._opts,
|
|
24
|
-
};
|
|
25
|
-
return (_, title, subtitle) => [
|
|
26
|
-
opts.element,
|
|
27
|
-
opts.attribs,
|
|
28
|
-
title,
|
|
29
|
-
subtitle ? [opts.subElement, opts.subAttribs, subtitle] : undefined,
|
|
30
|
-
];
|
|
1
|
+
const title = (_opts) => {
|
|
2
|
+
const opts = {
|
|
3
|
+
element: "h1",
|
|
4
|
+
attribs: {},
|
|
5
|
+
subElement: "small",
|
|
6
|
+
subAttribs: {},
|
|
7
|
+
..._opts
|
|
8
|
+
};
|
|
9
|
+
return (_, title2, subtitle) => [
|
|
10
|
+
opts.element,
|
|
11
|
+
opts.attribs,
|
|
12
|
+
title2,
|
|
13
|
+
subtitle ? [opts.subElement, opts.subAttribs, subtitle] : void 0
|
|
14
|
+
];
|
|
15
|
+
};
|
|
16
|
+
export {
|
|
17
|
+
title
|
|
31
18
|
};
|
package/toggle.js
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
1
|
const DEFAULT_OPTS = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
anim: 100,
|
|
3
|
+
pad: 1,
|
|
4
|
+
margin: 0,
|
|
5
|
+
vertical: false,
|
|
6
|
+
bgOn: { fill: "#000" },
|
|
7
|
+
bgOff: { fill: "#999" },
|
|
8
|
+
fgOn: { fill: "#fff" },
|
|
9
|
+
fgOff: { fill: "#fff" }
|
|
10
10
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
};
|
|
49
|
-
return $toggle("circle", svgSize, bgOn, bgOff, shapeOn, shapeOff);
|
|
11
|
+
const slideToggleDot = (opts = {}) => {
|
|
12
|
+
const _opts = {
|
|
13
|
+
r: 5,
|
|
14
|
+
...DEFAULT_OPTS,
|
|
15
|
+
...opts
|
|
16
|
+
};
|
|
17
|
+
const { r, pad, margin, vertical } = _opts;
|
|
18
|
+
const m2 = margin * 2;
|
|
19
|
+
const br = r + pad;
|
|
20
|
+
const cx = br + margin;
|
|
21
|
+
const width = (r * 2 + pad) * 2;
|
|
22
|
+
const height = br * 2;
|
|
23
|
+
const totalW = width + m2;
|
|
24
|
+
const totalH = height + m2;
|
|
25
|
+
const svgSize = vertical ? { width: totalH, height: totalW } : { width: totalW, height: totalH };
|
|
26
|
+
const style = { transition: `all ${_opts.anim}ms ease-out` };
|
|
27
|
+
const bgOn = {
|
|
28
|
+
x: margin,
|
|
29
|
+
y: margin,
|
|
30
|
+
rx: br,
|
|
31
|
+
ry: br,
|
|
32
|
+
...vertical ? { width: height, height: width } : { width, height },
|
|
33
|
+
..._opts.bgOn
|
|
34
|
+
};
|
|
35
|
+
const bgOff = { ...bgOn, ..._opts.bgOff };
|
|
36
|
+
const shapeOn = {
|
|
37
|
+
...vertical ? { cx, cy: cx } : { cx: width + margin - br, cy: cx },
|
|
38
|
+
..._opts.fgOn,
|
|
39
|
+
style,
|
|
40
|
+
r
|
|
41
|
+
};
|
|
42
|
+
const shapeOff = {
|
|
43
|
+
...shapeOn,
|
|
44
|
+
...vertical ? { cy: width + margin - br } : { cx },
|
|
45
|
+
..._opts.fgOff
|
|
46
|
+
};
|
|
47
|
+
return $toggle("circle", svgSize, bgOn, bgOff, shapeOn, shapeOff);
|
|
50
48
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
};
|
|
87
|
-
return $toggle("rect", svgSize, bgOn, bgOff, shapeOn, shapeOff);
|
|
49
|
+
const slideToggleRect = (opts = {}) => {
|
|
50
|
+
const _opts = {
|
|
51
|
+
w: 10,
|
|
52
|
+
h: 10,
|
|
53
|
+
...DEFAULT_OPTS,
|
|
54
|
+
...opts
|
|
55
|
+
};
|
|
56
|
+
const { w, h, pad, margin, vertical } = _opts;
|
|
57
|
+
const m2 = margin * 2;
|
|
58
|
+
const pm = pad + margin;
|
|
59
|
+
const width = vertical ? w + pad * 2 : (w + pad) * 2;
|
|
60
|
+
const height = vertical ? (h + pad) * 2 : h + pad * 2;
|
|
61
|
+
const svgSize = { width: width + m2, height: height + m2 };
|
|
62
|
+
const style = { transition: `all ${_opts.anim}ms ease-out` };
|
|
63
|
+
const bgOn = {
|
|
64
|
+
..._opts.bgOn,
|
|
65
|
+
width,
|
|
66
|
+
height,
|
|
67
|
+
x: margin,
|
|
68
|
+
y: margin
|
|
69
|
+
};
|
|
70
|
+
const bgOff = { ...bgOn, ..._opts.bgOff };
|
|
71
|
+
const shapeOn = {
|
|
72
|
+
...vertical ? { x: pm, y: pm } : { x: width + margin - pad - w, y: pm },
|
|
73
|
+
..._opts.fgOn,
|
|
74
|
+
style,
|
|
75
|
+
width: w,
|
|
76
|
+
height: h
|
|
77
|
+
};
|
|
78
|
+
const shapeOff = {
|
|
79
|
+
...shapeOn,
|
|
80
|
+
...vertical ? { y: height + margin - pad - h } : { x: pm },
|
|
81
|
+
..._opts.fgOff
|
|
82
|
+
};
|
|
83
|
+
return $toggle("rect", svgSize, bgOn, bgOff, shapeOn, shapeOff);
|
|
88
84
|
};
|
|
89
85
|
const $toggle = (shape, size, bgOn, bgOff, shapeOn, shapeOff) => (_, attribs, state) => [
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
"svg",
|
|
87
|
+
{ ...size, ...attribs },
|
|
88
|
+
["rect", state ? bgOn : bgOff],
|
|
89
|
+
[shape, state ? shapeOn : shapeOff]
|
|
94
90
|
];
|
|
91
|
+
export {
|
|
92
|
+
slideToggleDot,
|
|
93
|
+
slideToggleRect
|
|
94
|
+
};
|
package/utils/merge-attribs.js
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const mergeAttribs = (base, xs) => {
|
|
12
|
-
if (!xs)
|
|
13
|
-
return base;
|
|
14
|
-
const res = { ...base, ...xs };
|
|
15
|
-
base.class && xs.class && (res.class = base.class + " " + xs.class);
|
|
16
|
-
base.style && xs.style && (res.style = { ...base.style, ...xs.style });
|
|
17
|
-
return res;
|
|
1
|
+
const mergeAttribs = (base, xs) => {
|
|
2
|
+
if (!xs)
|
|
3
|
+
return base;
|
|
4
|
+
const res = { ...base, ...xs };
|
|
5
|
+
base.class && xs.class && (res.class = base.class + " " + xs.class);
|
|
6
|
+
base.style && xs.style && (res.style = { ...base.style, ...xs.style });
|
|
7
|
+
return res;
|
|
8
|
+
};
|
|
9
|
+
export {
|
|
10
|
+
mergeAttribs
|
|
18
11
|
};
|