dsh-theme-palette 1.5.1 → 1.5.3
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 +26 -0
- package/client.js +63 -28
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,32 @@
|
|
|
13
13
|
复核宿主源码发现它带 `includePrerelease`,结论相反。现在这条判断固化进脚本,不再靠手算
|
|
14
14
|
- 该改动只影响本地发版工具,**不进 npm 包**(`files` 不含 `tools/`),故不升版本号
|
|
15
15
|
|
|
16
|
+
### 1.5.3
|
|
17
|
+
修:选中「自定义」后滚动条不跟随取色。
|
|
18
|
+
|
|
19
|
+
- **根因**:`scrollbarTokens()` 收到的是 `SCHEMES` 里的**占位** scheme 对象
|
|
20
|
+
(`accentHue` 恒为 60),而真正按三色派生出的参数只在 `rampsFor()` 内部解引用。
|
|
21
|
+
于是画布/强调色都对,唯独滚动条永远停在暖橙。
|
|
22
|
+
- **修法**:`buildTokens()` 开头统一解引用一次(`params = scheme.custom ? customScheme(readCustom()) : scheme`),
|
|
23
|
+
之后所有读 `scheme.*` 的地方改用 `params`;`scrollbarTokens(ramps, params, mode)` 也改传解析后的对象。
|
|
24
|
+
- **防复发**:新增 `tools/check-custom.mjs` —— 断言三种强调色必须产出三种滚动条颜色,
|
|
25
|
+
且三组自选色的正文/次文/三级对比度仍在限内(现在输出
|
|
26
|
+
`#2f6fd0→#bfd6f9 #a9683e→#f2cbb3 #4f7a42→#c2ddbb`)。
|
|
27
|
+
- 顺带:`tools/preview-settings.mjs` 支持 `PREVIEW_ACCENT`,可预览任意强调色的自定义面板。
|
|
28
|
+
|
|
29
|
+
### 1.5.2
|
|
30
|
+
设置页交互重排(用户反馈:自定义不该埋在「更多选项」里、取色看不到即时效果):
|
|
31
|
+
|
|
32
|
+
- **自定义配色提为一级区块**:选中「自定义」卡片后,面板直接出现在卡片网格下方,
|
|
33
|
+
不再需要展开「更多选项」
|
|
34
|
+
- **取色实时生效**:同时接 `onInput`(拖动过程中)与 `onChange`(确认后),
|
|
35
|
+
一次 `buildTokens` 实测 **0.15 ms**,整页配色随取色实时变化,不需要"确认"动作
|
|
36
|
+
- **色块放大**:`input[type=color]` 变成 44px 高的圆角色块(隐藏原生 swatch 边框),
|
|
37
|
+
下方显示字段名与十六进制值;三个色块一排,窄屏自动堆叠
|
|
38
|
+
- **恢复默认**:面板右上角一键回到出厂三色
|
|
39
|
+
- 修:预览渲染器不输出 `value`/`placeholder`/`readonly`,导致静态预览里色块是黑的、
|
|
40
|
+
导出码框是空的(真实应用不受影响)
|
|
41
|
+
|
|
16
42
|
### 1.5.1
|
|
17
43
|
- `dsh.compatibility.profiles` 补 `web`:在 web profile 上实测 5 张卡片(含「自定义」)正常显示,
|
|
18
44
|
与 desktop 一致;`dshOperations` 的 install/start 保持 `passed`,uninstall/rollback 仍如实 `unknown`
|
package/client.js
CHANGED
|
@@ -27,7 +27,7 @@ window.__ModuleLoader__.load({
|
|
|
27
27
|
const React = require('react')
|
|
28
28
|
const h = React.createElement
|
|
29
29
|
|
|
30
|
-
const PLUGIN_VERSION = '1.5.
|
|
30
|
+
const PLUGIN_VERSION = '1.5.3'
|
|
31
31
|
const STORE_KEY = 'dsh-theme-palette.v1'
|
|
32
32
|
const OVERRIDE_SOURCE = 'dsh-theme-palette'
|
|
33
33
|
|
|
@@ -703,9 +703,12 @@ window.__ModuleLoader__.load({
|
|
|
703
703
|
|
|
704
704
|
function buildTokens(scheme, sidebarMode, textMode, rightbarMode, scrollMode, controlMode, mdMode, hcMode) {
|
|
705
705
|
const hc = hcMode === true
|
|
706
|
-
|
|
706
|
+
// 自定义配色必须先解引用:ramps 内部会派生参数,但 accent / scroll / control
|
|
707
|
+
// 这些直接读 params.accentHue、params.hue 的地方若拿到占位值,就会"不跟取色"
|
|
708
|
+
const params = scheme && scheme.custom === true ? customScheme(readCustom()) : scheme
|
|
709
|
+
const ramps = rampsFor(params, textMode || DEFAULT_TEXT, hc)
|
|
707
710
|
const pairs = {}
|
|
708
|
-
if (!
|
|
711
|
+
if (!params.tinted) {
|
|
709
712
|
// 黑白:只输出「被求解改动过」的那几步 + 派生链接,不整条覆盖(保持宿主原貌)
|
|
710
713
|
for (const step of ['400', '600', '700', '1000']) {
|
|
711
714
|
pairs['--dsw-static-neutral-bluish-' + step] = { light: ramps.bluish[step], dark: ramps.bluish[step] }
|
|
@@ -719,7 +722,7 @@ window.__ModuleLoader__.load({
|
|
|
719
722
|
pairs['--dsw-alias-button-primary-fill'] = { light: monoBtn, dark: ramps.bluish['1000'] }
|
|
720
723
|
}
|
|
721
724
|
// 其它配色:整条色阶 + 字面量别名覆盖。
|
|
722
|
-
if (
|
|
725
|
+
if (params.tinted) {
|
|
723
726
|
for (const [family, table] of Object.entries(ramps)) {
|
|
724
727
|
for (const [step, value] of Object.entries(table)) {
|
|
725
728
|
pairs['--dsw-static-' + (family === 'bluish' ? 'neutral-bluish-' : family + '-') + step] = {
|
|
@@ -731,13 +734,13 @@ window.__ModuleLoader__.load({
|
|
|
731
734
|
const aliases = aliasOverrides(ramps, hc)
|
|
732
735
|
for (const [name, pair] of Object.entries(aliases)) pairs[name] = pair
|
|
733
736
|
}
|
|
734
|
-
const sidebar = sidebarTokens(ramps, sidebarMode,
|
|
737
|
+
const sidebar = sidebarTokens(ramps, sidebarMode, params.tinted)
|
|
735
738
|
for (const [name, pair] of Object.entries(sidebar)) pairs[name] = pair
|
|
736
739
|
// 右栏底色只给一个间接层:同左栏时直接引用左栏 token,跟随画布时引用画布 token。
|
|
737
740
|
// 主按钮:浅色下宿主把 button-primary-fill 指到 state-error-primary(红),
|
|
738
741
|
// 于是页面上有「红主按钮 + 强调色」两个主色。改成强调色,并压暗到按钮文字 ≥4.5。
|
|
739
742
|
// 黑白配色在上面已经单独设过,这里跳过(它要按「更浅」档的画布兜底)。
|
|
740
|
-
if (
|
|
743
|
+
if (params.tinted) {
|
|
741
744
|
pairs['--dsw-alias-button-primary-fill'] = {
|
|
742
745
|
light: darkenUntil(ramps.deepseek['500'], ramps.bluish['00'], 4.5),
|
|
743
746
|
dark: ramps.deepseek['400'],
|
|
@@ -756,7 +759,7 @@ window.__ModuleLoader__.load({
|
|
|
756
759
|
: 'var(--dsw-specific-sidebar-fill)'
|
|
757
760
|
pairs['--dshtp-rightbar-fill'] = { light: rightbarFill, dark: rightbarFill }
|
|
758
761
|
// Markdown 强调色:标题 = 正文色混 40% 强调色;加粗 = 混 20%(比标题弱一档)
|
|
759
|
-
if (
|
|
762
|
+
if (params.tinted) {
|
|
760
763
|
if (mdMode === 'off') {
|
|
761
764
|
const inherit = { light: 'inherit', dark: 'inherit' }
|
|
762
765
|
pairs['--dshtp-md-heading'] = inherit
|
|
@@ -790,7 +793,7 @@ window.__ModuleLoader__.load({
|
|
|
790
793
|
light: mixHex(ramps.deepseek['500'], ramps.bluish['50'], 0.05),
|
|
791
794
|
dark: mixHex(ramps.deepseek['400'], ramps.bluish['900'], 0.07),
|
|
792
795
|
}
|
|
793
|
-
const scroll = scrollbarTokens(ramps,
|
|
796
|
+
const scroll = scrollbarTokens(ramps, params, scrollMode)
|
|
794
797
|
for (const [name, pair] of Object.entries(scroll)) pairs[name] = pair
|
|
795
798
|
// 开关/勾选/单选的共用支点:brand-primary 本来是近黑/近白,改成强调色。
|
|
796
799
|
if (controlMode === 'accent') {
|
|
@@ -798,7 +801,7 @@ window.__ModuleLoader__.load({
|
|
|
798
801
|
}
|
|
799
802
|
// 黑白配色的浅色画布本身就是纯白,「更浅」无处可提 —— 改成把会话区压一档浅灰,
|
|
800
803
|
// 侧栏保持纯白,同样得到区块层次(这是唯一需要动画布的情形)。
|
|
801
|
-
if (!
|
|
804
|
+
if (!params.tinted && sidebarMode === 'light') {
|
|
802
805
|
pairs['--dsw-static-neutral-bluish-00'] = { light: '#fafafa', dark: BASE.bluish['00'] }
|
|
803
806
|
}
|
|
804
807
|
return pairs
|
|
@@ -903,7 +906,18 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
903
906
|
.dsh-tp-input::placeholder{color:var(--dsw-alias-label-tertiary)}
|
|
904
907
|
.dsh-tp-mini{font:inherit;font-size:12.5px;line-height:20px;padding:5px 12px;border-radius:8px;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);cursor:pointer}
|
|
905
908
|
.dsh-tp-mini:hover{background:var(--dsw-alias-bg-layer-1)}
|
|
906
|
-
.dsh-tp-
|
|
909
|
+
.dsh-tp-custom{display:flex;flex-direction:column;gap:10px;padding:12px;border-radius:14px;border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-interactive-bg-hover)}
|
|
910
|
+
.dsh-tp-custom-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
|
|
911
|
+
.dsh-tp-custom-head b{font-size:13.5px;font-weight:500}
|
|
912
|
+
.dsh-tp-swatches{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}
|
|
913
|
+
@media (max-width:520px){.dsh-tp-swatches{grid-template-columns:1fr}}
|
|
914
|
+
.dsh-tp-swatch{display:flex;flex-direction:column;gap:6px;cursor:pointer}
|
|
915
|
+
.dsh-tp-color{width:100%;height:44px;padding:0;border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;background:transparent;cursor:pointer}
|
|
916
|
+
.dsh-tp-color::-webkit-color-swatch-wrapper{padding:3px}
|
|
917
|
+
.dsh-tp-color::-webkit-color-swatch{border:none;border-radius:8px}
|
|
918
|
+
.dsh-tp-swatch-name{font-size:12px;color:var(--dsw-alias-label-secondary)}
|
|
919
|
+
.dsh-tp-hex{font:11.5px/1 ui-monospace,Consolas,monospace;color:var(--dsw-alias-label-tertiary)}
|
|
920
|
+
.dsh-tp-custom-hint{margin:0;font-size:11.5px;line-height:17px;color:var(--dsw-alias-label-tertiary)}
|
|
907
921
|
.dsh-tp-note{font-size:11.5px;color:var(--dsw-alias-label-tertiary)}
|
|
908
922
|
.dsh-tp-status{margin:0;font-size:11.5px;line-height:18px;color:var(--dsw-alias-label-tertiary)}
|
|
909
923
|
.dsh-tp-status.is-bad{color:var(--dsw-alias-state-error-primary)}
|
|
@@ -1190,6 +1204,7 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1190
1204
|
customHint: '取三个色的色相与色度;明度由引擎按明暗模式算,对比度仍由求解器兜底。',
|
|
1191
1205
|
config: '配置',
|
|
1192
1206
|
configHint: '导出这台机器的配色选择,或粘贴短码导入;导入会覆盖全部 8 项。',
|
|
1207
|
+
reset: '恢复默认',
|
|
1193
1208
|
copy: '复制',
|
|
1194
1209
|
applyImport: '导入',
|
|
1195
1210
|
copied: '已复制',
|
|
@@ -1233,6 +1248,7 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1233
1248
|
customHint: '取三個色的色相與色度;明度由引擎依明暗模式計算,對比度仍由求解器兜底。',
|
|
1234
1249
|
config: '設定',
|
|
1235
1250
|
configHint: '匯出這台機器的配色選擇,或貼上短碼匯入;匯入會覆蓋全部 8 項。',
|
|
1251
|
+
reset: '恢復預設',
|
|
1236
1252
|
copy: '複製',
|
|
1237
1253
|
applyImport: '匯入',
|
|
1238
1254
|
copied: '已複製',
|
|
@@ -1276,6 +1292,7 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1276
1292
|
customHint: 'Takes hue and chroma from three colours; lightness comes from the engine per mode and contrast is still solved.',
|
|
1277
1293
|
config: 'Config',
|
|
1278
1294
|
configHint: 'Export this machine’s choices, or paste a short code to import. Import overwrites all 8 settings.',
|
|
1295
|
+
reset: 'Reset',
|
|
1279
1296
|
copy: 'Copy',
|
|
1280
1297
|
applyImport: 'Import',
|
|
1281
1298
|
copied: 'Copied',
|
|
@@ -1319,6 +1336,7 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1319
1336
|
customHint: '3 色の色相と彩度だけを使います。明度はモードごとにエンジンが決め、コントラストは従来どおり求解します。',
|
|
1320
1337
|
config: '設定の共有',
|
|
1321
1338
|
configHint: 'この端末の配色設定を書き出す/短いコードを貼り付けて読み込みます(8 項目すべて上書き)。',
|
|
1339
|
+
reset: 'リセット',
|
|
1322
1340
|
copy: 'コピー',
|
|
1323
1341
|
applyImport: '読み込み',
|
|
1324
1342
|
copied: 'コピーしました',
|
|
@@ -1426,6 +1444,34 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1426
1444
|
control,
|
|
1427
1445
|
)
|
|
1428
1446
|
|
|
1447
|
+
const customColors = props.getCustomColors()
|
|
1448
|
+
const customPanel = current === 'custom' && h(
|
|
1449
|
+
'div',
|
|
1450
|
+
{ className: 'dsh-tp-custom' },
|
|
1451
|
+
h('div', { className: 'dsh-tp-custom-head' },
|
|
1452
|
+
h('b', null, txt.custom),
|
|
1453
|
+
h('button', {
|
|
1454
|
+
type: 'button',
|
|
1455
|
+
className: 'dsh-tp-mini',
|
|
1456
|
+
onClick: () => props.resetCustom(),
|
|
1457
|
+
}, txt.reset)),
|
|
1458
|
+
h('div', { className: 'dsh-tp-swatches' },
|
|
1459
|
+
['bg', 'text', 'accent'].map((field) => h('label', { key: field, className: 'dsh-tp-swatch' },
|
|
1460
|
+
h('input', {
|
|
1461
|
+
type: 'color',
|
|
1462
|
+
className: 'dsh-tp-color',
|
|
1463
|
+
value: customColors[field],
|
|
1464
|
+
// input 是"拖动过程中"就触发,change 是"确认后"触发;两个都接,
|
|
1465
|
+
// 拖动时实时看到整页变化,松手/确认后不会再跳一次
|
|
1466
|
+
onInput: (e) => props.setCustomColor(field, e.target.value),
|
|
1467
|
+
onChange: (e) => props.setCustomColor(field, e.target.value),
|
|
1468
|
+
'aria-label': (lb.custom && lb.custom[field]) || field,
|
|
1469
|
+
}),
|
|
1470
|
+
h('span', { className: 'dsh-tp-swatch-name' }, (lb.custom && lb.custom[field]) || field),
|
|
1471
|
+
h('code', { className: 'dsh-tp-hex' }, customColors[field])))),
|
|
1472
|
+
h('p', { className: 'dsh-tp-custom-hint' }, txt.customHint),
|
|
1473
|
+
)
|
|
1474
|
+
|
|
1429
1475
|
const card = (scheme) => {
|
|
1430
1476
|
const picked = scheme.id === current
|
|
1431
1477
|
const c = cardColors(scheme, textMode)
|
|
@@ -1462,6 +1508,7 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1462
1508
|
h('span', { className: 'dsh-tp-badge' }, 'v' + PLUGIN_VERSION)),
|
|
1463
1509
|
h('p', { className: 'dsh-tp-sub' }, txt.hint),
|
|
1464
1510
|
h('div', { className: 'dsh-tp-grid' }, SCHEMES.map(card)),
|
|
1511
|
+
customPanel,
|
|
1465
1512
|
row(txt.text, txt.textSub, seg(TEXT_MODES, textMode, props.setTextMode, lb.text)),
|
|
1466
1513
|
row(txt.sidebar, txt.sidebarSub, seg(SIDEBAR_MODES, sidebarMode, props.setSidebarMode, lb.sidebar)),
|
|
1467
1514
|
row(txt.rightbar, txt.rightbarSub, seg(RIGHTBAR_MODES, rightbarMode, props.setRightbarMode, lb.rightbar)),
|
|
@@ -1480,24 +1527,6 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1480
1527
|
advanced && h(
|
|
1481
1528
|
'div',
|
|
1482
1529
|
{ className: 'dsh-tp-adv' },
|
|
1483
|
-
current === 'custom' && h(
|
|
1484
|
-
'div',
|
|
1485
|
-
{ style: { display: 'flex', flexDirection: 'column', gap: 6 } },
|
|
1486
|
-
h('div', { style: { fontSize: 14, lineHeight: '22px' } }, txt.custom),
|
|
1487
|
-
h('div', { style: { display: 'flex', gap: 10, flexWrap: 'wrap', alignItems: 'center' } },
|
|
1488
|
-
['bg', 'text', 'accent'].map((field) => h('label', {
|
|
1489
|
-
key: field,
|
|
1490
|
-
style: { display: 'inline-flex', alignItems: 'center', gap: 6, fontSize: 12.5, color: 'var(--dsw-alias-label-secondary)' },
|
|
1491
|
-
},
|
|
1492
|
-
h('input', {
|
|
1493
|
-
type: 'color',
|
|
1494
|
-
className: 'dsh-tp-color',
|
|
1495
|
-
value: props.getCustomColors()[field],
|
|
1496
|
-
onChange: (e) => props.setCustomColor(field, e.target.value),
|
|
1497
|
-
}),
|
|
1498
|
-
(lb.custom && lb.custom[field]) || field))),
|
|
1499
|
-
h('p', { style: { margin: 0, fontSize: 12, lineHeight: '18px', color: 'var(--dsw-alias-label-tertiary)' } }, txt.customHint),
|
|
1500
|
-
),
|
|
1501
1530
|
row(txt.lang, txt.langSub, seg(LANG_OPTIONS, langPref, props.setLangPref, lb.lang)),
|
|
1502
1531
|
h(
|
|
1503
1532
|
'div',
|
|
@@ -1820,6 +1849,11 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1820
1849
|
return true
|
|
1821
1850
|
}
|
|
1822
1851
|
const getCustomColors = () => readCustom()
|
|
1852
|
+
const resetCustom = () => {
|
|
1853
|
+
writeCustom(Object.assign({}, CUSTOM_DEFAULT))
|
|
1854
|
+
applyAll('custom:reset')
|
|
1855
|
+
emit()
|
|
1856
|
+
}
|
|
1823
1857
|
const setCustomColor = (field, hex) => {
|
|
1824
1858
|
if (CUSTOM_FIELDS.indexOf(field) === -1) return
|
|
1825
1859
|
if (typeof hex !== 'string' || !HEX_RE.test(hex)) return
|
|
@@ -1962,6 +1996,7 @@ body[data-ds-dark-theme] .dsh-tp-check{background:var(--t-accent-d);color:var(--
|
|
|
1962
1996
|
applyConfigCode,
|
|
1963
1997
|
getCustomColors,
|
|
1964
1998
|
setCustomColor,
|
|
1999
|
+
resetCustom,
|
|
1965
2000
|
getLangPref,
|
|
1966
2001
|
getLocale,
|
|
1967
2002
|
subscribeLocale,
|