dsh-cool-theme 0.6.1 → 0.7.0
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 +3 -2
- package/README.zh.md +3 -2
- package/lib/client.js +713 -369
- package/lib/types/client/components.d.ts +3 -6
- package/lib/types/client/components.d.ts.map +1 -1
- package/lib/types/client/locales.d.ts +4 -0
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/theme.d.ts.map +1 -1
- package/lib/types/contract.d.ts +1 -0
- package/lib/types/contract.d.ts.map +1 -1
- package/package.json +2 -1
package/lib/client.js
CHANGED
|
@@ -28,6 +28,7 @@ window.__ModuleLoader__.load({
|
|
|
28
28
|
//#endregion
|
|
29
29
|
let react = require("react");
|
|
30
30
|
react = __toESM(react, 1);
|
|
31
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
31
32
|
//#region src/contract.ts
|
|
32
33
|
/**
|
|
33
34
|
* Shared contract for dsh-cool-theme.
|
|
@@ -39,6 +40,7 @@ window.__ModuleLoader__.load({
|
|
|
39
40
|
const CUSTOM_LIST_STORAGE_KEY = "cool-theme-custom-list";
|
|
40
41
|
const CUSTOM_ACTIVE_STORAGE_KEY = "cool-theme-custom-active";
|
|
41
42
|
const CUSTOM_MIGRATED_STORAGE_KEY = "cool-theme-custom-migrated";
|
|
43
|
+
const SIDEBAR_TRANSPARENT_STORAGE_KEY = "cool-theme-sidebar-transparent";
|
|
42
44
|
const THEME_API_PATH_THEMES = `/cool-theme/api/themes`;
|
|
43
45
|
const THEME_ARCHIVE_EXTENSION = ".zip";
|
|
44
46
|
/**
|
|
@@ -2301,6 +2303,432 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2301
2303
|
};
|
|
2302
2304
|
}
|
|
2303
2305
|
//#endregion
|
|
2306
|
+
//#region node_modules/.pnpm/react-colorful@5.8.1_react-dom@19.3.0_react@18.3.1__react@18.3.1/node_modules/react-colorful/dist/index.mjs
|
|
2307
|
+
function l() {
|
|
2308
|
+
return (l = Object.assign || function(e) {
|
|
2309
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
2310
|
+
var n = arguments[r];
|
|
2311
|
+
for (var t in n) Object.prototype.hasOwnProperty.call(n, t) && (e[t] = n[t]);
|
|
2312
|
+
}
|
|
2313
|
+
return e;
|
|
2314
|
+
}).apply(this, arguments);
|
|
2315
|
+
}
|
|
2316
|
+
function c(e, r) {
|
|
2317
|
+
if (null == e) return {};
|
|
2318
|
+
var n, t, o = {}, a = Object.keys(e);
|
|
2319
|
+
for (t = 0; t < a.length; t++) r.indexOf(n = a[t]) >= 0 || (o[n] = e[n]);
|
|
2320
|
+
return o;
|
|
2321
|
+
}
|
|
2322
|
+
function i(e) {
|
|
2323
|
+
var n = (0, react.useRef)(e), t = (0, react.useRef)(function(e) {
|
|
2324
|
+
n.current && n.current(e);
|
|
2325
|
+
});
|
|
2326
|
+
return n.current = e, t.current;
|
|
2327
|
+
}
|
|
2328
|
+
var s = function(e, r, n) {
|
|
2329
|
+
return void 0 === r && (r = 0), void 0 === n && (n = 1), e > n ? n : e < r ? r : e;
|
|
2330
|
+
};
|
|
2331
|
+
var f = function(e) {
|
|
2332
|
+
return "touches" in e;
|
|
2333
|
+
};
|
|
2334
|
+
var d = function(e) {
|
|
2335
|
+
return e && e.ownerDocument.defaultView || self;
|
|
2336
|
+
};
|
|
2337
|
+
var v = function(e, r, n) {
|
|
2338
|
+
var t = e.getBoundingClientRect(), o = f(r) ? function(e, r) {
|
|
2339
|
+
for (var n = 0; n < e.length; n++) if (e[n].identifier === r) return e[n];
|
|
2340
|
+
return e[0];
|
|
2341
|
+
}(r.touches, n) : r;
|
|
2342
|
+
return {
|
|
2343
|
+
left: s((o.pageX - (t.left + d(e).pageXOffset)) / t.width),
|
|
2344
|
+
top: s((o.pageY - (t.top + d(e).pageYOffset)) / t.height)
|
|
2345
|
+
};
|
|
2346
|
+
};
|
|
2347
|
+
var h = function(e) {
|
|
2348
|
+
!f(e) && e.preventDefault();
|
|
2349
|
+
};
|
|
2350
|
+
var g = react.default.memo(function(o) {
|
|
2351
|
+
var a = o.onMove, u = o.onKey, s = o.onEnd, g = c(o, [
|
|
2352
|
+
"onMove",
|
|
2353
|
+
"onKey",
|
|
2354
|
+
"onEnd"
|
|
2355
|
+
]), m = (0, react.useRef)(null), p = i(a), b = i(u), _ = i(s), E = (0, react.useRef)(null), C = (0, react.useRef)(!1), x = (0, react.useMemo)(function() {
|
|
2356
|
+
var e = function(e) {
|
|
2357
|
+
h(e), (f(e) ? e.touches.length > 0 : e.buttons > 0) && m.current ? p(v(m.current, e, E.current)) : (n(!1), _());
|
|
2358
|
+
}, r = function() {
|
|
2359
|
+
n(!1), _();
|
|
2360
|
+
};
|
|
2361
|
+
function n(n) {
|
|
2362
|
+
var t = C.current, o = d(m.current), a = n ? o.addEventListener : o.removeEventListener;
|
|
2363
|
+
a(t ? "touchmove" : "mousemove", e), a(t ? "touchend" : "mouseup", r);
|
|
2364
|
+
}
|
|
2365
|
+
return [
|
|
2366
|
+
function(e) {
|
|
2367
|
+
var r = e.nativeEvent, t = m.current;
|
|
2368
|
+
if (t && (h(r), !function(e, r) {
|
|
2369
|
+
return r && !f(e);
|
|
2370
|
+
}(r, C.current) && t)) {
|
|
2371
|
+
if (f(r)) {
|
|
2372
|
+
C.current = !0;
|
|
2373
|
+
var o = r.changedTouches || [];
|
|
2374
|
+
o.length && (E.current = o[0].identifier);
|
|
2375
|
+
}
|
|
2376
|
+
t.focus(), p(v(t, r, E.current)), n(!0);
|
|
2377
|
+
}
|
|
2378
|
+
},
|
|
2379
|
+
function(e) {
|
|
2380
|
+
var r = e.which || e.keyCode;
|
|
2381
|
+
r < 37 || r > 40 || (e.preventDefault(), b({
|
|
2382
|
+
left: 39 === r ? .05 : 37 === r ? -.05 : 0,
|
|
2383
|
+
top: 40 === r ? .05 : 38 === r ? -.05 : 0
|
|
2384
|
+
}));
|
|
2385
|
+
},
|
|
2386
|
+
function(e) {
|
|
2387
|
+
var r = e.which || e.keyCode;
|
|
2388
|
+
r >= 37 && r <= 40 && _();
|
|
2389
|
+
},
|
|
2390
|
+
n
|
|
2391
|
+
];
|
|
2392
|
+
}, [
|
|
2393
|
+
b,
|
|
2394
|
+
p,
|
|
2395
|
+
_
|
|
2396
|
+
]), H = x[0], M = x[1], N = x[2], w = x[3];
|
|
2397
|
+
return (0, react.useEffect)(function() {
|
|
2398
|
+
return w;
|
|
2399
|
+
}, [w]), react.default.createElement("div", l({}, g, {
|
|
2400
|
+
onTouchStart: H,
|
|
2401
|
+
onMouseDown: H,
|
|
2402
|
+
className: "react-colorful__interactive",
|
|
2403
|
+
ref: m,
|
|
2404
|
+
onKeyDown: M,
|
|
2405
|
+
onKeyUp: N,
|
|
2406
|
+
tabIndex: 0,
|
|
2407
|
+
role: "slider"
|
|
2408
|
+
}));
|
|
2409
|
+
});
|
|
2410
|
+
var m = function(e) {
|
|
2411
|
+
return e.filter(Boolean).join(" ");
|
|
2412
|
+
};
|
|
2413
|
+
var p = function(r) {
|
|
2414
|
+
var n = r.color, t = r.left, o = r.top, a = void 0 === o ? .5 : o, u = m(["react-colorful__pointer", r.className]);
|
|
2415
|
+
return react.default.createElement("div", {
|
|
2416
|
+
className: u,
|
|
2417
|
+
style: {
|
|
2418
|
+
top: 100 * a + "%",
|
|
2419
|
+
left: 100 * t + "%"
|
|
2420
|
+
}
|
|
2421
|
+
}, react.default.createElement("div", {
|
|
2422
|
+
className: "react-colorful__pointer-fill",
|
|
2423
|
+
style: { backgroundColor: n }
|
|
2424
|
+
}));
|
|
2425
|
+
};
|
|
2426
|
+
var b = function(e, r, n) {
|
|
2427
|
+
return void 0 === r && (r = 0), void 0 === n && (n = Math.pow(10, r)), Math.round(n * e) / n;
|
|
2428
|
+
};
|
|
2429
|
+
360 / (2 * Math.PI);
|
|
2430
|
+
var E = function(e) {
|
|
2431
|
+
return L(C(e));
|
|
2432
|
+
};
|
|
2433
|
+
var C = function(e) {
|
|
2434
|
+
return "#" === e[0] && (e = e.substring(1)), e.length < 6 ? {
|
|
2435
|
+
r: parseInt(e[0] + e[0], 16),
|
|
2436
|
+
g: parseInt(e[1] + e[1], 16),
|
|
2437
|
+
b: parseInt(e[2] + e[2], 16),
|
|
2438
|
+
a: 4 === e.length ? b(parseInt(e[3] + e[3], 16) / 255, 2) : 1
|
|
2439
|
+
} : {
|
|
2440
|
+
r: parseInt(e.substring(0, 2), 16),
|
|
2441
|
+
g: parseInt(e.substring(2, 4), 16),
|
|
2442
|
+
b: parseInt(e.substring(4, 6), 16),
|
|
2443
|
+
a: 8 === e.length ? b(parseInt(e.substring(6, 8), 16) / 255, 2) : 1
|
|
2444
|
+
};
|
|
2445
|
+
};
|
|
2446
|
+
var w = function(e) {
|
|
2447
|
+
return B(I(e));
|
|
2448
|
+
};
|
|
2449
|
+
var y = function(e) {
|
|
2450
|
+
var r = e.s, n = e.v, t = e.a, o = (200 - r) * n / 100;
|
|
2451
|
+
return {
|
|
2452
|
+
h: b(e.h),
|
|
2453
|
+
s: b(o > 0 && o < 200 ? r * n / 100 / (o <= 100 ? o : 200 - o) * 100 : 0),
|
|
2454
|
+
l: b(o / 2),
|
|
2455
|
+
a: b(t, 2)
|
|
2456
|
+
};
|
|
2457
|
+
};
|
|
2458
|
+
var k = function(e) {
|
|
2459
|
+
var r = y(e);
|
|
2460
|
+
return "hsl(" + r.h + ", " + r.s + "%, " + r.l + "%)";
|
|
2461
|
+
};
|
|
2462
|
+
var I = function(e) {
|
|
2463
|
+
var r = e.h, n = e.s, t = e.v, o = e.a;
|
|
2464
|
+
r = r / 360 * 6, n /= 100, t /= 100;
|
|
2465
|
+
var a = Math.floor(r), u = t * (1 - n), l = t * (1 - (r - a) * n), c = t * (1 - (1 - r + a) * n), i = a % 6;
|
|
2466
|
+
return {
|
|
2467
|
+
r: b(255 * [
|
|
2468
|
+
t,
|
|
2469
|
+
l,
|
|
2470
|
+
u,
|
|
2471
|
+
u,
|
|
2472
|
+
c,
|
|
2473
|
+
t
|
|
2474
|
+
][i]),
|
|
2475
|
+
g: b(255 * [
|
|
2476
|
+
c,
|
|
2477
|
+
t,
|
|
2478
|
+
t,
|
|
2479
|
+
l,
|
|
2480
|
+
u,
|
|
2481
|
+
u
|
|
2482
|
+
][i]),
|
|
2483
|
+
b: b(255 * [
|
|
2484
|
+
u,
|
|
2485
|
+
u,
|
|
2486
|
+
c,
|
|
2487
|
+
t,
|
|
2488
|
+
t,
|
|
2489
|
+
l
|
|
2490
|
+
][i]),
|
|
2491
|
+
a: b(o, 2)
|
|
2492
|
+
};
|
|
2493
|
+
};
|
|
2494
|
+
var K = function(e) {
|
|
2495
|
+
var r = e.toString(16);
|
|
2496
|
+
return r.length < 2 ? "0" + r : r;
|
|
2497
|
+
};
|
|
2498
|
+
var B = function(e) {
|
|
2499
|
+
var r = e.r, n = e.g, t = e.b, o = e.a, a = o < 1 ? K(b(255 * o)) : "";
|
|
2500
|
+
return "#" + K(r) + K(n) + K(t) + a;
|
|
2501
|
+
};
|
|
2502
|
+
var L = function(e) {
|
|
2503
|
+
var r = e.r, n = e.g, t = e.b, o = e.a, a = Math.max(r, n, t), u = a - Math.min(r, n, t), l = u ? a === r ? (n - t) / u : a === n ? 2 + (t - r) / u : 4 + (r - n) / u : 0;
|
|
2504
|
+
return {
|
|
2505
|
+
h: 60 * (l < 0 ? l + 6 : l),
|
|
2506
|
+
s: a ? u / a * 100 : 0,
|
|
2507
|
+
v: a / 255 * 100,
|
|
2508
|
+
a: o
|
|
2509
|
+
};
|
|
2510
|
+
};
|
|
2511
|
+
var R = react.default.memo(function(r) {
|
|
2512
|
+
var n = r.hue, t = r.onChange, o = r.onChangeEnd, a = m(["react-colorful__hue", r.className]);
|
|
2513
|
+
return react.default.createElement("div", { className: a }, react.default.createElement(g, {
|
|
2514
|
+
onMove: function(e) {
|
|
2515
|
+
t({ h: 360 * e.left });
|
|
2516
|
+
},
|
|
2517
|
+
onKey: function(e) {
|
|
2518
|
+
t({ h: s(n + 360 * e.left, 0, 360) });
|
|
2519
|
+
},
|
|
2520
|
+
onEnd: o,
|
|
2521
|
+
"aria-label": "Hue",
|
|
2522
|
+
"aria-valuenow": b(n),
|
|
2523
|
+
"aria-valuemax": "360",
|
|
2524
|
+
"aria-valuemin": "0"
|
|
2525
|
+
}, react.default.createElement(p, {
|
|
2526
|
+
className: "react-colorful__hue-pointer",
|
|
2527
|
+
left: n / 360,
|
|
2528
|
+
color: k({
|
|
2529
|
+
h: n,
|
|
2530
|
+
s: 100,
|
|
2531
|
+
v: 100,
|
|
2532
|
+
a: 1
|
|
2533
|
+
})
|
|
2534
|
+
})));
|
|
2535
|
+
});
|
|
2536
|
+
var S = react.default.memo(function(r) {
|
|
2537
|
+
var n = r.hsva, t = r.onChange, o = r.onChangeEnd, a = { backgroundColor: k({
|
|
2538
|
+
h: n.h,
|
|
2539
|
+
s: 100,
|
|
2540
|
+
v: 100,
|
|
2541
|
+
a: 1
|
|
2542
|
+
}) };
|
|
2543
|
+
return react.default.createElement("div", {
|
|
2544
|
+
className: "react-colorful__saturation",
|
|
2545
|
+
style: a
|
|
2546
|
+
}, react.default.createElement(g, {
|
|
2547
|
+
onMove: function(e) {
|
|
2548
|
+
t({
|
|
2549
|
+
s: 100 * e.left,
|
|
2550
|
+
v: 100 - 100 * e.top
|
|
2551
|
+
});
|
|
2552
|
+
},
|
|
2553
|
+
onKey: function(e) {
|
|
2554
|
+
t({
|
|
2555
|
+
s: s(n.s + 100 * e.left, 0, 100),
|
|
2556
|
+
v: s(n.v - 100 * e.top, 0, 100)
|
|
2557
|
+
});
|
|
2558
|
+
},
|
|
2559
|
+
onEnd: o,
|
|
2560
|
+
"aria-label": "Color",
|
|
2561
|
+
"aria-valuetext": "Saturation " + b(n.s) + "%, Brightness " + b(n.v) + "%"
|
|
2562
|
+
}, react.default.createElement(p, {
|
|
2563
|
+
className: "react-colorful__saturation-pointer",
|
|
2564
|
+
top: 1 - n.v / 100,
|
|
2565
|
+
left: n.s / 100,
|
|
2566
|
+
color: k(n)
|
|
2567
|
+
})));
|
|
2568
|
+
});
|
|
2569
|
+
var T = function(e, r) {
|
|
2570
|
+
if (e === r) return !0;
|
|
2571
|
+
for (var n in e) if (e[n] !== r[n]) return !1;
|
|
2572
|
+
return !0;
|
|
2573
|
+
};
|
|
2574
|
+
var P = function(e, r) {
|
|
2575
|
+
return e.toLowerCase() === r.toLowerCase() || T(C(e), C(r));
|
|
2576
|
+
};
|
|
2577
|
+
function X(e, n, u, l) {
|
|
2578
|
+
var c = i(u), s = i(l), f = (0, react.useState)(function() {
|
|
2579
|
+
return e.toHsva(n);
|
|
2580
|
+
}), d = f[0], v = f[1], h = (0, react.useRef)({
|
|
2581
|
+
color: n,
|
|
2582
|
+
hsva: d
|
|
2583
|
+
}), g = (0, react.useRef)(!1);
|
|
2584
|
+
(0, react.useEffect)(function() {
|
|
2585
|
+
if (!e.equal(n, h.current.color)) {
|
|
2586
|
+
var r = e.toHsva(n);
|
|
2587
|
+
h.current = {
|
|
2588
|
+
hsva: r,
|
|
2589
|
+
color: n
|
|
2590
|
+
}, v(r), g.current = !1;
|
|
2591
|
+
}
|
|
2592
|
+
}, [n, e]), (0, react.useEffect)(function() {
|
|
2593
|
+
var r;
|
|
2594
|
+
T(d, h.current.hsva) || e.equal(r = e.fromHsva(d), h.current.color) || (h.current = {
|
|
2595
|
+
hsva: d,
|
|
2596
|
+
color: r
|
|
2597
|
+
}, c(r), g.current = !0);
|
|
2598
|
+
}, [
|
|
2599
|
+
d,
|
|
2600
|
+
e,
|
|
2601
|
+
c
|
|
2602
|
+
]);
|
|
2603
|
+
return [
|
|
2604
|
+
d,
|
|
2605
|
+
(0, react.useCallback)(function(e) {
|
|
2606
|
+
v(function(r) {
|
|
2607
|
+
return Object.assign({}, r, e);
|
|
2608
|
+
});
|
|
2609
|
+
}, []),
|
|
2610
|
+
(0, react.useCallback)(function() {
|
|
2611
|
+
g.current && (g.current = !1, s(h.current.color));
|
|
2612
|
+
}, [s])
|
|
2613
|
+
];
|
|
2614
|
+
}
|
|
2615
|
+
var Y;
|
|
2616
|
+
var U = "undefined" != typeof window ? react.useLayoutEffect : react.useEffect;
|
|
2617
|
+
var V = function() {
|
|
2618
|
+
return Y || ("undefined" != typeof __webpack_nonce__ ? __webpack_nonce__ : void 0);
|
|
2619
|
+
};
|
|
2620
|
+
var $ = /* @__PURE__ */ new WeakMap();
|
|
2621
|
+
var G = function(e) {
|
|
2622
|
+
U(function() {
|
|
2623
|
+
var r = e.current;
|
|
2624
|
+
if ("undefined" != typeof document && r) {
|
|
2625
|
+
var n = r.getRootNode ? r.getRootNode() : r.ownerDocument, t = n && ("head" in n || "host" in n) ? n : r.ownerDocument;
|
|
2626
|
+
if (!$.has(t)) {
|
|
2627
|
+
var o = "head" in t ? t.head : t, a = (o.ownerDocument || document).createElement("style");
|
|
2628
|
+
a.innerHTML = ".react-colorful{position:relative;display:flex;flex-direction:column;width:200px;height:200px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:default}.react-colorful__saturation{position:relative;flex-grow:1;border-color:transparent;border-bottom:12px solid #000;border-radius:8px 8px 0 0;background-image:linear-gradient(0deg,#000,transparent),linear-gradient(90deg,#fff,hsla(0,0%,100%,0))}.react-colorful__alpha-gradient,.react-colorful__pointer-fill{content:\"\";position:absolute;left:0;top:0;right:0;bottom:0;pointer-events:none;border-radius:inherit}.react-colorful__alpha-gradient,.react-colorful__saturation{box-shadow:inset 0 0 0 1px rgba(0,0,0,.05)}.react-colorful__alpha,.react-colorful__hue{position:relative;height:24px}.react-colorful__hue{background:linear-gradient(90deg,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red)}.react-colorful__last-control{border-radius:0 0 8px 8px}.react-colorful__interactive{position:absolute;left:0;top:0;right:0;bottom:0;border-radius:inherit;outline:none;touch-action:none}.react-colorful__pointer{position:absolute;z-index:1;box-sizing:border-box;width:28px;height:28px;transform:translate(-50%,-50%);background-color:#fff;border:2px solid #fff;border-radius:50%;box-shadow:0 2px 4px rgba(0,0,0,.2)}.react-colorful__interactive:focus .react-colorful__pointer{transform:translate(-50%,-50%) scale(1.1)}.react-colorful__alpha,.react-colorful__alpha-pointer{background-color:#fff;background-image:url('data:image/svg+xml;charset=utf-8,<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill-opacity=\".05\"><path d=\"M8 0h8v8H8zM0 8h8v8H0z\"/></svg>')}.react-colorful__saturation-pointer{z-index:3}.react-colorful__hue-pointer{z-index:2}";
|
|
2629
|
+
var u = V();
|
|
2630
|
+
u && a.setAttribute("nonce", u), $.set(t, a), o.appendChild(a);
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
}, []);
|
|
2634
|
+
};
|
|
2635
|
+
var J = function(n) {
|
|
2636
|
+
var t = n.className, o = n.colorModel, a = n.color, u = void 0 === a ? o.defaultColor : a, i = n.onChange, s = n.onChangeEnd, f = c(n, [
|
|
2637
|
+
"className",
|
|
2638
|
+
"colorModel",
|
|
2639
|
+
"color",
|
|
2640
|
+
"onChange",
|
|
2641
|
+
"onChangeEnd"
|
|
2642
|
+
]), d = (0, react.useRef)(null);
|
|
2643
|
+
G(d);
|
|
2644
|
+
var v = X(o, u, i, s), h = v[0], g = v[1], p = v[2], b = m(["react-colorful", t]);
|
|
2645
|
+
return react.default.createElement("div", l({}, f, {
|
|
2646
|
+
ref: d,
|
|
2647
|
+
className: b
|
|
2648
|
+
}), react.default.createElement(S, {
|
|
2649
|
+
hsva: h,
|
|
2650
|
+
onChange: g,
|
|
2651
|
+
onChangeEnd: p
|
|
2652
|
+
}), react.default.createElement(R, {
|
|
2653
|
+
hue: h.h,
|
|
2654
|
+
onChange: g,
|
|
2655
|
+
onChangeEnd: p,
|
|
2656
|
+
className: "react-colorful__last-control"
|
|
2657
|
+
}));
|
|
2658
|
+
};
|
|
2659
|
+
var Q = {
|
|
2660
|
+
defaultColor: "000",
|
|
2661
|
+
toHsva: E,
|
|
2662
|
+
fromHsva: function(e) {
|
|
2663
|
+
return w({
|
|
2664
|
+
h: e.h,
|
|
2665
|
+
s: e.s,
|
|
2666
|
+
v: e.v,
|
|
2667
|
+
a: 1
|
|
2668
|
+
});
|
|
2669
|
+
},
|
|
2670
|
+
equal: P
|
|
2671
|
+
};
|
|
2672
|
+
var Z = function(r) {
|
|
2673
|
+
return react.default.createElement(J, l({}, r, { colorModel: Q }));
|
|
2674
|
+
};
|
|
2675
|
+
var ke = /^#?([0-9A-F]{3,8})$/i;
|
|
2676
|
+
var qe = function(r) {
|
|
2677
|
+
var n = r.color, u = void 0 === n ? "" : n, s = r.onChange, f = r.onBlur, d = r.escape, v = r.validate, h = r.format, g = r.process, m = c(r, [
|
|
2678
|
+
"color",
|
|
2679
|
+
"onChange",
|
|
2680
|
+
"onBlur",
|
|
2681
|
+
"escape",
|
|
2682
|
+
"validate",
|
|
2683
|
+
"format",
|
|
2684
|
+
"process"
|
|
2685
|
+
]), p = (0, react.useState)(function() {
|
|
2686
|
+
return d(u);
|
|
2687
|
+
}), b = p[0], _ = p[1], E = i(s), C = i(f), x = (0, react.useCallback)(function(e) {
|
|
2688
|
+
var r = d(e.target.value);
|
|
2689
|
+
_(r), v(r) && E(g ? g(r) : r);
|
|
2690
|
+
}, [
|
|
2691
|
+
d,
|
|
2692
|
+
g,
|
|
2693
|
+
v,
|
|
2694
|
+
E
|
|
2695
|
+
]), H = (0, react.useCallback)(function(e) {
|
|
2696
|
+
v(e.target.value) || _(d(u)), C(e);
|
|
2697
|
+
}, [
|
|
2698
|
+
u,
|
|
2699
|
+
d,
|
|
2700
|
+
v,
|
|
2701
|
+
C
|
|
2702
|
+
]);
|
|
2703
|
+
return (0, react.useEffect)(function() {
|
|
2704
|
+
_(d(u));
|
|
2705
|
+
}, [u, d]), react.default.createElement("input", l({}, m, {
|
|
2706
|
+
value: h ? h(b) : b,
|
|
2707
|
+
spellCheck: "false",
|
|
2708
|
+
onChange: x,
|
|
2709
|
+
onBlur: H
|
|
2710
|
+
}));
|
|
2711
|
+
};
|
|
2712
|
+
var Ie = function(e) {
|
|
2713
|
+
return "#" + e;
|
|
2714
|
+
};
|
|
2715
|
+
var Oe = function(r) {
|
|
2716
|
+
var n = r.prefixed, t = r.alpha, o = c(r, ["prefixed", "alpha"]), u = (0, react.useCallback)(function(e) {
|
|
2717
|
+
return e.replace(/([^0-9A-F]+)/gi, "").substring(0, t ? 8 : 6);
|
|
2718
|
+
}, [t]), i = (0, react.useCallback)(function(e) {
|
|
2719
|
+
return function(e, r) {
|
|
2720
|
+
var n = ke.exec(e), t = n ? n[1].length : 0;
|
|
2721
|
+
return 3 === t || 6 === t || !!r && 4 === t || !!r && 8 === t;
|
|
2722
|
+
}(e, t);
|
|
2723
|
+
}, [t]);
|
|
2724
|
+
return react.default.createElement(qe, l({}, o, {
|
|
2725
|
+
escape: u,
|
|
2726
|
+
format: n ? Ie : void 0,
|
|
2727
|
+
process: Ie,
|
|
2728
|
+
validate: i
|
|
2729
|
+
}));
|
|
2730
|
+
};
|
|
2731
|
+
//#endregion
|
|
2304
2732
|
//#region src/client/custom.ts
|
|
2305
2733
|
/** The nine `--shiki-token-*` slots, in stylesheet order. */
|
|
2306
2734
|
const SHIKI_KEYS = [
|
|
@@ -2809,6 +3237,22 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2809
3237
|
/** Reserved menu value that switches to the user-defined theme. */
|
|
2810
3238
|
const CUSTOM_SELECTION = CUSTOM_PRESET_ID;
|
|
2811
3239
|
/**
|
|
3240
|
+
* Base id of the light/dark control in the colour editor — and the only place
|
|
3241
|
+
* that string is written. The shell's `SegmentedControl` derives both the tab
|
|
3242
|
+
* ids (`<id>-<value>`) and the panel ids (`<id>-<value>-panel`) from it, so the
|
|
3243
|
+
* tabpanel that answers them has to be built from the same value: a second
|
|
3244
|
+
* literal would drift silently and leave `aria-controls` pointing at nothing.
|
|
3245
|
+
*/
|
|
3246
|
+
const SEED_MODE_CONTROL_ID = "ct-seed-mode";
|
|
3247
|
+
/**
|
|
3248
|
+
* The one glyph size this panel draws at. Every icon here is explicit about it
|
|
3249
|
+
* because the shell's artwork does not default uniformly — the chevron falls
|
|
3250
|
+
* back to 14, the edit/share/trash/add/import glyphs to 16 — so passing no size
|
|
3251
|
+
* silently picks a different scale per icon. 14 is what the shell's own
|
|
3252
|
+
* settings pages pass.
|
|
3253
|
+
*/
|
|
3254
|
+
const ICON_SIZE = 14;
|
|
3255
|
+
/**
|
|
2812
3256
|
* Which message an import failure deserves. The Host answers with its own
|
|
2813
3257
|
* reason, so the shape of that reason is what selects the localized text; an
|
|
2814
3258
|
* unrecognised failure keeps the Host's own words rather than hiding them.
|
|
@@ -2854,114 +3298,54 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2854
3298
|
if (open.id === null) return true;
|
|
2855
3299
|
return open.name.trim() !== open.originName.trim() || !sameSeeds(current, open.originTheme);
|
|
2856
3300
|
}
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
}, react.createElement("path", {
|
|
2865
|
-
d: "M11.8486 5.5L11.4238 5.92383L8.69727 8.65137C8.44157 8.90706 8.21562 9.13382 8.01172 9.29785C7.79912 9.46883 7.55595 9.61756 7.25 9.66602C7.08435 9.69222 6.91565 9.69222 6.75 9.66602C6.44405 9.61756 6.20088 9.46883 5.98828 9.29785C5.78438 9.13382 5.55843 8.90706 5.30273 8.65137L2.57617 5.92383L2.15137 5.5L3 4.65137L3.42383 5.07617L6.15137 7.80273C6.42595 8.07732 6.59876 8.24849 6.74023 8.3623C6.87291 8.46904 6.92272 8.47813 6.9375 8.48047C6.97895 8.48703 7.02105 8.48703 7.0625 8.48047C7.07728 8.47813 7.12709 8.46904 7.25977 8.3623C7.40124 8.24849 7.57405 8.07732 7.84863 7.80273L10.5762 5.07617L11 4.65137L11.8486 5.5Z",
|
|
2866
|
-
fill: "currentColor"
|
|
2867
|
-
}));
|
|
2868
|
-
}
|
|
2869
|
-
/** The menu's selected-row tick: 16px, pushed to the trailing edge. */
|
|
2870
|
-
function IconCheck(props) {
|
|
2871
|
-
const { size = 16, className } = props;
|
|
2872
|
-
return react.createElement("svg", {
|
|
2873
|
-
width: size,
|
|
2874
|
-
height: size,
|
|
2875
|
-
viewBox: "0 0 16 16",
|
|
2876
|
-
fill: "none",
|
|
2877
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
2878
|
-
className
|
|
2879
|
-
}, react.createElement("path", {
|
|
2880
|
-
d: "M15.0498 3.92579L8.49512 12.3818C8.25774 12.6881 8.04517 12.9645 7.84668 13.1689C7.63957 13.3823 7.38732 13.5841 7.04492 13.6719C6.86373 13.7183 6.6757 13.7346 6.48926 13.7197C6.13666 13.6915 5.8528 13.5355 5.6123 13.3604C5.38201 13.1926 5.12573 12.9567 4.83984 12.6953L1.03125 9.21289L1.96875 8.1875L5.77734 11.6699C6.08684 11.9529 6.27773 12.1249 6.43066 12.2363C6.50183 12.2882 6.54699 12.3135 6.57324 12.3252C6.58525 12.3305 6.59269 12.3322 6.5957 12.333C6.59802 12.3336 6.59961 12.334 6.59961 12.334C6.63317 12.3367 6.66758 12.3335 6.7002 12.3252C6.7002 12.3252 6.70211 12.3251 6.7041 12.3242C6.70698 12.3229 6.71348 12.319 6.72461 12.3115C6.74849 12.2956 6.78843 12.2642 6.84961 12.2012C6.98138 12.0654 7.13957 11.8628 7.39648 11.5313L13.9502 3.07422L15.0498 3.92579Z",
|
|
2881
|
-
fill: "currentColor"
|
|
2882
|
-
}));
|
|
2883
|
-
}
|
|
3301
|
+
/**
|
|
3302
|
+
* The panel's value picker: a trigger in the row, the shell's `Menu` for the
|
|
3303
|
+
* list. Everything the list needs — outside pointerdown, Escape, the arrow
|
|
3304
|
+
* walk, the focus return to the trigger, the translucent material, the
|
|
3305
|
+
* viewport-clamped portal — belongs to the primitive, so this owns `open` and
|
|
3306
|
+
* which label the trigger shows, and nothing else.
|
|
3307
|
+
*/
|
|
2884
3308
|
function SchemeMenu(props) {
|
|
2885
3309
|
const { value, options, onSelect, disabled } = props;
|
|
2886
3310
|
const [open, setOpen] = react.useState(false);
|
|
2887
|
-
const rootRef = react.useRef(null);
|
|
2888
|
-
const listRef = react.useRef(null);
|
|
2889
|
-
react.useEffect(() => {
|
|
2890
|
-
if (!open) return;
|
|
2891
|
-
function onDown(e) {
|
|
2892
|
-
if (!(e.target instanceof Node)) return;
|
|
2893
|
-
if (rootRef.current?.contains(e.target)) return;
|
|
2894
|
-
if (listRef.current?.contains(e.target)) return;
|
|
2895
|
-
setOpen(false);
|
|
2896
|
-
}
|
|
2897
|
-
function onKey(e) {
|
|
2898
|
-
if (e.key === "Escape") setOpen(false);
|
|
2899
|
-
}
|
|
2900
|
-
document.addEventListener("pointerdown", onDown);
|
|
2901
|
-
document.addEventListener("keydown", onKey);
|
|
2902
|
-
return () => {
|
|
2903
|
-
document.removeEventListener("pointerdown", onDown);
|
|
2904
|
-
document.removeEventListener("keydown", onKey);
|
|
2905
|
-
};
|
|
2906
|
-
}, [open]);
|
|
2907
3311
|
const selected = options.find((o) => o.value === value);
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
ref: listRef,
|
|
2923
|
-
className: "ct-menu-list",
|
|
2924
|
-
style: {
|
|
2925
|
-
position: "absolute",
|
|
2926
|
-
top: "calc(100% + 4px)",
|
|
2927
|
-
right: 0,
|
|
2928
|
-
zIndex: 100
|
|
3312
|
+
const expanded = open && !disabled;
|
|
3313
|
+
return react.createElement(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
3314
|
+
open: expanded,
|
|
3315
|
+
align: "end",
|
|
3316
|
+
side: "bottom",
|
|
3317
|
+
portal: true,
|
|
3318
|
+
items: options.map((o) => ({
|
|
3319
|
+
id: o.value,
|
|
3320
|
+
label: o.label
|
|
3321
|
+
})),
|
|
3322
|
+
selectedId: value,
|
|
3323
|
+
onSelect: (v) => {
|
|
3324
|
+
setOpen(false);
|
|
3325
|
+
onSelect(v);
|
|
2929
3326
|
},
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
}, ...options.map((o) => {
|
|
2933
|
-
const sel = o.value === value;
|
|
2934
|
-
return react.createElement("button", {
|
|
2935
|
-
key: o.value,
|
|
3327
|
+
onClose: () => setOpen(false),
|
|
3328
|
+
anchor: react.createElement("button", {
|
|
2936
3329
|
type: "button",
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
})) : null);
|
|
2945
|
-
}
|
|
2946
|
-
/** Accessible on/off switch used to enable the custom theme. */
|
|
2947
|
-
function Switch(props) {
|
|
2948
|
-
const { checked, label, onChange } = props;
|
|
2949
|
-
return react.createElement("button", {
|
|
2950
|
-
type: "button",
|
|
2951
|
-
role: "switch",
|
|
2952
|
-
"aria-checked": checked,
|
|
2953
|
-
"aria-label": label,
|
|
2954
|
-
className: checked ? "ct-switch ct-switch-on" : "ct-switch",
|
|
2955
|
-
onClick: () => onChange(!checked)
|
|
2956
|
-
}, react.createElement("span", { className: "ct-switch-knob" }));
|
|
3330
|
+
className: "ct-select",
|
|
3331
|
+
disabled,
|
|
3332
|
+
"aria-haspopup": "menu",
|
|
3333
|
+
"aria-expanded": expanded,
|
|
3334
|
+
onClick: () => setOpen(!open)
|
|
3335
|
+
}, react.createElement("span", { className: "ct-select-label" }, selected?.label ?? ""), react.createElement("span", { className: "ct-select-chevron" }, react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, { size: ICON_SIZE })))
|
|
3336
|
+
});
|
|
2957
3337
|
}
|
|
2958
3338
|
/**
|
|
2959
3339
|
* Confirmation dialog for destructive actions, mirroring DSH's own Modal
|
|
2960
|
-
* (design-platform mask token + blur,
|
|
2961
|
-
*
|
|
3340
|
+
* (design-platform mask token + blur, `radius-panel` card on layer-2,
|
|
3341
|
+
* prominent shadow) and the footer its `RiskConfirmation` lays out: an outline
|
|
3342
|
+
* cancel beside the confirming action.
|
|
3343
|
+
* Still rendered inline rather than through the shell's `Modal`: its Escape has
|
|
3344
|
+
* to take part in the panel's own leave-the-draft questions, and a shell-owned
|
|
3345
|
+
* modal layer would answer the key before this dialog could.
|
|
2962
3346
|
*/
|
|
2963
3347
|
function ConfirmDialog(props) {
|
|
2964
|
-
const { title, description, confirmLabel, cancelLabel, onConfirm, onCancel } = props;
|
|
3348
|
+
const { title, description, confirmLabel, cancelLabel, danger, onConfirm, onCancel } = props;
|
|
2965
3349
|
react.useEffect(() => {
|
|
2966
3350
|
const onKey = (e) => {
|
|
2967
3351
|
if (e.key === "Escape") onCancel();
|
|
@@ -2978,13 +3362,13 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2978
3362
|
role: "dialog",
|
|
2979
3363
|
"aria-modal": true,
|
|
2980
3364
|
"aria-label": title
|
|
2981
|
-
}, react.createElement("div", { className: "ct-modal-title" }, title), react.createElement("div", { className: "ct-modal-desc" }, description), react.createElement("div", { className: "ct-modal-footer" }, react.createElement(
|
|
2982
|
-
|
|
2983
|
-
className: "ct-
|
|
3365
|
+
}, react.createElement("div", { className: "ct-modal-title" }, title), react.createElement("div", { className: "ct-modal-desc" }, description), react.createElement("div", { className: "ct-modal-footer" }, react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3366
|
+
variant: "outline",
|
|
3367
|
+
className: "ct-action-cancel",
|
|
2984
3368
|
onClick: onCancel
|
|
2985
|
-
}, cancelLabel), react.createElement(
|
|
2986
|
-
|
|
2987
|
-
className: "ct-
|
|
3369
|
+
}, cancelLabel), react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3370
|
+
variant: danger ? "outline" : "primary",
|
|
3371
|
+
className: danger ? "ct-action-confirm ct-danger" : "ct-action-confirm",
|
|
2988
3372
|
onClick: onConfirm
|
|
2989
3373
|
}, confirmLabel))));
|
|
2990
3374
|
}
|
|
@@ -2993,148 +3377,6 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2993
3377
|
return error instanceof ThemeApiUnavailableError ? "custom.toast.unavailable" : "custom.toast.failed";
|
|
2994
3378
|
}
|
|
2995
3379
|
/**
|
|
2996
|
-
* Transient confirmation banner: a leading result badge plus the copy, top
|
|
2997
|
-
* center, sliding in, holding, fading out, then reporting done so the owner can
|
|
2998
|
-
* unmount it. Metrics, tokens, badge and timing follow DSH's own toast — the
|
|
2999
|
-
* badge is the success circle its confirmations wear — but the component is
|
|
3000
|
-
* local: the plugin must keep answering a save on a host that does not share
|
|
3001
|
-
* the primitives module.
|
|
3002
|
-
*
|
|
3003
|
-
* TOAST_HOLD_MS and TOAST_FADE_MS have to agree with the `ct-toast` animation
|
|
3004
|
-
* in the injected stylesheet, which owns the visual timing.
|
|
3005
|
-
* @param props.text - resolved, already-localized copy.
|
|
3006
|
-
* @param props.onDone - called once the fade completes; unmount the toast here.
|
|
3007
|
-
*/
|
|
3008
|
-
function Toast(props) {
|
|
3009
|
-
const { text, onDone } = props;
|
|
3010
|
-
react.useEffect(() => {
|
|
3011
|
-
const timer = setTimeout(onDone, 4e3);
|
|
3012
|
-
return () => clearTimeout(timer);
|
|
3013
|
-
}, [onDone]);
|
|
3014
|
-
return react.createElement("div", {
|
|
3015
|
-
className: "ct-toast",
|
|
3016
|
-
role: "status"
|
|
3017
|
-
}, react.createElement(ToastBadge), react.createElement("span", { className: "ct-toast-text" }, text));
|
|
3018
|
-
}
|
|
3019
|
-
/** The leading badge every confirmation wears: a success ring around the check. */
|
|
3020
|
-
function ToastBadge() {
|
|
3021
|
-
return react.createElement("span", {
|
|
3022
|
-
className: "ct-toast-icon",
|
|
3023
|
-
"aria-hidden": true
|
|
3024
|
-
}, react.createElement(IconCheck, { size: 12 }));
|
|
3025
|
-
}
|
|
3026
|
-
/**
|
|
3027
|
-
* Plus glyph for the add button, path data taken verbatim from DSH's own
|
|
3028
|
-
* `IconPlusOutline16` so the two controls read as the same affordance.
|
|
3029
|
-
*/
|
|
3030
|
-
function IconPlus(props) {
|
|
3031
|
-
const { size = 14 } = props;
|
|
3032
|
-
return react.createElement("svg", {
|
|
3033
|
-
width: size,
|
|
3034
|
-
height: size,
|
|
3035
|
-
viewBox: "0 0 16 16",
|
|
3036
|
-
fill: "none",
|
|
3037
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3038
|
-
"aria-hidden": true,
|
|
3039
|
-
focusable: false
|
|
3040
|
-
}, react.createElement("path", {
|
|
3041
|
-
d: "M8.64453 1.5V7.34961H14.5V8.65039H8.64453V14.5H7.34473V8.65039H1.5V7.34961H7.34473V1.5H8.64453Z",
|
|
3042
|
-
fill: "currentColor"
|
|
3043
|
-
}));
|
|
3044
|
-
}
|
|
3045
|
-
/**
|
|
3046
|
-
* Lucide `edit` (the pencil in a square), path data verbatim. Row actions are
|
|
3047
|
-
* icon-only, so the glyph has to read as the label the accessible name still
|
|
3048
|
-
* carries.
|
|
3049
|
-
*/
|
|
3050
|
-
function IconEdit(props) {
|
|
3051
|
-
const { size = 14 } = props;
|
|
3052
|
-
return react.createElement("svg", {
|
|
3053
|
-
width: size,
|
|
3054
|
-
height: size,
|
|
3055
|
-
viewBox: "0 0 24 24",
|
|
3056
|
-
fill: "none",
|
|
3057
|
-
stroke: "currentColor",
|
|
3058
|
-
strokeWidth: 2,
|
|
3059
|
-
strokeLinecap: "round",
|
|
3060
|
-
strokeLinejoin: "round",
|
|
3061
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3062
|
-
"aria-hidden": true,
|
|
3063
|
-
focusable: false
|
|
3064
|
-
}, react.createElement("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }), react.createElement("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" }));
|
|
3065
|
-
}
|
|
3066
|
-
/** Lucide `trash`, path data verbatim; the row's danger action. */
|
|
3067
|
-
function IconTrash(props) {
|
|
3068
|
-
const { size = 14 } = props;
|
|
3069
|
-
return react.createElement("svg", {
|
|
3070
|
-
width: size,
|
|
3071
|
-
height: size,
|
|
3072
|
-
viewBox: "0 0 24 24",
|
|
3073
|
-
fill: "none",
|
|
3074
|
-
stroke: "currentColor",
|
|
3075
|
-
strokeWidth: 2,
|
|
3076
|
-
strokeLinecap: "round",
|
|
3077
|
-
strokeLinejoin: "round",
|
|
3078
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3079
|
-
"aria-hidden": true,
|
|
3080
|
-
focusable: false
|
|
3081
|
-
}, react.createElement("path", { d: "M3 6h18" }), react.createElement("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }), react.createElement("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" }), react.createElement("line", {
|
|
3082
|
-
x1: 10,
|
|
3083
|
-
y1: 11,
|
|
3084
|
-
x2: 10,
|
|
3085
|
-
y2: 17
|
|
3086
|
-
}), react.createElement("line", {
|
|
3087
|
-
x1: 14,
|
|
3088
|
-
y1: 11,
|
|
3089
|
-
x2: 14,
|
|
3090
|
-
y2: 17
|
|
3091
|
-
}));
|
|
3092
|
-
}
|
|
3093
|
-
/** Lucide `share`, path data verbatim; sends one theme out as an archive. */
|
|
3094
|
-
function IconShare(props) {
|
|
3095
|
-
const { size = 14 } = props;
|
|
3096
|
-
return react.createElement("svg", {
|
|
3097
|
-
width: size,
|
|
3098
|
-
height: size,
|
|
3099
|
-
viewBox: "0 0 24 24",
|
|
3100
|
-
fill: "none",
|
|
3101
|
-
stroke: "currentColor",
|
|
3102
|
-
strokeWidth: 2,
|
|
3103
|
-
strokeLinecap: "round",
|
|
3104
|
-
strokeLinejoin: "round",
|
|
3105
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3106
|
-
"aria-hidden": true,
|
|
3107
|
-
focusable: false
|
|
3108
|
-
}, react.createElement("path", { d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8" }), react.createElement("polyline", { points: "16 6 12 2 8 6" }), react.createElement("line", {
|
|
3109
|
-
x1: 12,
|
|
3110
|
-
y1: 2,
|
|
3111
|
-
x2: 12,
|
|
3112
|
-
y2: 15
|
|
3113
|
-
}));
|
|
3114
|
-
}
|
|
3115
|
-
/** Lucide `download`, path data verbatim; takes one archive in. */
|
|
3116
|
-
function IconDownload(props) {
|
|
3117
|
-
const { size = 14 } = props;
|
|
3118
|
-
return react.createElement("svg", {
|
|
3119
|
-
width: size,
|
|
3120
|
-
height: size,
|
|
3121
|
-
viewBox: "0 0 24 24",
|
|
3122
|
-
fill: "none",
|
|
3123
|
-
stroke: "currentColor",
|
|
3124
|
-
strokeWidth: 2,
|
|
3125
|
-
strokeLinecap: "round",
|
|
3126
|
-
strokeLinejoin: "round",
|
|
3127
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
3128
|
-
"aria-hidden": true,
|
|
3129
|
-
focusable: false
|
|
3130
|
-
}, react.createElement("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }), react.createElement("polyline", { points: "7 10 12 15 17 10" }), react.createElement("line", {
|
|
3131
|
-
x1: 12,
|
|
3132
|
-
y1: 15,
|
|
3133
|
-
x2: 12,
|
|
3134
|
-
y2: 3
|
|
3135
|
-
}));
|
|
3136
|
-
}
|
|
3137
|
-
/**
|
|
3138
3380
|
* One collapsed saved-theme card: the name activates the theme, and the trailing
|
|
3139
3381
|
* controls export it, open the editor or delete it. The card as a whole is a
|
|
3140
3382
|
* click target too, but its controls own their clicks.
|
|
@@ -3142,22 +3384,29 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3142
3384
|
function ThemeCard(props) {
|
|
3143
3385
|
const { entry, active, disabled, t, onActivate, onExport, onEdit, onDelete } = props;
|
|
3144
3386
|
/**
|
|
3145
|
-
* One square icon action
|
|
3146
|
-
*
|
|
3147
|
-
*
|
|
3148
|
-
*
|
|
3387
|
+
* One square icon action. The glyph is decorative, so the label travels as
|
|
3388
|
+
* the accessible name and as the shell's own `Tooltip` above the button.
|
|
3389
|
+
* `danger` paints the error face; `leave` marks the button on the markup the
|
|
3390
|
+
* outside-click guard watches (see that guard) — it is not a visual state.
|
|
3149
3391
|
*/
|
|
3150
|
-
const action = (label, icon, onClick,
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3392
|
+
const action = (label, icon, onClick, marks) => {
|
|
3393
|
+
const button = react.createElement("button", {
|
|
3394
|
+
type: "button",
|
|
3395
|
+
className: marks?.danger ? "ct-list-btn ct-list-btn-danger" : "ct-list-btn",
|
|
3396
|
+
"aria-label": label,
|
|
3397
|
+
...marks?.leave ? {
|
|
3398
|
+
"data-ct-leave": "true",
|
|
3399
|
+
"data-ct-entry": entry.id
|
|
3400
|
+
} : {},
|
|
3401
|
+
onClick
|
|
3402
|
+
}, icon);
|
|
3403
|
+
return react.createElement(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
3404
|
+
label,
|
|
3405
|
+
side: "top",
|
|
3406
|
+
gap: 6,
|
|
3407
|
+
children: button
|
|
3408
|
+
});
|
|
3409
|
+
};
|
|
3161
3410
|
return react.createElement("div", {
|
|
3162
3411
|
className: "ct-list-row",
|
|
3163
3412
|
"data-ct-leave": "true",
|
|
@@ -3174,7 +3423,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3174
3423
|
}, entry.name)), react.createElement("div", {
|
|
3175
3424
|
className: "ct-list-actions",
|
|
3176
3425
|
onClick: (e) => e.stopPropagation()
|
|
3177
|
-
}, active ? react.createElement("span", { className: "ct-list-badge" }, t("custom.inUse")) : null, action(t("custom.edit"), react.createElement(
|
|
3426
|
+
}, active ? react.createElement("span", { className: "ct-list-badge" }, t("custom.inUse")) : null, action(t("custom.edit"), react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineRegular, { size: ICON_SIZE }), onEdit, { leave: true }), action(t("custom.export"), react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconShareOutlineRegular, { size: ICON_SIZE }), onExport), action(t("custom.delete"), react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: ICON_SIZE }), onDelete, { danger: true })));
|
|
3178
3427
|
}
|
|
3179
3428
|
/**
|
|
3180
3429
|
* Which appearance the colour dots edit. `system` resolves through the same
|
|
@@ -3190,7 +3439,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3190
3439
|
}
|
|
3191
3440
|
}
|
|
3192
3441
|
function ThemePanel(props) {
|
|
3193
|
-
const { theme, getSelection, setSelection, getCustom, setCustom, setCustomBase, resetCustom, saved,
|
|
3442
|
+
const { theme, getSelection, setSelection, getCustom, setCustom, setCustomBase, resetCustom, saved, getSidebarTransparent, setSidebarTransparent, t, onRequestClose } = props;
|
|
3194
3443
|
let initScheme = "system";
|
|
3195
3444
|
try {
|
|
3196
3445
|
const snap = theme?.getTheme();
|
|
@@ -3209,6 +3458,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3209
3458
|
});
|
|
3210
3459
|
const [list, setList] = react.useState(() => saved.list());
|
|
3211
3460
|
const [activeId, setActiveId] = react.useState(() => saved.activeId());
|
|
3461
|
+
const [sidebarTransparent, setSidebarTransparentState] = react.useState(() => getSidebarTransparent());
|
|
3212
3462
|
const [pendingDelete, setPendingDelete] = react.useState(null);
|
|
3213
3463
|
const [importing, setImporting] = react.useState(false);
|
|
3214
3464
|
/** The hidden picker the import button opens. */
|
|
@@ -3240,6 +3490,72 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3240
3490
|
text
|
|
3241
3491
|
});
|
|
3242
3492
|
}
|
|
3493
|
+
const [pickerDotKey, setPickerDotKey] = react.useState(null);
|
|
3494
|
+
const [pickerPos, setPickerPos] = react.useState(null);
|
|
3495
|
+
const pickerOpen = pickerDotKey !== null;
|
|
3496
|
+
const pickerOpenRef = react.useRef(false);
|
|
3497
|
+
pickerOpenRef.current = pickerOpen;
|
|
3498
|
+
/** The swatch the popover is anchored to; re-read on every reposition. */
|
|
3499
|
+
const pickerAnchorRef = react.useRef(null);
|
|
3500
|
+
/** The popover node itself; outside-pointerdown detection needs its bounds. */
|
|
3501
|
+
const pickerPopRef = react.useRef(null);
|
|
3502
|
+
/** Viewport coordinates that put the popover beside its anchor swatch. */
|
|
3503
|
+
function placePicker(anchor) {
|
|
3504
|
+
const WIDTH = 224;
|
|
3505
|
+
const HEIGHT = 240;
|
|
3506
|
+
const GAP = 8;
|
|
3507
|
+
const MARGIN = 8;
|
|
3508
|
+
const rect = anchor.getBoundingClientRect();
|
|
3509
|
+
const viewW = window.innerWidth;
|
|
3510
|
+
const viewH = window.innerHeight;
|
|
3511
|
+
return {
|
|
3512
|
+
left: Math.min(Math.max(MARGIN, rect.right - WIDTH), Math.max(MARGIN, viewW - WIDTH - MARGIN)),
|
|
3513
|
+
top: rect.bottom + GAP + HEIGHT <= viewH - MARGIN ? rect.bottom + GAP : Math.max(MARGIN, rect.top - GAP - HEIGHT)
|
|
3514
|
+
};
|
|
3515
|
+
}
|
|
3516
|
+
/** Toggle one seed's popover; `anchor` is the swatch that was clicked. */
|
|
3517
|
+
function togglePicker(key, anchor) {
|
|
3518
|
+
if (pickerDotKey === key) {
|
|
3519
|
+
closePicker();
|
|
3520
|
+
return;
|
|
3521
|
+
}
|
|
3522
|
+
pickerAnchorRef.current = anchor;
|
|
3523
|
+
setPickerDotKey(key);
|
|
3524
|
+
setPickerPos(placePicker(anchor));
|
|
3525
|
+
}
|
|
3526
|
+
function closePicker() {
|
|
3527
|
+
setPickerDotKey(null);
|
|
3528
|
+
setPickerPos(null);
|
|
3529
|
+
}
|
|
3530
|
+
react.useEffect(() => {
|
|
3531
|
+
if (!pickerOpen) return;
|
|
3532
|
+
function onPointerDown(e) {
|
|
3533
|
+
const target = e.target instanceof Element ? e.target : null;
|
|
3534
|
+
if (!target) return;
|
|
3535
|
+
if (pickerPopRef.current?.contains(target)) return;
|
|
3536
|
+
if (pickerAnchorRef.current?.contains(target)) return;
|
|
3537
|
+
closePicker();
|
|
3538
|
+
}
|
|
3539
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3540
|
+
return () => document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3541
|
+
}, [pickerOpen]);
|
|
3542
|
+
react.useEffect(() => {
|
|
3543
|
+
if (!pickerOpen) return;
|
|
3544
|
+
let raf = 0;
|
|
3545
|
+
const update = () => {
|
|
3546
|
+
const anchor = pickerAnchorRef.current;
|
|
3547
|
+
if (!anchor) return;
|
|
3548
|
+
cancelAnimationFrame(raf);
|
|
3549
|
+
raf = requestAnimationFrame(() => setPickerPos(placePicker(anchor)));
|
|
3550
|
+
};
|
|
3551
|
+
window.addEventListener("scroll", update, true);
|
|
3552
|
+
window.addEventListener("resize", update);
|
|
3553
|
+
return () => {
|
|
3554
|
+
window.removeEventListener("scroll", update, true);
|
|
3555
|
+
window.removeEventListener("resize", update);
|
|
3556
|
+
cancelAnimationFrame(raf);
|
|
3557
|
+
};
|
|
3558
|
+
}, [pickerOpen]);
|
|
3243
3559
|
/** Re-read both the list and the active pointer after any list mutation. */
|
|
3244
3560
|
function syncSaved() {
|
|
3245
3561
|
setList(saved.list());
|
|
@@ -3361,6 +3677,12 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3361
3677
|
}
|
|
3362
3678
|
function onKeyDown(e) {
|
|
3363
3679
|
if (e.key !== "Escape") return;
|
|
3680
|
+
if (pickerOpenRef.current) {
|
|
3681
|
+
e.preventDefault();
|
|
3682
|
+
e.stopPropagation();
|
|
3683
|
+
closePicker();
|
|
3684
|
+
return;
|
|
3685
|
+
}
|
|
3364
3686
|
if (confirmCloseRef.current || pendingLeaveRef.current) {
|
|
3365
3687
|
e.preventDefault();
|
|
3366
3688
|
e.stopPropagation();
|
|
@@ -3378,6 +3700,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3378
3700
|
const target = e.target instanceof Element ? e.target : null;
|
|
3379
3701
|
if (!target) return;
|
|
3380
3702
|
if (target.closest("[data-ct-editor]")) return;
|
|
3703
|
+
if (target.closest("[role=\"menu\"]")) return;
|
|
3381
3704
|
const panel = settingsPanel();
|
|
3382
3705
|
if (!!panel && !panel.contains(target) || isCloseButton(target)) {
|
|
3383
3706
|
if (!onRequestClose) return;
|
|
@@ -3414,6 +3737,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3414
3737
|
}, [onRequestClose]);
|
|
3415
3738
|
/** Open a fresh, unsaved theme seeded from the currently selected preset. */
|
|
3416
3739
|
function startAdd() {
|
|
3740
|
+
closePicker();
|
|
3417
3741
|
const origin = beginEditing(null, nextThemeName(t("custom.defaultName"), list.map((e) => e.name)), "", getCustom().theme);
|
|
3418
3742
|
setCustomBase(shownPreset);
|
|
3419
3743
|
const draft = resetCustom();
|
|
@@ -3422,6 +3746,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3422
3746
|
}
|
|
3423
3747
|
/** Open an existing card for editing; it also becomes the previewed theme. */
|
|
3424
3748
|
function startEdit(entry) {
|
|
3749
|
+
closePicker();
|
|
3425
3750
|
const next = beginEditing(entry.id, entry.name, entry.name, entry.theme);
|
|
3426
3751
|
setEditing(next);
|
|
3427
3752
|
onLoadSaved(entry.id);
|
|
@@ -3429,6 +3754,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3429
3754
|
/** Discard the open editor and put the previously applied theme back. */
|
|
3430
3755
|
function cancelEdit() {
|
|
3431
3756
|
if (!editing) return;
|
|
3757
|
+
closePicker();
|
|
3432
3758
|
revertEditing(editing);
|
|
3433
3759
|
setEditing(null);
|
|
3434
3760
|
syncSaved();
|
|
@@ -3491,6 +3817,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3491
3817
|
/** Commit the open editor: create a new entry, or update the one being edited. */
|
|
3492
3818
|
async function saveEdit() {
|
|
3493
3819
|
if (!editing) return;
|
|
3820
|
+
closePicker();
|
|
3494
3821
|
const name = editing.name.trim() || t("custom.defaultName");
|
|
3495
3822
|
const id = editing.id;
|
|
3496
3823
|
savingRef.current = true;
|
|
@@ -3547,6 +3874,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3547
3874
|
setCustomState(getCustom().theme);
|
|
3548
3875
|
return;
|
|
3549
3876
|
}
|
|
3877
|
+
closePicker();
|
|
3550
3878
|
if (editing) revertEditing(editing);
|
|
3551
3879
|
setEditing(null);
|
|
3552
3880
|
setSelectionState(shownPreset);
|
|
@@ -3590,10 +3918,21 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3590
3918
|
onSelect: (v) => pickPreset(v),
|
|
3591
3919
|
disabled: customOn
|
|
3592
3920
|
})),
|
|
3921
|
+
react.createElement("div", {
|
|
3922
|
+
className: "ct-row",
|
|
3923
|
+
key: "sidebar-transparency"
|
|
3924
|
+
}, react.createElement("div", { className: "ct-row-main" }, react.createElement("div", { className: "ct-row-title" }, t("sidebar.title")), react.createElement("div", { className: "ct-row-desc" }, t("sidebar.desc"))), react.createElement(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
3925
|
+
checked: sidebarTransparent,
|
|
3926
|
+
label: t("sidebar.title"),
|
|
3927
|
+
onChange: (on) => {
|
|
3928
|
+
setSidebarTransparentState(on);
|
|
3929
|
+
setSidebarTransparent(on);
|
|
3930
|
+
}
|
|
3931
|
+
})),
|
|
3593
3932
|
react.createElement("div", {
|
|
3594
3933
|
className: "ct-row ct-row-flush",
|
|
3595
3934
|
key: "custom-toggle"
|
|
3596
|
-
}, react.createElement("div", { className: "ct-row-main" }, react.createElement("div", { className: "ct-row-title" }, t("custom.title")), react.createElement("div", { className: "ct-row-desc" }, t("custom.toggle.desc"))), react.createElement(Switch, {
|
|
3935
|
+
}, react.createElement("div", { className: "ct-row-main" }, react.createElement("div", { className: "ct-row-title" }, t("custom.title")), react.createElement("div", { className: "ct-row-desc" }, t("custom.toggle.desc"))), react.createElement(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
3597
3936
|
checked: customOn,
|
|
3598
3937
|
label: t("custom.title"),
|
|
3599
3938
|
onChange: toggleCustom
|
|
@@ -3604,18 +3943,21 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3604
3943
|
const dotRow = (key, label, dots) => react.createElement("div", {
|
|
3605
3944
|
className: "ct-seed-row",
|
|
3606
3945
|
key
|
|
3607
|
-
}, react.createElement("div", { className: "ct-seed-label" }, label), react.createElement("div", { className: "ct-seed-dots" }, ...dots.map((d) => react.createElement(
|
|
3946
|
+
}, react.createElement("div", { className: "ct-seed-label" }, label), react.createElement("div", { className: "ct-seed-dots" }, ...dots.map((d) => react.createElement(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
3608
3947
|
key: d.key,
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3948
|
+
label: d.name,
|
|
3949
|
+
side: "top",
|
|
3950
|
+
gap: 6,
|
|
3951
|
+
children: react.createElement("button", {
|
|
3952
|
+
type: "button",
|
|
3953
|
+
className: "ct-seed-dot",
|
|
3954
|
+
style: { background: d.value },
|
|
3955
|
+
"aria-haspopup": "dialog",
|
|
3956
|
+
"aria-expanded": pickerDotKey === d.key,
|
|
3957
|
+
"aria-label": `${d.name} — ${d.hint}`,
|
|
3958
|
+
onClick: (e) => togglePicker(d.key, e.currentTarget)
|
|
3959
|
+
})
|
|
3960
|
+
}))));
|
|
3619
3961
|
const pair = (key, title, desc) => ({
|
|
3620
3962
|
key,
|
|
3621
3963
|
name: t(title),
|
|
@@ -3672,21 +4014,24 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3672
4014
|
})
|
|
3673
4015
|
}));
|
|
3674
4016
|
/** The light/dark segmented control above the dots. */
|
|
3675
|
-
const
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
4017
|
+
const modeToggle = react.createElement(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
|
|
4018
|
+
id: SEED_MODE_CONTROL_ID,
|
|
4019
|
+
value: seedMode,
|
|
4020
|
+
options: [{
|
|
4021
|
+
value: "light",
|
|
4022
|
+
label: t("custom.seed.light")
|
|
4023
|
+
}, {
|
|
4024
|
+
value: "dark",
|
|
4025
|
+
label: t("custom.seed.dark")
|
|
4026
|
+
}],
|
|
4027
|
+
onChange: (next) => {
|
|
4028
|
+
const mode = next;
|
|
4029
|
+
setSeedMode(mode);
|
|
4030
|
+
previewAppearance(mode);
|
|
4031
|
+
},
|
|
4032
|
+
label: t("custom.mode.label"),
|
|
4033
|
+
className: "ct-mode"
|
|
4034
|
+
});
|
|
3690
4035
|
const editorName = react.createElement("input", {
|
|
3691
4036
|
className: "ct-editor-name",
|
|
3692
4037
|
type: "text",
|
|
@@ -3703,20 +4048,40 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3703
4048
|
else if (e.key === "Escape") cancelEdit();
|
|
3704
4049
|
}
|
|
3705
4050
|
});
|
|
3706
|
-
const editorActions = react.createElement("div", { className: "ct-editor-actions" }, react.createElement(
|
|
3707
|
-
|
|
3708
|
-
className: "ct-btn",
|
|
4051
|
+
const editorActions = react.createElement("div", { className: "ct-editor-actions" }, react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4052
|
+
variant: "outline",
|
|
3709
4053
|
onClick: cancelEdit
|
|
3710
|
-
}, t("custom.cancel")), react.createElement(
|
|
3711
|
-
|
|
3712
|
-
className: "ct-btn ct-btn-primary",
|
|
4054
|
+
}, t("custom.cancel")), react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4055
|
+
variant: "primary",
|
|
3713
4056
|
onClick: () => void saveEdit()
|
|
3714
4057
|
}, t("custom.save")));
|
|
4058
|
+
const pickerDot = pickerDotKey ? [...seedDots, ...shikiDots].find((d) => d.key === pickerDotKey) ?? null : null;
|
|
4059
|
+
const pickerPop = pickerDot && pickerPos ? react.createElement("div", {
|
|
4060
|
+
key: "color-picker",
|
|
4061
|
+
className: "ct-color-pop",
|
|
4062
|
+
ref: pickerPopRef,
|
|
4063
|
+
style: {
|
|
4064
|
+
left: pickerPos.left,
|
|
4065
|
+
top: pickerPos.top
|
|
4066
|
+
}
|
|
4067
|
+
}, react.createElement(Z, {
|
|
4068
|
+
color: pickerDot.value,
|
|
4069
|
+
onChange: (v) => pickerDot.onChange(v.toUpperCase())
|
|
4070
|
+
}), react.createElement(Oe, {
|
|
4071
|
+
className: "ct-hex-input",
|
|
4072
|
+
color: pickerDot.value,
|
|
4073
|
+
"aria-label": pickerDot.name,
|
|
4074
|
+
onChange: (v) => pickerDot.onChange(v.toUpperCase())
|
|
4075
|
+
})) : null;
|
|
3715
4076
|
const editorCard = (key) => react.createElement("div", {
|
|
3716
4077
|
className: "ct-editor",
|
|
3717
4078
|
key,
|
|
3718
4079
|
"data-ct-editor": "true"
|
|
3719
|
-
}, react.createElement("div", { className: "ct-editor-head" }, editorName, modeToggle),
|
|
4080
|
+
}, react.createElement("div", { className: "ct-editor-head" }, editorName, modeToggle), react.createElement("div", {
|
|
4081
|
+
role: "tabpanel",
|
|
4082
|
+
id: `${SEED_MODE_CONTROL_ID}-${seedMode}-panel`,
|
|
4083
|
+
"aria-labelledby": `${SEED_MODE_CONTROL_ID}-${seedMode}`
|
|
4084
|
+
}, dotRow("seeds", t("custom.group.seeds"), seedDots), dotRow("shiki", t("custom.group.shiki"), shikiDots)), editorActions, pickerPop);
|
|
3720
4085
|
const cards = list.map((entry) => editing && editing.id === entry.id ? editorCard(entry.id) : react.createElement(ThemeCard, {
|
|
3721
4086
|
key: entry.id,
|
|
3722
4087
|
entry,
|
|
@@ -3741,13 +4106,13 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3741
4106
|
className: "ct-add-btn",
|
|
3742
4107
|
disabled: importing,
|
|
3743
4108
|
onClick: startImport
|
|
3744
|
-
}, react.createElement(
|
|
4109
|
+
}, react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutlineRegular, { size: ICON_SIZE }), t("custom.import")), react.createElement("button", {
|
|
3745
4110
|
key: "add",
|
|
3746
4111
|
type: "button",
|
|
3747
4112
|
className: "ct-add-btn",
|
|
3748
4113
|
disabled: editing !== null,
|
|
3749
4114
|
onClick: startAdd
|
|
3750
|
-
}, react.createElement(
|
|
4115
|
+
}, react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: ICON_SIZE }), t("custom.add")), react.createElement("input", {
|
|
3751
4116
|
key: "import-input",
|
|
3752
4117
|
ref: importInputRef,
|
|
3753
4118
|
type: "file",
|
|
@@ -3762,6 +4127,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3762
4127
|
description: t("custom.delete.desc").replace("{0}", pendingDelete.name),
|
|
3763
4128
|
confirmLabel: t("custom.delete"),
|
|
3764
4129
|
cancelLabel: t("custom.cancel"),
|
|
4130
|
+
danger: true,
|
|
3765
4131
|
onConfirm: onConfirmDelete,
|
|
3766
4132
|
onCancel: () => setPendingDelete(null)
|
|
3767
4133
|
}));
|
|
@@ -3794,20 +4160,12 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3794
4160
|
},
|
|
3795
4161
|
onCancel: () => setPendingLeave(null)
|
|
3796
4162
|
}));
|
|
3797
|
-
if (toast) {
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
icon: react.createElement(ToastBadge),
|
|
3804
|
-
onDone
|
|
3805
|
-
}) : react.createElement(Toast, {
|
|
3806
|
-
key: `toast-${String(toast.seq)}`,
|
|
3807
|
-
text: toast.text,
|
|
3808
|
-
onDone
|
|
3809
|
-
}));
|
|
3810
|
-
}
|
|
4163
|
+
if (toast) children.push(react.createElement(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
4164
|
+
key: `toast-${String(toast.seq)}`,
|
|
4165
|
+
text: toast.text,
|
|
4166
|
+
tone: "success",
|
|
4167
|
+
onDone: () => setToast((cur) => cur?.seq === toast.seq ? null : cur)
|
|
4168
|
+
}));
|
|
3811
4169
|
return react.createElement("div", { style: {
|
|
3812
4170
|
display: "flex",
|
|
3813
4171
|
flexDirection: "column",
|
|
@@ -3830,6 +4188,8 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3830
4188
|
"presets.title": "预设主题",
|
|
3831
4189
|
"presets.desc": "一键套用主流配色方案",
|
|
3832
4190
|
"presets.disabled": "自定义主题已启用,关闭后才能选择预设",
|
|
4191
|
+
"sidebar.title": "侧边栏透明",
|
|
4192
|
+
"sidebar.desc": "侧边栏面板透明效果,仅 Mac 端生效",
|
|
3833
4193
|
"scheme.light": "浅色",
|
|
3834
4194
|
"scheme.dark": "深色",
|
|
3835
4195
|
"scheme.system": "跟随系统",
|
|
@@ -3903,6 +4263,8 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3903
4263
|
"presets.title": "Preset themes",
|
|
3904
4264
|
"presets.desc": "Apply popular color schemes in one click",
|
|
3905
4265
|
"presets.disabled": "Custom theme is on — turn it off to choose a preset",
|
|
4266
|
+
"sidebar.title": "Transparent sidebar",
|
|
4267
|
+
"sidebar.desc": "Sidebar panel transparency effect, macOS only",
|
|
3906
4268
|
"scheme.light": "Light",
|
|
3907
4269
|
"scheme.dark": "Dark",
|
|
3908
4270
|
"scheme.system": "System",
|
|
@@ -3978,19 +4340,6 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3978
4340
|
".ct-select-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;}",
|
|
3979
4341
|
".ct-select-chevron{flex:none;color:var(--dsw-alias-label-tertiary);display:inline-flex;transition:transform 120ms ease;}",
|
|
3980
4342
|
".ct-select[aria-expanded=\"true\"] .ct-select-chevron{transform:rotate(180deg);}",
|
|
3981
|
-
".ct-menu-list{box-sizing:border-box;padding:4px;display:flex;flex-direction:column;gap:0;border:1px solid var(--dsw-alias-border-inverted);border-radius:12px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv3);min-width:218px;max-width:360px;max-height:min(320px,50vh);overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l2) transparent;scrollbar-gutter:stable;}",
|
|
3982
|
-
".ct-menu-list:not(:hover){scrollbar-color:transparent transparent;}",
|
|
3983
|
-
".ct-menu-list::-webkit-scrollbar{width:8px;height:8px;}",
|
|
3984
|
-
".ct-menu-list::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l2);border-radius:999px;border:2px solid var(--dsw-specific-menu);background-clip:content-box;transition:background 150ms ease, border-color 150ms ease;}",
|
|
3985
|
-
".ct-menu-list::-webkit-scrollbar-thumb:hover{background:var(--dsw-alias-label-tertiary);border:2px solid var(--dsw-specific-menu);background-clip:content-box;}",
|
|
3986
|
-
".ct-menu-list::-webkit-scrollbar-thumb:active{background:var(--dsw-alias-label-secondary, var(--dsw-alias-label-tertiary));border:2px solid var(--dsw-specific-menu);background-clip:content-box;}",
|
|
3987
|
-
".ct-menu-list:not(:hover)::-webkit-scrollbar-thumb{background:transparent;border-color:transparent;}",
|
|
3988
|
-
".ct-menu-list::-webkit-scrollbar-track{background:transparent;margin:4px 0;}",
|
|
3989
|
-
".ct-menu-list::-webkit-scrollbar-corner{background:transparent;}",
|
|
3990
|
-
".ct-menu-item{display:flex;align-items:center;gap:8px;width:100%;min-height:40px;padding:8px 10px;border:none;border-radius:10px;background:transparent;cursor:pointer;font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary);text-align:left;font-family:inherit;}",
|
|
3991
|
-
".ct-menu-item:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);}",
|
|
3992
|
-
".ct-menu-check{flex:none;color:var(--dsw-alias-label-primary);display:inline-flex;margin-left:auto;}",
|
|
3993
|
-
".ct-menu-item-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}",
|
|
3994
4343
|
".ct-row{border-bottom:1px solid var(--dsw-alias-border-l2);padding:16px 2px;display:flex;align-items:center;gap:16px;}",
|
|
3995
4344
|
".ct-row:last-child{border-bottom:none;}",
|
|
3996
4345
|
".ct-row-flush{border-bottom:none;}",
|
|
@@ -4000,13 +4349,12 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4000
4349
|
".ct-seed-row{display:flex;align-items:center;gap:16px;padding:12px 0;}",
|
|
4001
4350
|
".ct-seed-label{flex:0 0 auto;min-width:96px;padding-left:3px;font-size:14px;line-height:22px;color:var(--dsw-alias-label-primary);}",
|
|
4002
4351
|
".ct-seed-dots{flex:1 1 auto;display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:10px;}",
|
|
4003
|
-
".ct-seed-dot{position:relative;box-sizing:border-box;display:inline-block;flex:none;width:26px;height:26px;border:1px solid var(--dsw-alias-border-l2);border-radius:50%;cursor:pointer;}",
|
|
4004
|
-
".ct-seed-
|
|
4005
|
-
".ct-
|
|
4006
|
-
".ct-
|
|
4007
|
-
".ct-
|
|
4008
|
-
".ct-
|
|
4009
|
-
"@media (prefers-reduced-motion: reduce){.ct-tip::after{transition:none;}}",
|
|
4352
|
+
".ct-seed-dot{position:relative;box-sizing:border-box;display:inline-block;flex:none;width:26px;height:26px;padding:0;border:1px solid var(--dsw-alias-border-l2);border-radius:50%;cursor:pointer;font:inherit;}",
|
|
4353
|
+
".ct-seed-dot:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
4354
|
+
".ct-color-pop{position:fixed;z-index:1200;box-sizing:border-box;width:224px;padding:12px;border:1px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-shadow-lv3);display:flex;flex-direction:column;gap:10px;}",
|
|
4355
|
+
".ct-color-pop .react-colorful{width:198px;height:170px;}",
|
|
4356
|
+
".ct-color-pop .ct-hex-input{box-sizing:border-box;width:100%;height:34px;padding:0 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:13px;line-height:20px;text-align:center;outline:none;}",
|
|
4357
|
+
".ct-color-pop .ct-hex-input:focus{border-color:var(--dsw-alias-border-l3);}",
|
|
4010
4358
|
".ct-list{margin-top:4px;display:flex;flex-direction:column;gap:8px;}",
|
|
4011
4359
|
".ct-list-row{display:flex;align-items:center;gap:10px;padding:12px 14px;border:.5px solid var(--dsw-alias-border-l4);border-radius:16px;background:transparent;cursor:pointer;transition:border-color .16s ease,background .16s ease;}",
|
|
4012
4360
|
".ct-list-row:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
@@ -4016,7 +4364,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4016
4364
|
".ct-list-actions{display:inline-flex;align-items:center;gap:4px;flex:none;margin-left:auto;}",
|
|
4017
4365
|
".ct-list-badge{display:inline-flex;align-items:center;height:28px;padding:0 10px;border-radius:14px;background:var(--dsw-alias-bg-module-platform,var(--dsw-alias-bg-layer-2));color:var(--dsw-alias-label-secondary,var(--dsw-alias-label-tertiary));font-size:12px;line-height:18px;white-space:nowrap;}",
|
|
4018
4366
|
".ct-list-badge + .ct-list-btn{margin-left:8px;}",
|
|
4019
|
-
".ct-list-btn{
|
|
4367
|
+
".ct-list-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;height:28px;width:28px;padding:0;border:none;border-radius:14px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;line-height:0;}",
|
|
4020
4368
|
".ct-list-btn:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4021
4369
|
".ct-list-btn:active{background:var(--dsw-alias-interactive-bg-active);}",
|
|
4022
4370
|
".ct-list-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
@@ -4025,19 +4373,15 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4025
4373
|
".ct-list-btn-danger{color:var(--dsw-alias-state-error-primary);}",
|
|
4026
4374
|
".ct-list-btn-danger:hover{background:var(--dsw-alias-interactive-bg-hover-danger);}",
|
|
4027
4375
|
".ct-list-btn-danger:active{background:var(--dsw-alias-interactive-bg-hover-danger);}",
|
|
4028
|
-
".ct-editor{padding:16px;border:.5px solid var(--dsw-alias-border-l4);border-radius:
|
|
4376
|
+
".ct-editor{padding:16px;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);background:transparent;display:flex;flex-direction:column;gap:0;}",
|
|
4029
4377
|
".ct-editor-head{display:flex;align-items:center;gap:10px;padding-bottom:12px;}",
|
|
4030
4378
|
".ct-editor-name{flex:1 1 auto;min-width:0;box-sizing:border-box;height:36px;padding:0 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:transparent;color:var(--dsw-alias-label-primary);font:inherit;font-size:14px;line-height:22px;}",
|
|
4031
4379
|
".ct-editor-name::placeholder{color:var(--dsw-alias-label-tertiary);}",
|
|
4032
4380
|
".ct-editor-name:hover{border-color:var(--dsw-alias-border-l3);}",
|
|
4033
4381
|
".ct-editor-name:focus{outline:none;border-color:var(--dsw-alias-border-l3);background:var(--dsw-alias-bg-base);}",
|
|
4034
|
-
".ct-mode{
|
|
4035
|
-
".ct-mode-btn{box-sizing:border-box;height:32px;padding:0 10px;border:none;border-radius:8px;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;font:inherit;font-size:12px;line-height:18px;}",
|
|
4036
|
-
".ct-mode-btn:hover{color:var(--dsw-alias-label-primary);}",
|
|
4037
|
-
".ct-mode-btn-on{background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary);}",
|
|
4038
|
-
".ct-mode-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
4382
|
+
".ct-mode{flex:none;}",
|
|
4039
4383
|
".ct-editor-actions{display:flex;justify-content:flex-end;gap:12px;padding-top:12px;}",
|
|
4040
|
-
".ct-add-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:6px;width:100%;height:44px;margin-top:8px;padding:0 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:
|
|
4384
|
+
".ct-add-btn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:6px;width:100%;height:44px;margin-top:8px;padding:0 14px;border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg);background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:14px;line-height:22px;}",
|
|
4041
4385
|
".ct-add-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4042
4386
|
".ct-add-btn:disabled{opacity:.4;cursor:default;}",
|
|
4043
4387
|
".ct-add-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
@@ -4045,28 +4389,13 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4045
4389
|
".ct-add-row .ct-add-btn{flex:1 1 0;width:auto;margin-top:0;min-width:0;}",
|
|
4046
4390
|
".ct-modal-root{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px;}",
|
|
4047
4391
|
".ct-modal-mask{position:absolute;inset:0;background:var(--dsw-alias-bg-mask-1,rgba(0,0,0,.24));backdrop-filter:var(--dsw-mask-blur,blur(2px));}",
|
|
4048
|
-
".ct-modal-card{position:relative;z-index:1;display:flex;flex-direction:column;gap:12px;width:min(380px,100%);padding:24px;border-radius:
|
|
4392
|
+
".ct-modal-card{position:relative;z-index:1;display:flex;flex-direction:column;gap:12px;width:min(380px,100%);padding:24px;border-radius:var(--dsw-radius-panel);background:var(--dsw-alias-bg-layer-2);box-shadow:var(--dsw-elevation-prominent);}",
|
|
4049
4393
|
".ct-modal-title{font-size:16px;line-height:24px;font-weight:600;color:var(--dsw-alias-label-primary);}",
|
|
4050
4394
|
".ct-modal-desc{font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary);}",
|
|
4051
4395
|
".ct-modal-footer{display:flex;justify-content:flex-end;gap:12px;margin-top:12px;}",
|
|
4052
|
-
".ct-
|
|
4053
|
-
".ct-
|
|
4054
|
-
".ct-
|
|
4055
|
-
".ct-switch-on .ct-switch-knob{transform:translateX(16px);}",
|
|
4056
|
-
".ct-switch:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
4057
|
-
".ct-btn{box-sizing:border-box;display:inline-flex;align-items:center;height:34px;padding:0 16px;border:1px solid var(--dsw-alias-border-l2);border-radius:17px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:20px;}",
|
|
4058
|
-
".ct-btn:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4059
|
-
".ct-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
4060
|
-
".ct-btn-primary{background:var(--dsw-static-deepseek-500,rgb(65,118,230));border-color:transparent;color:#fff;}",
|
|
4061
|
-
".ct-btn-primary:hover{background:var(--dsw-static-deepseek-450,var(--dsw-static-deepseek-500,rgb(86,134,254)));}",
|
|
4062
|
-
".ct-btn-danger{background:var(--dsw-static-red-500,rgb(239,68,68));border-color:transparent;color:#fff;}",
|
|
4063
|
-
".ct-btn-danger:hover{background:var(--dsw-static-red-600,var(--dsw-static-red-500,rgb(236,19,19)));}",
|
|
4064
|
-
".ct-toast{position:fixed;top:40px;left:50%;z-index:1100;pointer-events:none;display:flex;align-items:center;gap:10px;width:max-content;max-width:min(640px,calc(100vw - 48px));padding:12px 16px;border-radius:14px;background:var(--dsw-alias-button-contrast-fill);color:var(--dsw-alias-label-primary-inverted);font-size:14px;line-height:22px;box-shadow:var(--dsw-shadow-lv3);transform:translateX(-50%);animation:ct-toast-in 160ms ease-out,ct-toast-fade 1s ease 3s forwards;}",
|
|
4065
|
-
".ct-toast-icon{display:grid;place-items:center;flex:none;width:18px;height:18px;border:1.5px solid var(--dsw-alias-state-success-primary);border-radius:50%;corner-shape:round;color:var(--dsw-alias-state-success-primary);}",
|
|
4066
|
-
".ct-toast-text{min-width:0;}",
|
|
4067
|
-
"@keyframes ct-toast-in{from{opacity:0;transform:translate(-50%,-6px);}to{opacity:1;transform:translate(-50%,0);}}",
|
|
4068
|
-
"@keyframes ct-toast-fade{to{opacity:0;}}",
|
|
4069
|
-
"@media (prefers-reduced-motion: reduce){.ct-toast{animation:ct-toast-fade 1s ease 3s forwards;}}"
|
|
4396
|
+
".ct-action-cancel{min-width:72px}",
|
|
4397
|
+
".ct-action-confirm{min-width:136px}",
|
|
4398
|
+
"button.ct-danger{color:var(--dsw-alias-state-error-primary);border-color:color-mix(in srgb, var(--dsw-alias-state-error-primary) 30%, transparent);--dsw-alias-interactive-bg-hover:color-mix(in srgb, var(--dsw-alias-state-error-primary) 8%, transparent);}"
|
|
4070
4399
|
].join("\n");
|
|
4071
4400
|
function isValidSelection(v) {
|
|
4072
4401
|
return !!v && (v === CUSTOM_SELECTION || NOOP_PRESET_IDS.has(v) || v in PRESETS);
|
|
@@ -4122,6 +4451,25 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4122
4451
|
else localStorage.setItem(key, value);
|
|
4123
4452
|
} catch {}
|
|
4124
4453
|
}
|
|
4454
|
+
const SIDEBAR_OPAQUE_CSS = "html[data-platform=\"darwin\"] [class*=\"sidebarCol\"]:not([class*=\"sidebarCollapsed\"]){background:var(--dsw-specific-sidebar-fill) !important;}";
|
|
4455
|
+
let sidebarOpaqueDisposer = null;
|
|
4456
|
+
/**
|
|
4457
|
+
* Whether the sidebar keeps DSH's translucency. Only an explicit '1' turns it
|
|
4458
|
+
* on: an absent key means opaque, which is the state a fresh install starts in.
|
|
4459
|
+
*/
|
|
4460
|
+
function sidebarTransparent() {
|
|
4461
|
+
return readRaw(SIDEBAR_TRANSPARENT_STORAGE_KEY) === "1";
|
|
4462
|
+
}
|
|
4463
|
+
/** Paint the sidebar column opaque (on), or hand it back to DSH (off). */
|
|
4464
|
+
function applySidebarOpaque(opaque) {
|
|
4465
|
+
if (opaque) {
|
|
4466
|
+
if (!sidebarOpaqueDisposer) sidebarOpaqueDisposer = injector.insert(SIDEBAR_OPAQUE_CSS);
|
|
4467
|
+
} else if (sidebarOpaqueDisposer) sidebarOpaqueDisposer = release(sidebarOpaqueDisposer);
|
|
4468
|
+
}
|
|
4469
|
+
function setSidebarTransparent(on) {
|
|
4470
|
+
writeRaw(SIDEBAR_TRANSPARENT_STORAGE_KEY, on ? "1" : "0");
|
|
4471
|
+
applySidebarOpaque(!on);
|
|
4472
|
+
}
|
|
4125
4473
|
function getSelection() {
|
|
4126
4474
|
for (const key of [THEME_STORAGE_KEY, THEME_STORAGE_KEY_LEGACY]) {
|
|
4127
4475
|
const cur = readRaw(key);
|
|
@@ -4189,8 +4537,8 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4189
4537
|
/**
|
|
4190
4538
|
* Coalesce a burst of palette applications into one.
|
|
4191
4539
|
*
|
|
4192
|
-
* A
|
|
4193
|
-
*
|
|
4540
|
+
* A colour picker fires continuously while its slider is dragged. Each
|
|
4541
|
+
* application rebuilds both ramps, rewrites every token on
|
|
4194
4542
|
* `body` and forces a style flush in the shell's presenter, so applying once
|
|
4195
4543
|
* per event is what makes the colour editor stutter. The first change lands
|
|
4196
4544
|
* immediately and the rest are throttled to one per interval, newest request
|
|
@@ -4345,13 +4693,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4345
4693
|
if (env && isPresetId(env.base)) lastPreset = env.base;
|
|
4346
4694
|
}
|
|
4347
4695
|
apply(initialSelection);
|
|
4348
|
-
|
|
4349
|
-
const modules = ctx.get("modules");
|
|
4350
|
-
try {
|
|
4351
|
-
modules?.import?.("@deepseek-ai/dsh-client-ui-primitives").then((mod) => {
|
|
4352
|
-
if (typeof mod?.Toast === "function") sharedToast = mod.Toast;
|
|
4353
|
-
}).catch(() => {});
|
|
4354
|
-
} catch {}
|
|
4696
|
+
applySidebarOpaque(!sidebarTransparent());
|
|
4355
4697
|
ctx.effect(() => () => {
|
|
4356
4698
|
disposed = true;
|
|
4357
4699
|
cancelApply();
|
|
@@ -4359,6 +4701,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4359
4701
|
baselineDisposer = release(baselineDisposer);
|
|
4360
4702
|
overrideDispose = release(overrideDispose);
|
|
4361
4703
|
fallbackDispose = release(fallbackDispose);
|
|
4704
|
+
sidebarOpaqueDisposer = release(sidebarOpaqueDisposer);
|
|
4362
4705
|
injector.disposeAll();
|
|
4363
4706
|
});
|
|
4364
4707
|
slots.inject("settings.section", () => {
|
|
@@ -4379,7 +4722,8 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4379
4722
|
setCustomBase,
|
|
4380
4723
|
resetCustom,
|
|
4381
4724
|
saved,
|
|
4382
|
-
|
|
4725
|
+
getSidebarTransparent: sidebarTransparent,
|
|
4726
|
+
setSidebarTransparent,
|
|
4383
4727
|
onRequestClose: typeof props?.close === "function" ? props.close : null
|
|
4384
4728
|
}));
|
|
4385
4729
|
});
|