@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/src/styles.js CHANGED
@@ -1,9 +1,71 @@
1
- export const PrefViewerStyleVariables = {
2
- colorPrimary: "#ff6700", // Default accent color - can be overridden via attribute
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.1rem;
102
- --font-size-medium: 0.95rem;
103
- --font-size-small: 0.75rem;
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: 280px;
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-footer {
329
- margin-top: calc(var(--panel-spacing) / 2);
330
- display: flex;
331
- flex-direction: column;
332
- gap: calc(var(--panel-spacing) / 2);
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: 14px;
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-buttons>button:not(.active):hover {
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.1em;
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.05em;
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.95rem;
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);