@operato/property-editor 10.29.9 → 10.29.12
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 +23 -0
- package/coverage/lcov-report/index.html +5 -5
- package/coverage/lcov.info +92 -89
- package/dist/src/ox-property-editor-number-map.d.ts +13 -4
- package/dist/src/ox-property-editor-number-map.js +192 -22
- package/dist/src/ox-property-editor-number-map.js.map +1 -1
- package/dist/test/number-map.test.js +21 -1
- package/dist/test/number-map.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/test/number-map.test.ts +25 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,29 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
### [10.29.12](https://github.com/hatiolab/operato/compare/v10.29.11...v10.29.12) (2026-10-06)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @operato/property-editor
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### [10.29.11](https://github.com/hatiolab/operato/compare/v10.29.10...v10.29.11) (2026-10-06)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### :rocket: New Features
|
|
18
|
+
|
|
19
|
+
* **property-editor:** number-map rows are compact and aligned, with a slider for a ranged value ([97f145e](https://github.com/hatiolab/operato/commit/97f145e732cddb4340d162321a3ab88185e23795))
|
|
20
|
+
* **property-editor:** thinner number-map rows, and a slider drag applies as it moves ([75ef024](https://github.com/hatiolab/operato/commit/75ef024d217bbfab74a0d96c61ac770594159ab4))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### :bug: Bug Fix
|
|
24
|
+
|
|
25
|
+
* **property-editor:** number-map value field wide enough for a signed decimal ([7b4d851](https://github.com/hatiolab/operato/commit/7b4d8515d73e7a01cad53582c7f876d9953118ac))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
6
29
|
### [10.29.9](https://github.com/hatiolab/operato/compare/v10.29.8...v10.29.9) (2026-10-05)
|
|
7
30
|
|
|
8
31
|
**Note:** Version bump only for package @operato/property-editor
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">
|
|
33
|
+
<span class="strong">45.74% </span>
|
|
34
34
|
<span class="quiet">Branches</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>43/94</span>
|
|
36
36
|
</div>
|
|
37
37
|
|
|
38
38
|
|
|
@@ -115,8 +115,8 @@
|
|
|
115
115
|
</td>
|
|
116
116
|
<td data-value="84.39" class="pct high">84.39%</td>
|
|
117
117
|
<td data-value="410" class="abs high">346/410</td>
|
|
118
|
-
<td data-value="
|
|
119
|
-
<td data-value="
|
|
118
|
+
<td data-value="53.65" class="pct medium">53.65%</td>
|
|
119
|
+
<td data-value="41" class="abs medium">22/41</td>
|
|
120
120
|
<td data-value="56.25" class="pct medium">56.25%</td>
|
|
121
121
|
<td data-value="16" class="abs medium">9/16</td>
|
|
122
122
|
<td data-value="84.39" class="pct high">84.39%</td>
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
132
132
|
Code coverage generated by
|
|
133
133
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
134
|
-
at 2026-
|
|
134
|
+
at 2026-10-06T00:52:46.443Z
|
|
135
135
|
</div>
|
|
136
136
|
<script src="prettify.js"></script>
|
|
137
137
|
<script>
|
package/coverage/lcov.info
CHANGED
|
@@ -524,8 +524,8 @@ FN:56,hintOf
|
|
|
524
524
|
FN:62,_valueChanged
|
|
525
525
|
FNF:3
|
|
526
526
|
FNH:3
|
|
527
|
-
FNDA:
|
|
528
|
-
FNDA:
|
|
527
|
+
FNDA:5,editorTemplate
|
|
528
|
+
FNDA:10,hintOf
|
|
529
529
|
FNDA:3,_valueChanged
|
|
530
530
|
DA:1,1
|
|
531
531
|
DA:2,1
|
|
@@ -555,38 +555,38 @@ DA:25,1
|
|
|
555
555
|
DA:26,1
|
|
556
556
|
DA:27,1
|
|
557
557
|
DA:28,1
|
|
558
|
-
DA:29,
|
|
559
|
-
DA:30,
|
|
560
|
-
DA:31,
|
|
561
|
-
DA:32,
|
|
562
|
-
DA:33,
|
|
563
|
-
DA:34,
|
|
564
|
-
DA:35,
|
|
565
|
-
DA:36,
|
|
566
|
-
DA:37,
|
|
567
|
-
DA:38,
|
|
568
|
-
DA:39,
|
|
569
|
-
DA:40,
|
|
570
|
-
DA:41,
|
|
571
|
-
DA:42,
|
|
572
|
-
DA:43,
|
|
573
|
-
DA:44,
|
|
574
|
-
DA:45,
|
|
575
|
-
DA:46,
|
|
576
|
-
DA:47,
|
|
577
|
-
DA:48,
|
|
578
|
-
DA:49,
|
|
579
|
-
DA:50,
|
|
580
|
-
DA:51,
|
|
581
|
-
DA:52,
|
|
582
|
-
DA:53,
|
|
583
|
-
DA:54,
|
|
558
|
+
DA:29,5
|
|
559
|
+
DA:30,5
|
|
560
|
+
DA:31,5
|
|
561
|
+
DA:32,5
|
|
562
|
+
DA:33,5
|
|
563
|
+
DA:34,5
|
|
564
|
+
DA:35,10
|
|
565
|
+
DA:36,10
|
|
566
|
+
DA:37,10
|
|
567
|
+
DA:38,10
|
|
568
|
+
DA:39,10
|
|
569
|
+
DA:40,10
|
|
570
|
+
DA:41,10
|
|
571
|
+
DA:42,10
|
|
572
|
+
DA:43,10
|
|
573
|
+
DA:44,10
|
|
574
|
+
DA:45,10
|
|
575
|
+
DA:46,10
|
|
576
|
+
DA:47,10
|
|
577
|
+
DA:48,10
|
|
578
|
+
DA:49,10
|
|
579
|
+
DA:50,10
|
|
580
|
+
DA:51,5
|
|
581
|
+
DA:52,5
|
|
582
|
+
DA:53,5
|
|
583
|
+
DA:54,5
|
|
584
584
|
DA:55,1
|
|
585
585
|
DA:56,1
|
|
586
|
-
DA:57,
|
|
587
|
-
DA:58,
|
|
588
|
-
DA:59,
|
|
589
|
-
DA:60,
|
|
586
|
+
DA:57,10
|
|
587
|
+
DA:58,10
|
|
588
|
+
DA:59,10
|
|
589
|
+
DA:60,10
|
|
590
590
|
DA:61,1
|
|
591
591
|
DA:62,1
|
|
592
592
|
DA:63,3
|
|
@@ -598,28 +598,28 @@ DA:68,3
|
|
|
598
598
|
DA:69,3
|
|
599
599
|
DA:70,3
|
|
600
600
|
DA:71,3
|
|
601
|
-
DA:72,
|
|
602
|
-
DA:73,
|
|
603
|
-
DA:74,
|
|
604
|
-
DA:75,
|
|
605
|
-
DA:76,
|
|
606
|
-
DA:77,
|
|
607
|
-
DA:78,
|
|
608
|
-
DA:79,
|
|
609
|
-
DA:80,
|
|
601
|
+
DA:72,2
|
|
602
|
+
DA:73,2
|
|
603
|
+
DA:74,2
|
|
604
|
+
DA:75,2
|
|
605
|
+
DA:76,1
|
|
606
|
+
DA:77,1
|
|
607
|
+
DA:78,1
|
|
608
|
+
DA:79,1
|
|
609
|
+
DA:80,1
|
|
610
610
|
DA:81,1
|
|
611
611
|
LF:81
|
|
612
612
|
LH:81
|
|
613
|
-
BRDA:28,0,0,
|
|
613
|
+
BRDA:28,0,0,5
|
|
614
614
|
BRDA:29,1,0,0
|
|
615
615
|
BRDA:29,2,0,0
|
|
616
616
|
BRDA:30,3,0,0
|
|
617
|
-
BRDA:34,4,0,
|
|
618
|
-
BRDA:42,5,0,
|
|
617
|
+
BRDA:34,4,0,10
|
|
618
|
+
BRDA:42,5,0,6
|
|
619
619
|
BRDA:42,6,0,4
|
|
620
620
|
BRDA:42,7,0,0
|
|
621
621
|
BRDA:48,8,0,0
|
|
622
|
-
BRDA:56,9,0,
|
|
622
|
+
BRDA:56,9,0,10
|
|
623
623
|
BRDA:57,10,0,0
|
|
624
624
|
BRDA:58,11,0,0
|
|
625
625
|
BRDA:59,12,0,0
|
|
@@ -628,16 +628,19 @@ BRDA:66,14,0,0
|
|
|
628
628
|
BRDA:67,15,0,0
|
|
629
629
|
BRDA:67,16,0,0
|
|
630
630
|
BRDA:68,17,0,0
|
|
631
|
-
BRDA:70,18,0,
|
|
632
|
-
BRDA:70,19,0,
|
|
633
|
-
BRDA:70,20,0,
|
|
634
|
-
BRDA:
|
|
635
|
-
BRDA:
|
|
636
|
-
BRDA:73,23,0,
|
|
637
|
-
BRDA:
|
|
638
|
-
BRDA:
|
|
639
|
-
|
|
640
|
-
|
|
631
|
+
BRDA:70,18,0,2
|
|
632
|
+
BRDA:70,19,0,2
|
|
633
|
+
BRDA:70,20,0,2
|
|
634
|
+
BRDA:70,21,0,2
|
|
635
|
+
BRDA:71,22,0,2
|
|
636
|
+
BRDA:73,23,0,1
|
|
637
|
+
BRDA:73,24,0,1
|
|
638
|
+
BRDA:73,25,0,1
|
|
639
|
+
BRDA:73,26,0,0
|
|
640
|
+
BRDA:76,27,0,1
|
|
641
|
+
BRDA:67,28,0,5
|
|
642
|
+
BRF:29
|
|
643
|
+
BRH:16
|
|
641
644
|
end_of_record
|
|
642
645
|
TN:
|
|
643
646
|
SF:src/ox-property-editor.ts
|
|
@@ -662,13 +665,13 @@ FNDA:0,getEditor
|
|
|
662
665
|
FNDA:4,connectedCallback
|
|
663
666
|
FNDA:0,editorTemplate
|
|
664
667
|
FNDA:0,getDefaultValue
|
|
665
|
-
FNDA:
|
|
666
|
-
FNDA:
|
|
668
|
+
FNDA:5,render
|
|
669
|
+
FNDA:5,shouldUpdate
|
|
667
670
|
FNDA:0,get valueProperty
|
|
668
|
-
FNDA:
|
|
671
|
+
FNDA:5,makeup
|
|
669
672
|
FNDA:0,_computeLabelId
|
|
670
673
|
FNDA:0,_valueChanged
|
|
671
|
-
FNDA:
|
|
674
|
+
FNDA:1,observe
|
|
672
675
|
DA:1,1
|
|
673
676
|
DA:2,1
|
|
674
677
|
DA:3,1
|
|
@@ -903,13 +906,13 @@ DA:231,0
|
|
|
903
906
|
DA:232,0
|
|
904
907
|
DA:233,4
|
|
905
908
|
DA:234,4
|
|
906
|
-
DA:235,
|
|
907
|
-
DA:236,
|
|
908
|
-
DA:237,
|
|
909
|
-
DA:238,
|
|
910
|
-
DA:239,
|
|
911
|
-
DA:240,
|
|
912
|
-
DA:241,
|
|
909
|
+
DA:235,5
|
|
910
|
+
DA:236,5
|
|
911
|
+
DA:237,5
|
|
912
|
+
DA:238,5
|
|
913
|
+
DA:239,5
|
|
914
|
+
DA:240,5
|
|
915
|
+
DA:241,5
|
|
913
916
|
DA:242,0
|
|
914
917
|
DA:243,0
|
|
915
918
|
DA:244,0
|
|
@@ -918,8 +921,8 @@ DA:246,0
|
|
|
918
921
|
DA:247,0
|
|
919
922
|
DA:248,0
|
|
920
923
|
DA:249,0
|
|
921
|
-
DA:250,
|
|
922
|
-
DA:251,
|
|
924
|
+
DA:250,5
|
|
925
|
+
DA:251,5
|
|
923
926
|
DA:252,0
|
|
924
927
|
DA:253,0
|
|
925
928
|
DA:254,0
|
|
@@ -935,33 +938,33 @@ DA:263,0
|
|
|
935
938
|
DA:264,0
|
|
936
939
|
DA:265,0
|
|
937
940
|
DA:266,0
|
|
938
|
-
DA:267,
|
|
939
|
-
DA:268,
|
|
940
|
-
DA:269,
|
|
941
|
+
DA:267,5
|
|
942
|
+
DA:268,5
|
|
943
|
+
DA:269,5
|
|
941
944
|
DA:270,4
|
|
942
945
|
DA:271,4
|
|
943
946
|
DA:272,4
|
|
944
947
|
DA:273,4
|
|
945
|
-
DA:274,
|
|
948
|
+
DA:274,5
|
|
946
949
|
DA:275,0
|
|
947
950
|
DA:276,0
|
|
948
|
-
DA:277,
|
|
949
|
-
DA:278,
|
|
950
|
-
DA:279,
|
|
951
|
-
DA:280,
|
|
952
|
-
DA:281,
|
|
953
|
-
DA:282,
|
|
954
|
-
DA:283,
|
|
955
|
-
DA:284,
|
|
956
|
-
DA:285,
|
|
951
|
+
DA:277,5
|
|
952
|
+
DA:278,5
|
|
953
|
+
DA:279,5
|
|
954
|
+
DA:280,5
|
|
955
|
+
DA:281,5
|
|
956
|
+
DA:282,5
|
|
957
|
+
DA:283,5
|
|
958
|
+
DA:284,5
|
|
959
|
+
DA:285,5
|
|
957
960
|
DA:286,4
|
|
958
961
|
DA:287,4
|
|
959
962
|
DA:288,0
|
|
960
963
|
DA:289,0
|
|
961
964
|
DA:290,4
|
|
962
965
|
DA:291,4
|
|
963
|
-
DA:292,
|
|
964
|
-
DA:293,
|
|
966
|
+
DA:292,5
|
|
967
|
+
DA:293,5
|
|
965
968
|
DA:294,4
|
|
966
969
|
DA:295,4
|
|
967
970
|
DA:296,0
|
|
@@ -991,25 +994,25 @@ DA:319,0
|
|
|
991
994
|
DA:320,0
|
|
992
995
|
DA:321,4
|
|
993
996
|
DA:322,4
|
|
994
|
-
DA:323,
|
|
997
|
+
DA:323,1
|
|
995
998
|
DA:324,0
|
|
996
999
|
DA:325,0
|
|
997
1000
|
DA:326,0
|
|
998
1001
|
DA:327,0
|
|
999
|
-
DA:328,
|
|
1002
|
+
DA:328,1
|
|
1000
1003
|
DA:329,4
|
|
1001
1004
|
LF:329
|
|
1002
1005
|
LH:265
|
|
1003
1006
|
BRDA:9,0,0,4
|
|
1004
1007
|
BRDA:220,1,0,4
|
|
1005
|
-
BRDA:234,2,0,
|
|
1008
|
+
BRDA:234,2,0,5
|
|
1006
1009
|
BRDA:236,3,0,0
|
|
1007
1010
|
BRDA:241,4,0,0
|
|
1008
1011
|
BRDA:251,5,0,0
|
|
1009
|
-
BRDA:273,6,0,
|
|
1012
|
+
BRDA:273,6,0,5
|
|
1010
1013
|
BRDA:274,7,0,0
|
|
1011
|
-
BRDA:291,8,0,
|
|
1012
|
-
BRDA:322,9,0,
|
|
1014
|
+
BRDA:291,8,0,5
|
|
1015
|
+
BRDA:322,9,0,1
|
|
1013
1016
|
BRDA:323,10,0,0
|
|
1014
1017
|
BRDA:323,11,0,0
|
|
1015
1018
|
BRF:12
|
|
@@ -11,15 +11,24 @@ export interface NumberMapEntry {
|
|
|
11
11
|
default?: number;
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
|
-
* Several numbers kept as one map ({ key: number }) -- a figure's design values a board sets
|
|
15
|
-
* spacings. Each entry is
|
|
16
|
-
*
|
|
17
|
-
* map, so the map is the one value the component holds.
|
|
14
|
+
* Several numbers kept as one map ({ key: number }) -- a figure's design values and state values a board sets
|
|
15
|
+
* (ADR-0096), a shelf's spacings. Each entry is one compact row: its name, a slider when it has a range, the number
|
|
16
|
+
* field, and its unit. A value outside its range is not taken: the field goes back to what it was. A change sends the
|
|
17
|
+
* whole map, so the map is the one value the component holds.
|
|
18
|
+
*
|
|
19
|
+
* The slider is taken at every step of a drag, so what it drives moves with the handle.
|
|
18
20
|
*
|
|
19
21
|
* Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.
|
|
20
22
|
*/
|
|
21
23
|
export declare class OxPropertyEditorNumberMap extends OxPropertyEditor {
|
|
24
|
+
static styles: import("lit").CSSResult[];
|
|
22
25
|
editorTemplate(value: any, spec: PropertySpec): TemplateResult;
|
|
26
|
+
/** The slider's range, when the entry has one to slide over. */
|
|
27
|
+
private rangeOf;
|
|
28
|
+
/** How far along its range a value is, in percent, for the filled part of the track. */
|
|
29
|
+
private fillOf;
|
|
23
30
|
private hintOf;
|
|
31
|
+
/** While dragging the value is taken at every step, so the figure moves with the handle. */
|
|
32
|
+
private onSlide;
|
|
24
33
|
_valueChanged(e: Event): void;
|
|
25
34
|
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { html } from 'lit';
|
|
2
|
+
import { css, html, nothing } from 'lit';
|
|
3
3
|
import { customElement } from 'lit/decorators.js';
|
|
4
4
|
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
5
|
import { OxPropertyEditor } from './ox-property-editor.js';
|
|
6
6
|
/**
|
|
7
|
-
* Several numbers kept as one map ({ key: number }) -- a figure's design values a board sets
|
|
8
|
-
* spacings. Each entry is
|
|
9
|
-
*
|
|
10
|
-
* map, so the map is the one value the component holds.
|
|
7
|
+
* Several numbers kept as one map ({ key: number }) -- a figure's design values and state values a board sets
|
|
8
|
+
* (ADR-0096), a shelf's spacings. Each entry is one compact row: its name, a slider when it has a range, the number
|
|
9
|
+
* field, and its unit. A value outside its range is not taken: the field goes back to what it was. A change sends the
|
|
10
|
+
* whole map, so the map is the one value the component holds.
|
|
11
|
+
*
|
|
12
|
+
* The slider is taken at every step of a drag, so what it drives moves with the handle.
|
|
11
13
|
*
|
|
12
14
|
* Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.
|
|
13
15
|
*/
|
|
@@ -17,35 +19,65 @@ let OxPropertyEditorNumberMap = class OxPropertyEditorNumberMap extends OxProper
|
|
|
17
19
|
const entries = (_b = (_a = spec.property) === null || _a === void 0 ? void 0 : _a.entries) !== null && _b !== void 0 ? _b : [];
|
|
18
20
|
const map = value && typeof value === 'object' ? value : {};
|
|
19
21
|
return html `
|
|
20
|
-
<div fullwidth>
|
|
22
|
+
<div fullwidth rows>
|
|
21
23
|
${entries.map(entry => {
|
|
22
24
|
var _a, _b;
|
|
25
|
+
const shown = (_a = map[entry.key]) !== null && _a !== void 0 ? _a : entry.default;
|
|
26
|
+
const ranged = this.rangeOf(entry);
|
|
23
27
|
return html `
|
|
24
|
-
<
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
<span name title=${entry.label}>${entry.label}</span>
|
|
29
|
+
${ranged
|
|
30
|
+
? html `<input
|
|
31
|
+
type="range"
|
|
32
|
+
data-key=${entry.key}
|
|
33
|
+
aria-label=${entry.label}
|
|
34
|
+
min=${ranged.min}
|
|
35
|
+
max=${ranged.max}
|
|
36
|
+
step=${ranged.step}
|
|
37
|
+
.value=${String(shown !== null && shown !== void 0 ? shown : ranged.min)}
|
|
38
|
+
style=${`--fill: ${this.fillOf(shown !== null && shown !== void 0 ? shown : ranged.min, ranged)}%`}
|
|
39
|
+
?disabled=${this.disabled}
|
|
40
|
+
@input=${this.onSlide}
|
|
41
|
+
/>`
|
|
42
|
+
: nothing}
|
|
43
|
+
<input
|
|
44
|
+
type="number"
|
|
45
|
+
data-key=${entry.key}
|
|
46
|
+
aria-label=${entry.label}
|
|
47
|
+
?wide=${!ranged}
|
|
48
|
+
.value=${String(shown !== null && shown !== void 0 ? shown : '')}
|
|
49
|
+
placeholder=${ifDefined(this.hintOf(entry))}
|
|
50
|
+
min=${ifDefined(entry.min)}
|
|
51
|
+
max=${ifDefined(entry.max)}
|
|
52
|
+
step="any"
|
|
53
|
+
?disabled=${this.disabled}
|
|
54
|
+
/>
|
|
55
|
+
<span unit>${(_b = entry.unit) !== null && _b !== void 0 ? _b : ''}</span>
|
|
39
56
|
`;
|
|
40
57
|
})}
|
|
41
58
|
</div>
|
|
42
59
|
`;
|
|
43
60
|
}
|
|
61
|
+
/** The slider's range, when the entry has one to slide over. */
|
|
62
|
+
rangeOf(entry) {
|
|
63
|
+
const { min, max } = entry;
|
|
64
|
+
if (!Number.isFinite(min) || !Number.isFinite(max) || max <= min)
|
|
65
|
+
return undefined;
|
|
66
|
+
return { min: min, max: max, step: (max - min) / 100 };
|
|
67
|
+
}
|
|
68
|
+
/** How far along its range a value is, in percent, for the filled part of the track. */
|
|
69
|
+
fillOf(value, range) {
|
|
70
|
+
return Math.min(Math.max(((value - range.min) / (range.max - range.min)) * 100, 0), 100);
|
|
71
|
+
}
|
|
44
72
|
hintOf(entry) {
|
|
45
73
|
const range = entry.min !== undefined && entry.max !== undefined ? `${entry.min}–${entry.max}` : undefined;
|
|
46
74
|
const standard = entry.default !== undefined ? `(${entry.default})` : undefined;
|
|
47
75
|
return [range, standard].filter(Boolean).join(' ') || undefined;
|
|
48
76
|
}
|
|
77
|
+
/** While dragging the value is taken at every step, so the figure moves with the handle. */
|
|
78
|
+
onSlide(e) {
|
|
79
|
+
this._valueChanged(e);
|
|
80
|
+
}
|
|
49
81
|
_valueChanged(e) {
|
|
50
82
|
var _a, _b, _c, _d;
|
|
51
83
|
e.stopPropagation();
|
|
@@ -62,12 +94,150 @@ let OxPropertyEditorNumberMap = class OxPropertyEditorNumberMap extends OxProper
|
|
|
62
94
|
input.value = String((_d = (_c = map[key]) !== null && _c !== void 0 ? _c : entry === null || entry === void 0 ? void 0 : entry.default) !== null && _d !== void 0 ? _d : '');
|
|
63
95
|
return;
|
|
64
96
|
}
|
|
65
|
-
map[key] = number;
|
|
97
|
+
map[key] = input.type === 'range' ? Math.round(number * 100) / 100 : number;
|
|
66
98
|
this.value = map;
|
|
99
|
+
this.renderRoot.querySelectorAll(`input[data-key="${key}"]`).forEach(one => {
|
|
100
|
+
one.value = String(map[key]);
|
|
101
|
+
if (one.type === 'range')
|
|
102
|
+
one.style.setProperty('--fill', `${this.fillOf(map[key], { min: Number(one.min), max: Number(one.max) })}%`);
|
|
103
|
+
});
|
|
67
104
|
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
|
|
68
105
|
this.observe(this.value);
|
|
69
106
|
}
|
|
70
107
|
};
|
|
108
|
+
OxPropertyEditorNumberMap.styles = [
|
|
109
|
+
...OxPropertyEditor.styles,
|
|
110
|
+
css `
|
|
111
|
+
/*
|
|
112
|
+
* The rows take the editor's own 24 columns (subgrid), so a name sits in the label column, right-aligned like
|
|
113
|
+
* every other label, and the fields start where every other field starts.
|
|
114
|
+
*/
|
|
115
|
+
:host > div[rows] {
|
|
116
|
+
display: grid;
|
|
117
|
+
grid-template-columns: subgrid;
|
|
118
|
+
grid-auto-rows: 16px;
|
|
119
|
+
row-gap: 3px;
|
|
120
|
+
align-items: center;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
:host > div[rows] > [name] {
|
|
124
|
+
grid-column: 1 / var(--property-editor-label-end, 9);
|
|
125
|
+
text-align: right;
|
|
126
|
+
font: var(--property-editor-label-font, var(--label-font));
|
|
127
|
+
color: var(--property-editor-label-color, inherit);
|
|
128
|
+
overflow: hidden;
|
|
129
|
+
text-overflow: ellipsis;
|
|
130
|
+
white-space: nowrap;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* A thin track filled up to the value (--fill), and a small round thumb: quieter than the fields around it. */
|
|
134
|
+
:host > div[rows] > input[type='range'] {
|
|
135
|
+
grid-column: var(--property-editor-label-end, 9) / 18;
|
|
136
|
+
-webkit-appearance: none;
|
|
137
|
+
appearance: none;
|
|
138
|
+
width: 100%;
|
|
139
|
+
min-width: 0;
|
|
140
|
+
height: 12px;
|
|
141
|
+
margin: 0;
|
|
142
|
+
padding: 0;
|
|
143
|
+
border: none;
|
|
144
|
+
background: transparent;
|
|
145
|
+
cursor: pointer;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
:host > div[rows] > input[type='range']::-webkit-slider-runnable-track {
|
|
149
|
+
height: 2px;
|
|
150
|
+
border-radius: 1px;
|
|
151
|
+
background: linear-gradient(
|
|
152
|
+
to right,
|
|
153
|
+
var(--md-sys-color-primary) var(--fill, 0%),
|
|
154
|
+
var(--md-sys-color-outline-variant) var(--fill, 0%)
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
:host > div[rows] > input[type='range']::-webkit-slider-thumb {
|
|
159
|
+
-webkit-appearance: none;
|
|
160
|
+
width: 8px;
|
|
161
|
+
height: 8px;
|
|
162
|
+
margin-top: -3px;
|
|
163
|
+
border-radius: 50%;
|
|
164
|
+
background: var(--md-sys-color-primary);
|
|
165
|
+
transition: transform 0.12s;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
:host > div[rows] > input[type='range']:hover::-webkit-slider-thumb,
|
|
169
|
+
:host > div[rows] > input[type='range']:focus-visible::-webkit-slider-thumb {
|
|
170
|
+
transform: scale(1.4);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
:host > div[rows] > input[type='range']::-moz-range-track {
|
|
174
|
+
height: 2px;
|
|
175
|
+
border-radius: 1px;
|
|
176
|
+
background: var(--md-sys-color-outline-variant);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
:host > div[rows] > input[type='range']::-moz-range-progress {
|
|
180
|
+
height: 2px;
|
|
181
|
+
border-radius: 1px;
|
|
182
|
+
background: var(--md-sys-color-primary);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
:host > div[rows] > input[type='range']::-moz-range-thumb {
|
|
186
|
+
width: 8px;
|
|
187
|
+
height: 8px;
|
|
188
|
+
border: none;
|
|
189
|
+
border-radius: 50%;
|
|
190
|
+
background: var(--md-sys-color-primary);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
:host > div[rows] > input[type='range']:disabled {
|
|
194
|
+
cursor: default;
|
|
195
|
+
opacity: 0.5;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
:host > div[rows] > input[type='number'] {
|
|
199
|
+
grid-column: 18 / 22;
|
|
200
|
+
box-sizing: border-box;
|
|
201
|
+
width: 100%;
|
|
202
|
+
min-width: 0;
|
|
203
|
+
height: 16px;
|
|
204
|
+
min-height: 0;
|
|
205
|
+
padding: 0 2px;
|
|
206
|
+
font: 0.7rem/1 var(--theme-font, Roboto, sans-serif);
|
|
207
|
+
/* The value reads as text; the field shows itself only when pointed at or typed in. */
|
|
208
|
+
background: transparent;
|
|
209
|
+
border-color: transparent;
|
|
210
|
+
border-radius: 3px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
:host > div[rows] > input[type='number']:hover {
|
|
214
|
+
border-color: var(--md-sys-color-outline-variant);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
:host > div[rows] > input[type='number']:focus {
|
|
218
|
+
border-color: var(--md-sys-color-primary);
|
|
219
|
+
background: var(--property-editor-background, field);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
:host > div[rows] > input[type='number']::-webkit-inner-spin-button {
|
|
223
|
+
display: none;
|
|
224
|
+
min-width: 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/* No range, no slider: the field takes the slider's room. */
|
|
228
|
+
:host > div[rows] > input[type='number'][wide] {
|
|
229
|
+
grid-column: var(--property-editor-label-end, 9) / 22;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
:host > div[rows] > [unit] {
|
|
233
|
+
grid-column: 22 / -1;
|
|
234
|
+
overflow: hidden;
|
|
235
|
+
font: 0.66rem/1 var(--theme-font, Roboto, sans-serif);
|
|
236
|
+
color: var(--md-sys-color-outline);
|
|
237
|
+
white-space: nowrap;
|
|
238
|
+
}
|
|
239
|
+
`
|
|
240
|
+
];
|
|
71
241
|
OxPropertyEditorNumberMap = __decorate([
|
|
72
242
|
customElement('ox-property-editor-number-map')
|
|
73
243
|
], OxPropertyEditorNumberMap);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ox-property-editor-number-map.js","sourceRoot":"","sources":["../../src/ox-property-editor-number-map.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, TemplateResult } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { OxPropertyEditor } from './ox-property-editor.js'\nimport { PropertySpec } from './types.js'\n\n/** One number of the map: its key, the name shown, and what it is held to. */\nexport interface NumberMapEntry {\n key: string\n label: string\n unit?: string\n min?: number\n max?: number\n default?: number\n}\n\n/**\n * Several numbers kept as one map ({ key: number }) -- a figure's design values a board sets (ADR-0096), a shelf's\n * spacings. Each entry is the number editor's field on a row of its own, its unit beside it, its range and default in\n * the placeholder. A value outside its range is not taken: the field goes back to what it was. A change sends the whole\n * map, so the map is the one value the component holds.\n *\n * Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.\n */\n@customElement('ox-property-editor-number-map')\nexport class OxPropertyEditorNumberMap extends OxPropertyEditor {\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n const entries: NumberMapEntry[] = spec.property?.entries ?? []\n const map: Record<string, number> = value && typeof value === 'object' ? value : {}\n return html`\n <div fullwidth>\n ${entries.map(\n entry => html`\n <div data-key=${entry.key} style=\"display: flex; align-items: center; gap: var(--spacing-small, 4px)\">\n <span style=\"flex: 1\">${entry.label}</span>\n <input\n type=\"number\"\n data-key=${entry.key}\n aria-label=${entry.label}\n style=\"flex: 1\"\n .value=${String(map[entry.key] ?? entry.default ?? '')}\n placeholder=${ifDefined(this.hintOf(entry))}\n min=${ifDefined(entry.min)}\n max=${ifDefined(entry.max)}\n ?disabled=${this.disabled}\n />\n ${entry.unit ? html`<span>${entry.unit}</span>` : ''}\n </div>\n `\n )}\n </div>\n `\n }\n\n private hintOf(entry: NumberMapEntry): string | undefined {\n const range = entry.min !== undefined && entry.max !== undefined ? `${entry.min}–${entry.max}` : undefined\n const standard = entry.default !== undefined ? `(${entry.default})` : undefined\n return [range, standard].filter(Boolean).join(' ') || undefined\n }\n\n override _valueChanged(e: Event) {\n e.stopPropagation()\n const input = e.target as HTMLInputElement\n const key = input.getAttribute('data-key')\n if (!key) return\n const entry = ((this.property?.entries ?? []) as NumberMapEntry[]).find(one => one.key === key)\n const map: Record<string, number> = this.value && typeof this.value === 'object' ? { ...this.value } : {}\n const number = input.valueAsNumber\n const outside = !Number.isFinite(number) || (entry?.min !== undefined && number < entry.min) || (entry?.max !== undefined && number > entry.max)\n if (outside) {\n /* Not taken: the field shows what the map holds. */\n input.value = String(map[key] ?? entry?.default ?? '')\n return\n }\n map[key] = number\n this.value = map\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n this.observe(this.value)\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ox-property-editor-number-map.js","sourceRoot":"","sources":["../../src/ox-property-editor-number-map.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, nothing, TemplateResult } from 'lit'\nimport { customElement } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { OxPropertyEditor } from './ox-property-editor.js'\nimport { PropertySpec } from './types.js'\n\n/** One number of the map: its key, the name shown, and what it is held to. */\nexport interface NumberMapEntry {\n key: string\n label: string\n unit?: string\n min?: number\n max?: number\n default?: number\n}\n\n/**\n * Several numbers kept as one map ({ key: number }) -- a figure's design values and state values a board sets\n * (ADR-0096), a shelf's spacings. Each entry is one compact row: its name, a slider when it has a range, the number\n * field, and its unit. A value outside its range is not taken: the field goes back to what it was. A change sends the\n * whole map, so the map is the one value the component holds.\n *\n * The slider is taken at every step of a drag, so what it drives moves with the handle.\n *\n * Built by the Figure lane after the existing editors (chief architect, 2026-09-26); open for the UX lane's review.\n */\n@customElement('ox-property-editor-number-map')\nexport class OxPropertyEditorNumberMap extends OxPropertyEditor {\n static styles = [\n ...OxPropertyEditor.styles,\n css`\n /*\n * The rows take the editor's own 24 columns (subgrid), so a name sits in the label column, right-aligned like\n * every other label, and the fields start where every other field starts.\n */\n :host > div[rows] {\n display: grid;\n grid-template-columns: subgrid;\n grid-auto-rows: 16px;\n row-gap: 3px;\n align-items: center;\n }\n\n :host > div[rows] > [name] {\n grid-column: 1 / var(--property-editor-label-end, 9);\n text-align: right;\n font: var(--property-editor-label-font, var(--label-font));\n color: var(--property-editor-label-color, inherit);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n /* A thin track filled up to the value (--fill), and a small round thumb: quieter than the fields around it. */\n :host > div[rows] > input[type='range'] {\n grid-column: var(--property-editor-label-end, 9) / 18;\n -webkit-appearance: none;\n appearance: none;\n width: 100%;\n min-width: 0;\n height: 12px;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n cursor: pointer;\n }\n\n :host > div[rows] > input[type='range']::-webkit-slider-runnable-track {\n height: 2px;\n border-radius: 1px;\n background: linear-gradient(\n to right,\n var(--md-sys-color-primary) var(--fill, 0%),\n var(--md-sys-color-outline-variant) var(--fill, 0%)\n );\n }\n\n :host > div[rows] > input[type='range']::-webkit-slider-thumb {\n -webkit-appearance: none;\n width: 8px;\n height: 8px;\n margin-top: -3px;\n border-radius: 50%;\n background: var(--md-sys-color-primary);\n transition: transform 0.12s;\n }\n\n :host > div[rows] > input[type='range']:hover::-webkit-slider-thumb,\n :host > div[rows] > input[type='range']:focus-visible::-webkit-slider-thumb {\n transform: scale(1.4);\n }\n\n :host > div[rows] > input[type='range']::-moz-range-track {\n height: 2px;\n border-radius: 1px;\n background: var(--md-sys-color-outline-variant);\n }\n\n :host > div[rows] > input[type='range']::-moz-range-progress {\n height: 2px;\n border-radius: 1px;\n background: var(--md-sys-color-primary);\n }\n\n :host > div[rows] > input[type='range']::-moz-range-thumb {\n width: 8px;\n height: 8px;\n border: none;\n border-radius: 50%;\n background: var(--md-sys-color-primary);\n }\n\n :host > div[rows] > input[type='range']:disabled {\n cursor: default;\n opacity: 0.5;\n }\n\n :host > div[rows] > input[type='number'] {\n grid-column: 18 / 22;\n box-sizing: border-box;\n width: 100%;\n min-width: 0;\n height: 16px;\n min-height: 0;\n padding: 0 2px;\n font: 0.7rem/1 var(--theme-font, Roboto, sans-serif);\n /* The value reads as text; the field shows itself only when pointed at or typed in. */\n background: transparent;\n border-color: transparent;\n border-radius: 3px;\n }\n\n :host > div[rows] > input[type='number']:hover {\n border-color: var(--md-sys-color-outline-variant);\n }\n\n :host > div[rows] > input[type='number']:focus {\n border-color: var(--md-sys-color-primary);\n background: var(--property-editor-background, field);\n }\n\n :host > div[rows] > input[type='number']::-webkit-inner-spin-button {\n display: none;\n min-width: 0;\n }\n\n /* No range, no slider: the field takes the slider's room. */\n :host > div[rows] > input[type='number'][wide] {\n grid-column: var(--property-editor-label-end, 9) / 22;\n }\n\n :host > div[rows] > [unit] {\n grid-column: 22 / -1;\n overflow: hidden;\n font: 0.66rem/1 var(--theme-font, Roboto, sans-serif);\n color: var(--md-sys-color-outline);\n white-space: nowrap;\n }\n `\n ]\n\n editorTemplate(value: any, spec: PropertySpec): TemplateResult {\n const entries: NumberMapEntry[] = spec.property?.entries ?? []\n const map: Record<string, number> = value && typeof value === 'object' ? value : {}\n return html`\n <div fullwidth rows>\n ${entries.map(entry => {\n const shown = map[entry.key] ?? entry.default\n const ranged = this.rangeOf(entry)\n return html`\n <span name title=${entry.label}>${entry.label}</span>\n ${ranged\n ? html`<input\n type=\"range\"\n data-key=${entry.key}\n aria-label=${entry.label}\n min=${ranged.min}\n max=${ranged.max}\n step=${ranged.step}\n .value=${String(shown ?? ranged.min)}\n style=${`--fill: ${this.fillOf(shown ?? ranged.min, ranged)}%`}\n ?disabled=${this.disabled}\n @input=${this.onSlide}\n />`\n : nothing}\n <input\n type=\"number\"\n data-key=${entry.key}\n aria-label=${entry.label}\n ?wide=${!ranged}\n .value=${String(shown ?? '')}\n placeholder=${ifDefined(this.hintOf(entry))}\n min=${ifDefined(entry.min)}\n max=${ifDefined(entry.max)}\n step=\"any\"\n ?disabled=${this.disabled}\n />\n <span unit>${entry.unit ?? ''}</span>\n `\n })}\n </div>\n `\n }\n\n /** The slider's range, when the entry has one to slide over. */\n private rangeOf(entry: NumberMapEntry): { min: number; max: number; step: number } | undefined {\n const { min, max } = entry\n if (!Number.isFinite(min) || !Number.isFinite(max) || max! <= min!) return undefined\n return { min: min!, max: max!, step: (max! - min!) / 100 }\n }\n\n /** How far along its range a value is, in percent, for the filled part of the track. */\n private fillOf(value: number, range: { min: number; max: number }): number {\n return Math.min(Math.max(((value - range.min) / (range.max - range.min)) * 100, 0), 100)\n }\n\n private hintOf(entry: NumberMapEntry): string | undefined {\n const range = entry.min !== undefined && entry.max !== undefined ? `${entry.min}–${entry.max}` : undefined\n const standard = entry.default !== undefined ? `(${entry.default})` : undefined\n return [range, standard].filter(Boolean).join(' ') || undefined\n }\n\n /** While dragging the value is taken at every step, so the figure moves with the handle. */\n private onSlide(e: Event) {\n this._valueChanged(e)\n }\n\n override _valueChanged(e: Event) {\n e.stopPropagation()\n const input = e.target as HTMLInputElement\n const key = input.getAttribute('data-key')\n if (!key) return\n const entry = ((this.property?.entries ?? []) as NumberMapEntry[]).find(one => one.key === key)\n const map: Record<string, number> = this.value && typeof this.value === 'object' ? { ...this.value } : {}\n const number = input.valueAsNumber\n const outside = !Number.isFinite(number) || (entry?.min !== undefined && number < entry.min) || (entry?.max !== undefined && number > entry.max)\n if (outside) {\n /* Not taken: the field shows what the map holds. */\n input.value = String(map[key] ?? entry?.default ?? '')\n return\n }\n map[key] = input.type === 'range' ? Math.round(number * 100) / 100 : number\n this.value = map\n this.renderRoot.querySelectorAll<HTMLInputElement>(`input[data-key=\"${key}\"]`).forEach(one => {\n one.value = String(map[key])\n if (one.type === 'range') one.style.setProperty('--fill', `${this.fillOf(map[key]!, { min: Number(one.min), max: Number(one.max) })}%`)\n })\n this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }))\n this.observe(this.value)\n }\n}\n"]}
|