pi-studio 0.9.48 → 0.9.50

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.
@@ -43,10 +43,62 @@
43
43
  return { attempted: images.length, resolved };
44
44
  }
45
45
 
46
+ function buildStudioPdfVersionSignature(headers) {
47
+ if (!headers || typeof headers.get !== "function") return "";
48
+ const etag = String(headers.get("etag") || "").trim();
49
+ const modified = String(headers.get("last-modified") || "").trim();
50
+ const length = String(headers.get("content-length") || "").trim();
51
+ if (!etag && !modified && !length) return "";
52
+ return [etag, modified, length].join("\n");
53
+ }
54
+
55
+ function createStudioPdfVersionObservationState() {
56
+ return {
57
+ baseline: "",
58
+ candidate: "",
59
+ candidateCount: 0,
60
+ };
61
+ }
62
+
63
+ function observeStudioPdfVersion(previousState, signature, stableObservations) {
64
+ const state = previousState && typeof previousState === "object"
65
+ ? previousState
66
+ : createStudioPdfVersionObservationState();
67
+ const nextSignature = String(signature || "").trim();
68
+ const required = Math.max(2, Number.parseInt(String(stableObservations || "2"), 10) || 2);
69
+ if (!nextSignature) return { state, changed: false };
70
+ if (!state.baseline) {
71
+ return {
72
+ state: { baseline: nextSignature, candidate: "", candidateCount: 0 },
73
+ changed: false,
74
+ };
75
+ }
76
+ if (nextSignature === state.baseline) {
77
+ return {
78
+ state: { baseline: state.baseline, candidate: "", candidateCount: 0 },
79
+ changed: false,
80
+ };
81
+ }
82
+ const candidateCount = nextSignature === state.candidate ? state.candidateCount + 1 : 1;
83
+ if (candidateCount < required) {
84
+ return {
85
+ state: { baseline: state.baseline, candidate: nextSignature, candidateCount },
86
+ changed: false,
87
+ };
88
+ }
89
+ return {
90
+ state: { baseline: nextSignature, candidate: "", candidateCount: 0 },
91
+ changed: true,
92
+ };
93
+ }
94
+
46
95
  globalThis.PiStudioPreviewResourceHelpers = Object.freeze({
47
96
  STUDIO_PREVIEW_LOCAL_IMAGE_LIMIT,
48
97
  areStudioPreviewResourceContextsEqual,
98
+ buildStudioPdfVersionSignature,
99
+ createStudioPdfVersionObservationState,
49
100
  hydrateStudioPreviewLocalImages,
50
101
  isResolvableStudioPreviewImageSource,
102
+ observeStudioPdfVersion,
51
103
  });
52
104
  })();
package/client/studio.css CHANGED
@@ -59,28 +59,77 @@
59
59
  flex-wrap: wrap;
60
60
  }
61
61
 
62
- .zen-mode-btn {
62
+ .zen-mode-btn,
63
+ .header-visibility-btn {
63
64
  font-weight: inherit;
64
65
  white-space: nowrap;
65
66
  }
66
67
 
67
- body.studio-zen-mode > header {
68
- padding: 8px 12px;
68
+ body.studio-header-hidden > #studioHeader,
69
+ body.studio-zen-mode > #studioHeader {
70
+ display: none !important;
69
71
  }
70
72
 
71
- body.studio-zen-mode .app-subtitle {
72
- display: none;
73
+ .studio-header-reveal {
74
+ position: fixed;
75
+ top: 0;
76
+ right: max(8px, env(safe-area-inset-right));
77
+ z-index: 60;
78
+ width: 118px;
79
+ height: 10px;
80
+ cursor: pointer;
73
81
  }
74
82
 
75
- body.studio-zen-mode > header .controls > :not(#zenModeBtn) {
83
+ .studio-header-reveal[hidden] {
76
84
  display: none !important;
77
85
  }
78
86
 
79
- body.studio-zen-mode #zenModeBtn {
87
+ .studio-header-reveal::after {
88
+ content: "";
89
+ position: absolute;
90
+ right: 10px;
91
+ bottom: 2px;
92
+ left: 10px;
93
+ height: 3px;
94
+ border-radius: 999px;
95
+ background: var(--accent);
96
+ opacity: 0.62;
97
+ pointer-events: none;
98
+ }
99
+
100
+ .studio-header-reveal button {
101
+ position: absolute;
102
+ top: 0;
103
+ right: 0;
104
+ min-width: 100%;
105
+ min-height: 32px;
106
+ padding: 5px 10px;
107
+ border-top: 0;
108
+ border-radius: 0 0 9px 9px;
80
109
  background: var(--panel);
81
- border-color: var(--control-border);
82
110
  color: var(--text);
83
- font-weight: inherit;
111
+ box-shadow: 0 8px 24px var(--shadow-color);
112
+ white-space: nowrap;
113
+ transform: translateY(calc(-100% + 5px));
114
+ transition: transform 140ms ease;
115
+ }
116
+
117
+ .studio-header-reveal.is-open button,
118
+ .studio-header-reveal:hover button,
119
+ .studio-header-reveal:focus-within button {
120
+ transform: translateY(0);
121
+ }
122
+
123
+ .studio-header-reveal button:not(:disabled):hover,
124
+ .studio-header-reveal button:focus-visible {
125
+ background: var(--panel-2);
126
+ color: var(--accent);
127
+ }
128
+
129
+ @media (prefers-reduced-motion: reduce) {
130
+ .studio-header-reveal button {
131
+ transition: none;
132
+ }
84
133
  }
85
134
 
86
135
  .export-preview-controls {
@@ -1822,6 +1871,20 @@
1822
1871
  border-color: var(--control-border);
1823
1872
  }
1824
1873
 
1874
+ .rendered-markdown button.studio-pdf-card-auto-refresh[aria-pressed="true"] {
1875
+ background: transparent;
1876
+ color: var(--accent);
1877
+ border-color: transparent;
1878
+ font-weight: 600;
1879
+ }
1880
+
1881
+ .rendered-markdown button.studio-pdf-card-auto-refresh[aria-pressed="true"]:not(:disabled):hover,
1882
+ .rendered-markdown button.studio-pdf-card-auto-refresh[aria-pressed="true"]:focus-visible {
1883
+ background: var(--panel);
1884
+ color: var(--accent);
1885
+ border-color: var(--control-border);
1886
+ }
1887
+
1825
1888
  .rendered-markdown button.studio-pdf-card-focus {
1826
1889
  width: 29px;
1827
1890
  min-width: 29px;
@@ -1983,6 +2046,20 @@
1983
2046
  color: var(--text);
1984
2047
  }
1985
2048
 
2049
+ .studio-pdf-focus-auto-refresh[aria-pressed="true"] {
2050
+ background: transparent;
2051
+ border-color: transparent;
2052
+ color: var(--accent);
2053
+ font-weight: 600;
2054
+ }
2055
+
2056
+ .studio-pdf-focus-auto-refresh[aria-pressed="true"]:not(:disabled):hover,
2057
+ .studio-pdf-focus-auto-refresh[aria-pressed="true"]:focus-visible {
2058
+ background: var(--panel);
2059
+ border-color: var(--control-border);
2060
+ color: var(--accent);
2061
+ }
2062
+
1986
2063
  .studio-pdf-focus-btn .studio-refresh-icon {
1987
2064
  width: 14px;
1988
2065
  height: 14px;
@@ -5360,10 +5437,6 @@
5360
5437
  gap: 5px;
5361
5438
  }
5362
5439
 
5363
- body.studio-ui-refresh.studio-zen-mode > header {
5364
- padding: 7px 12px;
5365
- }
5366
-
5367
5440
  body.studio-ui-refresh > header button,
5368
5441
  body.studio-ui-refresh #responseActions button,
5369
5442
  body.studio-ui-refresh #responseActions select {