@preference-sl/pref-viewer 2.16.0 → 2.16.2-beta.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 +129 -102
- package/index.d.ts +373 -12
- package/package.json +2 -1
- package/src/babylonjs-animation-opening.js +11 -5
- package/src/babylonjs-controller.js +442 -65
- package/src/panzoom-controller.js +36 -17
- package/src/pref-viewer-2d.js +395 -21
- package/src/pref-viewer-3d.js +140 -85
- package/src/pref-viewer-menu-3d.js +84 -40
- package/src/pref-viewer-task.js +7 -2
- package/src/pref-viewer.js +615 -185
- package/src/styles.js +111 -29
package/src/styles.js
CHANGED
|
@@ -1,9 +1,71 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* localStorage key used to persist supported PrefViewer runtime style overrides.
|
|
3
|
+
* @type {string}
|
|
4
|
+
*/
|
|
5
|
+
export const PREF_VIEWER_STYLES_STORAGE_KEY = "pref-viewer/styles";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Default style variables used before host overrides or persisted values are applied.
|
|
9
|
+
* @type {{colorPrimary: string, fontFamily: string, fontSize: string}}
|
|
10
|
+
*/
|
|
11
|
+
const PrefViewerDefaultStyleVariables = {
|
|
12
|
+
colorPrimary: "#ff6700",
|
|
3
13
|
fontFamily: "'Roboto', ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji",
|
|
14
|
+
fontSize: "15px",
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Reads persisted runtime style overrides in browser contexts.
|
|
19
|
+
* Only `colorPrimary` is consumed by `PrefViewerStyleVariables`; other keys are ignored by the host component.
|
|
20
|
+
* @returns {object} Parsed persisted style overrides, or an empty object when unavailable or invalid.
|
|
21
|
+
*/
|
|
22
|
+
function readPersistedStyleVariables() {
|
|
23
|
+
if (typeof window === "undefined") {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
const serialized = window.localStorage?.getItem(PREF_VIEWER_STYLES_STORAGE_KEY);
|
|
28
|
+
return serialized ? JSON.parse(serialized) : {};
|
|
29
|
+
} catch (_error) {
|
|
30
|
+
return {};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** @type {object} Persisted raw style overrides loaded during module initialization. */
|
|
35
|
+
const persistedStyleVariables = readPersistedStyleVariables();
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Shared style variables consumed by PrefViewer CSS templates and Babylon defaults.
|
|
39
|
+
* `colorPrimary` can be overridden at runtime through `<pref-viewer styles>`, `viewer.styles`, `viewer.setStyles()`, or `loadConfig({ styles })`.
|
|
40
|
+
* @type {{colorPrimary: string, fontFamily: string, fontSize: string}}
|
|
41
|
+
*/
|
|
42
|
+
export const PrefViewerStyleVariables = {
|
|
43
|
+
...PrefViewerDefaultStyleVariables,
|
|
44
|
+
colorPrimary: typeof persistedStyleVariables.colorPrimary === "string" && persistedStyleVariables.colorPrimary.trim().length > 0
|
|
45
|
+
? persistedStyleVariables.colorPrimary.trim()
|
|
46
|
+
: PrefViewerDefaultStyleVariables.colorPrimary,
|
|
4
47
|
};
|
|
5
48
|
|
|
49
|
+
/** Root `<pref-viewer>` host styles. Uses `--pref-viewer-color-primary` so `setStyles({ colorPrimary })` can update mounted instances. */
|
|
6
50
|
export const PrefViewerStyles = `
|
|
51
|
+
:host {
|
|
52
|
+
all: initial;
|
|
53
|
+
display: block;
|
|
54
|
+
font-family: ${PrefViewerStyleVariables.fontFamily};
|
|
55
|
+
font-size: ${PrefViewerStyleVariables.fontSize};
|
|
56
|
+
line-height: 1.2;
|
|
57
|
+
color: #000000;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
:host *, :host *::before, :host *::after {
|
|
61
|
+
box-sizing: border-box;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
:host ::selection {
|
|
65
|
+
background: var(--pref-viewer-color-primary, ${PrefViewerStyleVariables.colorPrimary});
|
|
66
|
+
color: #ffffff;
|
|
67
|
+
}
|
|
68
|
+
|
|
7
69
|
:host .pref-viewer-wrapper {
|
|
8
70
|
display: grid !important;
|
|
9
71
|
position: relative;
|
|
@@ -50,7 +112,6 @@ export const PrefViewer2DStyles = `
|
|
|
50
112
|
display: block;
|
|
51
113
|
position: relative;
|
|
52
114
|
outline: none;
|
|
53
|
-
box-sizing: border-box;
|
|
54
115
|
}
|
|
55
116
|
|
|
56
117
|
pref-viewer-2d>div>svg {
|
|
@@ -67,9 +128,6 @@ export const PrefViewer3DStyles = `
|
|
|
67
128
|
display: none;
|
|
68
129
|
}
|
|
69
130
|
|
|
70
|
-
pref-viewer-3d[show-animation-menu="false"] > div.animation-menu {
|
|
71
|
-
display: none;
|
|
72
|
-
}
|
|
73
131
|
|
|
74
132
|
pref-viewer-3d {
|
|
75
133
|
grid-column: 1;
|
|
@@ -89,7 +147,6 @@ export const PrefViewer3DStyles = `
|
|
|
89
147
|
display: block;
|
|
90
148
|
position: relative;
|
|
91
149
|
outline: none;
|
|
92
|
-
box-sizing: border-box;
|
|
93
150
|
}
|
|
94
151
|
`;
|
|
95
152
|
|
|
@@ -98,12 +155,12 @@ export const PrefViewerMenu3DStyles = `
|
|
|
98
155
|
--font-family: ${PrefViewerStyleVariables.fontFamily};
|
|
99
156
|
--font-weight-bold: 600;
|
|
100
157
|
--font-weight-medium: 500;
|
|
101
|
-
--font-size-large: 1.
|
|
102
|
-
--font-size-medium: 0.
|
|
103
|
-
--font-size-small: 0.
|
|
158
|
+
--font-size-large: calc(1.1 * ${PrefViewerStyleVariables.fontSize});
|
|
159
|
+
--font-size-medium: calc(0.95 * ${PrefViewerStyleVariables.fontSize});
|
|
160
|
+
--font-size-small: calc(0.75 * ${PrefViewerStyleVariables.fontSize});
|
|
104
161
|
--text-color: #ffffff;
|
|
105
162
|
--muted-color: #b2b2b2;
|
|
106
|
-
--accent-color: ${PrefViewerStyleVariables.colorPrimary};
|
|
163
|
+
--accent-color: var(--pref-viewer-color-primary, ${PrefViewerStyleVariables.colorPrimary});
|
|
107
164
|
|
|
108
165
|
--separator-border: 1px solid rgba(255, 255, 255, 0.1);
|
|
109
166
|
|
|
@@ -121,7 +178,7 @@ export const PrefViewerMenu3DStyles = `
|
|
|
121
178
|
--button-shadow: 0 8px 16px rgba(0, 0, 0, 0.35);
|
|
122
179
|
--button-radius: 8px;
|
|
123
180
|
|
|
124
|
-
--panel-width:
|
|
181
|
+
--panel-width: 300px;
|
|
125
182
|
--panel-spacing: 16px;
|
|
126
183
|
--panel-spacing-large: calc(var(--panel-spacing) * 1.5);
|
|
127
184
|
--panel-bg-color: rgba(19, 21, 28, 0.85);
|
|
@@ -149,6 +206,12 @@ export const PrefViewerMenu3DStyles = `
|
|
|
149
206
|
top: var(--toggle-margin);
|
|
150
207
|
right: var(--toggle-margin);
|
|
151
208
|
z-index: 1200;
|
|
209
|
+
/* The closed panel keeps its place in the flex column (opacity:0, not display:none), so
|
|
210
|
+
this host spans the panel's full 300px x 70vh even when only the toggle is showing.
|
|
211
|
+
Left clickable, that empty space is an invisible catcher over the right edge of the
|
|
212
|
+
viewer: it swallowed the XR entry button and orbiting alike. The toggle and the panel
|
|
213
|
+
each flip back to auto when they become usable, so nothing else is needed. */
|
|
214
|
+
pointer-events: none;
|
|
152
215
|
|
|
153
216
|
font-family: var(--font-family);
|
|
154
217
|
}
|
|
@@ -279,6 +342,10 @@ export const PrefViewerMenu3DStyles = `
|
|
|
279
342
|
cursor: pointer;
|
|
280
343
|
}
|
|
281
344
|
|
|
345
|
+
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-switches>.menu-switch[data-hidden] {
|
|
346
|
+
display: none;
|
|
347
|
+
}
|
|
348
|
+
|
|
282
349
|
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-switches>.menu-switch[data-disabled]>.menu-switch-copy {
|
|
283
350
|
opacity: 0.6;
|
|
284
351
|
}
|
|
@@ -325,11 +392,20 @@ export const PrefViewerMenu3DStyles = `
|
|
|
325
392
|
transform: translateX(var(--switch-control-thumb-size));
|
|
326
393
|
}
|
|
327
394
|
|
|
328
|
-
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
395
|
+
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-slider[data-hidden] {
|
|
396
|
+
display: none;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-slider[data-disabled] .menu-slider-label {
|
|
400
|
+
opacity: 0.6;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-slider[data-disabled] input[type="range"] {
|
|
404
|
+
opacity: 0.4;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-slider[data-disabled] input[type="range"]:disabled {
|
|
408
|
+
cursor: not-allowed;
|
|
333
409
|
}
|
|
334
410
|
|
|
335
411
|
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-color-picker {
|
|
@@ -366,7 +442,6 @@ export const PrefViewerMenu3DStyles = `
|
|
|
366
442
|
appearance: none;
|
|
367
443
|
width: 100%;
|
|
368
444
|
height: var(--slider-bar-height);
|
|
369
|
-
box-sizing: border-box;
|
|
370
445
|
border-radius: calc(var(--slider-bar-height) / 2);
|
|
371
446
|
background: linear-gradient(to right,
|
|
372
447
|
hsl(0,100%,50%), hsl(30,100%,50%), hsl(60,100%,50%), hsl(90,100%,50%),
|
|
@@ -437,7 +512,6 @@ export const PrefViewerMenu3DStyles = `
|
|
|
437
512
|
-webkit-appearance: none;
|
|
438
513
|
appearance: none;
|
|
439
514
|
width: 100%;
|
|
440
|
-
box-sizing: border-box;
|
|
441
515
|
height: var(--slider-bar-height);
|
|
442
516
|
border-radius: calc(var(--slider-bar-height) / 2);
|
|
443
517
|
background: linear-gradient(to right,
|
|
@@ -508,17 +582,23 @@ export const PrefViewerMenu3DStyles = `
|
|
|
508
582
|
outline: none;
|
|
509
583
|
box-shadow: var(--button-shadow);
|
|
510
584
|
}
|
|
585
|
+
|
|
586
|
+
pref-viewer-menu-3d>.menu-wrapper>.menu-panel>.menu-footer {
|
|
587
|
+
margin-top: calc(var(--panel-spacing) / 2);
|
|
588
|
+
display: flex;
|
|
589
|
+
flex-direction: column;
|
|
590
|
+
gap: calc(var(--panel-spacing) / 2);
|
|
591
|
+
}
|
|
511
592
|
`;
|
|
512
593
|
|
|
513
594
|
export const PrefViewer3DAnimationMenuStyles = `
|
|
514
595
|
div.pref-viewer-3d.animation-menu, div.pref-viewer-3d.animation-menu * {
|
|
515
|
-
box-sizing: border-box;
|
|
516
596
|
padding: 0;
|
|
517
597
|
margin: 0;
|
|
518
598
|
}
|
|
519
599
|
|
|
520
600
|
div.pref-viewer-3d.animation-menu {
|
|
521
|
-
--color-primary: ${PrefViewerStyleVariables.colorPrimary};
|
|
601
|
+
--color-primary: var(--pref-viewer-color-primary, ${PrefViewerStyleVariables.colorPrimary});
|
|
522
602
|
--color-active: var(--color-primary);
|
|
523
603
|
--color-active-hover: color-mix(in oklab, var(--color-active), black 10%);
|
|
524
604
|
--color-enabled: #7a7a7a;
|
|
@@ -536,7 +616,7 @@ export const PrefViewer3DAnimationMenuStyles = `
|
|
|
536
616
|
--selector-button-radius: 6px;
|
|
537
617
|
--selector-button-padding-horizontal: 8px;
|
|
538
618
|
--selector-button-padding-vertical: 4px;
|
|
539
|
-
--selector-button-font-size:
|
|
619
|
+
--selector-button-font-size: ${PrefViewerStyleVariables.fontSize};
|
|
540
620
|
--selector-button-font-weight: 500;
|
|
541
621
|
--width: calc(var(--button-size) * 6 + var(--button-spacing) * 5 + var(--button-loop-margin-left));
|
|
542
622
|
|
|
@@ -577,6 +657,7 @@ export const PrefViewer3DAnimationMenuStyles = `
|
|
|
577
657
|
font-size: var(--selector-button-font-size);
|
|
578
658
|
font-weight: var(--selector-button-font-weight);
|
|
579
659
|
line-height: 1;
|
|
660
|
+
letter-spacing: 0.05em;
|
|
580
661
|
flex: 1;
|
|
581
662
|
}
|
|
582
663
|
|
|
@@ -592,7 +673,7 @@ export const PrefViewer3DAnimationMenuStyles = `
|
|
|
592
673
|
cursor: pointer;
|
|
593
674
|
}
|
|
594
675
|
|
|
595
|
-
div.pref-viewer-3d.animation-menu>div.animation-menu-
|
|
676
|
+
div.pref-viewer-3d.animation-menu>div.animation-menu-selector>button:not(.active):hover {
|
|
596
677
|
background: var(--color-enabled-hover);
|
|
597
678
|
}
|
|
598
679
|
|
|
@@ -609,7 +690,6 @@ export const PrefViewer3DAnimationMenuStyles = `
|
|
|
609
690
|
justify-content: center;
|
|
610
691
|
padding: 0;
|
|
611
692
|
margin: 0;
|
|
612
|
-
cursor: pointer;
|
|
613
693
|
border: 1px solid var(--color-border);
|
|
614
694
|
width: var(--button-size);
|
|
615
695
|
height: var(--button-size);
|
|
@@ -632,13 +712,15 @@ export const PrefViewer3DAnimationMenuStyles = `
|
|
|
632
712
|
|
|
633
713
|
div.pref-viewer-3d.animation-menu>div.animation-menu-buttons>button.enabled {
|
|
634
714
|
background: var(--color-enabled);
|
|
715
|
+
cursor: pointer;
|
|
635
716
|
}
|
|
636
717
|
|
|
637
718
|
div.pref-viewer-3d.animation-menu>div.animation-menu-buttons>button.enabled:hover {
|
|
638
719
|
background: var(--color-enabled-hover);
|
|
639
720
|
}
|
|
640
721
|
|
|
641
|
-
div.pref-viewer-3d.animation-menu>div.animation-menu-buttons>button.disabled
|
|
722
|
+
div.pref-viewer-3d.animation-menu>div.animation-menu-buttons>button.disabled,
|
|
723
|
+
div.pref-viewer-3d.animation-menu>div.animation-menu-buttons>button.disabled:hover {
|
|
642
724
|
background: var(--color-disabled);
|
|
643
725
|
}
|
|
644
726
|
|
|
@@ -704,7 +786,7 @@ export const PrefViewer3DAnimationMenuStyles = `
|
|
|
704
786
|
|
|
705
787
|
export const PrefViewerDialogStyles = `
|
|
706
788
|
pref-viewer-dialog {
|
|
707
|
-
--color-primary: ${PrefViewerStyleVariables.colorPrimary};
|
|
789
|
+
--color-primary: var(--pref-viewer-color-primary, ${PrefViewerStyleVariables.colorPrimary});
|
|
708
790
|
--dialog-general-space: 16px;
|
|
709
791
|
--dialog-bg-color: #ffffff;
|
|
710
792
|
--dialog-backdrop-color: rgba(0, 0, 0, 0.25);
|
|
@@ -764,7 +846,7 @@ export const PrefViewerDialogStyles = `
|
|
|
764
846
|
pref-viewer-dialog .dialog-header h3 {
|
|
765
847
|
margin: 0;
|
|
766
848
|
font-weight: 500;
|
|
767
|
-
font-size: 1.
|
|
849
|
+
font-size: calc(1.1 * ${PrefViewerStyleVariables.fontSize});
|
|
768
850
|
}
|
|
769
851
|
|
|
770
852
|
pref-viewer-dialog .dialog-content {
|
|
@@ -774,7 +856,7 @@ export const PrefViewerDialogStyles = `
|
|
|
774
856
|
pref-viewer-dialog .dialog-content h4 {
|
|
775
857
|
margin: 0;
|
|
776
858
|
font-weight: 500;
|
|
777
|
-
font-size: 1.
|
|
859
|
+
font-size: calc(1.05 * ${PrefViewerStyleVariables.fontSize});
|
|
778
860
|
}
|
|
779
861
|
|
|
780
862
|
pref-viewer-dialog .dialog-footer {
|
|
@@ -787,7 +869,7 @@ export const PrefViewerDialogStyles = `
|
|
|
787
869
|
|
|
788
870
|
pref-viewer-dialog .dialog-footer button {
|
|
789
871
|
width: 100%;
|
|
790
|
-
font-size: 0.
|
|
872
|
+
font-size: calc(0.95 * ${PrefViewerStyleVariables.fontSize});
|
|
791
873
|
font-weight: 600;
|
|
792
874
|
padding: var(--button-padding-vertical) var(--button-padding-horizontal);
|
|
793
875
|
border-radius: var(--button-border-radius);
|