@fusion.dev/helix-core 0.150.0 → 0.152.0
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/custom-elements.json +424 -6
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.d.ts +62 -5
- package/dist/controllers/chart-pointer-controller/chart-pointer-controller.js +112 -12
- package/dist/events/details.d.ts +14 -0
- package/dist/events/events.d.ts +6 -2
- package/dist/events/events.js +5 -1
- package/dist/events/names.js +2 -1
- package/dist/events/reading-change.d.ts +14 -0
- package/dist/events/reading-change.js +11 -0
- package/dist/events/reading-press.d.ts +13 -0
- package/dist/events/reading-press.js +11 -0
- package/dist/helix-element/helix-element.js +2 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -2
- package/dist/mixins/mixin-collection/mixin-collection.d.ts +5 -0
- package/dist/mixins/mixin-collection/mixin-collection.js +7 -1
- package/dist/utils/chord/key-names.d.ts +14 -2
- package/dist/utils/chord/key-names.js +58 -3
- package/dist/utils/draw-value-axis/draw-value-axis.d.ts +22 -0
- package/dist/utils/draw-value-axis/draw-value-axis.js +9 -0
- package/dist/utils/read-color/read-color.d.ts +24 -8
- package/dist/utils/read-color/read-color.js +20 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
|
@@ -36,17 +36,72 @@ const ELSEWHERE = {
|
|
|
36
36
|
tab: 'Tab',
|
|
37
37
|
up: '↑',
|
|
38
38
|
};
|
|
39
|
+
const SPOKEN = {
|
|
40
|
+
alt: 'Option',
|
|
41
|
+
backspace: 'Delete',
|
|
42
|
+
cmd: 'Command',
|
|
43
|
+
ctrl: 'Control',
|
|
44
|
+
del: 'Forward Delete',
|
|
45
|
+
down: 'Down Arrow',
|
|
46
|
+
enter: 'Return',
|
|
47
|
+
left: 'Left Arrow',
|
|
48
|
+
meta: 'Command',
|
|
49
|
+
mod: 'Command',
|
|
50
|
+
opt: 'Option',
|
|
51
|
+
right: 'Right Arrow',
|
|
52
|
+
shift: 'Shift',
|
|
53
|
+
tab: 'Tab',
|
|
54
|
+
up: 'Up Arrow',
|
|
55
|
+
};
|
|
56
|
+
const ORDER_APPLE = {
|
|
57
|
+
alt: 1,
|
|
58
|
+
cmd: 3,
|
|
59
|
+
ctrl: 0,
|
|
60
|
+
meta: 3,
|
|
61
|
+
mod: 3,
|
|
62
|
+
opt: 1,
|
|
63
|
+
shift: 2,
|
|
64
|
+
};
|
|
65
|
+
const ORDER_ELSEWHERE = {
|
|
66
|
+
alt: 2,
|
|
67
|
+
cmd: 0,
|
|
68
|
+
ctrl: 1,
|
|
69
|
+
meta: 0,
|
|
70
|
+
mod: 1,
|
|
71
|
+
opt: 2,
|
|
72
|
+
shift: 3,
|
|
73
|
+
};
|
|
74
|
+
const ordered = (parts, apple) => {
|
|
75
|
+
const order = apple ? ORDER_APPLE : ORDER_ELSEWHERE;
|
|
76
|
+
const rank = (part) => order[part.toLowerCase()] ?? Number.POSITIVE_INFINITY;
|
|
77
|
+
return parts
|
|
78
|
+
.map((part, index) => ({ index, part }))
|
|
79
|
+
.sort((a, b) => rank(a.part) - rank(b.part) || a.index - b.index)
|
|
80
|
+
.map(({ part }) => part);
|
|
81
|
+
};
|
|
39
82
|
export const keyNames = (parts, apple, own = {}) => {
|
|
40
83
|
const names = apple ? APPLE : ELSEWHERE;
|
|
41
84
|
let worded = false;
|
|
42
|
-
|
|
85
|
+
let glyphs = false;
|
|
86
|
+
const words = [];
|
|
87
|
+
const keys = ordered(parts, apple).map((part) => {
|
|
43
88
|
const name = part.toLowerCase();
|
|
44
89
|
const mine = own[name];
|
|
45
90
|
if (mine !== undefined) {
|
|
46
91
|
worded ||= [...mine].length > 1;
|
|
92
|
+
words.push(mine);
|
|
47
93
|
return mine;
|
|
48
94
|
}
|
|
49
|
-
|
|
95
|
+
const shown = names[name] ?? (part.length === 1 ? part.toUpperCase() : part);
|
|
96
|
+
const said = SPOKEN[name];
|
|
97
|
+
const glyph = said !== undefined && [...shown].length === 1;
|
|
98
|
+
glyphs ||= glyph;
|
|
99
|
+
words.push(glyph ? said : shown);
|
|
100
|
+
return shown;
|
|
50
101
|
});
|
|
51
|
-
return {
|
|
102
|
+
return {
|
|
103
|
+
keys,
|
|
104
|
+
separator: apple ? (worded ? '-' : '') : '+',
|
|
105
|
+
spoken: glyphs ? words.join(' ') : '',
|
|
106
|
+
};
|
|
52
107
|
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type TemplateResult } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* The numbers of a chart's value scale, beside its drawing: an `axis` part
|
|
4
|
+
* holding a `tick` part at each level `ticks` picks, which are the levels
|
|
5
|
+
* `gridlines` rules.
|
|
6
|
+
*
|
|
7
|
+
* HTML beside the plot, for the reason a chart's reading names are: text
|
|
8
|
+
* inside an `<svg>` that fills its box scales with the box. Each tick is placed
|
|
9
|
+
* with `inset-block-start`, as a percentage of the axis, so a stylesheet that
|
|
10
|
+
* makes the axis as tall as the plot puts each number on its level.
|
|
11
|
+
*
|
|
12
|
+
* `width` builds the axis's style from the number of characters in its widest
|
|
13
|
+
* number. The ticks are positioned absolutely and give the column no width of
|
|
14
|
+
* their own, so each family writes its own custom property there, such as
|
|
15
|
+
* `--line-chart-axis` in `ch`, and a stylesheet sizes the column from it.
|
|
16
|
+
*
|
|
17
|
+
* @param domain The scale's lowest and highest values.
|
|
18
|
+
* @param place Where a value sits down the plot, from 0 at the top to 100 at the bottom.
|
|
19
|
+
* @param format How a value is written, such as a number in the chart's locale.
|
|
20
|
+
* @param width The style the axis carries, from the number of characters in its widest number.
|
|
21
|
+
*/
|
|
22
|
+
export declare const drawValueAxis: (domain: readonly [number, number], place: (value: number) => number, format: (value: number) => string, width: (widest: number) => string) => TemplateResult;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { html } from 'lit';
|
|
2
|
+
import { ticks } from '../scale/ticks.js';
|
|
3
|
+
export const drawValueAxis = (domain, place, format, width) => {
|
|
4
|
+
const levels = ticks(domain);
|
|
5
|
+
const widest = Math.max(1, ...levels.map((level) => format(level).length));
|
|
6
|
+
return html `<div aria-hidden="true" part="axis" style=${width(widest)}>
|
|
7
|
+
${levels.map((level) => html `<span part="tick" style=${`inset-block-start: ${place(level)}%`}>${format(level)}</span>`)}
|
|
8
|
+
</div>`;
|
|
9
|
+
};
|
|
@@ -7,8 +7,16 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/** A color as three sRGB bytes, which is what a canvas reports and takes. */
|
|
9
9
|
export type ColorBytes = [number, number, number];
|
|
10
|
+
/** A color as three sRGB bytes and its alpha, from 0 to 1. */
|
|
11
|
+
export type ColorBytesAlpha = [number, number, number, number];
|
|
10
12
|
/**
|
|
11
|
-
*
|
|
13
|
+
* `value` painted onto a clear pixel and read back, alpha and all, or nothing
|
|
14
|
+
* where the engine does not parse it.
|
|
15
|
+
*/
|
|
16
|
+
export declare const paintedColor: (context: CanvasRenderingContext2D, value: string) => ColorBytesAlpha | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* A computed color as three sRGB bytes and its alpha, or nothing where it
|
|
19
|
+
* cannot be read.
|
|
12
20
|
*
|
|
13
21
|
* **Painting it is the only way to read it.** A color-typed property is
|
|
14
22
|
* resolved before it is reported, but resolved is not the same as converted:
|
|
@@ -18,13 +26,11 @@ export type ColorBytes = [number, number, number];
|
|
|
18
26
|
* `lab(0 0 0)`, which scrapes to black and looks right, so only dark mode
|
|
19
27
|
* showed it: dark red mixed toward black, on a near-black ground.
|
|
20
28
|
*
|
|
21
|
-
* **
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* chooses its own fallback rather than being handed a color nobody picked,
|
|
27
|
-
* which is the half both earlier copies of this had to guess at.
|
|
29
|
+
* **A value the engine does not parse is refused**, so a caller chooses its
|
|
30
|
+
* own fallback rather than being handed a color nobody picked. A see-through
|
|
31
|
+
* color is read with its alpha: `rgb(255 0 0 / 50%)` is `[255, 0, 0, 0.5]`.
|
|
32
|
+
* It was refused too, when the test for parsing was painting over black and
|
|
33
|
+
* over white, and Orb drew it gray.
|
|
28
34
|
*
|
|
29
35
|
* A readback is not free, so the answer is held against the string it came
|
|
30
36
|
* from, refusals included. The oldest goes when the store is full rather than
|
|
@@ -33,6 +39,16 @@ export type ColorBytes = [number, number, number];
|
|
|
33
39
|
*
|
|
34
40
|
* @param value A resolved color, as `getComputedStyle` reports one.
|
|
35
41
|
*/
|
|
42
|
+
export declare const readColorAlpha: (value: string) => ColorBytesAlpha | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* A computed color as three sRGB bytes, or nothing where it cannot be read or
|
|
45
|
+
* is see-through.
|
|
46
|
+
*
|
|
47
|
+
* `readColorAlpha` is the reading, and this keeps an opaque color only, which
|
|
48
|
+
* is what a caller with no use for alpha can draw as it is.
|
|
49
|
+
*
|
|
50
|
+
* @param value A resolved color, as `getComputedStyle` reports one.
|
|
51
|
+
*/
|
|
36
52
|
export declare const readColor: (value: string) => ColorBytes | undefined;
|
|
37
53
|
/**
|
|
38
54
|
* A computed color as `rgb()`, or `rgba()` where it is see-through, which
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
let swatch;
|
|
2
2
|
const known = new Map();
|
|
3
3
|
const KEPT = 64;
|
|
4
|
-
const
|
|
5
|
-
context.fillStyle =
|
|
4
|
+
const parses = (context, value) => {
|
|
5
|
+
context.fillStyle = '#000000';
|
|
6
6
|
context.fillStyle = value;
|
|
7
|
+
const overBlack = String(context.fillStyle);
|
|
8
|
+
context.fillStyle = '#ffffff';
|
|
9
|
+
context.fillStyle = value;
|
|
10
|
+
return String(context.fillStyle) === overBlack;
|
|
11
|
+
};
|
|
12
|
+
export const paintedColor = (context, value) => {
|
|
13
|
+
if (!parses(context, value)) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
context.clearRect(0, 0, 1, 1);
|
|
7
17
|
context.fillRect(0, 0, 1, 1);
|
|
8
|
-
const [red, green, blue] = context.getImageData(0, 0, 1, 1).data;
|
|
9
|
-
return [red ?? 0, green ?? 0, blue ?? 0];
|
|
18
|
+
const [red, green, blue, alpha] = context.getImageData(0, 0, 1, 1).data;
|
|
19
|
+
return [red ?? 0, green ?? 0, blue ?? 0, Math.round(((alpha ?? 0) / 255) * 1000) / 1000];
|
|
10
20
|
};
|
|
11
|
-
export const
|
|
21
|
+
export const readColorAlpha = (value) => {
|
|
12
22
|
if (known.has(value)) {
|
|
13
23
|
const seen = known.get(value);
|
|
14
24
|
return seen ? [...seen] : undefined;
|
|
@@ -22,9 +32,7 @@ export const readColor = (value) => {
|
|
|
22
32
|
if (!swatch) {
|
|
23
33
|
return undefined;
|
|
24
34
|
}
|
|
25
|
-
const
|
|
26
|
-
const under = painted(swatch, value, '#ffffff');
|
|
27
|
-
const read = over.every((one, at) => one === under[at]) ? over : undefined;
|
|
35
|
+
const read = paintedColor(swatch, value);
|
|
28
36
|
if (known.size >= KEPT) {
|
|
29
37
|
const oldest = known.keys().next().value;
|
|
30
38
|
if (oldest !== undefined) {
|
|
@@ -34,6 +42,10 @@ export const readColor = (value) => {
|
|
|
34
42
|
known.set(value, read);
|
|
35
43
|
return read ? [...read] : undefined;
|
|
36
44
|
};
|
|
45
|
+
export const readColor = (value) => {
|
|
46
|
+
const read = readColorAlpha(value);
|
|
47
|
+
return read && read[3] === 1 ? [read[0], read[1], read[2]] : undefined;
|
|
48
|
+
};
|
|
37
49
|
export const rgbOf = (color) => {
|
|
38
50
|
const pixel = typeof document === 'undefined' ? null : document.createElement('canvas');
|
|
39
51
|
const context = pixel?.getContext?.('2d', { willReadFrequently: true });
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.152.0';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-core",
|
|
3
3
|
"description": "Helix element primitives: base classes, mixins, decorators, utilities.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.152.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@floating-ui/dom": "^1.8.0",
|
|
59
|
-
"@fusion.dev/helix-icons": "0.
|
|
59
|
+
"@fusion.dev/helix-icons": "0.152.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@fusion.dev/helix-cem": "0.
|
|
63
|
-
"@fusion.dev/helix-testing": "0.
|
|
62
|
+
"@fusion.dev/helix-cem": "0.152.0",
|
|
63
|
+
"@fusion.dev/helix-testing": "0.152.0",
|
|
64
64
|
"@lit-labs/ssr": "^4.1.0",
|
|
65
65
|
"lit": "^3.2.1"
|
|
66
66
|
},
|