@nsnanocat/preference-panes 0.9.6 → 0.9.8
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 +6 -8
- package/dist/api.js +1 -1
- package/dist/module/app.mjs +15 -29
- package/dist/module/index.html +1 -1
- package/dist/preference-panes.mjs +15 -29
- package/package.json +1 -1
- package/src/browser/components.mjs +6 -6
- package/src/browser/index.mjs +3 -16
- package/src/browser/panel.css +50 -8
- package/src/browser/panel.mjs +5 -5
- package/dist/module/host.mjs +0 -589
- package/src/browser/BilibiliHost.mjs +0 -142
- package/src/browser/host.mjs +0 -82
- package/src/browser/official-styles.json +0 -4
package/dist/module/app.mjs
CHANGED
|
@@ -130,24 +130,24 @@ function element(tag, className, text) {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
133
|
+
* 创建通用设置行;外部 CSS 可通过 pp 类名覆盖视觉样式。
|
|
134
|
+
* Create a generic settings row whose appearance can be overridden through pp classes.
|
|
135
135
|
* @template {"div" | "label"} T
|
|
136
136
|
* @param {T} tag 行元素 / Row element.
|
|
137
137
|
* @returns {HTMLElementTagNameMap[T]} 设置行 / Settings row.
|
|
138
138
|
*/
|
|
139
139
|
function settingRow(tag) {
|
|
140
|
-
return element(tag, "pp-row
|
|
140
|
+
return element(tag, "pp-row");
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
144
|
+
* 为标准 HTML 输入控件添加通用面板类名。
|
|
145
|
+
* Add the generic panel class to a standard HTML input control.
|
|
146
146
|
* @param {HTMLElement} control 已创建的原生控件 / Existing native control.
|
|
147
147
|
* @returns {HTMLElement} 输入控件 / Input control.
|
|
148
148
|
*/
|
|
149
149
|
function fieldControl(control) {
|
|
150
|
-
control.classList.add("pp-editor"
|
|
150
|
+
control.classList.add("pp-editor");
|
|
151
151
|
return control;
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -213,9 +213,7 @@ function requestConfirmation(host, message) {
|
|
|
213
213
|
});
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
var
|
|
217
|
-
|
|
218
|
-
var defaults = "/* 官方 b-style 负责行布局与配色;本文件只定义面板容器和控件约束。\n * Official b-style owns row layout and colors; this file defines panel containers and control constraints. */\n.pp-panel {\n --pp-text: var(--text1);\n --pp-background: var(--bg2);\n --pp-surface: var(--bg1);\n --pp-border: var(--line_regular);\n --pp-muted: var(--text3);\n --pp-accent: var(--brand_pink);\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n font: inherit;\n border: 0;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n}\n.pp-row {\n min-height: 48px;\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
|
|
216
|
+
var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n.pp-panel {\n --pp-text: #18191c;\n --pp-background: #f6f7f8;\n --pp-surface: #fff;\n --pp-field: #f1f2f3;\n --pp-border: #e3e5e7;\n --pp-muted: #797f87;\n --pp-accent: #1677ff;\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n\n:root[data-theme=\"dark\"] .pp-panel {\n --pp-text: #f1f2f3;\n --pp-background: #0d0e0f;\n --pp-surface: #18191c;\n --pp-field: #2f3238;\n --pp-border: #2f3238;\n --pp-muted: #9499a0;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n padding: 8px 10px;\n font: inherit;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n margin-right: 16px;\n}\n.pp-field-name {\n color: var(--pp-text);\n font-size: 15px;\n}\n.pp-field-description {\n margin-top: 2px;\n color: var(--pp-muted);\n font-size: 12px;\n}\n.pp-group {\n margin-top: 16px;\n}\n.pp-group-title {\n margin: 0 0 8px;\n color: var(--pp-muted);\n font-size: 15px;\n font-weight: 400;\n}\n.pp-row {\n min-height: 48px;\n padding: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
|
|
219
217
|
|
|
220
218
|
/**
|
|
221
219
|
* 标题栏共用三点菜单;Shadow DOM 隔离项目样式,保留继承的主题色。
|
|
@@ -1046,17 +1044,17 @@ function mountPanel(root, catalog) {
|
|
|
1046
1044
|
const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
|
|
1047
1045
|
const group = match?.[1] ?? "通用";
|
|
1048
1046
|
if (!groups.has(group)) {
|
|
1049
|
-
const section = element("section", "pp-group
|
|
1047
|
+
const section = element("section", "pp-group");
|
|
1050
1048
|
const rows = element("div", "pp-rows");
|
|
1051
|
-
section.append(element("h2", "
|
|
1049
|
+
section.append(element("h2", "pp-group-title", group), rows);
|
|
1052
1050
|
groups.set(group, rows);
|
|
1053
1051
|
view.append(section);
|
|
1054
1052
|
}
|
|
1055
1053
|
const row = settingRow("div");
|
|
1056
1054
|
row.classList.add("pp-field");
|
|
1057
|
-
const label = element("div", "pp-label
|
|
1058
|
-
label.append(element("span", "
|
|
1059
|
-
if (field.description) label.append(element("span", "
|
|
1055
|
+
const label = element("div", "pp-label");
|
|
1056
|
+
label.append(element("span", "pp-field-name", match?.[2] ?? field.name));
|
|
1057
|
+
if (field.description) label.append(element("span", "pp-field-description", field.description));
|
|
1060
1058
|
row.append(label);
|
|
1061
1059
|
const value = values[field.key];
|
|
1062
1060
|
/**
|
|
@@ -1304,8 +1302,8 @@ function mountPanel(root, catalog) {
|
|
|
1304
1302
|
}
|
|
1305
1303
|
|
|
1306
1304
|
/**
|
|
1307
|
-
*
|
|
1308
|
-
* Mount
|
|
1305
|
+
* 挂载模块设置页;默认样式由包提供,可选 CSS 仅作用于当前模块。
|
|
1306
|
+
* Mount a module page with package defaults and optional module-scoped CSS.
|
|
1309
1307
|
* @param {import("../index.js").BoxJSInput} boxjs 单个模块的 BoxJS JSON / BoxJS JSON for one module.
|
|
1310
1308
|
* @param {string} [css] 可选 CSS 正文 / Optional CSS text.
|
|
1311
1309
|
* @returns {import("./index.js").MountedPreferences} 模块生命周期句柄 / Module lifecycle handle.
|
|
@@ -1323,22 +1321,13 @@ function mount(boxjs, css = "") {
|
|
|
1323
1321
|
root.id = "preferences";
|
|
1324
1322
|
document.body.append(root);
|
|
1325
1323
|
}
|
|
1326
|
-
// 远程视觉资源与基础布局分开加载,网络状态不控制分页定位。
|
|
1327
|
-
// Load remote visual resources separately so network state cannot control page positioning.
|
|
1328
|
-
const links = styleURLs.map(url => {
|
|
1329
|
-
const link = element("link", "");
|
|
1330
|
-
link.rel = "stylesheet";
|
|
1331
|
-
link.href = url;
|
|
1332
|
-
return link;
|
|
1333
|
-
});
|
|
1334
1324
|
const base = element("style", ""),
|
|
1335
1325
|
custom = element("style", "");
|
|
1336
1326
|
base.textContent = defaults;
|
|
1337
1327
|
custom.textContent = css;
|
|
1338
|
-
document.head.append(
|
|
1328
|
+
document.head.append(base, custom);
|
|
1339
1329
|
const previousTitle = document.title;
|
|
1340
1330
|
const previousTheme = document.documentElement.dataset.theme;
|
|
1341
|
-
const previousDark = document.documentElement.classList.contains("bili_dark");
|
|
1342
1331
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1343
1332
|
const previousKeyboard = document.documentElement.style.getPropertyValue("--pp-keyboard-height");
|
|
1344
1333
|
const host = window.frameElement?.ownerDocument.documentElement;
|
|
@@ -1350,7 +1339,6 @@ function mount(boxjs, css = "") {
|
|
|
1350
1339
|
const syncAppearance = () => {
|
|
1351
1340
|
const theme = host?.dataset.theme ?? previousTheme ?? (systemTheme.matches ? "dark" : "light");
|
|
1352
1341
|
document.documentElement.dataset.theme = theme;
|
|
1353
|
-
document.documentElement.classList.toggle("bili_dark", theme === "dark");
|
|
1354
1342
|
if (host) document.documentElement.style.setProperty("--pp-keyboard-height", host.style.getPropertyValue("--pp-keyboard-height"));
|
|
1355
1343
|
};
|
|
1356
1344
|
let observer;
|
|
@@ -1371,9 +1359,7 @@ function mount(boxjs, css = "") {
|
|
|
1371
1359
|
destroy() {
|
|
1372
1360
|
observer?.disconnect();
|
|
1373
1361
|
systemTheme.removeEventListener("change", syncAppearance);
|
|
1374
|
-
document.documentElement.classList.toggle("bili_dark", previousDark);
|
|
1375
1362
|
panel?.destroy();
|
|
1376
|
-
for (const link of links) link.remove();
|
|
1377
1363
|
base.remove();
|
|
1378
1364
|
custom.remove();
|
|
1379
1365
|
if (existing) root.replaceChildren();
|
package/dist/module/index.html
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
var defaults = "/* 官方 b-style 负责行布局与配色;本文件只定义面板容器和控件约束。\n * Official b-style owns row layout and colors; this file defines panel containers and control constraints. */\n.pp-panel {\n --pp-text: var(--text1);\n --pp-background: var(--bg2);\n --pp-surface: var(--bg1);\n --pp-border: var(--line_regular);\n --pp-muted: var(--text3);\n --pp-accent: var(--brand_pink);\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n font: inherit;\n border: 0;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n}\n.pp-row {\n min-height: 48px;\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
|
|
1
|
+
var defaults = "/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。\n * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */\n.pp-panel {\n --pp-text: #18191c;\n --pp-background: #f6f7f8;\n --pp-surface: #fff;\n --pp-field: #f1f2f3;\n --pp-border: #e3e5e7;\n --pp-muted: #797f87;\n --pp-accent: #1677ff;\n font:\n 15px / 1.5 -apple-system,\n BlinkMacSystemFont,\n \"Segoe UI\",\n sans-serif;\n color: var(--pp-text);\n background: var(--pp-background);\n position: relative;\n display: flex;\n flex-direction: column;\n height: 100vh;\n}\n\n:root[data-theme=\"dark\"] .pp-panel {\n --pp-text: #f1f2f3;\n --pp-background: #0d0e0f;\n --pp-surface: #18191c;\n --pp-field: #2f3238;\n --pp-border: #2f3238;\n --pp-muted: #9499a0;\n}\n.pp-panel * {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n.pp-header {\n flex: none;\n height: calc(52px + env(safe-area-inset-top));\n padding: env(safe-area-inset-top) 12px 0;\n display: flex;\n align-items: center;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n position: relative;\n z-index: 2;\n}\n.pp-title {\n flex: 1;\n text-align: center;\n font-size: 17px;\n font-weight: 500;\n margin: 0;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n/* 模块图标在正文内;嵌入宿主可使用纯文字原生标题栏。\n * Keep module icons in content so embedded hosts can use text-only native titles. */\n.pp-module-logo {\n display: none;\n width: 64px;\n height: 64px;\n margin: 8px auto 20px;\n}\n.pp-module-logo:not(:empty) {\n display: block;\n}\n.pp-module-logo img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.pp-nav-spacer {\n width: 44px;\n flex: none;\n}\n.pp-panel button {\n font: inherit;\n cursor: pointer;\n border: 0;\n background: none;\n color: inherit;\n}\n.pp-panel .pp-back {\n width: 44px;\n height: 44px;\n flex: none;\n font-size: 34px;\n line-height: 32px;\n padding: 0;\n}\n.pp-panel button:disabled {\n opacity: 0.5;\n cursor: wait;\n}\n/* 固定工具区与滚动视口共用弹性布局,不按工具栏高度拼接页面偏移。\n * Fixed tools and the scrolling viewport share a flex layout without toolbar-height offsets. */\n.pp-toolbar {\n flex: none;\n padding: 12px max(16px, calc((100% - 688px) / 2));\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-viewport {\n position: relative;\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n:root[data-preference-panes-embedded] .pp-header {\n display: none;\n}\n@supports (height: 100dvh) {\n .pp-panel {\n height: 100dvh;\n }\n}\n.pp-fields,\n.pp-choice-page,\n.pp-cache-page {\n position: absolute;\n inset: 0;\n overflow: auto;\n padding: 12px max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height, 0px));\n scroll-padding-bottom: var(--pp-keyboard-height, 0px);\n background: var(--pp-background);\n}\n.pp-choice-link {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 8px;\n max-width: 45%;\n min-width: 44px;\n min-height: 44px;\n padding: 0;\n text-align: right;\n flex: 1;\n}\n.pp-summary {\n color: var(--pp-muted);\n font-size: 13px;\n line-height: 18px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n overflow-wrap: anywhere;\n}\n.pp-chevron {\n color: var(--pp-muted);\n font-size: 22px;\n flex: none;\n}\n.pp-editor {\n flex: none;\n width: 45%;\n min-width: 0;\n min-height: 36px;\n padding: 8px 10px;\n font: inherit;\n color: var(--pp-text);\n background: var(--pp-field);\n border: 0;\n border-radius: 6px;\n}\n.pp-search {\n width: 100%;\n margin: 0;\n}\n.pp-panel .pp-multiline {\n display: block;\n}\n.pp-multiline .pp-editor {\n width: 100%;\n margin-top: 10px;\n}\n.pp-panel [hidden] {\n display: none !important;\n}\n.pp-label {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n margin-right: 16px;\n}\n.pp-field-name {\n color: var(--pp-text);\n font-size: 15px;\n}\n.pp-field-description {\n margin-top: 2px;\n color: var(--pp-muted);\n font-size: 12px;\n}\n.pp-group {\n margin-top: 16px;\n}\n.pp-group-title {\n margin: 0 0 8px;\n color: var(--pp-muted);\n font-size: 15px;\n font-weight: 400;\n}\n.pp-row {\n min-height: 48px;\n padding: 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n background: var(--pp-surface);\n border-bottom: 1px solid var(--pp-border);\n}\n.pp-rows > :last-child {\n border-bottom: 0 !important;\n}\n.pp-switch {\n flex: none;\n accent-color: var(--pp-accent);\n}\n.pp-choice {\n justify-content: space-between;\n cursor: pointer;\n}\n.pp-choice input {\n width: 20px;\n height: 20px;\n flex: none;\n accent-color: var(--pp-accent);\n margin: 0;\n}\n.pp-description {\n font-size: 12px;\n line-height: 1.6;\n color: var(--pp-muted);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-module-info {\n display: flex;\n gap: 12px;\n margin: 12px 0;\n}\n.pp-module-details {\n min-width: 0;\n overflow-wrap: anywhere;\n}\n.pp-module-source {\n color: inherit;\n text-decoration: underline;\n}\n.pp-error button {\n min-height: 44px;\n padding: 8px 12px;\n border-radius: 6px;\n background: var(--pp-surface);\n}\n.pp-cache {\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n.pp-toast {\n pointer-events: none;\n position: fixed;\n bottom: calc(30px + env(safe-area-inset-bottom));\n left: 50%;\n transform: translateX(-50%);\n max-width: 90vw;\n padding: 10px 16px;\n border-radius: 8px;\n background: #333e;\n color: white;\n font-size: 13px;\n z-index: 20;\n}\n.pp-toast[data-kind=\"error\"] {\n background: #8d2424;\n}\n.pp-panel :focus-visible {\n outline: 2px solid var(--pp-accent);\n outline-offset: -2px;\n}\n";
|
|
4
2
|
|
|
5
3
|
/**
|
|
6
4
|
* 校验原始路径片段,不进行 URL 编码转换。
|
|
@@ -116,24 +114,24 @@ function element(tag, className, text) {
|
|
|
116
114
|
}
|
|
117
115
|
|
|
118
116
|
/**
|
|
119
|
-
*
|
|
120
|
-
*
|
|
117
|
+
* 创建通用设置行;外部 CSS 可通过 pp 类名覆盖视觉样式。
|
|
118
|
+
* Create a generic settings row whose appearance can be overridden through pp classes.
|
|
121
119
|
* @template {"div" | "label"} T
|
|
122
120
|
* @param {T} tag 行元素 / Row element.
|
|
123
121
|
* @returns {HTMLElementTagNameMap[T]} 设置行 / Settings row.
|
|
124
122
|
*/
|
|
125
123
|
function settingRow(tag) {
|
|
126
|
-
return element(tag, "pp-row
|
|
124
|
+
return element(tag, "pp-row");
|
|
127
125
|
}
|
|
128
126
|
|
|
129
127
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
128
|
+
* 为标准 HTML 输入控件添加通用面板类名。
|
|
129
|
+
* Add the generic panel class to a standard HTML input control.
|
|
132
130
|
* @param {HTMLElement} control 已创建的原生控件 / Existing native control.
|
|
133
131
|
* @returns {HTMLElement} 输入控件 / Input control.
|
|
134
132
|
*/
|
|
135
133
|
function fieldControl(control) {
|
|
136
|
-
control.classList.add("pp-editor"
|
|
134
|
+
control.classList.add("pp-editor");
|
|
137
135
|
return control;
|
|
138
136
|
}
|
|
139
137
|
|
|
@@ -1028,17 +1026,17 @@ function mountPanel(root, catalog) {
|
|
|
1028
1026
|
const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
|
|
1029
1027
|
const group = match?.[1] ?? "通用";
|
|
1030
1028
|
if (!groups.has(group)) {
|
|
1031
|
-
const section = element("section", "pp-group
|
|
1029
|
+
const section = element("section", "pp-group");
|
|
1032
1030
|
const rows = element("div", "pp-rows");
|
|
1033
|
-
section.append(element("h2", "
|
|
1031
|
+
section.append(element("h2", "pp-group-title", group), rows);
|
|
1034
1032
|
groups.set(group, rows);
|
|
1035
1033
|
view.append(section);
|
|
1036
1034
|
}
|
|
1037
1035
|
const row = settingRow("div");
|
|
1038
1036
|
row.classList.add("pp-field");
|
|
1039
|
-
const label = element("div", "pp-label
|
|
1040
|
-
label.append(element("span", "
|
|
1041
|
-
if (field.description) label.append(element("span", "
|
|
1037
|
+
const label = element("div", "pp-label");
|
|
1038
|
+
label.append(element("span", "pp-field-name", match?.[2] ?? field.name));
|
|
1039
|
+
if (field.description) label.append(element("span", "pp-field-description", field.description));
|
|
1042
1040
|
row.append(label);
|
|
1043
1041
|
const value = values[field.key];
|
|
1044
1042
|
/**
|
|
@@ -1286,8 +1284,8 @@ function mountPanel(root, catalog) {
|
|
|
1286
1284
|
}
|
|
1287
1285
|
|
|
1288
1286
|
/**
|
|
1289
|
-
*
|
|
1290
|
-
* Mount
|
|
1287
|
+
* 挂载模块设置页;默认样式由包提供,可选 CSS 仅作用于当前模块。
|
|
1288
|
+
* Mount a module page with package defaults and optional module-scoped CSS.
|
|
1291
1289
|
* @param {import("../index.js").BoxJSInput} boxjs 单个模块的 BoxJS JSON / BoxJS JSON for one module.
|
|
1292
1290
|
* @param {string} [css] 可选 CSS 正文 / Optional CSS text.
|
|
1293
1291
|
* @returns {import("./index.js").MountedPreferences} 模块生命周期句柄 / Module lifecycle handle.
|
|
@@ -1305,22 +1303,13 @@ function mount(boxjs, css = "") {
|
|
|
1305
1303
|
root.id = "preferences";
|
|
1306
1304
|
document.body.append(root);
|
|
1307
1305
|
}
|
|
1308
|
-
// 远程视觉资源与基础布局分开加载,网络状态不控制分页定位。
|
|
1309
|
-
// Load remote visual resources separately so network state cannot control page positioning.
|
|
1310
|
-
const links = styleURLs.map(url => {
|
|
1311
|
-
const link = element("link", "");
|
|
1312
|
-
link.rel = "stylesheet";
|
|
1313
|
-
link.href = url;
|
|
1314
|
-
return link;
|
|
1315
|
-
});
|
|
1316
1306
|
const base = element("style", ""),
|
|
1317
1307
|
custom = element("style", "");
|
|
1318
1308
|
base.textContent = defaults;
|
|
1319
1309
|
custom.textContent = css;
|
|
1320
|
-
document.head.append(
|
|
1310
|
+
document.head.append(base, custom);
|
|
1321
1311
|
const previousTitle = document.title;
|
|
1322
1312
|
const previousTheme = document.documentElement.dataset.theme;
|
|
1323
|
-
const previousDark = document.documentElement.classList.contains("bili_dark");
|
|
1324
1313
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
|
|
1325
1314
|
const previousKeyboard = document.documentElement.style.getPropertyValue("--pp-keyboard-height");
|
|
1326
1315
|
const host = window.frameElement?.ownerDocument.documentElement;
|
|
@@ -1332,7 +1321,6 @@ function mount(boxjs, css = "") {
|
|
|
1332
1321
|
const syncAppearance = () => {
|
|
1333
1322
|
const theme = host?.dataset.theme ?? previousTheme ?? (systemTheme.matches ? "dark" : "light");
|
|
1334
1323
|
document.documentElement.dataset.theme = theme;
|
|
1335
|
-
document.documentElement.classList.toggle("bili_dark", theme === "dark");
|
|
1336
1324
|
if (host) document.documentElement.style.setProperty("--pp-keyboard-height", host.style.getPropertyValue("--pp-keyboard-height"));
|
|
1337
1325
|
};
|
|
1338
1326
|
let observer;
|
|
@@ -1353,9 +1341,7 @@ function mount(boxjs, css = "") {
|
|
|
1353
1341
|
destroy() {
|
|
1354
1342
|
observer?.disconnect();
|
|
1355
1343
|
systemTheme.removeEventListener("change", syncAppearance);
|
|
1356
|
-
document.documentElement.classList.toggle("bili_dark", previousDark);
|
|
1357
1344
|
panel?.destroy();
|
|
1358
|
-
for (const link of links) link.remove();
|
|
1359
1345
|
base.remove();
|
|
1360
1346
|
custom.remove();
|
|
1361
1347
|
if (existing) root.replaceChildren();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nsnanocat/preference-panes",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.8",
|
|
4
4
|
"description": "Shared settings API runtime for JavaScript proxy modules",
|
|
5
5
|
"author": "VirgilClyne <Virgil@nanocat.me>",
|
|
6
6
|
"homepage": "https://NSNanoCat.github.io/preference-panes",
|
|
@@ -15,24 +15,24 @@ export function element(tag, className, text) {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* 创建通用设置行;外部 CSS 可通过 pp 类名覆盖视觉样式。
|
|
19
|
+
* Create a generic settings row whose appearance can be overridden through pp classes.
|
|
20
20
|
* @template {"div" | "label"} T
|
|
21
21
|
* @param {T} tag 行元素 / Row element.
|
|
22
22
|
* @returns {HTMLElementTagNameMap[T]} 设置行 / Settings row.
|
|
23
23
|
*/
|
|
24
24
|
export function settingRow(tag) {
|
|
25
|
-
return element(tag, "pp-row
|
|
25
|
+
return element(tag, "pp-row");
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
29
|
+
* 为标准 HTML 输入控件添加通用面板类名。
|
|
30
|
+
* Add the generic panel class to a standard HTML input control.
|
|
31
31
|
* @param {HTMLElement} control 已创建的原生控件 / Existing native control.
|
|
32
32
|
* @returns {HTMLElement} 输入控件 / Input control.
|
|
33
33
|
*/
|
|
34
34
|
export function fieldControl(control) {
|
|
35
|
-
control.classList.add("pp-editor"
|
|
35
|
+
control.classList.add("pp-editor");
|
|
36
36
|
return control;
|
|
37
37
|
}
|
|
38
38
|
|
package/src/browser/index.mjs
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import styleURLs from "#style-urls";
|
|
2
1
|
import defaults from "#styles";
|
|
3
2
|
import { BoxJS } from "../BoxJS.mjs";
|
|
4
3
|
import { element, resourceURL } from "./components.mjs";
|
|
5
4
|
import { mountPanel } from "./panel.mjs";
|
|
6
5
|
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
* Mount
|
|
7
|
+
* 挂载模块设置页;默认样式由包提供,可选 CSS 仅作用于当前模块。
|
|
8
|
+
* Mount a module page with package defaults and optional module-scoped CSS.
|
|
10
9
|
* @param {import("../index.js").BoxJSInput} boxjs 单个模块的 BoxJS JSON / BoxJS JSON for one module.
|
|
11
10
|
* @param {string} [css] 可选 CSS 正文 / Optional CSS text.
|
|
12
11
|
* @returns {import("./index.js").MountedPreferences} 模块生命周期句柄 / Module lifecycle handle.
|
|
@@ -24,22 +23,13 @@ export function mount(boxjs, css = "") {
|
|
|
24
23
|
root.id = "preferences";
|
|
25
24
|
document.body.append(root);
|
|
26
25
|
}
|
|
27
|
-
// 远程视觉资源与基础布局分开加载,网络状态不控制分页定位。
|
|
28
|
-
// Load remote visual resources separately so network state cannot control page positioning.
|
|
29
|
-
const links = styleURLs.map(url => {
|
|
30
|
-
const link = element("link", "");
|
|
31
|
-
link.rel = "stylesheet";
|
|
32
|
-
link.href = url;
|
|
33
|
-
return link;
|
|
34
|
-
});
|
|
35
26
|
const base = element("style", ""),
|
|
36
27
|
custom = element("style", "");
|
|
37
28
|
base.textContent = defaults;
|
|
38
29
|
custom.textContent = css;
|
|
39
|
-
document.head.append(
|
|
30
|
+
document.head.append(base, custom);
|
|
40
31
|
const previousTitle = document.title;
|
|
41
32
|
const previousTheme = document.documentElement.dataset.theme;
|
|
42
|
-
const previousDark = document.documentElement.classList.contains("bili_dark");
|
|
43
33
|
const systemTheme = window.matchMedia("(prefers-color-scheme: dark)");
|
|
44
34
|
const previousKeyboard = document.documentElement.style.getPropertyValue("--pp-keyboard-height");
|
|
45
35
|
const host = window.frameElement?.ownerDocument.documentElement;
|
|
@@ -51,7 +41,6 @@ export function mount(boxjs, css = "") {
|
|
|
51
41
|
const syncAppearance = () => {
|
|
52
42
|
const theme = host?.dataset.theme ?? previousTheme ?? (systemTheme.matches ? "dark" : "light");
|
|
53
43
|
document.documentElement.dataset.theme = theme;
|
|
54
|
-
document.documentElement.classList.toggle("bili_dark", theme === "dark");
|
|
55
44
|
if (host) document.documentElement.style.setProperty("--pp-keyboard-height", host.style.getPropertyValue("--pp-keyboard-height"));
|
|
56
45
|
};
|
|
57
46
|
let observer;
|
|
@@ -72,9 +61,7 @@ export function mount(boxjs, css = "") {
|
|
|
72
61
|
destroy() {
|
|
73
62
|
observer?.disconnect();
|
|
74
63
|
systemTheme.removeEventListener("change", syncAppearance);
|
|
75
|
-
document.documentElement.classList.toggle("bili_dark", previousDark);
|
|
76
64
|
panel?.destroy();
|
|
77
|
-
for (const link of links) link.remove();
|
|
78
65
|
base.remove();
|
|
79
66
|
custom.remove();
|
|
80
67
|
if (existing) root.replaceChildren();
|
package/src/browser/panel.css
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
1
|
+
/* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。
|
|
2
|
+
* Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */
|
|
3
3
|
.pp-panel {
|
|
4
|
-
--pp-text:
|
|
5
|
-
--pp-background:
|
|
6
|
-
--pp-surface:
|
|
7
|
-
--pp-
|
|
8
|
-
--pp-
|
|
9
|
-
--pp-
|
|
4
|
+
--pp-text: #18191c;
|
|
5
|
+
--pp-background: #f6f7f8;
|
|
6
|
+
--pp-surface: #fff;
|
|
7
|
+
--pp-field: #f1f2f3;
|
|
8
|
+
--pp-border: #e3e5e7;
|
|
9
|
+
--pp-muted: #797f87;
|
|
10
|
+
--pp-accent: #1677ff;
|
|
10
11
|
font:
|
|
11
12
|
15px / 1.5 -apple-system,
|
|
12
13
|
BlinkMacSystemFont,
|
|
@@ -19,6 +20,15 @@
|
|
|
19
20
|
flex-direction: column;
|
|
20
21
|
height: 100vh;
|
|
21
22
|
}
|
|
23
|
+
|
|
24
|
+
:root[data-theme="dark"] .pp-panel {
|
|
25
|
+
--pp-text: #f1f2f3;
|
|
26
|
+
--pp-background: #0d0e0f;
|
|
27
|
+
--pp-surface: #18191c;
|
|
28
|
+
--pp-field: #2f3238;
|
|
29
|
+
--pp-border: #2f3238;
|
|
30
|
+
--pp-muted: #9499a0;
|
|
31
|
+
}
|
|
22
32
|
.pp-panel * {
|
|
23
33
|
box-sizing: border-box;
|
|
24
34
|
letter-spacing: 0;
|
|
@@ -147,8 +157,12 @@
|
|
|
147
157
|
width: 45%;
|
|
148
158
|
min-width: 0;
|
|
149
159
|
min-height: 36px;
|
|
160
|
+
padding: 8px 10px;
|
|
150
161
|
font: inherit;
|
|
162
|
+
color: var(--pp-text);
|
|
163
|
+
background: var(--pp-field);
|
|
151
164
|
border: 0;
|
|
165
|
+
border-radius: 6px;
|
|
152
166
|
}
|
|
153
167
|
.pp-search {
|
|
154
168
|
width: 100%;
|
|
@@ -167,9 +181,37 @@
|
|
|
167
181
|
.pp-label {
|
|
168
182
|
flex: 1;
|
|
169
183
|
min-width: 0;
|
|
184
|
+
display: flex;
|
|
185
|
+
flex-direction: column;
|
|
186
|
+
align-items: flex-start;
|
|
187
|
+
margin-right: 16px;
|
|
188
|
+
}
|
|
189
|
+
.pp-field-name {
|
|
190
|
+
color: var(--pp-text);
|
|
191
|
+
font-size: 15px;
|
|
192
|
+
}
|
|
193
|
+
.pp-field-description {
|
|
194
|
+
margin-top: 2px;
|
|
195
|
+
color: var(--pp-muted);
|
|
196
|
+
font-size: 12px;
|
|
197
|
+
}
|
|
198
|
+
.pp-group {
|
|
199
|
+
margin-top: 16px;
|
|
200
|
+
}
|
|
201
|
+
.pp-group-title {
|
|
202
|
+
margin: 0 0 8px;
|
|
203
|
+
color: var(--pp-muted);
|
|
204
|
+
font-size: 15px;
|
|
205
|
+
font-weight: 400;
|
|
170
206
|
}
|
|
171
207
|
.pp-row {
|
|
172
208
|
min-height: 48px;
|
|
209
|
+
padding: 16px;
|
|
210
|
+
display: flex;
|
|
211
|
+
align-items: center;
|
|
212
|
+
justify-content: space-between;
|
|
213
|
+
background: var(--pp-surface);
|
|
214
|
+
border-bottom: 1px solid var(--pp-border);
|
|
173
215
|
}
|
|
174
216
|
.pp-rows > :last-child {
|
|
175
217
|
border-bottom: 0 !important;
|
package/src/browser/panel.mjs
CHANGED
|
@@ -236,17 +236,17 @@ export function mountPanel(root, catalog) {
|
|
|
236
236
|
const match = /^\[([^\]]+)\]\s*(.*)$/.exec(field.name);
|
|
237
237
|
const group = match?.[1] ?? "通用";
|
|
238
238
|
if (!groups.has(group)) {
|
|
239
|
-
const section = node("section", "pp-group
|
|
239
|
+
const section = node("section", "pp-group");
|
|
240
240
|
const rows = node("div", "pp-rows");
|
|
241
|
-
section.append(node("h2", "
|
|
241
|
+
section.append(node("h2", "pp-group-title", group), rows);
|
|
242
242
|
groups.set(group, rows);
|
|
243
243
|
view.append(section);
|
|
244
244
|
}
|
|
245
245
|
const row = settingRow("div");
|
|
246
246
|
row.classList.add("pp-field");
|
|
247
|
-
const label = node("div", "pp-label
|
|
248
|
-
label.append(node("span", "
|
|
249
|
-
if (field.description) label.append(node("span", "
|
|
247
|
+
const label = node("div", "pp-label");
|
|
248
|
+
label.append(node("span", "pp-field-name", match?.[2] ?? field.name));
|
|
249
|
+
if (field.description) label.append(node("span", "pp-field-description", field.description));
|
|
250
250
|
row.append(label);
|
|
251
251
|
const value = values[field.key];
|
|
252
252
|
/**
|