@ash-qw/dsh-theme-prts 1.1.0 → 1.1.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.
- package/CHANGELOG.md +11 -10
- package/THIRD_PARTY_NOTICES.md +4 -2
- package/THIRD_PARTY_NOTICES.zh-CN.md +4 -2
- package/lib/client.js +20 -89
- package/package.json +1 -1
- package/src/assets/cursors/animation.json +56 -0
- package/src/assets/cursors/prts-grab.png +0 -0
- package/src/assets/cursors/prts-grabbing.png +0 -0
- package/src/assets/cursors/prts-not-allowed.png +0 -0
- package/src/client/cursor-adapter.js +2 -2
- package/src/client/operations-shell-v2.js +0 -8
- package/src/client/theme-settings-workbench.js +18 -15
- package/src/styles/cursor.css +7 -1
- package/src/styles/prts.css +0 -8
- package/src/styles/refinement.css +2 -2
- package/src/styles/theme-settings-workbench.css +14 -34
- package/src/client/resize-shield-adapter.js +0 -69
package/package.json
CHANGED
|
@@ -506,5 +506,61 @@
|
|
|
506
506
|
"duration": 60000.0
|
|
507
507
|
}
|
|
508
508
|
]
|
|
509
|
+
},
|
|
510
|
+
"states": {
|
|
511
|
+
"grab": {
|
|
512
|
+
"file": "prts-grab.png",
|
|
513
|
+
"source": "PRTS-Replica-v8-96x-grab_enter_0011.cur",
|
|
514
|
+
"crop": [
|
|
515
|
+
18,
|
|
516
|
+
40,
|
|
517
|
+
86,
|
|
518
|
+
96
|
|
519
|
+
],
|
|
520
|
+
"size": [
|
|
521
|
+
45,
|
|
522
|
+
37
|
|
523
|
+
],
|
|
524
|
+
"hotspot": [
|
|
525
|
+
22,
|
|
526
|
+
19
|
|
527
|
+
]
|
|
528
|
+
},
|
|
529
|
+
"grabbing": {
|
|
530
|
+
"file": "prts-grabbing.png",
|
|
531
|
+
"source": "PRTS-Replica-v8-96x-grab_loop_0000.cur",
|
|
532
|
+
"crop": [
|
|
533
|
+
18,
|
|
534
|
+
40,
|
|
535
|
+
86,
|
|
536
|
+
96
|
|
537
|
+
],
|
|
538
|
+
"size": [
|
|
539
|
+
45,
|
|
540
|
+
37
|
|
541
|
+
],
|
|
542
|
+
"hotspot": [
|
|
543
|
+
22,
|
|
544
|
+
19
|
|
545
|
+
]
|
|
546
|
+
},
|
|
547
|
+
"not-allowed": {
|
|
548
|
+
"file": "prts-not-allowed.png",
|
|
549
|
+
"source": "PRTS-Replica-v8-96x-unavail1_static.cur",
|
|
550
|
+
"crop": [
|
|
551
|
+
18,
|
|
552
|
+
10,
|
|
553
|
+
96,
|
|
554
|
+
96
|
|
555
|
+
],
|
|
556
|
+
"size": [
|
|
557
|
+
51,
|
|
558
|
+
56
|
|
559
|
+
],
|
|
560
|
+
"hotspot": [
|
|
561
|
+
7,
|
|
562
|
+
7
|
|
563
|
+
]
|
|
564
|
+
}
|
|
509
565
|
}
|
|
510
566
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -107,7 +107,7 @@ export function createCursorAdapter({ document, window, assets }) {
|
|
|
107
107
|
restoreHandTarget()
|
|
108
108
|
if (!canAnimate(target) || !handCursor || target === textTarget) return
|
|
109
109
|
const cursor = window.getComputedStyle(target).cursor
|
|
110
|
-
if (!cursor.includes('data:image/png') || /(?:,\s*text|resize)$/.test(cursor)) return
|
|
110
|
+
if (!cursor.includes('data:image/png') || /(?:,\s*(?:text|grab|grabbing|not-allowed|no-drop)|resize)$/.test(cursor)) return
|
|
111
111
|
handTarget = target
|
|
112
112
|
originalCursor = target.style.getPropertyValue('cursor')
|
|
113
113
|
originalPriority = target.style.getPropertyPriority('cursor')
|
|
@@ -160,7 +160,7 @@ export function createCursorAdapter({ document, window, assets }) {
|
|
|
160
160
|
reset()
|
|
161
161
|
const cursor = target ? window.getComputedStyle(target).cursor : ''
|
|
162
162
|
if (!cursor.includes('data:image/png')) return
|
|
163
|
-
if (/(?:,\s*text|resize)$/.test(cursor) || !canAnimate(target)) return
|
|
163
|
+
if (/(?:,\s*(?:text|grab|grabbing|not-allowed|no-drop)|resize)$/.test(cursor) || !canAnimate(target)) return
|
|
164
164
|
gestureAssets = /,\s*pointer$/.test(cursor) && assets.link ? assets.link : assets
|
|
165
165
|
pointerId = event.pointerId
|
|
166
166
|
handCursor = cursor
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { createThemeSettingsOverlay, themeSettingsMarkup } from './theme-settings-workbench.js'
|
|
2
|
-
import { createResizeShieldAdapter } from './resize-shield-adapter.js'
|
|
3
2
|
|
|
4
3
|
const PHONE_RAIL_BREAKPOINT = 640
|
|
5
4
|
const RAIL_HOLD_DELAY_MS = 350
|
|
@@ -53,7 +52,6 @@ export function createOperationsShell({
|
|
|
53
52
|
onRetrySave = () => {},
|
|
54
53
|
}) {
|
|
55
54
|
const root = document.documentElement
|
|
56
|
-
const resizeShield = createResizeShieldAdapter({ window })
|
|
57
55
|
let shell
|
|
58
56
|
let navRail
|
|
59
57
|
let railLauncher
|
|
@@ -463,11 +461,6 @@ export function createOperationsShell({
|
|
|
463
461
|
onResetVisual: onVisualReset,
|
|
464
462
|
onRetrySave,
|
|
465
463
|
})
|
|
466
|
-
resizeShield.start([
|
|
467
|
-
operationRegion,
|
|
468
|
-
shell.querySelector('[data-prts-theme-settings]'),
|
|
469
|
-
shell.querySelector('[data-prts-settings-backdrop]'),
|
|
470
|
-
])
|
|
471
464
|
conversationObserver = new window.MutationObserver(syncConversationState)
|
|
472
465
|
conversationObserver.observe(operationRegion, { childList: true, subtree: true, attributes: true, attributeFilter: ['hidden', 'data-chat-flow-kind', 'data-message-role'] })
|
|
473
466
|
schemeObserver = new window.MutationObserver(syncSchemeToggle)
|
|
@@ -520,7 +513,6 @@ export function createOperationsShell({
|
|
|
520
513
|
railViewportQuery = undefined
|
|
521
514
|
railPointerQuery = undefined
|
|
522
515
|
railHoverQuery = undefined
|
|
523
|
-
resizeShield.dispose()
|
|
524
516
|
settingsOverlay?.dispose()
|
|
525
517
|
conversationObserver?.disconnect()
|
|
526
518
|
schemeObserver?.disconnect()
|
|
@@ -121,12 +121,29 @@ export function themeSettingsMarkup() {
|
|
|
121
121
|
</header>
|
|
122
122
|
|
|
123
123
|
<div data-prts-settings-body>
|
|
124
|
+
<div data-prts-settings-sidebar>
|
|
124
125
|
<nav data-prts-settings-nav role="tablist" aria-label="设置分区">
|
|
125
126
|
<button type="button" data-prts-settings-jump="appearance" role="tab" id="prts-tab-appearance" aria-controls="prts-page-appearance" aria-selected="true" tabindex="0">外观</button>
|
|
126
127
|
<button type="button" data-prts-settings-jump="interaction" role="tab" id="prts-tab-interaction" aria-controls="prts-page-interaction" aria-selected="false" tabindex="-1">交互</button>
|
|
127
128
|
<button type="button" data-prts-settings-jump="flow" role="tab" id="prts-tab-flow" aria-controls="prts-page-flow" aria-selected="false" tabindex="-1">会话流线</button>
|
|
128
129
|
<button type="button" data-prts-settings-jump="particles" role="tab" id="prts-tab-particles" aria-controls="prts-page-particles" aria-selected="false" tabindex="-1">粒子效果</button>
|
|
129
130
|
</nav>
|
|
131
|
+
<footer data-prts-settings-actions aria-label="全局主题设置操作">
|
|
132
|
+
<div data-prts-persistence-error hidden role="alert">
|
|
133
|
+
<span><strong>仅本次会话生效</strong><small>无法写入本地设置,当前视觉效果仍会保留。</small></span>
|
|
134
|
+
<button type="button" data-prts-retry-save>重试保存</button>
|
|
135
|
+
</div>
|
|
136
|
+
<div data-prts-reset-zone>
|
|
137
|
+
|
|
138
|
+
<button type="button" data-prts-reset-visual title="恢复全部外观设置" aria-label="恢复全部外观设置">恢复默认</button>
|
|
139
|
+
<div data-prts-reset-confirm hidden role="group" aria-label="确认恢复全部外观设置">
|
|
140
|
+
<span>重置四个分类的外观参数,保留主题开关、启动动画和徽记配置。</span>
|
|
141
|
+
<button type="button" data-prts-reset-confirm-action>确认恢复</button>
|
|
142
|
+
<button type="button" data-prts-reset-cancel>取消</button>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</footer>
|
|
146
|
+
</div>
|
|
130
147
|
<div data-prts-theme-settings-scroll>
|
|
131
148
|
<section data-prts-settings-section="appearance" role="tabpanel" id="prts-page-appearance" aria-labelledby="prts-tab-appearance" tabindex="0">
|
|
132
149
|
<header data-prts-section-heading><strong>外观</strong><small>预设、界面材质与会话样式</small></header>
|
|
@@ -178,23 +195,9 @@ export function themeSettingsMarkup() {
|
|
|
178
195
|
</div>
|
|
179
196
|
</section>
|
|
180
197
|
|
|
181
|
-
<footer data-prts-settings-actions>
|
|
182
|
-
<div data-prts-persistence-error hidden role="alert">
|
|
183
|
-
<span><strong>仅本次会话生效</strong><small>无法写入本地设置,当前视觉效果仍会保留。</small></span>
|
|
184
|
-
<button type="button" data-prts-retry-save>重试保存</button>
|
|
185
|
-
</div>
|
|
186
|
-
<div data-prts-reset-zone>
|
|
187
|
-
<span><strong>恢复主题默认</strong><small>保留主题开关和启动动画设置</small></span>
|
|
188
|
-
<button type="button" data-prts-reset-visual>恢复默认</button>
|
|
189
|
-
<div data-prts-reset-confirm hidden role="group" aria-label="确认恢复主题默认">
|
|
190
|
-
<span>确认恢复全部主题参数?</span>
|
|
191
|
-
<button type="button" data-prts-reset-confirm-action>确认恢复</button>
|
|
192
|
-
<button type="button" data-prts-reset-cancel>取消</button>
|
|
193
|
-
</div>
|
|
194
|
-
</div>
|
|
195
|
-
</footer>
|
|
196
198
|
</div>
|
|
197
199
|
</div>
|
|
200
|
+
|
|
198
201
|
</div>
|
|
199
202
|
</dialog>`
|
|
200
203
|
}
|
package/src/styles/cursor.css
CHANGED
|
@@ -15,7 +15,13 @@
|
|
|
15
15
|
html[data-dsh-prts][data-prts-cursor="prts"] :is(textarea, input:not([type]), input[type="text"], input[type="search"], input[type="email"], input[type="url"], input[type="password"], input[type="number"], input[type="tel"], [contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]) {
|
|
16
16
|
cursor: var(--prts-text-cursor), text;
|
|
17
17
|
}
|
|
18
|
+
html[data-dsh-prts][data-prts-cursor="prts"] :is(.dsh-partner-pendant-hit, .dsh-partner-pendant-anchor, [data-prts-emblem-reorder]):enabled {
|
|
19
|
+
cursor: url("__PRTS_GRAB__") 22 19, grab;
|
|
20
|
+
}
|
|
21
|
+
html[data-dsh-prts][data-prts-cursor="prts"] :is(.dsh-partner-pendant-hit, .dsh-partner-pendant-anchor, [data-prts-emblem-reorder]):enabled:active {
|
|
22
|
+
cursor: url("__PRTS_GRABBING__") 22 19, grabbing;
|
|
23
|
+
}
|
|
18
24
|
html[data-dsh-prts][data-prts-cursor="prts"] :is(:disabled, [aria-disabled="true"]) {
|
|
19
|
-
cursor: not-allowed !important;
|
|
25
|
+
cursor: url("__PRTS_NOT_ALLOWED__") 7 7, not-allowed !important;
|
|
20
26
|
}
|
|
21
27
|
}
|
package/src/styles/prts.css
CHANGED
|
@@ -1461,14 +1461,6 @@ html[data-dsh-prts] [data-prts-particle-layer] {
|
|
|
1461
1461
|
transition: opacity 120ms ease-out;
|
|
1462
1462
|
}
|
|
1463
1463
|
|
|
1464
|
-
/* Keep the host frame measurable while pruning the expensive operation subtree
|
|
1465
|
-
during a viewport resize burst. Navigation and the native sessions sidebar
|
|
1466
|
-
remain rendered; the shield is removed after the viewport settles. */
|
|
1467
|
-
html[data-dsh-prts] [data-prts-resize-shield] {
|
|
1468
|
-
content-visibility: hidden !important;
|
|
1469
|
-
contain-intrinsic-size: auto 800px;
|
|
1470
|
-
}
|
|
1471
|
-
|
|
1472
1464
|
/* Resize state lives on the small visual surfaces that need it, never on the root tree. */
|
|
1473
1465
|
html[data-dsh-prts] [data-prts-particle-layer][data-prts-resizing] {
|
|
1474
1466
|
opacity: .78;
|
|
@@ -203,8 +203,8 @@ html[data-dsh-prts] [data-prts-composer-fallback]::after {
|
|
|
203
203
|
calc(100% - 2px) 0, 100% 2px, 100% calc(100% - 2px), calc(100% - 2px) 100%,
|
|
204
204
|
2px 100%, 0 calc(100% - 2px), 0 2px
|
|
205
205
|
);
|
|
206
|
-
backdrop-filter:
|
|
207
|
-
-webkit-backdrop-filter:
|
|
206
|
+
backdrop-filter: none;
|
|
207
|
+
-webkit-backdrop-filter: none;
|
|
208
208
|
pointer-events: none;
|
|
209
209
|
}
|
|
210
210
|
|
|
@@ -544,39 +544,6 @@ html[data-dsh-prts] [data-prts-setting-range-row] input[type="range"] {
|
|
|
544
544
|
flex: 1;
|
|
545
545
|
}
|
|
546
546
|
html[data-dsh-prts] [data-prts-setting-range] { accent-color: var(--prts-cyan); }
|
|
547
|
-
html[data-dsh-prts] [data-prts-settings-actions] {
|
|
548
|
-
min-height: 58px;
|
|
549
|
-
display: block;
|
|
550
|
-
padding: 0;
|
|
551
|
-
border-bottom: 1px solid var(--prts-line-strong);
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
html[data-dsh-prts] [data-prts-persistence-error],
|
|
555
|
-
html[data-dsh-prts] [data-prts-reset-zone] {
|
|
556
|
-
min-height: 58px;
|
|
557
|
-
display: flex;
|
|
558
|
-
align-items: center;
|
|
559
|
-
justify-content: space-between;
|
|
560
|
-
gap: 12px;
|
|
561
|
-
padding: 9px 11px;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
html[data-dsh-prts] [data-prts-persistence-error] { border-bottom: 1px solid var(--prts-yellow); background: color-mix(in srgb, var(--prts-yellow) 7%, transparent); }
|
|
565
|
-
html[data-dsh-prts] [data-prts-persistence-error] > span,
|
|
566
|
-
html[data-dsh-prts] [data-prts-reset-zone] > span { display: grid; gap: 4px; }
|
|
567
|
-
html[data-dsh-prts] [data-prts-persistence-error] strong { color: var(--prts-yellow); }
|
|
568
|
-
html[data-dsh-prts] [data-prts-reset-visual],
|
|
569
|
-
html[data-dsh-prts] [data-prts-reset-confirm-action] { color: var(--prts-yellow); box-shadow: inset 0 0 0 1px var(--prts-yellow); }
|
|
570
|
-
|
|
571
|
-
html[data-dsh-prts] [data-prts-reset-confirm] {
|
|
572
|
-
display: flex;
|
|
573
|
-
align-items: center;
|
|
574
|
-
justify-content: flex-end;
|
|
575
|
-
gap: 5px;
|
|
576
|
-
color: var(--prts-yellow);
|
|
577
|
-
font: 700 8px/1.3 var(--prts-mono);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
547
|
html[data-dsh-prts] [hidden] { display: none !important; }
|
|
581
548
|
|
|
582
549
|
/* Readable settings typography: information never drops below 12px. */
|
|
@@ -863,7 +830,20 @@ html[data-dsh-prts] [data-prts-theme-settings] {
|
|
|
863
830
|
& [data-prts-settings-advanced-content] { border: 0; }
|
|
864
831
|
& [data-prts-settings-advanced-content] > section { padding: 0 0 20px; }
|
|
865
832
|
& :is([data-prts-advanced-summary], [data-prts-session-flow-speed-output], [data-prts-particle-traversal-output]) { color: var(--prts-muted); font-size: 12px; font-weight: 400; }
|
|
866
|
-
& [data-prts-settings-
|
|
833
|
+
& [data-prts-settings-sidebar] { display:flex; flex-direction:column; min-height:0; position:relative; border-right:1px solid var(--prts-line); }
|
|
834
|
+
& [data-prts-settings-nav] { border:0; background:none; }
|
|
835
|
+
& [data-prts-settings-actions] { margin:auto 0 0; padding:14px; border:0; min-height:0; }
|
|
836
|
+
& [data-prts-reset-zone] { min-height:0; }
|
|
837
|
+
& [data-prts-reset-visual] { color:var(--prts-muted); box-shadow:none; background:none; font-size:12px; }
|
|
838
|
+
& [data-prts-reset-confirm], & [data-prts-persistence-error] { display:flex; gap:8px; align-items:center; position:absolute; left:12px; bottom:52px; width:270px; padding:16px; border:1px solid var(--prts-line); border-radius:6px; background:var(--prts-panel-raised); box-shadow:0 8px 24px #0004; z-index:5; flex-wrap:wrap; font:400 12px/1.6 var(--prts-body); }
|
|
839
|
+
& [data-prts-reset-confirm] > span { flex-basis:100%; }
|
|
840
|
+
@media(max-width:720px) {
|
|
841
|
+
& [data-prts-settings-sidebar] { flex-direction:row; border:0; border-bottom:1px solid var(--prts-line); }
|
|
842
|
+
& [data-prts-settings-nav] { flex:1; padding:8px 4px; border:0; }
|
|
843
|
+
& [data-prts-settings-jump] { padding:10px 8px; }
|
|
844
|
+
& [data-prts-settings-actions] { margin:0; padding:8px 4px; align-self:center; }
|
|
845
|
+
& [data-prts-reset-confirm], & [data-prts-persistence-error] { left:auto; right:8px; top:100%; bottom:auto; max-width:calc(100vw - 32px); }
|
|
846
|
+
}
|
|
867
847
|
& [data-prts-reset-zone] { padding: 0; }
|
|
868
848
|
}
|
|
869
849
|
@media (max-width: 720px) {
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
const RESIZE_SHIELD_ATTRIBUTE = 'data-prts-resize-shield'
|
|
2
|
-
const DEFAULT_SETTLE_DELAY = 180
|
|
3
|
-
|
|
4
|
-
export function createResizeShieldAdapter({
|
|
5
|
-
window,
|
|
6
|
-
settleDelay = DEFAULT_SETTLE_DELAY,
|
|
7
|
-
} = {}) {
|
|
8
|
-
let targets = []
|
|
9
|
-
let settleTimer
|
|
10
|
-
let started = false
|
|
11
|
-
|
|
12
|
-
function setActive(active) {
|
|
13
|
-
for (const node of targets) {
|
|
14
|
-
if (!node || node.hasAttribute?.(RESIZE_SHIELD_ATTRIBUTE) === active) continue
|
|
15
|
-
node.toggleAttribute?.(RESIZE_SHIELD_ATTRIBUTE, active)
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function clearTimer() {
|
|
20
|
-
if (settleTimer === undefined) return
|
|
21
|
-
window?.clearTimeout?.(settleTimer)
|
|
22
|
-
settleTimer = undefined
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function settle() {
|
|
26
|
-
settleTimer = undefined
|
|
27
|
-
setActive(false)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function onResize() {
|
|
31
|
-
if (!started) return
|
|
32
|
-
if (Number(window?.innerWidth) <= 640) {
|
|
33
|
-
clearTimer()
|
|
34
|
-
setActive(false)
|
|
35
|
-
return
|
|
36
|
-
}
|
|
37
|
-
setActive(true)
|
|
38
|
-
clearTimer()
|
|
39
|
-
settleTimer = window?.setTimeout?.(settle, settleDelay)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function dispose() {
|
|
43
|
-
clearTimer()
|
|
44
|
-
window?.removeEventListener?.('resize', onResize)
|
|
45
|
-
setActive(false)
|
|
46
|
-
targets = []
|
|
47
|
-
started = false
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
start(nextTargets = []) {
|
|
52
|
-
const resolved = [...new Set(nextTargets)].filter(Boolean)
|
|
53
|
-
if (!window || !resolved.length) {
|
|
54
|
-
dispose()
|
|
55
|
-
return false
|
|
56
|
-
}
|
|
57
|
-
if (started) {
|
|
58
|
-
clearTimer()
|
|
59
|
-
setActive(false)
|
|
60
|
-
window.removeEventListener?.('resize', onResize)
|
|
61
|
-
}
|
|
62
|
-
targets = resolved
|
|
63
|
-
started = true
|
|
64
|
-
window.addEventListener?.('resize', onResize, { passive: true })
|
|
65
|
-
return true
|
|
66
|
-
},
|
|
67
|
-
dispose,
|
|
68
|
-
}
|
|
69
|
-
}
|