@ash-qw/dsh-theme-prts 2.5.3 → 2.5.5
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 +27 -0
- package/lib/client.js +238 -47
- package/package.json +1 -1
- package/src/client/background-layout.js +21 -7
- package/src/client/conversation-control-adapter.js +41 -11
- package/src/client/cursor-adapter.js +41 -9
- package/src/client/host-geometry-adapter.js +11 -5
- package/src/client/index.js +1 -0
- package/src/client/preferences.js +9 -1
- package/src/client/preview-markdown.js +5 -2
- package/src/client/session-summary-preview.js +49 -5
- package/src/client/sidebar-control-adapter.js +38 -1
- package/src/client/theme-controller-v2.js +1 -0
- package/src/client/theme-controller.js +1 -0
- package/src/client/theme-settings-workbench.js +9 -0
- package/src/client/theme-transfer-panel.js +2 -3
- package/src/styles/custom-background.css +2 -1
- package/src/styles/facility-vector.css +16 -4
- package/src/styles/prts.css +1 -1
- package/src/styles/refinement.css +1 -1
- package/src/styles/theme-settings-workbench.css +14 -1
- package/src/vendor/react-bits/GlassSurface.jsx +16 -2
|
@@ -171,6 +171,7 @@ export function themeSettingsMarkup() {
|
|
|
171
171
|
<section data-prts-settings-common data-prts-settings-section="interaction" role="tabpanel" id="prts-page-interaction" aria-labelledby="prts-tab-interaction" tabindex="0" hidden>
|
|
172
172
|
<div data-prts-settings-common-grid>
|
|
173
173
|
${COMMON_CONTROLS.filter(([key]) => ['cursor', 'railDefaultHidden', 'motion'].includes(key)).map(([key, label, options]) => settingButtons(key, label, options)).join('')}
|
|
174
|
+
<div data-prts-setting-row="cornerColor"><span><strong>交互提示框颜色</strong><small data-prts-setting-note>部分按钮和卡片的四角提示颜色,危险操作保持红色。</small></span><div data-prts-corner-presets role="group" aria-label="交互提示框预设颜色">${[['黄色','#f0c800'],['白色','#ffffff'],['青色','#65ddb0'],['蓝色','#6eb7f3'],['紫色','#b487ef']].map(([name,color]) => `<button type="button" data-prts-corner-preset="${color}" aria-label="${name}" title="${name}" aria-pressed="false" style="--swatch:${color}"><i aria-hidden="true"></i></button>`).join('')}<button type="button" data-prts-corner-custom title="选择自定义颜色"><i data-prts-corner-preview aria-hidden="true"></i><span>自定义</span></button><input type="color" data-prts-corner-color aria-label="交互提示框颜色" value="#f0c800" hidden></div></div>
|
|
174
175
|
</div>
|
|
175
176
|
</section>
|
|
176
177
|
<section data-prts-settings-section="ai-tools" data-prts-ai-tools role="tabpanel" id="prts-page-ai-tools" aria-labelledby="prts-tab-ai-tools" tabindex="0" hidden>
|
|
@@ -531,6 +532,10 @@ export function createThemeSettingsOverlay({
|
|
|
531
532
|
|
|
532
533
|
function renderState() {
|
|
533
534
|
if (!panel || !currentPreferences) return
|
|
535
|
+
const cornerColor = panel.querySelector('[data-prts-corner-color]')
|
|
536
|
+
if (cornerColor) cornerColor.value = currentPreferences.cornerCustomColor
|
|
537
|
+
panel.querySelector('[data-prts-corner-preview]')?.style.setProperty('--swatch', currentPreferences.cornerCustomColor)
|
|
538
|
+
for (const preset of panel.querySelectorAll('[data-prts-corner-preset]')) preset.setAttribute('aria-pressed', String(preset.dataset.prtsCornerPreset === currentPreferences.cornerColor))
|
|
534
539
|
for (const toggle of panel.querySelectorAll('[data-prts-setting-switch]')) {
|
|
535
540
|
const key = toggle.dataset.prtsSettingSwitch
|
|
536
541
|
const enabled = key === 'cursor' ? currentPreferences.cursor === 'prts'
|
|
@@ -625,6 +630,8 @@ export function createThemeSettingsOverlay({
|
|
|
625
630
|
if (event.target === panel) { setOpen(false); return }
|
|
626
631
|
const target = event.target?.closest?.('button')
|
|
627
632
|
if (!target) return
|
|
633
|
+
if (target.hasAttribute('data-prts-corner-custom')) { panel.querySelector('[data-prts-corner-color]').click(); return }
|
|
634
|
+
if (target.hasAttribute('data-prts-corner-preset')) { onPreferenceChange('cornerColor', target.dataset.prtsCornerPreset); return }
|
|
628
635
|
if (target.hasAttribute('data-prts-settings-jump')) {
|
|
629
636
|
selectSection(target.dataset.prtsSettingsJump)
|
|
630
637
|
return
|
|
@@ -663,6 +670,7 @@ export function createThemeSettingsOverlay({
|
|
|
663
670
|
|
|
664
671
|
function onPanelInput(event) {
|
|
665
672
|
const target = event.target
|
|
673
|
+
if (target?.matches?.('[data-prts-corner-color]')) { onPreferencePreview('cornerColor', target.value); return }
|
|
666
674
|
if (target?.matches?.('[data-prts-preview-reply-limit]')) { onPreferenceChange('previewReplyLimit', Number(target.value)); return }
|
|
667
675
|
if (target?.matches?.('input[data-prts-setting-color]')) {
|
|
668
676
|
const key = target.dataset.prtsSettingKey
|
|
@@ -725,6 +733,7 @@ export function createThemeSettingsOverlay({
|
|
|
725
733
|
const renderMediaState = () => renderState()
|
|
726
734
|
const commitFromControl = event => {
|
|
727
735
|
const target = event.target
|
|
736
|
+
if (target?.matches?.('[data-prts-corner-color]')) { if (event.type === 'change') onPreferenceChange('cornerCustomColor', target.value); return }
|
|
728
737
|
if (target?.matches?.('input[data-prts-setting-color]')) {
|
|
729
738
|
if (event.type === 'change' || event.type === 'focusout') commitSessionFlowColor(target.dataset.prtsSettingKey)
|
|
730
739
|
return
|
|
@@ -13,9 +13,8 @@ export function themeTransferMarkup() {
|
|
|
13
13
|
<button type="button" data-prts-transfer-export>导出主题文件 <span aria-hidden="true">↓</span></button>
|
|
14
14
|
</section>
|
|
15
15
|
<section data-prts-transfer-card="import" data-prts-transfer-drop>
|
|
16
|
-
<h3>导入主题</h3><p
|
|
17
|
-
<
|
|
18
|
-
<button type="button" data-prts-transfer-choose>选择主题文件 <span aria-hidden="true">↑</span></button>
|
|
16
|
+
<h3>导入主题</h3><p>导入已导出的主题文件,确认内容后应用。</p>
|
|
17
|
+
<button type="button" data-prts-transfer-file-hint data-prts-transfer-choose><span aria-hidden="true">↑</span><strong>点击选择或拖拽主题文件到此处</strong><small>.prts-theme.json · 最大 160 MB</small></button>
|
|
19
18
|
<input type="file" accept=".prts-theme.json,application/json" aria-label="导入主题文件" data-prts-transfer-file hidden>
|
|
20
19
|
</section>
|
|
21
20
|
</div>
|
|
@@ -5,9 +5,10 @@ background: linear-gradient(var(--prts-background-wash), var(--prts-background-w
|
|
|
5
5
|
}
|
|
6
6
|
html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] :is([data-prts-region="sessions"], [data-prts-region="operation"]) { background: transparent; }
|
|
7
7
|
html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] {
|
|
8
|
+
& :is([data-prts-region="sessions"],[data-prts-nav-rail]) {
|
|
8
9
|
--prts-wall-width:var(--prts-protected-sidebar-width,max(calc(var(--prts-sidebar-width,280px) + var(--prts-nav-width)),calc((100dvh - var(--prts-host-top-inset)) * var(--prts-sidebar-image-ratio,1))));
|
|
9
10
|
--prts-wall-x:var(--prts-protected-sidebar-x,calc((var(--prts-sidebar-width,280px) + var(--prts-nav-width) - var(--prts-wall-width)) / 2));
|
|
10
|
-
|
|
11
|
+
background:linear-gradient(var(--prts-background-wash),var(--prts-background-wash)),var(--prts-background-sidebar) var(--prts-wall-x) var(--prts-protected-sidebar-y, 50%) / var(--prts-wall-width) auto no-repeat}
|
|
11
12
|
& [data-prts-region="sessions"]{background-position:center,calc(var(--prts-wall-x) - var(--prts-nav-width)) var(--prts-protected-sidebar-y, 50%)}
|
|
12
13
|
}
|
|
13
14
|
html[data-dsh-prts][data-prts-rail-mode="overlay"]:is([data-prts-background-mode="split"][data-prts-background-sidebar],[data-prts-background-mode="full"][data-prts-background-full]) [data-prts-nav-rail] { background: transparent; }
|
|
@@ -48,7 +48,7 @@ html[data-dsh-prts] [data-prts-session-idle-indicator] {
|
|
|
48
48
|
fill: var(--prts-dim);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
html[data-dsh-prts] [data-prts-session-state] [data-prts-session-idle-indicator] {
|
|
51
|
+
html[data-dsh-prts] :is([data-prts-session-state], [data-prts-session-row]:has([data-session-schedule-mark])) [data-prts-session-idle-indicator] {
|
|
52
52
|
opacity: 0;
|
|
53
53
|
}
|
|
54
54
|
|
|
@@ -572,11 +572,11 @@ html[data-dsh-prts] [data-prts-session-pickup-bar]:nth-of-type(10) { --prts-pick
|
|
|
572
572
|
html[data-dsh-prts] [data-prts-session-pickup-bar]:nth-of-type(11) { --prts-pickup-duration: 560ms; --prts-pickup-delay: -.3s; }
|
|
573
573
|
|
|
574
574
|
@media (prefers-reduced-motion: no-preference) {
|
|
575
|
-
html[data-dsh-prts]:not([data-prts-motion="reduced"]) [data-prts-session-row]:hover [data-prts-session-pickup-indicator] {
|
|
575
|
+
html[data-dsh-prts]:not([data-prts-motion="reduced"]) [data-prts-session-row]:hover[data-prts-pickup-ready] [data-prts-session-pickup-indicator] {
|
|
576
576
|
animation: prts-session-record-indicator 1.1s ease-in-out infinite;
|
|
577
577
|
}
|
|
578
578
|
|
|
579
|
-
html[data-dsh-prts]:not([data-prts-motion="reduced"]) [data-prts-session-row]:hover [data-prts-session-pickup-bar] {
|
|
579
|
+
html[data-dsh-prts]:not([data-prts-motion="reduced"]) [data-prts-session-row]:hover[data-prts-pickup-ready] [data-prts-session-pickup-bar] {
|
|
580
580
|
animation: prts-session-pickup-sample var(--prts-pickup-duration) ease-in-out var(--prts-pickup-delay) infinite;
|
|
581
581
|
}
|
|
582
582
|
}
|
|
@@ -824,7 +824,7 @@ html[data-dsh-prts] [data-prts-session-summary-popover]:has(> [data-prts-preview
|
|
|
824
824
|
}
|
|
825
825
|
|
|
826
826
|
/* Keep different-sized state markers centered on the same axis. */
|
|
827
|
-
html[data-dsh-prts] [data-prts-session-row]
|
|
827
|
+
html[data-dsh-prts] [data-prts-session-row] :is([data-state="ongoing"], [data-state="done"], [data-state="warning"], [data-state="error"], [data-session-schedule-mark]) {
|
|
828
828
|
flex-shrink: 0;
|
|
829
829
|
margin-left: 20px;
|
|
830
830
|
}
|
|
@@ -886,3 +886,15 @@ html[data-dsh-prts] [data-prts-tool-record] > div { display:flex;align-items:bas
|
|
|
886
886
|
html[data-dsh-prts] [data-prts-tool-record] b { flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--prts-cyan);font:11px/1.6 var(--prts-mono); }
|
|
887
887
|
html[data-dsh-prts] [data-prts-tool-record] small { flex:none;color:var(--prts-muted);font-size:10px; }
|
|
888
888
|
html[data-dsh-prts] [data-prts-tool-record] p { display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;margin:4px 0 0; }
|
|
889
|
+
|
|
890
|
+
/* Show the baseline immediately; only start the pickup after a deliberate hover. */
|
|
891
|
+
html[data-dsh-prts] [data-prts-session-row]:not([data-prts-pickup-ready]) :is([data-prts-session-pickup-bar],[data-prts-session-pickup-indicator]) { visibility:hidden; }
|
|
892
|
+
|
|
893
|
+
html[data-dsh-prts] [data-prts-reply-entry][data-prts-reply-complete] { cursor:text; }
|
|
894
|
+
|
|
895
|
+
/* Reserve the cue's width so showing it never changes the truncation measurement. */
|
|
896
|
+
html[data-dsh-prts] [data-prts-reply-entry] > span { display:block;-webkit-line-clamp:unset;max-height:3.2em;color:#b8bec6; }
|
|
897
|
+
html[data-dsh-prts] [data-prts-reply-ellipsis] { flex:0 0 12px;align-self:flex-end;color:#f0e6d6;font:600 14px/1.4 var(--prts-body);visibility:hidden; }
|
|
898
|
+
html[data-dsh-prts] [data-prts-reply-overflow] > [data-prts-reply-ellipsis] { visibility:visible; }
|
|
899
|
+
|
|
900
|
+
html[data-dsh-prts] [data-prts-reply-overflow] > span { color:#f0e6d6; }
|
package/src/styles/prts.css
CHANGED
|
@@ -963,7 +963,7 @@ html[data-dsh-prts] [data-prts-row-title] {
|
|
|
963
963
|
white-space: nowrap;
|
|
964
964
|
}
|
|
965
965
|
|
|
966
|
-
html[data-dsh-prts] [data-prts-session-row] > span:has(> [data-state]) {
|
|
966
|
+
html[data-dsh-prts] [data-prts-session-row] > span:has(> :is([data-state], [data-session-schedule-mark])) {
|
|
967
967
|
padding-left: 0 !important;
|
|
968
968
|
}
|
|
969
969
|
|
|
@@ -508,7 +508,7 @@ html[data-dsh-prts] [data-turn-trigger] {
|
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
/* Body interactions lock onto four corners; shell controls keep their own treatment. */
|
|
511
|
-
html[data-dsh-prts] :is([data-chat-flow-kind],[data-message-role]) :is([data-prts-conversation-control],[data-presented-file],[data-changed-files],[data-produced-files-row] > button) {
|
|
511
|
+
html[data-dsh-prts] :is([data-chat-flow-kind],[data-message-role],[data-submission-echo],[data-pending-steering]) :is([data-prts-conversation-control],[data-presented-file],[data-changed-files],[data-produced-files-row] > button) {
|
|
512
512
|
position:relative;
|
|
513
513
|
--prts-control-outline:var(--prts-line);
|
|
514
514
|
&:is(:hover,:focus-visible,:focus-within) {
|
|
@@ -967,7 +967,8 @@ html[data-dsh-prts] [data-prts-transfer] {
|
|
|
967
967
|
& [data-prts-transfer-option] { align-items:flex-start; flex-wrap:nowrap; padding:12px 0 0; }
|
|
968
968
|
& [data-prts-transfer-option] input { margin:5px 0 0; }
|
|
969
969
|
& [data-prts-transfer-option] small { display:block; margin-top:4px; }
|
|
970
|
-
& [data-prts-transfer-file-hint] { display:
|
|
970
|
+
& [data-prts-transfer-card] > [data-prts-transfer-file-hint] { display:flex; flex-direction:column; justify-content:center; flex:1; gap:6px; min-height:130px; padding:16px 12px; border:1px dashed var(--prts-line-strong); text-align:center; white-space:normal; }
|
|
971
|
+
& [data-prts-transfer-file-hint] > strong { font-size:13px; font-weight:500; }
|
|
971
972
|
& [data-prts-transfer-file-hint] > span { font-size:24px; color:var(--prts-muted); }
|
|
972
973
|
& [data-prts-transfer-buttons] { display:flex; gap:8px; }
|
|
973
974
|
& [data-prts-transfer-compatibility] { margin:0; padding:10px 12px; border:1px solid var(--prts-yellow); overflow-wrap:anywhere; }
|
|
@@ -1032,3 +1033,15 @@ html[data-dsh-prts] [data-prts-transfer]:not([aria-busy="true"]) [data-prts-tran
|
|
|
1032
1033
|
}
|
|
1033
1034
|
html[data-prts-motion="reduced"] [data-prts-transfer-card] { transition:none; }
|
|
1034
1035
|
@media (prefers-reduced-motion:reduce) { [data-prts-transfer-card] { transition:none; } }
|
|
1036
|
+
|
|
1037
|
+
html[data-dsh-prts] [data-prts-setting-row="cornerColor"] { flex-wrap:wrap;gap:16px; }
|
|
1038
|
+
html[data-dsh-prts] [data-prts-corner-presets] { display:flex;flex-wrap:wrap;gap:6px;align-items:center;
|
|
1039
|
+
& > button { position:relative;display:grid;place-items:center;width:32px;height:32px;padding:5px;border:1px solid transparent;border-radius:4px;background:transparent; }
|
|
1040
|
+
& i { display:block;width:18px;height:18px;border-radius:3px;background:var(--swatch);box-shadow:inset 0 0 0 1px #8884; }
|
|
1041
|
+
& > button:hover { background:var(--prts-panel-raised); }
|
|
1042
|
+
& > button[aria-pressed="true"] { border-color:var(--prts-ink);background:var(--prts-panel-raised); }
|
|
1043
|
+
& > button[aria-pressed="true"]::after { content:"";position:absolute;width:8px;height:4px;border-left:2px solid #172025;border-bottom:2px solid #172025;transform:translateY(-1px) rotate(-45deg); }
|
|
1044
|
+
& > button:focus-visible { outline:2px solid var(--prts-ink);outline-offset:2px; }
|
|
1045
|
+
}
|
|
1046
|
+
html[data-dsh-prts] [data-prts-corner-presets] > [data-prts-corner-custom] { display:flex;align-items:center;gap:8px;width:auto;height:32px;margin-left:8px;padding:5px 10px;border:1px solid var(--prts-line-strong);border-radius:4px;background:var(--prts-panel-raised);color:var(--prts-ink);font:12px/1 var(--prts-body);white-space:nowrap; }
|
|
1047
|
+
html[data-dsh-prts] [data-prts-corner-presets] > [data-prts-corner-custom]:is(:hover,:focus-visible) { border-color:var(--prts-ink);background:color-mix(in srgb,var(--prts-ink) 8%,var(--prts-panel-raised)); }
|
|
@@ -407,14 +407,28 @@ const GlassSurface = ({
|
|
|
407
407
|
useEffect(() => {
|
|
408
408
|
if (!containerRef.current) return;
|
|
409
409
|
|
|
410
|
-
|
|
410
|
+
// PRTS: keep the existing map stretched with the live container while
|
|
411
|
+
// resizing. Rebuilding its distance field on every intermediate width
|
|
412
|
+
// defeats the outer composer's settled-shape update.
|
|
413
|
+
let timer;
|
|
414
|
+
let committed = '';
|
|
415
|
+
const commit = () => {
|
|
416
|
+
timer = undefined;
|
|
411
417
|
const element = containerRef.current;
|
|
412
|
-
if (element
|
|
418
|
+
if (!element || !element.offsetWidth || !element.offsetHeight) return;
|
|
419
|
+
const next = `${element.offsetWidth}x${element.offsetHeight}`;
|
|
420
|
+
if (next !== committed) { committed = next; setBoxSize(next); }
|
|
421
|
+
};
|
|
422
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
423
|
+
clearTimeout(timer);
|
|
424
|
+
if (!committed) commit();
|
|
425
|
+
else timer = setTimeout(commit, 160);
|
|
413
426
|
});
|
|
414
427
|
|
|
415
428
|
resizeObserver.observe(containerRef.current);
|
|
416
429
|
|
|
417
430
|
return () => {
|
|
431
|
+
clearTimeout(timer);
|
|
418
432
|
resizeObserver.disconnect();
|
|
419
433
|
};
|
|
420
434
|
}, []);
|