@21stware/rpui 0.4.2 → 0.4.4
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/dist/core/style.d.ts +1 -1
- package/dist/core/theme.d.ts +6 -0
- package/dist/gallery.js +126 -24
- package/dist/gallery.js.map +1 -1
- package/dist/rpml-loader.js +70 -0
- package/dist/rpml-loader.js.map +1 -1
- package/dist/rpui.js +13 -6
- package/dist/rpui.js.map +1 -1
- package/package.json +1 -1
package/dist/rpml-loader.js
CHANGED
|
@@ -1,4 +1,73 @@
|
|
|
1
1
|
import { registerAll, parseToPage } from "./rpui.js";
|
|
2
|
+
const THEME_STYLE_ID = "rpml-theme-style";
|
|
3
|
+
const ATTR = "data-rpml-theme";
|
|
4
|
+
const THEME_CSS = `
|
|
5
|
+
:root {
|
|
6
|
+
--rpml-gx-border:#e5e7eb; --rpml-gx-side-bg:#fff; --rpml-gx-main-bg:#f4f6f8;
|
|
7
|
+
--rpml-gx-fg:#111827; --rpml-gx-muted:#6b7280; --rpml-gx-group:#9ca3af;
|
|
8
|
+
--rpml-gx-hover:#f3f4f6; --rpml-gx-item:#374151; --rpml-gx-active-bg:#eff6ff;
|
|
9
|
+
--rpml-gx-active-fg:#1d4ed8; --rpml-gx-copy-hover:#e5e7eb; --rpml-gx-ok:#059669;
|
|
10
|
+
}
|
|
11
|
+
html[${ATTR}="dark"] {
|
|
12
|
+
--rpml-gx-border:#2a3344; --rpml-gx-side-bg:#0f172a; --rpml-gx-main-bg:#0b1120;
|
|
13
|
+
--rpml-gx-fg:#e2e8f0; --rpml-gx-muted:#94a3b8; --rpml-gx-group:#64748b;
|
|
14
|
+
--rpml-gx-hover:#1e293b; --rpml-gx-item:#cbd5e1; --rpml-gx-active-bg:#1e3a5f;
|
|
15
|
+
--rpml-gx-active-fg:#93c5fd; --rpml-gx-copy-hover:#334155; --rpml-gx-ok:#34d399;
|
|
16
|
+
}
|
|
17
|
+
html[${ATTR}="dark"] body { background:#0b1120; }
|
|
18
|
+
/* Invert the rendered prototype as a whole; hue-rotate keeps colors recognizable. */
|
|
19
|
+
html[${ATTR}="dark"] page-el { filter:invert(0.92) hue-rotate(180deg); }
|
|
20
|
+
|
|
21
|
+
.rpml-theme-fab {
|
|
22
|
+
position:fixed; top:12px; right:12px; z-index:50; display:flex; align-items:center;
|
|
23
|
+
justify-content:center; width:34px; height:34px; padding:0; border:1px solid var(--rpml-gx-border);
|
|
24
|
+
border-radius:9px; background:var(--rpml-gx-side-bg); color:var(--rpml-gx-fg); font-size:16px;
|
|
25
|
+
line-height:1; cursor:pointer; box-shadow:0 1px 3px rgba(0,0,0,.12);
|
|
26
|
+
}
|
|
27
|
+
.rpml-theme-fab:hover { background:var(--rpml-gx-hover); }
|
|
28
|
+
`;
|
|
29
|
+
function injectThemeStyle() {
|
|
30
|
+
if (document.getElementById(THEME_STYLE_ID)) return;
|
|
31
|
+
const s = document.createElement("style");
|
|
32
|
+
s.id = THEME_STYLE_ID;
|
|
33
|
+
s.textContent = THEME_CSS;
|
|
34
|
+
document.head.appendChild(s);
|
|
35
|
+
}
|
|
36
|
+
function themeFromUrl() {
|
|
37
|
+
const t = new URLSearchParams(location.search).get("theme");
|
|
38
|
+
return t === "dark" || t === "light" ? t : null;
|
|
39
|
+
}
|
|
40
|
+
function currentTheme() {
|
|
41
|
+
return document.documentElement.getAttribute(ATTR) === "dark" ? "dark" : "light";
|
|
42
|
+
}
|
|
43
|
+
function setTheme(theme) {
|
|
44
|
+
document.documentElement.setAttribute(ATTR, theme);
|
|
45
|
+
const url = new URL(location.href);
|
|
46
|
+
url.searchParams.set("theme", theme);
|
|
47
|
+
history.replaceState(history.state, "", url);
|
|
48
|
+
}
|
|
49
|
+
function initTheme() {
|
|
50
|
+
const fromUrl = themeFromUrl();
|
|
51
|
+
if (fromUrl) {
|
|
52
|
+
document.documentElement.setAttribute(ATTR, fromUrl);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const prefersDark = typeof matchMedia === "function" && matchMedia("(prefers-color-scheme: dark)").matches;
|
|
56
|
+
document.documentElement.setAttribute(ATTR, prefersDark ? "dark" : "light");
|
|
57
|
+
}
|
|
58
|
+
function mountThemeFab(host = document.body) {
|
|
59
|
+
injectThemeStyle();
|
|
60
|
+
initTheme();
|
|
61
|
+
if (document.querySelector(".rpml-theme-fab")) return;
|
|
62
|
+
const btn = document.createElement("button");
|
|
63
|
+
btn.className = "rpml-theme-fab";
|
|
64
|
+
btn.type = "button";
|
|
65
|
+
btn.title = "切换亮色/暗色";
|
|
66
|
+
btn.setAttribute("aria-label", "切换亮色/暗色");
|
|
67
|
+
btn.textContent = "◑";
|
|
68
|
+
btn.addEventListener("click", () => setTheme(currentTheme() === "dark" ? "light" : "dark"));
|
|
69
|
+
host.appendChild(btn);
|
|
70
|
+
}
|
|
2
71
|
registerAll();
|
|
3
72
|
class RpmlApp extends HTMLElement {
|
|
4
73
|
async connectedCallback() {
|
|
@@ -8,6 +77,7 @@ class RpmlApp extends HTMLElement {
|
|
|
8
77
|
const res = await fetch(src);
|
|
9
78
|
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
10
79
|
this.replaceWith(parseToPage(await res.text()));
|
|
80
|
+
mountThemeFab();
|
|
11
81
|
const section = new URLSearchParams(location.search).get("section");
|
|
12
82
|
if (section) requestAnimationFrame(() => requestAnimationFrame(() => window.dispatchEvent(new CustomEvent("rp-section", { detail: section }))));
|
|
13
83
|
} catch (e) {
|
package/dist/rpml-loader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpml-loader.js","sources":["../src/rpml-loader.ts"],"sourcesContent":["import { registerAll, parseToPage } from './rpui';\n\nexport { parseToPage };\nregisterAll();\n\nclass RpmlApp extends HTMLElement {\n async connectedCallback() {\n const src = this.getAttribute('src');\n if (!src) return;\n try {\n const res = await fetch(src);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n this.replaceWith(parseToPage(await res.text()));\n // Honor a ?section= deep-link (e.g. arriving from an <anchor> fallback).\n const section = new URLSearchParams(location.search).get('section');\n if (section) requestAnimationFrame(() => requestAnimationFrame(() =>\n window.dispatchEvent(new CustomEvent('rp-section', { detail: section }))));\n } catch (e) {\n this.textContent = `RPML load error: ${e}`;\n console.error(e);\n }\n }\n}\n\ncustomElements.define('rpml-app', RpmlApp);\n\nconst rpmlSrc = new URLSearchParams(location.search).get('rpml');\nif (rpmlSrc && !document.querySelector('rpml-app')) {\n const app = document.createElement('rpml-app') as HTMLElement;\n app.setAttribute('src', rpmlSrc);\n document.body.appendChild(app);\n}\n"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"rpml-loader.js","sources":["../src/core/theme.ts","../src/rpml-loader.ts"],"sourcesContent":["/**\n * Light/dark theme, shared by the gallery (sidebar present) and the single-file\n * loader (no sidebar). The chosen theme lives in the `theme` URL param so it\n * survives reloads and can be deep-linked; on first load with no param we fall\n * back to the OS `prefers-color-scheme`.\n *\n * Strategy:\n * - Chrome (sidebar/header/main bg) is themed with CSS variables (--rpml-gx-*).\n * - The rendered prototype (page-el) carries 256+ hardcoded colors, so instead\n * of remapping each one we invert it as a whole with `invert + hue-rotate`,\n * which flips light/dark while keeping hues (blue stays blue) — guaranteed\n * readable without touching the runtime stylesheet.\n */\n\nconst THEME_STYLE_ID = 'rpml-theme-style';\nconst ATTR = 'data-rpml-theme';\n\nexport const THEME_CSS = `\n:root {\n --rpml-gx-border:#e5e7eb; --rpml-gx-side-bg:#fff; --rpml-gx-main-bg:#f4f6f8;\n --rpml-gx-fg:#111827; --rpml-gx-muted:#6b7280; --rpml-gx-group:#9ca3af;\n --rpml-gx-hover:#f3f4f6; --rpml-gx-item:#374151; --rpml-gx-active-bg:#eff6ff;\n --rpml-gx-active-fg:#1d4ed8; --rpml-gx-copy-hover:#e5e7eb; --rpml-gx-ok:#059669;\n}\nhtml[${ATTR}=\"dark\"] {\n --rpml-gx-border:#2a3344; --rpml-gx-side-bg:#0f172a; --rpml-gx-main-bg:#0b1120;\n --rpml-gx-fg:#e2e8f0; --rpml-gx-muted:#94a3b8; --rpml-gx-group:#64748b;\n --rpml-gx-hover:#1e293b; --rpml-gx-item:#cbd5e1; --rpml-gx-active-bg:#1e3a5f;\n --rpml-gx-active-fg:#93c5fd; --rpml-gx-copy-hover:#334155; --rpml-gx-ok:#34d399;\n}\nhtml[${ATTR}=\"dark\"] body { background:#0b1120; }\n/* Invert the rendered prototype as a whole; hue-rotate keeps colors recognizable. */\nhtml[${ATTR}=\"dark\"] page-el { filter:invert(0.92) hue-rotate(180deg); }\n\n.rpml-theme-fab {\n position:fixed; top:12px; right:12px; z-index:50; display:flex; align-items:center;\n justify-content:center; width:34px; height:34px; padding:0; border:1px solid var(--rpml-gx-border);\n border-radius:9px; background:var(--rpml-gx-side-bg); color:var(--rpml-gx-fg); font-size:16px;\n line-height:1; cursor:pointer; box-shadow:0 1px 3px rgba(0,0,0,.12);\n}\n.rpml-theme-fab:hover { background:var(--rpml-gx-hover); }\n`;\n\nexport function injectThemeStyle(): void {\n if (document.getElementById(THEME_STYLE_ID)) return;\n const s = document.createElement('style');\n s.id = THEME_STYLE_ID;\n s.textContent = THEME_CSS;\n document.head.appendChild(s);\n}\n\nfunction themeFromUrl(): 'light' | 'dark' | null {\n const t = new URLSearchParams(location.search).get('theme');\n return t === 'dark' || t === 'light' ? t : null;\n}\n\nexport function currentTheme(): 'light' | 'dark' {\n return document.documentElement.getAttribute(ATTR) === 'dark' ? 'dark' : 'light';\n}\n\n/** Apply a theme to <html> and reflect it in the `theme` URL param. */\nexport function setTheme(theme: 'light' | 'dark'): void {\n document.documentElement.setAttribute(ATTR, theme);\n const url = new URL(location.href);\n url.searchParams.set('theme', theme);\n history.replaceState(history.state, '', url);\n}\n\n/** Seed the theme from the URL param, falling back to the OS preference.\n * Does not write the URL on the OS-preference path, keeping links clean until\n * the user explicitly toggles. */\nexport function initTheme(): void {\n const fromUrl = themeFromUrl();\n if (fromUrl) { document.documentElement.setAttribute(ATTR, fromUrl); return; }\n const prefersDark = typeof matchMedia === 'function' && matchMedia('(prefers-color-scheme: dark)').matches;\n document.documentElement.setAttribute(ATTR, prefersDark ? 'dark' : 'light');\n}\n\n/** A floating top-right toggle, mirroring the sidebar-collapse FAB, so the theme\n * switch is reachable even when there is no sidebar (single-file preview) or it\n * is collapsed. Idempotent. */\nexport function mountThemeFab(host: HTMLElement = document.body): void {\n injectThemeStyle();\n initTheme();\n if (document.querySelector('.rpml-theme-fab')) return;\n const btn = document.createElement('button');\n btn.className = 'rpml-theme-fab';\n btn.type = 'button';\n btn.title = '切换亮色/暗色';\n btn.setAttribute('aria-label', '切换亮色/暗色');\n btn.textContent = '◑';\n btn.addEventListener('click', () => setTheme(currentTheme() === 'dark' ? 'light' : 'dark'));\n host.appendChild(btn);\n}\n","import { registerAll, parseToPage } from './rpui';\nimport { mountThemeFab } from './core/theme';\n\nexport { parseToPage };\nregisterAll();\n\nclass RpmlApp extends HTMLElement {\n async connectedCallback() {\n const src = this.getAttribute('src');\n if (!src) return;\n try {\n const res = await fetch(src);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n this.replaceWith(parseToPage(await res.text()));\n // A single .rpml preview has no sidebar, so surface the theme toggle as a\n // floating button (mirrors the gallery's collapse FAB).\n mountThemeFab();\n // Honor a ?section= deep-link (e.g. arriving from an <anchor> fallback).\n const section = new URLSearchParams(location.search).get('section');\n if (section) requestAnimationFrame(() => requestAnimationFrame(() =>\n window.dispatchEvent(new CustomEvent('rp-section', { detail: section }))));\n } catch (e) {\n this.textContent = `RPML load error: ${e}`;\n console.error(e);\n }\n }\n}\n\ncustomElements.define('rpml-app', RpmlApp);\n\nconst rpmlSrc = new URLSearchParams(location.search).get('rpml');\nif (rpmlSrc && !document.querySelector('rpml-app')) {\n const app = document.createElement('rpml-app') as HTMLElement;\n app.setAttribute('src', rpmlSrc);\n document.body.appendChild(app);\n}\n"],"names":[],"mappings":";AAcA,MAAM,iBAAiB;AACvB,MAAM,OAAO;AAEN,MAAM,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAOlB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAMJ,IAAI;AAAA;AAAA,OAEJ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWJ,SAAS,mBAAyB;AACvC,MAAI,SAAS,eAAe,cAAc,EAAG;AAC7C,QAAM,IAAI,SAAS,cAAc,OAAO;AACxC,IAAE,KAAK;AACP,IAAE,cAAc;AAChB,WAAS,KAAK,YAAY,CAAC;AAC7B;AAEA,SAAS,eAAwC;AAC/C,QAAM,IAAI,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,OAAO;AAC1D,SAAO,MAAM,UAAU,MAAM,UAAU,IAAI;AAC7C;AAEO,SAAS,eAAiC;AAC/C,SAAO,SAAS,gBAAgB,aAAa,IAAI,MAAM,SAAS,SAAS;AAC3E;AAGO,SAAS,SAAS,OAA+B;AACtD,WAAS,gBAAgB,aAAa,MAAM,KAAK;AACjD,QAAM,MAAM,IAAI,IAAI,SAAS,IAAI;AACjC,MAAI,aAAa,IAAI,SAAS,KAAK;AACnC,UAAQ,aAAa,QAAQ,OAAO,IAAI,GAAG;AAC7C;AAKO,SAAS,YAAkB;AAChC,QAAM,UAAU,aAAA;AAChB,MAAI,SAAS;AAAE,aAAS,gBAAgB,aAAa,MAAM,OAAO;AAAG;AAAA,EAAQ;AAC7E,QAAM,cAAc,OAAO,eAAe,cAAc,WAAW,8BAA8B,EAAE;AACnG,WAAS,gBAAgB,aAAa,MAAM,cAAc,SAAS,OAAO;AAC5E;AAKO,SAAS,cAAc,OAAoB,SAAS,MAAY;AACrE,mBAAA;AACA,YAAA;AACA,MAAI,SAAS,cAAc,iBAAiB,EAAG;AAC/C,QAAM,MAAM,SAAS,cAAc,QAAQ;AAC3C,MAAI,YAAY;AAChB,MAAI,OAAO;AACX,MAAI,QAAQ;AACZ,MAAI,aAAa,cAAc,SAAS;AACxC,MAAI,cAAc;AAClB,MAAI,iBAAiB,SAAS,MAAM,SAAS,mBAAmB,SAAS,UAAU,MAAM,CAAC;AAC1F,OAAK,YAAY,GAAG;AACtB;ACzFA,YAAA;AAEA,MAAM,gBAAgB,YAAY;AAAA,EAChC,MAAM,oBAAoB;AACxB,UAAM,MAAM,KAAK,aAAa,KAAK;AACnC,QAAI,CAAC,IAAK;AACV,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,QAAQ,IAAI,MAAM,EAAE;AACjD,WAAK,YAAY,YAAY,MAAM,IAAI,KAAA,CAAM,CAAC;AAG9C,oBAAA;AAEA,YAAM,UAAU,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,SAAS;AAClE,UAAI,QAAS,uBAAsB,MAAM,sBAAsB,MAC7D,OAAO,cAAc,IAAI,YAAY,cAAc,EAAE,QAAQ,QAAA,CAAS,CAAC,CAAC,CAAC;AAAA,IAC7E,SAAS,GAAG;AACV,WAAK,cAAc,oBAAoB,CAAC;AACxC,cAAQ,MAAM,CAAC;AAAA,IACjB;AAAA,EACF;AACF;AAEA,eAAe,OAAO,YAAY,OAAO;AAEzC,MAAM,UAAU,IAAI,gBAAgB,SAAS,MAAM,EAAE,IAAI,MAAM;AAC/D,IAAI,WAAW,CAAC,SAAS,cAAc,UAAU,GAAG;AAClD,QAAM,MAAM,SAAS,cAAc,UAAU;AAC7C,MAAI,aAAa,OAAO,OAAO;AAC/B,WAAS,KAAK,YAAY,GAAG;AAC/B;"}
|
package/dist/rpui.js
CHANGED
|
@@ -246,8 +246,8 @@ const style = `
|
|
|
246
246
|
* { box-sizing:border-box; }
|
|
247
247
|
body { margin:0; font-family:var(--rp-font); color:var(--rp-text); background:var(--rp-bg); }
|
|
248
248
|
.rp-icon { display:inline-block; flex:0 0 auto; vertical-align:-0.16em; }
|
|
249
|
-
page-el, page-el { display:block;
|
|
250
|
-
.page-el-shell { display:grid; grid-template-columns:max-content max-content; gap:24px; min-height:100vh; align-items:start; }
|
|
249
|
+
page-el, page-el { display:block; padding:32px 40px; overflow:visible; }
|
|
250
|
+
.page-el-shell { display:grid; grid-template-columns:max-content max-content; gap:24px; min-height:calc(100vh - 64px); align-items:start; }
|
|
251
251
|
.page-el-main { display:flex; flex-direction:column; min-width:0; overflow:visible; }
|
|
252
252
|
.page-el-header { flex:0 0 auto; width:fit-content; max-width:none; margin:0 0 22px; }
|
|
253
253
|
.page-el-title-row { display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
|
|
@@ -255,7 +255,7 @@ page-el, page-el { display:block; min-height:100vh; padding:32px 40px; overflow:
|
|
|
255
255
|
.page-el-route { font-size:13px; color:var(--rp-muted); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; background:rgba(255,255,255,.7); border:1px solid var(--rp-border); border-radius:999px; padding:3px 9px; }
|
|
256
256
|
.page-el-description { margin:10px 0 0; color:#374151; line-height:1.6; font-size:14px; }
|
|
257
257
|
.page-el-body { flex:0 1 auto; display:block; width:fit-content; max-width:100%; min-height:0; overflow:visible; }
|
|
258
|
-
.annotation-el-pane { min-width:380px; max-width:680px; position:sticky; top:
|
|
258
|
+
.annotation-el-pane { min-width:380px; max-width:680px; position:sticky; top:32px; height:auto; min-height:calc(100vh - 64px); max-height:calc(100vh - 64px); overflow-y:auto; overflow-x:auto; padding:0 0 48px 0; align-self:start; }
|
|
259
259
|
.annotation-el-pane-inner { padding:4px 12px 24px 6px; }
|
|
260
260
|
main-view, main-view { display:block; width:fit-content; margin:0 0 28px; position:relative; }
|
|
261
261
|
.rp-main-shell { position:relative; overflow:visible; border:1px solid var(--rp-border-strong); border-radius:var(--rp-radius-md); background:var(--rp-surface); box-shadow:var(--rp-shadow); }
|
|
@@ -275,7 +275,7 @@ annotation-el annotation-el, annotation-el annotation-el, annotation-el annotati
|
|
|
275
275
|
.annotation-el-marker.triangle { width:18px; height:16px; background:var(--rp-success); clip-path:polygon(50% 0, 100% 100%, 0 100%); }
|
|
276
276
|
.annotation-el-marker.triangle > span { transform:translateY(2px); font-size:9px; }
|
|
277
277
|
.annotation-el-marker.global { width:20px; height:20px; background:#0f172a; border-radius:6px; font-size:11px; }
|
|
278
|
-
annotation-global-el, annotation-global-el { display:block; width:fit-content; max-width:980px; margin:0 0 18px; padding:10px 12px 12px; line-height:1.65; color:#1f2937; font-size:14px; background:
|
|
278
|
+
annotation-global-el, annotation-global-el { display:block; width:fit-content; max-width:980px; margin:0 0 18px; padding:10px 12px 12px; line-height:1.65; color:#1f2937; font-size:14px; background:var(--rp-surface-soft); border:1px solid var(--rp-border); border-radius:var(--rp-radius-md); }
|
|
279
279
|
.annotation-el-pane annotation-global-el, .annotation-el-pane annotation-global-el { max-width:none; }
|
|
280
280
|
.annotation-el-pane annotation-global-el .annotation-el-body { max-width:none; }
|
|
281
281
|
.annotation-el-body { display:block; position:relative; width:fit-content; max-width:920px; }
|
|
@@ -302,8 +302,8 @@ layout-el > *, layout-el > * { min-width:0; }
|
|
|
302
302
|
viewport-el layout-el, viewport-el layout-el { width:100%; }
|
|
303
303
|
viewport-el > layout-el, viewport-el > layout-el { flex:1 1 auto; min-height:0; }
|
|
304
304
|
viewport-el > navbar-el, viewport-el > navbar-el { flex:0 0 auto; }
|
|
305
|
-
panel-el, panel-el { display:block; width:fit-content; max-width:100%; background:#fff; border:1px solid var(--rp-border); border-radius:var(--rp-radius-md); padding:var(--snap-padding,16px); }
|
|
306
|
-
viewport-el panel-el, viewport-el panel-el { width:auto; min-width:0; }
|
|
305
|
+
panel-el, panel-el { margin:8px; display:block; width:fit-content; max-width:100%; background:#fff; border:1px solid var(--rp-border); border-radius:var(--rp-radius-md); padding:var(--snap-padding,16px); }
|
|
306
|
+
viewport-el panel-el, viewport-el panel-el { margin:8px; width:auto; min-width:0; }
|
|
307
307
|
panel-el[elevation="1"], panel-el[elevation="1"] { box-shadow:0 4px 16px rgba(15,23,42,.06); }
|
|
308
308
|
panel-el[elevation="2"], panel-el[elevation="2"] { box-shadow:var(--rp-shadow); }
|
|
309
309
|
navbar-el, navbar-el { display:flex; align-items:center; gap:14px; height:var(--snap-height,64px); padding:0 24px; background:#fff; border-bottom:1px solid var(--rp-border); }
|
|
@@ -868,6 +868,10 @@ class RpAnnotationGlobal extends HTMLElement {
|
|
|
868
868
|
this.dataset.rpReady = "true";
|
|
869
869
|
const existing = Array.from(this.childNodes);
|
|
870
870
|
const label = attr(this, "label", "全局说明");
|
|
871
|
+
const globalSiblings = this.parentElement ? Array.from(this.parentElement.children).filter(
|
|
872
|
+
(el) => el.tagName.toLowerCase() === "annotation-global-el"
|
|
873
|
+
) : [];
|
|
874
|
+
this.dataset.rpSection = `global-${globalSiblings.indexOf(this) + 1}`;
|
|
871
875
|
const marker = document.createElement("span");
|
|
872
876
|
marker.className = "annotation-el-marker global";
|
|
873
877
|
marker.innerHTML = "<span>★</span>";
|
|
@@ -943,6 +947,7 @@ class RpMainView extends HTMLElement {
|
|
|
943
947
|
stage2.style.transform = `scale(${scale})`;
|
|
944
948
|
const clip = document.createElement("div");
|
|
945
949
|
clip.className = "rp-main-stage-clip";
|
|
950
|
+
if (!autoHeight) clip.style.height = `${height * scale}px`;
|
|
946
951
|
children.forEach((n) => {
|
|
947
952
|
if (isViewportNode(n)) {
|
|
948
953
|
if (!n.hasAttribute("width") && !n.hasAttribute("device")) n.style.setProperty("--snap-width", `${width}px`);
|
|
@@ -980,10 +985,12 @@ class RpMainView extends HTMLElement {
|
|
|
980
985
|
if (!usesAutoHeight(this)) return;
|
|
981
986
|
const shell = this.querySelector(".rp-main-shell");
|
|
982
987
|
const stage = this.querySelector(".rp-main-stage");
|
|
988
|
+
const clip = this.querySelector(".rp-main-stage-clip");
|
|
983
989
|
if (!shell || !stage) return;
|
|
984
990
|
const scale = Number(attr(this, "scale", "0.7")) || 0.7;
|
|
985
991
|
const next = `${Math.ceil(stage.scrollHeight * scale)}px`;
|
|
986
992
|
if (shell.style.height !== next) shell.style.height = next;
|
|
993
|
+
if (clip && clip.style.height !== next) clip.style.height = next;
|
|
987
994
|
}
|
|
988
995
|
renderPins() {
|
|
989
996
|
const shell = this.querySelector(".rp-main-shell");
|