@thi.ng/hdom-components 5.1.81 → 5.1.83

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Change Log
2
2
 
3
- - **Last updated**: 2023-12-09T19:12:03Z
3
+ - **Last updated**: 2023-12-18T13:41:20Z
4
4
  - **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
5
5
 
6
6
  All notable changes to this project will be documented in this file.
package/button-group.js CHANGED
@@ -1,47 +1,33 @@
1
1
  import { mergeAttribs } from "./utils/merge-attribs.js";
2
- /**
3
- * Higher order function to create a new stateless button group
4
- * component, pre-configured via user supplied options. The returned
5
- * component function accepts the following arguments:
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
- switch (buttons.length) {
26
- case 0:
27
- return [];
28
- case 1:
29
- return [bt(opts.inner || opts.first, disabled, buttons[0])];
30
- case 2:
31
- return [
32
- bt(opts.first, disabled, buttons[0]),
33
- bt(opts.last || opts.first, disabled, buttons[1]),
34
- ];
35
- default: {
36
- const res = [bt(opts.first, disabled, buttons[0])];
37
- const el = opts.inner || opts.first;
38
- const n = buttons.length - 1;
39
- for (let i = 1; i < n; i++) {
40
- res[i] = bt(el, disabled, buttons[i]);
41
- }
42
- res[n] = bt(opts.last || opts.first, disabled, buttons[n]);
43
- return res;
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
- * Higher order function to create a new stateless button component,
4
- * pre-configured via user supplied options. The returned component
5
- * function accepts the following arguments:
6
- *
7
- * - hdom context object (unused)
8
- * - partial {@link ButtonArgs} object (extra attribs, onclick, disabled)
9
- * - body content (varargs)
10
- *
11
- * Any `attribs` provided as arg via {@link ButtonArgs} are merged with the
12
- * default options provided to the HOF. The `disabled` arg decides which
13
- * button version to create. The button can have any number of body
14
- * elements (e.g. icon and label), given as varargs.
15
- */
16
- export const button = (opts) => {
17
- // init with defaults
18
- opts = {
19
- tag: "a",
20
- tagDisabled: "span",
21
- preventDefault: true,
22
- attribs: {},
23
- ...opts,
24
- };
25
- !opts.attribs.role && (opts.attribs.role = "button");
26
- return (_, args, ...body) => args.disabled
27
- ? [
28
- opts.tagDisabled,
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
- let el;
12
- let ctx;
13
- let frame = 0;
14
- let time = 0;
15
- return {
16
- init(_el, hctx, ...args) {
17
- el = _el;
18
- adaptDPI(el, el.width, el.height);
19
- ctx = el.getContext(type, opts);
20
- time = Date.now();
21
- handlers.init && handlers.init(el, ctx, hctx, ...args);
22
- handlers.update &&
23
- handlers.update(el, ctx, hctx, time, frame++, ...args);
24
- },
25
- render(hctx, ...args) {
26
- ctx &&
27
- handlers.update &&
28
- handlers.update(el, ctx, hctx, Date.now() - time, frame++, ...args);
29
- return ["canvas", args[0]];
30
- },
31
- release(hctx, ...args) {
32
- handlers.release && handlers.release(el, ctx, hctx, ...args);
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
- export const option = ([value, label, disabled], sel) => [
2
- "option",
3
- { value, disabled: !!disabled, selected: value === sel },
4
- label,
1
+ const option = ([value, label, disabled], sel) => [
2
+ "option",
3
+ { value, disabled: !!disabled, selected: value === sel },
4
+ label
5
5
  ];
6
- export const optgroup = (attribs, options, sel) => [
7
- "optgroup",
8
- { ...attribs, label: attribs.label || "--" },
9
- ...options.map((o) => option(o, sel)),
6
+ const optgroup = (attribs, options, sel) => [
7
+ "optgroup",
8
+ { ...attribs, label: attribs.label || "--" },
9
+ ...options.map((o) => option(o, sel))
10
10
  ];
11
- export const dropdown = (_, attribs, options, sel) => ["select", attribs, ...options.map((o) => option(o, sel))];
12
- export const groupedDropdown = (_, attribs, groups, sel) => ["select", attribs, ...groups.map((o) => optgroup(o[0], o[1], sel))];
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
- * Customizable FPS counter with sparkline visualization of N previous
6
- * frames.
7
- *
8
- * @param opts -
9
- */
10
- export const fpsCounter = (_opts) => {
11
- const opts = {
12
- history: 25,
13
- smooth: 5,
14
- labelPeriod: 250,
15
- sparkline: {},
16
- ..._opts,
17
- };
18
- return {
19
- init() {
20
- this.last = Date.now();
21
- this.lastLabel = this.last;
22
- this.buffer = [];
23
- this.ma = step(sma(opts.smooth));
24
- },
25
- render() {
26
- const t = Date.now();
27
- const fps = 1000 / (t - this.last);
28
- this.last = t;
29
- if (!this.buffer)
30
- return ["div"];
31
- const smoothFps = this.ma(fps);
32
- if (!smoothFps)
33
- return ["div"];
34
- this.buffer.push(smoothFps);
35
- this.buffer.length > opts.history && this.buffer.shift();
36
- const updateLabel = t - this.lastLabel > opts.labelPeriod;
37
- updateLabel && (this.lastLabel = t);
38
- return [
39
- "div",
40
- [
41
- sparkline,
42
- { min: 0, max: 65, ...opts.sparkline },
43
- this.buffer,
44
- ],
45
- [
46
- "span",
47
- { __skip: !updateLabel },
48
- smoothFps ? smoothFps.toFixed(2) + " fps" : "",
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
- export const link = (attribs, body) => [
3
- "a",
4
- isString(attribs) ? { href: attribs } : attribs,
5
- body,
2
+ const link = (attribs, body) => [
3
+ "a",
4
+ isString(attribs) ? { href: attribs } : attribs,
5
+ body
6
6
  ];
7
- export const appLink = (_, attribs, onclick, body) => [
8
- "a",
9
- {
10
- href: "#",
11
- onclick: (e) => {
12
- e.preventDefault();
13
- onclick(e);
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
- body,
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
- * Higher order function to create a new stateless notification
4
- * component, pre-configured via user supplied options. The returned
5
- * component function accepts the following arguments:
6
- *
7
- * - hdom context object (unused)
8
- * - partial {@link NotificationArgs} object (extra attribs, onclose handler)
9
- * - body content
10
- *
11
- * Any `attribs` provided as arg via {@link NotificationArgs} are merged with
12
- * the default options provided to the HOF. If the notification body
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.81",
3
+ "version": "5.1.83",
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 clean && tsc --declaration",
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,15 +35,16 @@
33
35
  "test": "bun test"
34
36
  },
35
37
  "dependencies": {
36
- "@thi.ng/adapt-dpi": "^2.2.27",
37
- "@thi.ng/api": "^8.9.11",
38
- "@thi.ng/checks": "^3.4.11",
39
- "@thi.ng/math": "^5.7.6",
40
- "@thi.ng/transducers": "^8.8.14",
41
- "@thi.ng/transducers-stats": "^2.1.81"
38
+ "@thi.ng/adapt-dpi": "^2.2.28",
39
+ "@thi.ng/api": "^8.9.13",
40
+ "@thi.ng/checks": "^3.4.13",
41
+ "@thi.ng/math": "^5.7.8",
42
+ "@thi.ng/transducers": "^8.8.16",
43
+ "@thi.ng/transducers-stats": "^2.1.83"
42
44
  },
43
45
  "devDependencies": {
44
46
  "@microsoft/api-extractor": "^7.38.3",
47
+ "esbuild": "^0.19.8",
45
48
  "rimraf": "^5.0.5",
46
49
  "tools": "^0.0.1",
47
50
  "typedoc": "^0.25.4",
@@ -55,7 +58,7 @@
55
58
  "access": "public"
56
59
  },
57
60
  "engines": {
58
- "node": ">=12.7"
61
+ "node": ">=18"
59
62
  },
60
63
  "files": [
61
64
  "./*.js",
@@ -108,5 +111,5 @@
108
111
  "status": "beta",
109
112
  "year": 2018
110
113
  },
111
- "gitHead": "25f2ac8ff795a432a930119661b364d4d93b59a0\n"
114
+ "gitHead": "25a42a81fac8603a1e440a7aa8bc343276211ff4\n"
112
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
- * Higher order container component for paged navigation buttons. The
5
- * returned component function takes these arguments:
6
- *
7
- * - `ctx` - hdom context object
8
- * - `id` - current page ID (zero-based)
9
- * - `numItems` - current number of items
10
- * - `pageLen` - number of items per page (only used for calculation)
11
- * - `maxButtons` - number of page buttons to show (default: 5). If
12
- * zero, only the prev / next and first / last buttons will be shown.
13
- *
14
- * If there are more pages than the specified number, only the
15
- * neighboring page IDs (relative to the current page) are shown. E.g.
16
- * If there are 10 pages, the current page ID is 5 and 3 visible page
17
- * buttons then the pager will look like this (the `|` character here
18
- * indicates button group boundaries):
19
- *
20
- * ```
21
- * << < | 4 5 6 | > >>
22
- * ```
23
- *
24
- * Providing `pageLen` and `maxButtons` as arguments allows to
25
- * dynamically control the number of page buttons at runtime, e.g. in
26
- * response to window resizing.
27
- *
28
- * Yields a component of page buttons and prev / next and first / last
29
- * navigation buttons. The actual button and button group components are
30
- * defined via the user supplied options. The first / prev and next /
31
- * last nav buttons are paired within inner `div` elements (one per
32
- * pair) and can be styled (or hidden) separately.
33
- *
34
- * ```
35
- * // initialization
36
- * const mypager = pager({
37
- * button: (i, curr, max, label, disabled) =>
38
- * ["a", {href: `/page/${i}`, disabled}, label]
39
- * });
40
- *
41
- * // usage
42
- * [mypager, currPage, currNumItems, 10, 5]
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
- if (maxID > maxBt - 1) {
82
- const from = Math.max(Math.min(id - (maxBt >> 1), maxID - maxBt + 1), 0);
83
- return range(from, from + maxBt);
84
- }
85
- return range(0, maxID + 1);
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
- * Customizable, stateless SVG sparkline component.
6
- *
7
- * @param _ - hdom context object (ignored)
8
- * @param opts - config options
9
- * @param vals - data values
10
- */
11
- export const sparkline = (_, _opts, vals) => {
12
- const opts = {
13
- min: 0,
14
- max: 100,
15
- width: 50,
16
- height: 16,
17
- col: "red",
18
- r: 1.5,
19
- ..._opts,
20
- };
21
- const n = vals.length;
22
- const s = opts.width / n;
23
- const r = opts.r;
24
- const h = opts.height - r;
25
- return [
26
- "svg",
27
- {
28
- width: opts.width + 2 * r,
29
- height: opts.height,
30
- stroke: opts.col,
31
- fill: "none",
32
- },
33
- [
34
- "polyline",
35
- {
36
- points: str(",", mapIndexed((i, y) => [
37
- (i * s) | 0,
38
- fitClamped(y, opts.min, opts.max, h, r) | 0,
39
- ], 0, vals)),
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
- ];
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
- * Configurable Higher order title with optional subtitle component. The
3
- * returned component function takes two args: title, subtitle.
4
- *
5
- * @example
6
- * ```ts
7
- * const h1 = title();
8
- * const h2 = title({ element: "h2", attribs: { class: "blue" }});
9
- *
10
- * [h1, "Hello world", "Once upon a time..."]
11
- *
12
- * [h2, "Chapter 1", "Once upon a time..."]
13
- * ```
14
- *
15
- * @param opts -
16
- */
17
- export const title = (_opts) => {
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
- 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" },
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
- export 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
26
- ? { width: totalH, height: totalW }
27
- : { width: totalW, height: totalH };
28
- const style = { transition: `all ${_opts.anim}ms ease-out` };
29
- const bgOn = {
30
- x: margin,
31
- y: margin,
32
- rx: br,
33
- ry: br,
34
- ...(vertical ? { width: height, height: width } : { width, height }),
35
- ..._opts.bgOn,
36
- };
37
- const bgOff = { ...bgOn, ..._opts.bgOff };
38
- const shapeOn = {
39
- ...(vertical ? { cx, cy: cx } : { cx: width + margin - br, cy: cx }),
40
- ..._opts.fgOn,
41
- style,
42
- r,
43
- };
44
- const shapeOff = {
45
- ...shapeOn,
46
- ...(vertical ? { cy: width + margin - br } : { cx }),
47
- ..._opts.fgOff,
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
- export const slideToggleRect = (opts = {}) => {
52
- const _opts = {
53
- w: 10,
54
- h: 10,
55
- ...DEFAULT_OPTS,
56
- ...opts,
57
- };
58
- const { w, h, pad, margin, vertical } = _opts;
59
- const m2 = margin * 2;
60
- const pm = pad + margin;
61
- const width = vertical ? w + pad * 2 : (w + pad) * 2;
62
- const height = vertical ? (h + pad) * 2 : h + pad * 2;
63
- const svgSize = { width: width + m2, height: height + m2 };
64
- const style = { transition: `all ${_opts.anim}ms ease-out` };
65
- const bgOn = {
66
- ..._opts.bgOn,
67
- width,
68
- height,
69
- x: margin,
70
- y: margin,
71
- };
72
- const bgOff = { ...bgOn, ..._opts.bgOff };
73
- const shapeOn = {
74
- ...(vertical
75
- ? { x: pm, y: pm }
76
- : { x: width + margin - pad - w, y: pm }),
77
- ..._opts.fgOn,
78
- style,
79
- width: w,
80
- height: h,
81
- };
82
- const shapeOff = {
83
- ...shapeOn,
84
- ...(vertical ? { y: height + margin - pad - h } : { x: pm }),
85
- ..._opts.fgOff,
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
- "svg",
91
- { ...size, ...attribs },
92
- ["rect", state ? bgOn : bgOff],
93
- [shape, state ? shapeOn : shapeOff],
86
+ "svg",
87
+ { ...size, ...attribs },
88
+ ["rect", state ? bgOn : bgOff],
89
+ [shape, state ? shapeOn : shapeOff]
94
90
  ];
91
+ export {
92
+ slideToggleDot,
93
+ slideToggleRect
94
+ };
@@ -1,18 +1,11 @@
1
- /**
2
- * Helper function to immutably merge attribs from two sources and
3
- * concatenate their `class` values and merge their `style` maps (if
4
- * present). Returns merged result object.
5
- *
6
- * @param base - base attribs
7
- * @param xs - overrides
8
- *
9
- * @internal
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
  };