@nsnanocat/preference-panes 1.2.5 → 1.3.1

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.
@@ -0,0 +1,565 @@
1
+ /* 通用默认样式只使用 pp 命名空间;项目可通过 CSS 输入覆盖变量和组件。
2
+ * Generic defaults use only the pp namespace; projects may override variables and components through CSS input. */
3
+ :root {
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;
11
+ --pp-warning: #9a6700;
12
+ --pp-host-height: 0px;
13
+ --pp-keyboard-height: 0px;
14
+ }
15
+ .pp-panel {
16
+ font:
17
+ 15px / 1.5 -apple-system,
18
+ BlinkMacSystemFont,
19
+ "Segoe UI",
20
+ sans-serif;
21
+ color: var(--pp-text);
22
+ background: var(--pp-background);
23
+ position: relative;
24
+ display: flex;
25
+ flex-direction: column;
26
+ width: 100%;
27
+ max-width: 100vw;
28
+ min-width: 0;
29
+ }
30
+
31
+ :root[data-theme="dark"] {
32
+ --pp-text: #f1f2f3;
33
+ --pp-background: #0d0e0f;
34
+ --pp-surface: #18191c;
35
+ --pp-field: #2f3238;
36
+ --pp-border: #2f3238;
37
+ --pp-muted: #9499a0;
38
+ --pp-warning: #f0b849;
39
+ }
40
+ .pp-panel * {
41
+ box-sizing: border-box;
42
+ letter-spacing: 0;
43
+ }
44
+ .pp-panel button {
45
+ font: inherit;
46
+ cursor: pointer;
47
+ border: 0;
48
+ background: none;
49
+ color: inherit;
50
+ }
51
+ .pp-panel button:disabled {
52
+ opacity: 0.5;
53
+ cursor: wait;
54
+ }
55
+ .pp-viewport {
56
+ min-width: 0;
57
+ }
58
+ .pp-fields,
59
+ .pp-choice-page,
60
+ .pp-settings-page,
61
+ .pp-cache-page {
62
+ box-sizing: border-box;
63
+ min-width: 0;
64
+ padding: calc(12px + var(--pp-host-height)) max(16px, calc((100% - 688px) / 2)) calc(28px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));
65
+ scroll-padding-bottom: var(--pp-keyboard-height);
66
+ background: var(--pp-background);
67
+ }
68
+ .pp-choice-link {
69
+ display: flex;
70
+ align-items: center;
71
+ justify-content: flex-end;
72
+ gap: 8px;
73
+ max-width: 45%;
74
+ min-width: 44px;
75
+ min-height: 44px;
76
+ padding: 0;
77
+ text-align: right;
78
+ flex: 1;
79
+ }
80
+ .pp-panel a.pp-choice-link {
81
+ color: var(--pp-accent);
82
+ text-decoration: none;
83
+ }
84
+ .pp-summary {
85
+ color: var(--pp-muted);
86
+ font-size: 13px;
87
+ line-height: 18px;
88
+ display: -webkit-box;
89
+ -webkit-line-clamp: 2;
90
+ -webkit-box-orient: vertical;
91
+ overflow: hidden;
92
+ overflow-wrap: anywhere;
93
+ }
94
+ .pp-chevron {
95
+ color: var(--pp-muted);
96
+ font-size: 22px;
97
+ flex: none;
98
+ }
99
+ .pp-editor {
100
+ flex: none;
101
+ width: 45%;
102
+ min-width: 0;
103
+ min-height: 36px;
104
+ padding: 8px 10px;
105
+ font: inherit;
106
+ font-size: 16px;
107
+ color: var(--pp-text);
108
+ background: var(--pp-field);
109
+ border: 0;
110
+ border-radius: 6px;
111
+ }
112
+ .pp-panel .pp-multiline {
113
+ display: block;
114
+ }
115
+ .pp-multiline .pp-editor {
116
+ width: 100%;
117
+ margin-top: 10px;
118
+ }
119
+ .pp-panel [hidden] {
120
+ display: none !important;
121
+ }
122
+ .pp-label {
123
+ flex: 1;
124
+ min-width: 0;
125
+ display: flex;
126
+ flex-direction: column;
127
+ align-items: flex-start;
128
+ margin-right: 16px;
129
+ }
130
+ .pp-field-name {
131
+ color: var(--pp-text);
132
+ font-size: 15px;
133
+ }
134
+ .pp-field-description {
135
+ margin-top: 2px;
136
+ color: var(--pp-muted);
137
+ font-size: 12px;
138
+ }
139
+ .pp-field-warning {
140
+ margin-top: 4px;
141
+ color: var(--pp-warning);
142
+ font-size: 12px;
143
+ overflow-wrap: anywhere;
144
+ }
145
+ .pp-group {
146
+ margin-top: 16px;
147
+ }
148
+ .pp-group-title {
149
+ margin: 0 0 8px;
150
+ color: var(--pp-muted);
151
+ font-size: 15px;
152
+ font-weight: 400;
153
+ }
154
+ .pp-row {
155
+ min-width: 0;
156
+ min-height: 48px;
157
+ padding: 16px;
158
+ display: flex;
159
+ align-items: center;
160
+ justify-content: space-between;
161
+ background: var(--pp-surface);
162
+ border-bottom: 1px solid var(--pp-border);
163
+ }
164
+ .pp-rows > :last-child {
165
+ border-bottom: 0 !important;
166
+ }
167
+ .pp-switch {
168
+ flex: none;
169
+ accent-color: var(--pp-accent);
170
+ }
171
+ .pp-choice {
172
+ justify-content: space-between;
173
+ cursor: pointer;
174
+ }
175
+ .pp-choice input {
176
+ width: 20px;
177
+ height: 20px;
178
+ flex: none;
179
+ accent-color: var(--pp-accent);
180
+ margin: 0;
181
+ }
182
+ .pp-description {
183
+ font-size: 12px;
184
+ line-height: 1.6;
185
+ color: var(--pp-muted);
186
+ white-space: pre-wrap;
187
+ overflow-wrap: anywhere;
188
+ }
189
+ .pp-status {
190
+ position: absolute;
191
+ inset: 0;
192
+ display: grid;
193
+ place-content: center;
194
+ justify-items: center;
195
+ gap: 12px;
196
+ min-width: 0;
197
+ min-height: 0;
198
+ margin: 0;
199
+ padding: 24px;
200
+ color: var(--pp-muted, GrayText);
201
+ text-align: center;
202
+ background: var(--pp-background, Canvas);
203
+ }
204
+ .pp-viewport > .pp-status {
205
+ position: absolute;
206
+ }
207
+ .pp-status-spinner {
208
+ box-sizing: border-box;
209
+ width: 28px;
210
+ height: 28px;
211
+ border: 3px solid var(--pp-border, #8884);
212
+ border-top-color: var(--pp-accent, AccentColor);
213
+ border-radius: 50%;
214
+ animation: pp-status-spin 0.8s linear infinite;
215
+ }
216
+ .pp-status-message {
217
+ max-width: 100%;
218
+ margin: 0;
219
+ overflow-wrap: anywhere;
220
+ }
221
+ .pp-status-action {
222
+ min-width: 96px;
223
+ min-height: 44px;
224
+ padding: 8px 16px;
225
+ border: 0;
226
+ border-radius: 6px;
227
+ color: var(--pp-text, ButtonText);
228
+ font: inherit;
229
+ cursor: pointer;
230
+ background: var(--pp-surface, ButtonFace);
231
+ }
232
+ @keyframes pp-status-spin {
233
+ to {
234
+ transform: rotate(1turn);
235
+ }
236
+ }
237
+ .pp-cache {
238
+ white-space: pre-wrap;
239
+ overflow-wrap: anywhere;
240
+ }
241
+ .pp-panel :focus-visible {
242
+ outline: 2px solid var(--pp-accent);
243
+ outline-offset: -2px;
244
+ }
245
+
246
+ /* 首页沿用表单的分组与说明样式,入口按屏幕宽度自动换行。
247
+ * The landing page reuses form groups and descriptions, with entries wrapping by viewport width. */
248
+ :root.pp-page {
249
+ color-scheme: light dark;
250
+ }
251
+ .pp-page body {
252
+ margin: 0;
253
+ overflow: hidden;
254
+ font:
255
+ 16px / 1.5 -apple-system,
256
+ BlinkMacSystemFont,
257
+ "Segoe UI",
258
+ sans-serif;
259
+ background: var(--pp-background, Canvas);
260
+ color: var(--pp-text, CanvasText);
261
+ }
262
+ [data-preference-panes-pages] {
263
+ position: relative;
264
+ height: 100vh;
265
+ background: inherit;
266
+ overflow: hidden;
267
+ }
268
+ @supports (height: 100dvh) {
269
+ [data-preference-panes-pages] {
270
+ height: 100dvh;
271
+ }
272
+ }
273
+ .pp-home,
274
+ .pp-module-page,
275
+ .pp-detail,
276
+ .pp-link-page {
277
+ position: absolute;
278
+ inset: 0;
279
+ overflow-x: hidden;
280
+ overflow-y: auto;
281
+ overscroll-behavior: contain;
282
+ background: var(--pp-background);
283
+ }
284
+ .pp-module-page,
285
+ .pp-detail,
286
+ .pp-link-page {
287
+ z-index: 1;
288
+ box-shadow: -8px 0 24px #00000014;
289
+ }
290
+ .pp-link-page {
291
+ top: var(--pp-host-height);
292
+ }
293
+ .pp-link-page iframe {
294
+ display: block;
295
+ border: 0;
296
+ width: 100%;
297
+ height: 100%;
298
+ background: inherit;
299
+ }
300
+ .pp-host-header {
301
+ box-sizing: border-box;
302
+ position: fixed;
303
+ inset: 0 0 auto;
304
+ z-index: 2;
305
+ display: flex;
306
+ align-items: center;
307
+ height: calc(64px + env(safe-area-inset-top));
308
+ padding: env(safe-area-inset-top) max(20px, env(safe-area-inset-right)) 0 max(20px, env(safe-area-inset-left));
309
+ border-bottom: 1px solid transparent;
310
+ background: transparent;
311
+ -webkit-backdrop-filter: blur(25px);
312
+ backdrop-filter: blur(25px);
313
+ color: var(--pp-text);
314
+ transition:
315
+ background-color 200ms ease-in-out,
316
+ border-color 200ms ease-in-out;
317
+ }
318
+ .pp-host-header.pp-scrolled {
319
+ background: rgba(255, 255, 255, 0.6);
320
+ border-color: var(--pp-border);
321
+ }
322
+ :root[data-theme="dark"] .pp-host-header.pp-scrolled {
323
+ background: rgba(13, 14, 15, 0.6);
324
+ }
325
+ @media (min-width: 1280px) {
326
+ .pp-host-header {
327
+ padding-right: max(20px, calc((100vw - 1588px) / 2));
328
+ padding-left: max(20px, calc((100vw - 1588px) / 2));
329
+ }
330
+ }
331
+ @media (prefers-reduced-motion: reduce) {
332
+ .pp-host-header {
333
+ transition: none;
334
+ }
335
+ }
336
+ .pp-host-brand {
337
+ display: flex;
338
+ align-items: center;
339
+ flex: 1;
340
+ height: 36px;
341
+ min-width: 0;
342
+ margin-right: 8px;
343
+ }
344
+ .pp-host-brand-link {
345
+ display: flex;
346
+ align-items: center;
347
+ height: 100%;
348
+ min-width: 0;
349
+ max-width: 100%;
350
+ color: inherit;
351
+ text-decoration: none;
352
+ transition: opacity 0.3s;
353
+ }
354
+ .pp-host-brand-link:hover {
355
+ opacity: 0.6;
356
+ }
357
+ .pp-host-logo {
358
+ flex: none;
359
+ min-width: 2rem;
360
+ margin-right: 0.25rem;
361
+ }
362
+ .pp-host-logo img {
363
+ display: block;
364
+ height: 1.6rem;
365
+ }
366
+ .pp-host-title {
367
+ min-width: 0;
368
+ text-align: left;
369
+ font-size: 16px;
370
+ font-weight: 600;
371
+ overflow: hidden;
372
+ text-overflow: ellipsis;
373
+ white-space: nowrap;
374
+ }
375
+ .pp-host-left {
376
+ display: flex;
377
+ align-items: center;
378
+ justify-content: center;
379
+ flex: none;
380
+ }
381
+ .pp-host-left::after {
382
+ content: "";
383
+ display: inline-block;
384
+ width: 1px;
385
+ height: 24px;
386
+ margin: 0 16px;
387
+ background-color: #0000001f;
388
+ }
389
+ :root[data-theme="dark"] .pp-host-left::after {
390
+ background-color: #5454547a;
391
+ }
392
+ .pp-host-left[hidden] {
393
+ display: none;
394
+ }
395
+ .pp-host-back {
396
+ border: 0;
397
+ border-radius: 18px;
398
+ background: none;
399
+ color: inherit;
400
+ width: 36px;
401
+ height: 36px;
402
+ padding: 8px;
403
+ cursor: pointer;
404
+ transition: background-color 0.2s ease-in-out;
405
+ }
406
+ .pp-host-back svg {
407
+ display: block;
408
+ width: 20px;
409
+ height: 20px;
410
+ fill: none;
411
+ stroke: currentColor;
412
+ stroke-width: 2;
413
+ }
414
+ .pp-host-back:hover {
415
+ background: #f1f1f1;
416
+ }
417
+ :root[data-theme="dark"] .pp-host-back:hover {
418
+ background: #343a46;
419
+ }
420
+ .pp-host-toast {
421
+ position: fixed;
422
+ z-index: 3;
423
+ bottom: calc(24px + env(safe-area-inset-bottom) + var(--pp-keyboard-height));
424
+ left: 50%;
425
+ transform: translateX(-50%);
426
+ max-width: calc(100% - 48px);
427
+ padding: 10px 18px;
428
+ border-radius: 12px;
429
+ background: #222e;
430
+ color: #fff;
431
+ font-size: 14px;
432
+ text-align: center;
433
+ }
434
+ .pp-host-toast[hidden] {
435
+ display: none;
436
+ }
437
+ .pp-host-error {
438
+ margin: 24px;
439
+ padding: 16px;
440
+ border: 1px solid var(--pp-danger, #e45656);
441
+ border-radius: 12px;
442
+ font-size: 16px;
443
+ overflow-wrap: anywhere;
444
+ }
445
+
446
+ .pp-home {
447
+ max-width: 1000px;
448
+ margin: auto;
449
+ padding: var(--pp-host-height) max(16px, env(safe-area-inset-right)) calc(24px + env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
450
+ }
451
+ .pp-home-entries {
452
+ display: flex;
453
+ flex-wrap: wrap;
454
+ justify-content: space-around;
455
+ row-gap: 16px;
456
+ padding: 16px 0;
457
+ background: var(--pp-surface);
458
+ }
459
+ .pp-home-item {
460
+ box-sizing: border-box;
461
+ display: flex;
462
+ flex-direction: column;
463
+ align-items: center;
464
+ width: 25%;
465
+ min-width: 0;
466
+ padding: 0 4px;
467
+ border: 0;
468
+ background: none;
469
+ color: var(--pp-text);
470
+ font:
471
+ 12px / 1.5 -apple-system,
472
+ sans-serif;
473
+ cursor: pointer;
474
+ text-decoration: none;
475
+ }
476
+ @media (min-width: 500px) {
477
+ .pp-home-item {
478
+ width: calc(100% / 6);
479
+ }
480
+ }
481
+ @media (min-width: 700px) {
482
+ .pp-home-item {
483
+ width: 12.5%;
484
+ }
485
+ }
486
+ .pp-home-icon {
487
+ box-sizing: border-box;
488
+ width: 56px;
489
+ height: 56px;
490
+ padding: 8px;
491
+ border-radius: 50%;
492
+ background: var(--pp-field);
493
+ font-size: 32px;
494
+ line-height: 40px;
495
+ text-align: center;
496
+ }
497
+ .pp-home-icon img {
498
+ display: block;
499
+ width: 100%;
500
+ height: 100%;
501
+ object-fit: contain;
502
+ }
503
+ .pp-home-name {
504
+ margin-top: 8px;
505
+ }
506
+ .pp-home-content {
507
+ min-width: 0;
508
+ width: 100%;
509
+ }
510
+ .pp-home-content > span {
511
+ display: block;
512
+ }
513
+ .pp-home-name,
514
+ .pp-home-item [data-module-status] {
515
+ width: 100%;
516
+ overflow: hidden;
517
+ text-align: center;
518
+ text-overflow: ellipsis;
519
+ white-space: nowrap;
520
+ }
521
+ .pp-home-item [data-module-status] {
522
+ min-height: 20px;
523
+ }
524
+ .pp-home-item:disabled {
525
+ opacity: 0.45;
526
+ cursor: default;
527
+ }
528
+ .pp-home-entries[data-layout="list"] {
529
+ display: block;
530
+ padding: 0;
531
+ }
532
+ .pp-home-entries[data-layout="list"] .pp-home-item {
533
+ flex-direction: row;
534
+ gap: 12px;
535
+ width: 100%;
536
+ padding: 12px 16px;
537
+ font-size: 15px;
538
+ }
539
+ .pp-home-entries[data-layout="list"] .pp-home-item + .pp-home-item {
540
+ border-top: 1px solid var(--pp-border);
541
+ }
542
+ .pp-home-entries[data-layout="list"] .pp-home-icon {
543
+ flex: none;
544
+ width: 40px;
545
+ height: 40px;
546
+ padding: 4px;
547
+ font-size: 24px;
548
+ line-height: 32px;
549
+ }
550
+ .pp-home-entries[data-layout="list"] .pp-home-name {
551
+ margin-top: 0;
552
+ text-align: left;
553
+ }
554
+ .pp-home-arrow {
555
+ color: var(--pp-muted);
556
+ font-size: 24px;
557
+ }
558
+ .pp-home-footer {
559
+ margin-top: 16px;
560
+ text-align: center;
561
+ white-space: normal;
562
+ }
563
+ .pp-home-footer p {
564
+ margin: 8px 0 0;
565
+ }
package/src/index.d.ts CHANGED
@@ -123,6 +123,10 @@ export interface SettingsResponse {
123
123
  * Fields, storage root and optional display metadata belonging to one module.
124
124
  */
125
125
  export interface ModuleDefinition {
126
+ /** 页面重置的完整设置路径,默认删除当前模块数据 / Complete setting paths reset by the page; defaults to deleting this module's data. */
127
+ resetPaths?: string[];
128
+ /** 同一存储根中的完整缓存路径,默认当前模块 Caches / Complete cache path in the same storage root, defaulting to this module's Caches. */
129
+ cachePath?: string;
126
130
  /**
127
131
  * 字段 ID 的模块段,不能由 app 名称推断
128
132
  * Module segment from field IDs, never inferred from app names.
@@ -246,6 +250,10 @@ export interface BoxJSSetting {
246
250
  * A BoxJS application.
247
251
  */
248
252
  export interface BoxJSApp extends BoxJSMetadata {
253
+ /** 共享模块存储时,限定本页面可重置的设置路径 / Limit reset paths when multiple pages share module storage. */
254
+ resetPaths?: string[];
255
+ /** 可选共享缓存路径,例如 @Root.Composite.Caches / Optional shared cache path, such as @Root.Composite.Caches. */
256
+ cachePath?: string;
249
257
  /**
250
258
  * 应用设置
251
259
  * Application settings.
@@ -1,16 +0,0 @@
1
- <!doctype html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover">
6
- <meta name="color-scheme" content="light dark">
7
-
8
- <title>Module Preferences</title>
9
- <style>body { margin: 0; }</style>
10
-
11
- </head>
12
- <body>
13
- <main id="preferences"></main>
14
- <script type="module" src="/settings/assets/index.mjs?v=1.2.5"></script>
15
- </body>
16
- </html>