@mosaicajs/components 0.3.0 → 0.4.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/README.md +2 -0
- package/dist/aggregate.d.ts +4 -10
- package/dist/aggregate.js +7 -13
- package/dist/artifact-card.d.ts +21 -7
- package/dist/artifact-card.js +136 -79
- package/dist/base.d.ts +44 -5
- package/dist/base.js +54 -5
- package/dist/cluster-filter.d.ts +29 -25
- package/dist/cluster-filter.js +123 -106
- package/dist/colour-editor.d.ts +15 -4
- package/dist/colour-editor.js +107 -34
- package/dist/colour-picker.d.ts +12 -5
- package/dist/colour-picker.js +119 -32
- package/dist/display.js +77 -9
- package/dist/events.d.ts +21 -7
- package/dist/explorer.d.ts +116 -37
- package/dist/explorer.js +476 -210
- package/dist/field-card.d.ts +304 -48
- package/dist/field-card.js +1364 -244
- package/dist/filter-panel.d.ts +54 -10
- package/dist/filter-panel.js +242 -42
- package/dist/filter.d.ts +22 -4
- package/dist/filter.js +113 -34
- package/dist/hierarchy.d.ts +68 -45
- package/dist/hierarchy.js +320 -243
- package/dist/item-card.d.ts +47 -16
- package/dist/item-card.js +241 -108
- package/dist/key-picker.d.ts +2 -1
- package/dist/key-picker.js +4 -3
- package/dist/layer-picker.d.ts +4 -2
- package/dist/layer-picker.js +16 -7
- package/dist/lineage.d.ts +132 -0
- package/dist/lineage.js +307 -0
- package/dist/map.d.ts +135 -24
- package/dist/map.js +387 -117
- package/dist/mosaica-components.js +1837 -833
- package/dist/mosaica-components.js.sri +1 -1
- package/dist/mosaica-components.json +2 -2
- package/dist/parts.d.ts +4 -4
- package/dist/parts.js +18 -4
- package/dist/paths.d.ts +34 -12
- package/dist/paths.js +84 -46
- package/dist/selection.d.ts +22 -3
- package/dist/selection.js +125 -59
- package/dist/states.d.ts +72 -0
- package/dist/states.js +135 -26
- package/dist/status.d.ts +63 -5
- package/dist/status.js +215 -36
- package/dist/tokens.d.ts +8 -4
- package/dist/tokens.js +144 -14
- package/dist/view-picker.js +5 -0
- package/package.json +4 -3
package/dist/colour-editor.js
CHANGED
|
@@ -37,8 +37,9 @@ import { property, state } from 'lit/decorators.js';
|
|
|
37
37
|
import { repeat } from 'lit/directives/repeat.js';
|
|
38
38
|
import { CLUSTER_PREFIX, PALETTES, artifactColour, colourLayers } from '@mosaicajs/client';
|
|
39
39
|
import { CATEGORY_PALETTES } from '@mosaicajs/deck';
|
|
40
|
+
import { levelOfLayer } from '@mosaicajs/client/internal';
|
|
40
41
|
import { hexOf } from '@mosaicajs/deck/internal';
|
|
41
|
-
import { HeldAggregate, artifactGroupings, isTree,
|
|
42
|
+
import { HeldAggregate, artifactGroupings, isTree, listedGroups, rankedGrouping } from './aggregate.js';
|
|
42
43
|
import { MosaicaElement, UNNAMED, columnCaption, countText, emit, idString, keyTitle } from './base.js';
|
|
43
44
|
import { ColourPicker, pickerStyles } from './colour-picker.js';
|
|
44
45
|
import { clusterColour, colouringOf, holdColours, paletteValueColour, setClusterColours, setValueColours, valueColour, valueMet, watchChoices } from './colouring.js';
|
|
@@ -49,8 +50,6 @@ import { ClusterPaths } from './paths.js';
|
|
|
49
50
|
import { chrome, tokens } from './tokens.js';
|
|
50
51
|
import './filter.js';
|
|
51
52
|
import './cluster-filter.js';
|
|
52
|
-
/** The height of a row in pixels, from which the rows in sight are worked out. */
|
|
53
|
-
const ROW_HEIGHT = 40;
|
|
54
53
|
/** The rows whose paths are asked for before the list has been measured. */
|
|
55
54
|
const FIRST_ROWS = 8;
|
|
56
55
|
/**
|
|
@@ -108,9 +107,9 @@ let MosaicaColourEditor = (() => {
|
|
|
108
107
|
let _field_decorators;
|
|
109
108
|
let _field_initializers = [];
|
|
110
109
|
let _field_extraInitializers = [];
|
|
111
|
-
let
|
|
112
|
-
let
|
|
113
|
-
let
|
|
110
|
+
let _clusterLevels_decorators;
|
|
111
|
+
let _clusterLevels_initializers = [];
|
|
112
|
+
let _clusterLevels_extraInitializers = [];
|
|
114
113
|
let _isOpen_decorators;
|
|
115
114
|
let _isOpen_initializers = [];
|
|
116
115
|
let _isOpen_extraInitializers = [];
|
|
@@ -124,12 +123,12 @@ let MosaicaColourEditor = (() => {
|
|
|
124
123
|
static {
|
|
125
124
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
126
125
|
_field_decorators = [property()];
|
|
127
|
-
|
|
126
|
+
_clusterLevels_decorators = [property({ attribute: false })];
|
|
128
127
|
_isOpen_decorators = [state()];
|
|
129
128
|
_ticked_decorators = [state()];
|
|
130
129
|
_found_decorators = [state()];
|
|
131
130
|
__esDecorate(this, null, _field_decorators, { kind: "accessor", name: "field", static: false, private: false, access: { has: obj => "field" in obj, get: obj => obj.field, set: (obj, value) => { obj.field = value; } }, metadata: _metadata }, _field_initializers, _field_extraInitializers);
|
|
132
|
-
__esDecorate(this, null,
|
|
131
|
+
__esDecorate(this, null, _clusterLevels_decorators, { kind: "accessor", name: "clusterLevels", static: false, private: false, access: { has: obj => "clusterLevels" in obj, get: obj => obj.clusterLevels, set: (obj, value) => { obj.clusterLevels = value; } }, metadata: _metadata }, _clusterLevels_initializers, _clusterLevels_extraInitializers);
|
|
133
132
|
__esDecorate(this, null, _isOpen_decorators, { kind: "accessor", name: "isOpen", static: false, private: false, access: { has: obj => "isOpen" in obj, get: obj => obj.isOpen, set: (obj, value) => { obj.isOpen = value; } }, metadata: _metadata }, _isOpen_initializers, _isOpen_extraInitializers);
|
|
134
133
|
__esDecorate(this, null, _ticked_decorators, { kind: "accessor", name: "ticked", static: false, private: false, access: { has: obj => "ticked" in obj, get: obj => obj.ticked, set: (obj, value) => { obj.ticked = value; } }, metadata: _metadata }, _ticked_initializers, _ticked_extraInitializers);
|
|
135
134
|
__esDecorate(this, null, _found_decorators, { kind: "accessor", name: "found", static: false, private: false, access: { has: obj => "found" in obj, get: obj => obj.found, set: (obj, value) => { obj.found = value; } }, metadata: _metadata }, _found_initializers, _found_extraInitializers);
|
|
@@ -189,7 +188,8 @@ let MosaicaColourEditor = (() => {
|
|
|
189
188
|
color: var(--_mosaica-ink);
|
|
190
189
|
overflow: hidden;
|
|
191
190
|
text-overflow: ellipsis;
|
|
192
|
-
white-space:
|
|
191
|
+
white-space: var(--_mosaica-long-text);
|
|
192
|
+
overflow-wrap: anywhere;
|
|
193
193
|
}
|
|
194
194
|
[part='sub'] {
|
|
195
195
|
font-size: 12px;
|
|
@@ -227,6 +227,18 @@ let MosaicaColourEditor = (() => {
|
|
|
227
227
|
font-weight: 600;
|
|
228
228
|
margin-right: auto;
|
|
229
229
|
}
|
|
230
|
+
/* Drawn as a line of text, each with a target 24 px high around it, inside the bar. */
|
|
231
|
+
[part='set-colour'],
|
|
232
|
+
[part='deselect'] {
|
|
233
|
+
position: relative;
|
|
234
|
+
}
|
|
235
|
+
[part='set-colour']::before,
|
|
236
|
+
[part='deselect']::before {
|
|
237
|
+
content: '';
|
|
238
|
+
position: absolute;
|
|
239
|
+
inset: -4px 0;
|
|
240
|
+
min-width: 24px;
|
|
241
|
+
}
|
|
230
242
|
[part='set-colour'] {
|
|
231
243
|
display: inline-flex;
|
|
232
244
|
align-items: center;
|
|
@@ -238,6 +250,7 @@ let MosaicaColourEditor = (() => {
|
|
|
238
250
|
height: 18px;
|
|
239
251
|
border: 2px solid currentColor;
|
|
240
252
|
border-radius: 5px;
|
|
253
|
+
forced-color-adjust: none;
|
|
241
254
|
}
|
|
242
255
|
[part='deselect'] {
|
|
243
256
|
text-decoration: underline;
|
|
@@ -256,17 +269,21 @@ let MosaicaColourEditor = (() => {
|
|
|
256
269
|
color: var(--_mosaica-ink-3);
|
|
257
270
|
}
|
|
258
271
|
[part='columns'] span:last-child,
|
|
259
|
-
|
|
272
|
+
.n {
|
|
260
273
|
text-align: right;
|
|
261
274
|
}
|
|
275
|
+
.n {
|
|
276
|
+
font-size: 12px;
|
|
277
|
+
}
|
|
262
278
|
[part='rows'] {
|
|
263
279
|
flex: 1 1 auto;
|
|
264
280
|
min-height: 0;
|
|
265
281
|
overflow-y: auto;
|
|
266
282
|
padding: 2px 8px 8px;
|
|
267
283
|
}
|
|
284
|
+
/* A row holds a name and a path on a line each, and grows only where a host has long names wrap. */
|
|
268
285
|
[part~='row'] {
|
|
269
|
-
height:
|
|
286
|
+
min-height: 40px;
|
|
270
287
|
padding: 0 8px;
|
|
271
288
|
border-radius: 6px;
|
|
272
289
|
}
|
|
@@ -277,21 +294,43 @@ let MosaicaColourEditor = (() => {
|
|
|
277
294
|
[part~='row'][data-found] {
|
|
278
295
|
box-shadow: inset 2px 0 0 var(--_mosaica-ink-3);
|
|
279
296
|
}
|
|
297
|
+
/* The checkbox's target, 24 px square around the box, which keeps its size and its place. */
|
|
298
|
+
.tick {
|
|
299
|
+
position: relative;
|
|
300
|
+
display: grid;
|
|
301
|
+
align-items: center;
|
|
302
|
+
height: 24px;
|
|
303
|
+
cursor: pointer;
|
|
304
|
+
}
|
|
305
|
+
.tick::before {
|
|
306
|
+
content: '';
|
|
307
|
+
position: absolute;
|
|
308
|
+
inset: 0 -1px 0 -5px;
|
|
309
|
+
}
|
|
280
310
|
[part='check'] {
|
|
281
311
|
width: 14px;
|
|
282
312
|
height: 14px;
|
|
283
313
|
margin: 0;
|
|
284
314
|
}
|
|
315
|
+
/* Drawn 22 px square, with a 24 px target around it. */
|
|
285
316
|
[part='swatch'] {
|
|
317
|
+
position: relative;
|
|
286
318
|
width: 22px;
|
|
287
319
|
height: 22px;
|
|
288
320
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
|
289
321
|
border-radius: 5px;
|
|
290
322
|
background: var(--c);
|
|
323
|
+
forced-color-adjust: none;
|
|
324
|
+
}
|
|
325
|
+
[part='swatch']::before {
|
|
326
|
+
content: '';
|
|
327
|
+
position: absolute;
|
|
328
|
+
inset: -2px;
|
|
291
329
|
}
|
|
292
330
|
[part='swatch'][data-unmet] {
|
|
293
331
|
background: none;
|
|
294
332
|
border-color: var(--_mosaica-line-control);
|
|
333
|
+
forced-color-adjust: auto;
|
|
295
334
|
}
|
|
296
335
|
.label {
|
|
297
336
|
display: flex;
|
|
@@ -302,7 +341,8 @@ let MosaicaColourEditor = (() => {
|
|
|
302
341
|
[part='path'] {
|
|
303
342
|
overflow: hidden;
|
|
304
343
|
text-overflow: ellipsis;
|
|
305
|
-
white-space:
|
|
344
|
+
white-space: var(--_mosaica-long-text);
|
|
345
|
+
overflow-wrap: anywhere;
|
|
306
346
|
}
|
|
307
347
|
[part='path'] {
|
|
308
348
|
font-size: 12px;
|
|
@@ -314,10 +354,13 @@ let MosaicaColourEditor = (() => {
|
|
|
314
354
|
font-variant-numeric: tabular-nums;
|
|
315
355
|
}
|
|
316
356
|
.none {
|
|
317
|
-
padding: 12px
|
|
357
|
+
padding: 14px 24px 12px;
|
|
318
358
|
font-size: 12px;
|
|
319
359
|
color: var(--_mosaica-ink-3);
|
|
320
360
|
}
|
|
361
|
+
.none:empty {
|
|
362
|
+
padding: 0;
|
|
363
|
+
}
|
|
321
364
|
.foot {
|
|
322
365
|
display: flex;
|
|
323
366
|
align-items: center;
|
|
@@ -343,11 +386,15 @@ let MosaicaColourEditor = (() => {
|
|
|
343
386
|
/** What the dialog colours: a rendered category column, or `cluster:<layer>`. */
|
|
344
387
|
get field() { return this.#field_accessor_storage; }
|
|
345
388
|
set field(value) { this.#field_accessor_storage = value; }
|
|
346
|
-
#
|
|
347
|
-
/**
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
389
|
+
#clusterLevels_accessor_storage = (__runInitializers(this, _field_extraInitializers), __runInitializers(this, _clusterLevels_initializers, new Map()));
|
|
390
|
+
/**
|
|
391
|
+
* The level each `stacked` or `tiered` layer's clusters are listed at, keyed by layer name. A
|
|
392
|
+
* layer with no entry is listed at the level the map draws it at, which follows the zoom where its
|
|
393
|
+
* levels declare no zoom range. Set it as a property; it has no attribute.
|
|
394
|
+
*/
|
|
395
|
+
get clusterLevels() { return this.#clusterLevels_accessor_storage; }
|
|
396
|
+
set clusterLevels(value) { this.#clusterLevels_accessor_storage = value; }
|
|
397
|
+
#isOpen_accessor_storage = (__runInitializers(this, _clusterLevels_extraInitializers), __runInitializers(this, _isOpen_initializers, false));
|
|
351
398
|
/** Whether the dialog is open. @internal */
|
|
352
399
|
get isOpen() { return this.#isOpen_accessor_storage; }
|
|
353
400
|
set isOpen(value) { this.#isOpen_accessor_storage = value; }
|
|
@@ -368,6 +415,8 @@ let MosaicaColourEditor = (() => {
|
|
|
368
415
|
opener = null;
|
|
369
416
|
/** The frame the paths of the rows in sight are next asked for in, while one is waiting. */
|
|
370
417
|
pathFrame = null;
|
|
418
|
+
/** The level the layer was listed at in the last update, chosen or followed. */
|
|
419
|
+
listedAt = undefined;
|
|
371
420
|
/** Open the dialog. */
|
|
372
421
|
async show() {
|
|
373
422
|
this.opener = deepActive();
|
|
@@ -426,23 +475,32 @@ let MosaicaColourEditor = (() => {
|
|
|
426
475
|
super.disconnectedCallback();
|
|
427
476
|
}
|
|
428
477
|
/**
|
|
429
|
-
* A change of field or level
|
|
430
|
-
*
|
|
478
|
+
* A change of field or of the level its layer is listed at, chosen or followed as the map zooms,
|
|
479
|
+
* drops what was found and ticked and closes the picker, since each names the last field's
|
|
480
|
+
* values; the dialog closes where the field is now nothing it can edit.
|
|
431
481
|
*/
|
|
432
482
|
willUpdate(changed) {
|
|
433
483
|
super.willUpdate(changed);
|
|
434
|
-
|
|
484
|
+
const meta = this.resolvedStore?.get('meta') ?? null;
|
|
485
|
+
const layer = meta ? this.layerOf(meta) : null;
|
|
486
|
+
const level = layer ? this.levelOf(layer) : undefined;
|
|
487
|
+
const levelMoved = level !== this.listedAt;
|
|
488
|
+
this.listedAt = level;
|
|
489
|
+
if (changed.has('field') || levelMoved) {
|
|
435
490
|
this.found = [];
|
|
436
491
|
this.ticked = new Set();
|
|
437
492
|
this.picker.close(false);
|
|
438
493
|
}
|
|
439
|
-
const meta = this.resolvedStore?.get('meta') ?? null;
|
|
440
494
|
if (this.isOpen && (meta === null || !this.editable(meta)))
|
|
441
495
|
this.close();
|
|
442
496
|
}
|
|
443
497
|
get layerName() {
|
|
444
498
|
return this.field.startsWith(CLUSTER_PREFIX) ? this.field.slice(CLUSTER_PREFIX.length) : null;
|
|
445
499
|
}
|
|
500
|
+
/** The level `layer` is listed at: its entry in `clusterLevels`, else the level the map draws it at. */
|
|
501
|
+
levelOf(layer) {
|
|
502
|
+
return levelOfLayer(layer, this.clusterLevels.get(layer.name), this.resolvedStore?.get('artifacts').followedLevels);
|
|
503
|
+
}
|
|
446
504
|
/** The layer listed, where `field` names one the points can be coloured by. */
|
|
447
505
|
layerOf(meta) {
|
|
448
506
|
const name = this.layerName;
|
|
@@ -461,7 +519,7 @@ let MosaicaColourEditor = (() => {
|
|
|
461
519
|
if (this.isCategory(meta))
|
|
462
520
|
return { groupings: [{ count: true, by: { field: this.field, top } }], subject: 'visible' };
|
|
463
521
|
const layer = this.layerOf(meta);
|
|
464
|
-
return layer ? { groupings: [rankedGrouping(layer, top, levelOf(layer
|
|
522
|
+
return layer ? { groupings: [rankedGrouping(layer, top, this.levelOf(layer) ?? null)], subject: 'visible' } : null;
|
|
465
523
|
}
|
|
466
524
|
/** The aggregate that counts what the search box found. */
|
|
467
525
|
foundSpec(meta) {
|
|
@@ -506,10 +564,18 @@ let MosaicaColourEditor = (() => {
|
|
|
506
564
|
if (!s || !meta || !layer || !isTree(layer))
|
|
507
565
|
return;
|
|
508
566
|
const list = this.renderRoot.querySelector('[part="rows"]');
|
|
509
|
-
const
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
567
|
+
const rows = this.rows(s, meta);
|
|
568
|
+
const box = list?.getBoundingClientRect();
|
|
569
|
+
// A row is as tall as its name needs, so the rows in sight are those whose boxes are.
|
|
570
|
+
const inSight = list && box && box.height > 0
|
|
571
|
+
? new Set(Array.from(list.querySelectorAll('[part~="row"]'))
|
|
572
|
+
.filter((el) => {
|
|
573
|
+
const r = el.getBoundingClientRect();
|
|
574
|
+
return r.bottom > box.top && r.top < box.bottom;
|
|
575
|
+
})
|
|
576
|
+
.map((el) => el.dataset.key))
|
|
577
|
+
: new Set(rows.slice(0, FIRST_ROWS).map((r) => r.key));
|
|
578
|
+
this.paths.ask(s, layer, rows.filter((r) => inSight.has(r.key) && !r.found).map((r) => BigInt(r.key)));
|
|
513
579
|
}
|
|
514
580
|
/**
|
|
515
581
|
* The rows: what the search box found, then the field's values or the layer's clusters, largest
|
|
@@ -605,6 +671,12 @@ let MosaicaColourEditor = (() => {
|
|
|
605
671
|
next.delete(key);
|
|
606
672
|
this.ticked = next;
|
|
607
673
|
}
|
|
674
|
+
/** Untick every row. The bar Deselect is on goes with them, so focus moves to the first row's checkbox. */
|
|
675
|
+
async deselect() {
|
|
676
|
+
this.ticked = new Set();
|
|
677
|
+
await this.updateComplete;
|
|
678
|
+
this.renderRoot.querySelector('[part="check"]')?.focus();
|
|
679
|
+
}
|
|
608
680
|
/** A match the search box found: its row gets focus where the list holds it; else it goes at the top. */
|
|
609
681
|
onFound(f, listed) {
|
|
610
682
|
const at = listed.find((r) => r.key === f.key);
|
|
@@ -637,7 +709,7 @@ let MosaicaColourEditor = (() => {
|
|
|
637
709
|
const rows = this.rows(s, meta);
|
|
638
710
|
const ranked = this.ranked.entryOf(s, this.rankedSpec(meta));
|
|
639
711
|
const table = ranked?.result?.tables[0];
|
|
640
|
-
const level = layer ? levelOf(layer
|
|
712
|
+
const level = layer ? this.levelOf(layer) : undefined;
|
|
641
713
|
const levelTitle = layer && level !== undefined && layer.levels.length > 1 ? (layer.levels.find((l) => l.level === level)?.title ?? `Level ${level}`) : null;
|
|
642
714
|
const where = layer && isTree(layer) ? 'Clusters drawn' : levelTitle;
|
|
643
715
|
const sub = [where, this.palette(s).title].filter(Boolean).join(' · ');
|
|
@@ -655,19 +727,19 @@ let MosaicaColourEditor = (() => {
|
|
|
655
727
|
? html `<div part="selected" role="group" aria-label="Ticked rows">
|
|
656
728
|
<b>${ticked.length.toLocaleString('en-GB')} selected</b>
|
|
657
729
|
<button part="set-colour" type="button" aria-haspopup="dialog" @click=${(e) => this.pick(e, `${ticked.length.toLocaleString('en-GB')} selected`, ticked)}>Set colour<span style=${`background:${ticked[0].colour}`}></span></button>
|
|
658
|
-
<button part="deselect" type="button" @click=${() =>
|
|
730
|
+
<button part="deselect" type="button" @click=${() => void this.deselect()}>Deselect</button>
|
|
659
731
|
</div>`
|
|
660
732
|
: nothing;
|
|
661
733
|
const row = (r) => {
|
|
662
734
|
const on = this.ticked.has(r.key);
|
|
663
735
|
return html `<div part="row" role="listitem" data-key=${r.key} ?data-found=${r.found} ?data-ticked=${on}>
|
|
664
|
-
<input part="check" type="checkbox" .checked=${on} aria-label=${`Select ${r.name}`} @change=${(e) => this.tick(r.key, e.target.checked)}
|
|
665
|
-
<button part="swatch" type="button" style=${`--c:${r.colour}`} ?data-unmet=${r.unmet} aria-haspopup="dialog" aria-label=${`Colour of ${r.name}`} title=${r.unmet ? 'Not drawn yet' : r.colour} @click=${(e) => this.pick(e, r.name, [r])}></button>
|
|
736
|
+
<label class="tick"><input part="check" type="checkbox" .checked=${on} aria-label=${`Select ${r.name}`} @change=${(e) => this.tick(r.key, e.target.checked)} /></label>
|
|
737
|
+
<button part="swatch" type="button" style=${`--c:${r.colour}`} ?data-unmet=${r.unmet} aria-haspopup="dialog" aria-label=${`Colour of ${r.name}${r.unmet ? ', not drawn yet' : ''}`} title=${r.unmet ? 'Not drawn yet' : r.colour} @click=${(e) => this.pick(e, r.name, [r])}></button>
|
|
666
738
|
<span class="label"><span part="name" title=${r.name} ?data-unnamed=${r.name === UNNAMED}>${r.name}</span>${r.path ? html `<span part="path" title=${r.path}>${r.path}</span>` : nothing}</span>
|
|
667
|
-
<span
|
|
739
|
+
<span class="n">${r.count === null ? nothing : html `<span part="count">${countText(r.count)}</span><span class="sr-only"> items</span>`}</span>
|
|
668
740
|
</div>`;
|
|
669
741
|
};
|
|
670
|
-
const empty = rows.length
|
|
742
|
+
const empty = rows.length > 0 ? nothing : ranked?.status === 'refused' ? `${layer ? 'Clusters' : 'Values'} unavailable` : ranked?.result ? 'Nothing to colour' : 'Loading…';
|
|
671
743
|
const chosen = this.chosenKeys(s);
|
|
672
744
|
return dialog(html `<div class="box">
|
|
673
745
|
<div class="head">
|
|
@@ -676,7 +748,8 @@ let MosaicaColourEditor = (() => {
|
|
|
676
748
|
</div>
|
|
677
749
|
${search}${bar}
|
|
678
750
|
<div part="columns" aria-hidden="true"><span></span><span></span><span>${layer ? 'Cluster' : 'Value'}</span><span>Items</span></div>
|
|
679
|
-
<div
|
|
751
|
+
<div class="none" role="status">${empty}</div>
|
|
752
|
+
<div part="rows" role="list" aria-label=${`${name}: ${noun} by size`} @scroll=${this.onScroll}>${repeat(rows, (r) => r.key, row)}</div>
|
|
680
753
|
<div class="foot">
|
|
681
754
|
<button part="reset-all" class="btn" type="button" ?disabled=${chosen.length === 0} @click=${() => this.apply(chosen, null, true)}>Reset to palette</button>
|
|
682
755
|
<span part="changed" role="status">${chosen.length === 1 ? '1 colour changed' : `${chosen.length.toLocaleString('en-GB')} colours changed`}</span>
|
package/dist/colour-picker.d.ts
CHANGED
|
@@ -25,10 +25,12 @@ type Host = ReactiveElement & {
|
|
|
25
25
|
* The colour picker a swatch opens: the palette's colours and a lighter row of them, a custom area
|
|
26
26
|
* with a saturation and brightness square, a hue bar and a hex field, and Reset. A choice applies
|
|
27
27
|
* at once. It is shown in the top layer beside the rectangle `beside` gives, level with the swatch
|
|
28
|
-
* it was opened from,
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
28
|
+
* it was opened from, or under or over that swatch's row where the window has no room beside, and
|
|
29
|
+
* focus goes into it; Escape, Tab past either end of it, or a press outside
|
|
30
|
+
* it and its swatch, closes it, the keys giving focus back to the swatch. A custom colour shows on
|
|
31
|
+
* the map as it is dragged and is reported as it is let go; a drag cancelled, or ended by closing
|
|
32
|
+
* the picker, puts back the colour from before it. Text in the hex field that is not a colour is
|
|
33
|
+
* kept and marked invalid, and the line under the field says what to write.
|
|
32
34
|
*
|
|
33
35
|
* The host renders {@link render} where the picker belongs in its tree and adds
|
|
34
36
|
* {@link pickerStyles} to its styles. The parts are the host's: `colour-popover`, `choice`, `sv`,
|
|
@@ -47,6 +49,8 @@ export declare class ColourPicker implements ReactiveController {
|
|
|
47
49
|
private live;
|
|
48
50
|
/** What puts back the colour from before a drag, while one shows a colour not yet reported. */
|
|
49
51
|
private restore;
|
|
52
|
+
/** What was typed in the hex field, while it is not a colour. */
|
|
53
|
+
private typed;
|
|
50
54
|
constructor(host: Host, beside: () => DOMRect);
|
|
51
55
|
open(from: HTMLElement, target: PickerTarget): void;
|
|
52
56
|
close(refocus: boolean): void;
|
|
@@ -60,7 +64,10 @@ export declare class ColourPicker implements ReactiveController {
|
|
|
60
64
|
private applyLive;
|
|
61
65
|
private choose;
|
|
62
66
|
render(): TemplateResult | typeof nothing;
|
|
63
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* Show the picker in the top layer, beside {@link beside} and level with its swatch, or, where
|
|
69
|
+
* neither side has room, under or over its swatch's row; focus goes into it as it opens.
|
|
70
|
+
*/
|
|
64
71
|
private place;
|
|
65
72
|
}
|
|
66
73
|
/** The picker's styles, for the element that renders it. */
|