dsh-cool-theme 0.6.1 → 0.6.2
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/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.
|
|
@@ -2301,6 +2302,432 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2301
2302
|
};
|
|
2302
2303
|
}
|
|
2303
2304
|
//#endregion
|
|
2305
|
+
//#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
|
|
2306
|
+
function l() {
|
|
2307
|
+
return (l = Object.assign || function(e) {
|
|
2308
|
+
for (var r = 1; r < arguments.length; r++) {
|
|
2309
|
+
var n = arguments[r];
|
|
2310
|
+
for (var t in n) Object.prototype.hasOwnProperty.call(n, t) && (e[t] = n[t]);
|
|
2311
|
+
}
|
|
2312
|
+
return e;
|
|
2313
|
+
}).apply(this, arguments);
|
|
2314
|
+
}
|
|
2315
|
+
function c(e, r) {
|
|
2316
|
+
if (null == e) return {};
|
|
2317
|
+
var n, t, o = {}, a = Object.keys(e);
|
|
2318
|
+
for (t = 0; t < a.length; t++) r.indexOf(n = a[t]) >= 0 || (o[n] = e[n]);
|
|
2319
|
+
return o;
|
|
2320
|
+
}
|
|
2321
|
+
function i(e) {
|
|
2322
|
+
var n = (0, react.useRef)(e), t = (0, react.useRef)(function(e) {
|
|
2323
|
+
n.current && n.current(e);
|
|
2324
|
+
});
|
|
2325
|
+
return n.current = e, t.current;
|
|
2326
|
+
}
|
|
2327
|
+
var s = function(e, r, n) {
|
|
2328
|
+
return void 0 === r && (r = 0), void 0 === n && (n = 1), e > n ? n : e < r ? r : e;
|
|
2329
|
+
};
|
|
2330
|
+
var f = function(e) {
|
|
2331
|
+
return "touches" in e;
|
|
2332
|
+
};
|
|
2333
|
+
var d = function(e) {
|
|
2334
|
+
return e && e.ownerDocument.defaultView || self;
|
|
2335
|
+
};
|
|
2336
|
+
var v = function(e, r, n) {
|
|
2337
|
+
var t = e.getBoundingClientRect(), o = f(r) ? function(e, r) {
|
|
2338
|
+
for (var n = 0; n < e.length; n++) if (e[n].identifier === r) return e[n];
|
|
2339
|
+
return e[0];
|
|
2340
|
+
}(r.touches, n) : r;
|
|
2341
|
+
return {
|
|
2342
|
+
left: s((o.pageX - (t.left + d(e).pageXOffset)) / t.width),
|
|
2343
|
+
top: s((o.pageY - (t.top + d(e).pageYOffset)) / t.height)
|
|
2344
|
+
};
|
|
2345
|
+
};
|
|
2346
|
+
var h = function(e) {
|
|
2347
|
+
!f(e) && e.preventDefault();
|
|
2348
|
+
};
|
|
2349
|
+
var g = react.default.memo(function(o) {
|
|
2350
|
+
var a = o.onMove, u = o.onKey, s = o.onEnd, g = c(o, [
|
|
2351
|
+
"onMove",
|
|
2352
|
+
"onKey",
|
|
2353
|
+
"onEnd"
|
|
2354
|
+
]), 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() {
|
|
2355
|
+
var e = function(e) {
|
|
2356
|
+
h(e), (f(e) ? e.touches.length > 0 : e.buttons > 0) && m.current ? p(v(m.current, e, E.current)) : (n(!1), _());
|
|
2357
|
+
}, r = function() {
|
|
2358
|
+
n(!1), _();
|
|
2359
|
+
};
|
|
2360
|
+
function n(n) {
|
|
2361
|
+
var t = C.current, o = d(m.current), a = n ? o.addEventListener : o.removeEventListener;
|
|
2362
|
+
a(t ? "touchmove" : "mousemove", e), a(t ? "touchend" : "mouseup", r);
|
|
2363
|
+
}
|
|
2364
|
+
return [
|
|
2365
|
+
function(e) {
|
|
2366
|
+
var r = e.nativeEvent, t = m.current;
|
|
2367
|
+
if (t && (h(r), !function(e, r) {
|
|
2368
|
+
return r && !f(e);
|
|
2369
|
+
}(r, C.current) && t)) {
|
|
2370
|
+
if (f(r)) {
|
|
2371
|
+
C.current = !0;
|
|
2372
|
+
var o = r.changedTouches || [];
|
|
2373
|
+
o.length && (E.current = o[0].identifier);
|
|
2374
|
+
}
|
|
2375
|
+
t.focus(), p(v(t, r, E.current)), n(!0);
|
|
2376
|
+
}
|
|
2377
|
+
},
|
|
2378
|
+
function(e) {
|
|
2379
|
+
var r = e.which || e.keyCode;
|
|
2380
|
+
r < 37 || r > 40 || (e.preventDefault(), b({
|
|
2381
|
+
left: 39 === r ? .05 : 37 === r ? -.05 : 0,
|
|
2382
|
+
top: 40 === r ? .05 : 38 === r ? -.05 : 0
|
|
2383
|
+
}));
|
|
2384
|
+
},
|
|
2385
|
+
function(e) {
|
|
2386
|
+
var r = e.which || e.keyCode;
|
|
2387
|
+
r >= 37 && r <= 40 && _();
|
|
2388
|
+
},
|
|
2389
|
+
n
|
|
2390
|
+
];
|
|
2391
|
+
}, [
|
|
2392
|
+
b,
|
|
2393
|
+
p,
|
|
2394
|
+
_
|
|
2395
|
+
]), H = x[0], M = x[1], N = x[2], w = x[3];
|
|
2396
|
+
return (0, react.useEffect)(function() {
|
|
2397
|
+
return w;
|
|
2398
|
+
}, [w]), react.default.createElement("div", l({}, g, {
|
|
2399
|
+
onTouchStart: H,
|
|
2400
|
+
onMouseDown: H,
|
|
2401
|
+
className: "react-colorful__interactive",
|
|
2402
|
+
ref: m,
|
|
2403
|
+
onKeyDown: M,
|
|
2404
|
+
onKeyUp: N,
|
|
2405
|
+
tabIndex: 0,
|
|
2406
|
+
role: "slider"
|
|
2407
|
+
}));
|
|
2408
|
+
});
|
|
2409
|
+
var m = function(e) {
|
|
2410
|
+
return e.filter(Boolean).join(" ");
|
|
2411
|
+
};
|
|
2412
|
+
var p = function(r) {
|
|
2413
|
+
var n = r.color, t = r.left, o = r.top, a = void 0 === o ? .5 : o, u = m(["react-colorful__pointer", r.className]);
|
|
2414
|
+
return react.default.createElement("div", {
|
|
2415
|
+
className: u,
|
|
2416
|
+
style: {
|
|
2417
|
+
top: 100 * a + "%",
|
|
2418
|
+
left: 100 * t + "%"
|
|
2419
|
+
}
|
|
2420
|
+
}, react.default.createElement("div", {
|
|
2421
|
+
className: "react-colorful__pointer-fill",
|
|
2422
|
+
style: { backgroundColor: n }
|
|
2423
|
+
}));
|
|
2424
|
+
};
|
|
2425
|
+
var b = function(e, r, n) {
|
|
2426
|
+
return void 0 === r && (r = 0), void 0 === n && (n = Math.pow(10, r)), Math.round(n * e) / n;
|
|
2427
|
+
};
|
|
2428
|
+
360 / (2 * Math.PI);
|
|
2429
|
+
var E = function(e) {
|
|
2430
|
+
return L(C(e));
|
|
2431
|
+
};
|
|
2432
|
+
var C = function(e) {
|
|
2433
|
+
return "#" === e[0] && (e = e.substring(1)), e.length < 6 ? {
|
|
2434
|
+
r: parseInt(e[0] + e[0], 16),
|
|
2435
|
+
g: parseInt(e[1] + e[1], 16),
|
|
2436
|
+
b: parseInt(e[2] + e[2], 16),
|
|
2437
|
+
a: 4 === e.length ? b(parseInt(e[3] + e[3], 16) / 255, 2) : 1
|
|
2438
|
+
} : {
|
|
2439
|
+
r: parseInt(e.substring(0, 2), 16),
|
|
2440
|
+
g: parseInt(e.substring(2, 4), 16),
|
|
2441
|
+
b: parseInt(e.substring(4, 6), 16),
|
|
2442
|
+
a: 8 === e.length ? b(parseInt(e.substring(6, 8), 16) / 255, 2) : 1
|
|
2443
|
+
};
|
|
2444
|
+
};
|
|
2445
|
+
var w = function(e) {
|
|
2446
|
+
return B(I(e));
|
|
2447
|
+
};
|
|
2448
|
+
var y = function(e) {
|
|
2449
|
+
var r = e.s, n = e.v, t = e.a, o = (200 - r) * n / 100;
|
|
2450
|
+
return {
|
|
2451
|
+
h: b(e.h),
|
|
2452
|
+
s: b(o > 0 && o < 200 ? r * n / 100 / (o <= 100 ? o : 200 - o) * 100 : 0),
|
|
2453
|
+
l: b(o / 2),
|
|
2454
|
+
a: b(t, 2)
|
|
2455
|
+
};
|
|
2456
|
+
};
|
|
2457
|
+
var k = function(e) {
|
|
2458
|
+
var r = y(e);
|
|
2459
|
+
return "hsl(" + r.h + ", " + r.s + "%, " + r.l + "%)";
|
|
2460
|
+
};
|
|
2461
|
+
var I = function(e) {
|
|
2462
|
+
var r = e.h, n = e.s, t = e.v, o = e.a;
|
|
2463
|
+
r = r / 360 * 6, n /= 100, t /= 100;
|
|
2464
|
+
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;
|
|
2465
|
+
return {
|
|
2466
|
+
r: b(255 * [
|
|
2467
|
+
t,
|
|
2468
|
+
l,
|
|
2469
|
+
u,
|
|
2470
|
+
u,
|
|
2471
|
+
c,
|
|
2472
|
+
t
|
|
2473
|
+
][i]),
|
|
2474
|
+
g: b(255 * [
|
|
2475
|
+
c,
|
|
2476
|
+
t,
|
|
2477
|
+
t,
|
|
2478
|
+
l,
|
|
2479
|
+
u,
|
|
2480
|
+
u
|
|
2481
|
+
][i]),
|
|
2482
|
+
b: b(255 * [
|
|
2483
|
+
u,
|
|
2484
|
+
u,
|
|
2485
|
+
c,
|
|
2486
|
+
t,
|
|
2487
|
+
t,
|
|
2488
|
+
l
|
|
2489
|
+
][i]),
|
|
2490
|
+
a: b(o, 2)
|
|
2491
|
+
};
|
|
2492
|
+
};
|
|
2493
|
+
var K = function(e) {
|
|
2494
|
+
var r = e.toString(16);
|
|
2495
|
+
return r.length < 2 ? "0" + r : r;
|
|
2496
|
+
};
|
|
2497
|
+
var B = function(e) {
|
|
2498
|
+
var r = e.r, n = e.g, t = e.b, o = e.a, a = o < 1 ? K(b(255 * o)) : "";
|
|
2499
|
+
return "#" + K(r) + K(n) + K(t) + a;
|
|
2500
|
+
};
|
|
2501
|
+
var L = function(e) {
|
|
2502
|
+
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;
|
|
2503
|
+
return {
|
|
2504
|
+
h: 60 * (l < 0 ? l + 6 : l),
|
|
2505
|
+
s: a ? u / a * 100 : 0,
|
|
2506
|
+
v: a / 255 * 100,
|
|
2507
|
+
a: o
|
|
2508
|
+
};
|
|
2509
|
+
};
|
|
2510
|
+
var R = react.default.memo(function(r) {
|
|
2511
|
+
var n = r.hue, t = r.onChange, o = r.onChangeEnd, a = m(["react-colorful__hue", r.className]);
|
|
2512
|
+
return react.default.createElement("div", { className: a }, react.default.createElement(g, {
|
|
2513
|
+
onMove: function(e) {
|
|
2514
|
+
t({ h: 360 * e.left });
|
|
2515
|
+
},
|
|
2516
|
+
onKey: function(e) {
|
|
2517
|
+
t({ h: s(n + 360 * e.left, 0, 360) });
|
|
2518
|
+
},
|
|
2519
|
+
onEnd: o,
|
|
2520
|
+
"aria-label": "Hue",
|
|
2521
|
+
"aria-valuenow": b(n),
|
|
2522
|
+
"aria-valuemax": "360",
|
|
2523
|
+
"aria-valuemin": "0"
|
|
2524
|
+
}, react.default.createElement(p, {
|
|
2525
|
+
className: "react-colorful__hue-pointer",
|
|
2526
|
+
left: n / 360,
|
|
2527
|
+
color: k({
|
|
2528
|
+
h: n,
|
|
2529
|
+
s: 100,
|
|
2530
|
+
v: 100,
|
|
2531
|
+
a: 1
|
|
2532
|
+
})
|
|
2533
|
+
})));
|
|
2534
|
+
});
|
|
2535
|
+
var S = react.default.memo(function(r) {
|
|
2536
|
+
var n = r.hsva, t = r.onChange, o = r.onChangeEnd, a = { backgroundColor: k({
|
|
2537
|
+
h: n.h,
|
|
2538
|
+
s: 100,
|
|
2539
|
+
v: 100,
|
|
2540
|
+
a: 1
|
|
2541
|
+
}) };
|
|
2542
|
+
return react.default.createElement("div", {
|
|
2543
|
+
className: "react-colorful__saturation",
|
|
2544
|
+
style: a
|
|
2545
|
+
}, react.default.createElement(g, {
|
|
2546
|
+
onMove: function(e) {
|
|
2547
|
+
t({
|
|
2548
|
+
s: 100 * e.left,
|
|
2549
|
+
v: 100 - 100 * e.top
|
|
2550
|
+
});
|
|
2551
|
+
},
|
|
2552
|
+
onKey: function(e) {
|
|
2553
|
+
t({
|
|
2554
|
+
s: s(n.s + 100 * e.left, 0, 100),
|
|
2555
|
+
v: s(n.v - 100 * e.top, 0, 100)
|
|
2556
|
+
});
|
|
2557
|
+
},
|
|
2558
|
+
onEnd: o,
|
|
2559
|
+
"aria-label": "Color",
|
|
2560
|
+
"aria-valuetext": "Saturation " + b(n.s) + "%, Brightness " + b(n.v) + "%"
|
|
2561
|
+
}, react.default.createElement(p, {
|
|
2562
|
+
className: "react-colorful__saturation-pointer",
|
|
2563
|
+
top: 1 - n.v / 100,
|
|
2564
|
+
left: n.s / 100,
|
|
2565
|
+
color: k(n)
|
|
2566
|
+
})));
|
|
2567
|
+
});
|
|
2568
|
+
var T = function(e, r) {
|
|
2569
|
+
if (e === r) return !0;
|
|
2570
|
+
for (var n in e) if (e[n] !== r[n]) return !1;
|
|
2571
|
+
return !0;
|
|
2572
|
+
};
|
|
2573
|
+
var P = function(e, r) {
|
|
2574
|
+
return e.toLowerCase() === r.toLowerCase() || T(C(e), C(r));
|
|
2575
|
+
};
|
|
2576
|
+
function X(e, n, u, l) {
|
|
2577
|
+
var c = i(u), s = i(l), f = (0, react.useState)(function() {
|
|
2578
|
+
return e.toHsva(n);
|
|
2579
|
+
}), d = f[0], v = f[1], h = (0, react.useRef)({
|
|
2580
|
+
color: n,
|
|
2581
|
+
hsva: d
|
|
2582
|
+
}), g = (0, react.useRef)(!1);
|
|
2583
|
+
(0, react.useEffect)(function() {
|
|
2584
|
+
if (!e.equal(n, h.current.color)) {
|
|
2585
|
+
var r = e.toHsva(n);
|
|
2586
|
+
h.current = {
|
|
2587
|
+
hsva: r,
|
|
2588
|
+
color: n
|
|
2589
|
+
}, v(r), g.current = !1;
|
|
2590
|
+
}
|
|
2591
|
+
}, [n, e]), (0, react.useEffect)(function() {
|
|
2592
|
+
var r;
|
|
2593
|
+
T(d, h.current.hsva) || e.equal(r = e.fromHsva(d), h.current.color) || (h.current = {
|
|
2594
|
+
hsva: d,
|
|
2595
|
+
color: r
|
|
2596
|
+
}, c(r), g.current = !0);
|
|
2597
|
+
}, [
|
|
2598
|
+
d,
|
|
2599
|
+
e,
|
|
2600
|
+
c
|
|
2601
|
+
]);
|
|
2602
|
+
return [
|
|
2603
|
+
d,
|
|
2604
|
+
(0, react.useCallback)(function(e) {
|
|
2605
|
+
v(function(r) {
|
|
2606
|
+
return Object.assign({}, r, e);
|
|
2607
|
+
});
|
|
2608
|
+
}, []),
|
|
2609
|
+
(0, react.useCallback)(function() {
|
|
2610
|
+
g.current && (g.current = !1, s(h.current.color));
|
|
2611
|
+
}, [s])
|
|
2612
|
+
];
|
|
2613
|
+
}
|
|
2614
|
+
var Y;
|
|
2615
|
+
var U = "undefined" != typeof window ? react.useLayoutEffect : react.useEffect;
|
|
2616
|
+
var V = function() {
|
|
2617
|
+
return Y || ("undefined" != typeof __webpack_nonce__ ? __webpack_nonce__ : void 0);
|
|
2618
|
+
};
|
|
2619
|
+
var $ = /* @__PURE__ */ new WeakMap();
|
|
2620
|
+
var G = function(e) {
|
|
2621
|
+
U(function() {
|
|
2622
|
+
var r = e.current;
|
|
2623
|
+
if ("undefined" != typeof document && r) {
|
|
2624
|
+
var n = r.getRootNode ? r.getRootNode() : r.ownerDocument, t = n && ("head" in n || "host" in n) ? n : r.ownerDocument;
|
|
2625
|
+
if (!$.has(t)) {
|
|
2626
|
+
var o = "head" in t ? t.head : t, a = (o.ownerDocument || document).createElement("style");
|
|
2627
|
+
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}";
|
|
2628
|
+
var u = V();
|
|
2629
|
+
u && a.setAttribute("nonce", u), $.set(t, a), o.appendChild(a);
|
|
2630
|
+
}
|
|
2631
|
+
}
|
|
2632
|
+
}, []);
|
|
2633
|
+
};
|
|
2634
|
+
var J = function(n) {
|
|
2635
|
+
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, [
|
|
2636
|
+
"className",
|
|
2637
|
+
"colorModel",
|
|
2638
|
+
"color",
|
|
2639
|
+
"onChange",
|
|
2640
|
+
"onChangeEnd"
|
|
2641
|
+
]), d = (0, react.useRef)(null);
|
|
2642
|
+
G(d);
|
|
2643
|
+
var v = X(o, u, i, s), h = v[0], g = v[1], p = v[2], b = m(["react-colorful", t]);
|
|
2644
|
+
return react.default.createElement("div", l({}, f, {
|
|
2645
|
+
ref: d,
|
|
2646
|
+
className: b
|
|
2647
|
+
}), react.default.createElement(S, {
|
|
2648
|
+
hsva: h,
|
|
2649
|
+
onChange: g,
|
|
2650
|
+
onChangeEnd: p
|
|
2651
|
+
}), react.default.createElement(R, {
|
|
2652
|
+
hue: h.h,
|
|
2653
|
+
onChange: g,
|
|
2654
|
+
onChangeEnd: p,
|
|
2655
|
+
className: "react-colorful__last-control"
|
|
2656
|
+
}));
|
|
2657
|
+
};
|
|
2658
|
+
var Q = {
|
|
2659
|
+
defaultColor: "000",
|
|
2660
|
+
toHsva: E,
|
|
2661
|
+
fromHsva: function(e) {
|
|
2662
|
+
return w({
|
|
2663
|
+
h: e.h,
|
|
2664
|
+
s: e.s,
|
|
2665
|
+
v: e.v,
|
|
2666
|
+
a: 1
|
|
2667
|
+
});
|
|
2668
|
+
},
|
|
2669
|
+
equal: P
|
|
2670
|
+
};
|
|
2671
|
+
var Z = function(r) {
|
|
2672
|
+
return react.default.createElement(J, l({}, r, { colorModel: Q }));
|
|
2673
|
+
};
|
|
2674
|
+
var ke = /^#?([0-9A-F]{3,8})$/i;
|
|
2675
|
+
var qe = function(r) {
|
|
2676
|
+
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, [
|
|
2677
|
+
"color",
|
|
2678
|
+
"onChange",
|
|
2679
|
+
"onBlur",
|
|
2680
|
+
"escape",
|
|
2681
|
+
"validate",
|
|
2682
|
+
"format",
|
|
2683
|
+
"process"
|
|
2684
|
+
]), p = (0, react.useState)(function() {
|
|
2685
|
+
return d(u);
|
|
2686
|
+
}), b = p[0], _ = p[1], E = i(s), C = i(f), x = (0, react.useCallback)(function(e) {
|
|
2687
|
+
var r = d(e.target.value);
|
|
2688
|
+
_(r), v(r) && E(g ? g(r) : r);
|
|
2689
|
+
}, [
|
|
2690
|
+
d,
|
|
2691
|
+
g,
|
|
2692
|
+
v,
|
|
2693
|
+
E
|
|
2694
|
+
]), H = (0, react.useCallback)(function(e) {
|
|
2695
|
+
v(e.target.value) || _(d(u)), C(e);
|
|
2696
|
+
}, [
|
|
2697
|
+
u,
|
|
2698
|
+
d,
|
|
2699
|
+
v,
|
|
2700
|
+
C
|
|
2701
|
+
]);
|
|
2702
|
+
return (0, react.useEffect)(function() {
|
|
2703
|
+
_(d(u));
|
|
2704
|
+
}, [u, d]), react.default.createElement("input", l({}, m, {
|
|
2705
|
+
value: h ? h(b) : b,
|
|
2706
|
+
spellCheck: "false",
|
|
2707
|
+
onChange: x,
|
|
2708
|
+
onBlur: H
|
|
2709
|
+
}));
|
|
2710
|
+
};
|
|
2711
|
+
var Ie = function(e) {
|
|
2712
|
+
return "#" + e;
|
|
2713
|
+
};
|
|
2714
|
+
var Oe = function(r) {
|
|
2715
|
+
var n = r.prefixed, t = r.alpha, o = c(r, ["prefixed", "alpha"]), u = (0, react.useCallback)(function(e) {
|
|
2716
|
+
return e.replace(/([^0-9A-F]+)/gi, "").substring(0, t ? 8 : 6);
|
|
2717
|
+
}, [t]), i = (0, react.useCallback)(function(e) {
|
|
2718
|
+
return function(e, r) {
|
|
2719
|
+
var n = ke.exec(e), t = n ? n[1].length : 0;
|
|
2720
|
+
return 3 === t || 6 === t || !!r && 4 === t || !!r && 8 === t;
|
|
2721
|
+
}(e, t);
|
|
2722
|
+
}, [t]);
|
|
2723
|
+
return react.default.createElement(qe, l({}, o, {
|
|
2724
|
+
escape: u,
|
|
2725
|
+
format: n ? Ie : void 0,
|
|
2726
|
+
process: Ie,
|
|
2727
|
+
validate: i
|
|
2728
|
+
}));
|
|
2729
|
+
};
|
|
2730
|
+
//#endregion
|
|
2304
2731
|
//#region src/client/custom.ts
|
|
2305
2732
|
/** The nine `--shiki-token-*` slots, in stylesheet order. */
|
|
2306
2733
|
const SHIKI_KEYS = [
|
|
@@ -2809,6 +3236,22 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2809
3236
|
/** Reserved menu value that switches to the user-defined theme. */
|
|
2810
3237
|
const CUSTOM_SELECTION = CUSTOM_PRESET_ID;
|
|
2811
3238
|
/**
|
|
3239
|
+
* Base id of the light/dark control in the colour editor — and the only place
|
|
3240
|
+
* that string is written. The shell's `SegmentedControl` derives both the tab
|
|
3241
|
+
* ids (`<id>-<value>`) and the panel ids (`<id>-<value>-panel`) from it, so the
|
|
3242
|
+
* tabpanel that answers them has to be built from the same value: a second
|
|
3243
|
+
* literal would drift silently and leave `aria-controls` pointing at nothing.
|
|
3244
|
+
*/
|
|
3245
|
+
const SEED_MODE_CONTROL_ID = "ct-seed-mode";
|
|
3246
|
+
/**
|
|
3247
|
+
* The one glyph size this panel draws at. Every icon here is explicit about it
|
|
3248
|
+
* because the shell's artwork does not default uniformly — the chevron falls
|
|
3249
|
+
* back to 14, the edit/share/trash/add/import glyphs to 16 — so passing no size
|
|
3250
|
+
* silently picks a different scale per icon. 14 is what the shell's own
|
|
3251
|
+
* settings pages pass.
|
|
3252
|
+
*/
|
|
3253
|
+
const ICON_SIZE = 14;
|
|
3254
|
+
/**
|
|
2812
3255
|
* Which message an import failure deserves. The Host answers with its own
|
|
2813
3256
|
* reason, so the shape of that reason is what selects the localized text; an
|
|
2814
3257
|
* unrecognised failure keeps the Host's own words rather than hiding them.
|
|
@@ -2854,114 +3297,54 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2854
3297
|
if (open.id === null) return true;
|
|
2855
3298
|
return open.name.trim() !== open.originName.trim() || !sameSeeds(current, open.originTheme);
|
|
2856
3299
|
}
|
|
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
|
-
}
|
|
3300
|
+
/**
|
|
3301
|
+
* The panel's value picker: a trigger in the row, the shell's `Menu` for the
|
|
3302
|
+
* list. Everything the list needs — outside pointerdown, Escape, the arrow
|
|
3303
|
+
* walk, the focus return to the trigger, the translucent material, the
|
|
3304
|
+
* viewport-clamped portal — belongs to the primitive, so this owns `open` and
|
|
3305
|
+
* which label the trigger shows, and nothing else.
|
|
3306
|
+
*/
|
|
2884
3307
|
function SchemeMenu(props) {
|
|
2885
3308
|
const { value, options, onSelect, disabled } = props;
|
|
2886
3309
|
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
3310
|
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
|
|
3311
|
+
const expanded = open && !disabled;
|
|
3312
|
+
return react.createElement(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
3313
|
+
open: expanded,
|
|
3314
|
+
align: "end",
|
|
3315
|
+
side: "bottom",
|
|
3316
|
+
portal: true,
|
|
3317
|
+
items: options.map((o) => ({
|
|
3318
|
+
id: o.value,
|
|
3319
|
+
label: o.label
|
|
3320
|
+
})),
|
|
3321
|
+
selectedId: value,
|
|
3322
|
+
onSelect: (v) => {
|
|
3323
|
+
setOpen(false);
|
|
3324
|
+
onSelect(v);
|
|
2929
3325
|
},
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
}, ...options.map((o) => {
|
|
2933
|
-
const sel = o.value === value;
|
|
2934
|
-
return react.createElement("button", {
|
|
2935
|
-
key: o.value,
|
|
3326
|
+
onClose: () => setOpen(false),
|
|
3327
|
+
anchor: react.createElement("button", {
|
|
2936
3328
|
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" }));
|
|
3329
|
+
className: "ct-select",
|
|
3330
|
+
disabled,
|
|
3331
|
+
"aria-haspopup": "menu",
|
|
3332
|
+
"aria-expanded": expanded,
|
|
3333
|
+
onClick: () => setOpen(!open)
|
|
3334
|
+
}, 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 })))
|
|
3335
|
+
});
|
|
2957
3336
|
}
|
|
2958
3337
|
/**
|
|
2959
3338
|
* Confirmation dialog for destructive actions, mirroring DSH's own Modal
|
|
2960
|
-
* (design-platform mask token + blur,
|
|
2961
|
-
*
|
|
3339
|
+
* (design-platform mask token + blur, `radius-panel` card on layer-2,
|
|
3340
|
+
* prominent shadow) and the footer its `RiskConfirmation` lays out: an outline
|
|
3341
|
+
* cancel beside the confirming action.
|
|
3342
|
+
* Still rendered inline rather than through the shell's `Modal`: its Escape has
|
|
3343
|
+
* to take part in the panel's own leave-the-draft questions, and a shell-owned
|
|
3344
|
+
* modal layer would answer the key before this dialog could.
|
|
2962
3345
|
*/
|
|
2963
3346
|
function ConfirmDialog(props) {
|
|
2964
|
-
const { title, description, confirmLabel, cancelLabel, onConfirm, onCancel } = props;
|
|
3347
|
+
const { title, description, confirmLabel, cancelLabel, danger, onConfirm, onCancel } = props;
|
|
2965
3348
|
react.useEffect(() => {
|
|
2966
3349
|
const onKey = (e) => {
|
|
2967
3350
|
if (e.key === "Escape") onCancel();
|
|
@@ -2978,13 +3361,13 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2978
3361
|
role: "dialog",
|
|
2979
3362
|
"aria-modal": true,
|
|
2980
3363
|
"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-
|
|
3364
|
+
}, 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, {
|
|
3365
|
+
variant: "outline",
|
|
3366
|
+
className: "ct-action-cancel",
|
|
2984
3367
|
onClick: onCancel
|
|
2985
|
-
}, cancelLabel), react.createElement(
|
|
2986
|
-
|
|
2987
|
-
className: "ct-
|
|
3368
|
+
}, cancelLabel), react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
3369
|
+
variant: danger ? "outline" : "primary",
|
|
3370
|
+
className: danger ? "ct-action-confirm ct-danger" : "ct-action-confirm",
|
|
2988
3371
|
onClick: onConfirm
|
|
2989
3372
|
}, confirmLabel))));
|
|
2990
3373
|
}
|
|
@@ -2993,148 +3376,6 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
2993
3376
|
return error instanceof ThemeApiUnavailableError ? "custom.toast.unavailable" : "custom.toast.failed";
|
|
2994
3377
|
}
|
|
2995
3378
|
/**
|
|
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
3379
|
* One collapsed saved-theme card: the name activates the theme, and the trailing
|
|
3139
3380
|
* controls export it, open the editor or delete it. The card as a whole is a
|
|
3140
3381
|
* click target too, but its controls own their clicks.
|
|
@@ -3142,22 +3383,29 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3142
3383
|
function ThemeCard(props) {
|
|
3143
3384
|
const { entry, active, disabled, t, onActivate, onExport, onEdit, onDelete } = props;
|
|
3144
3385
|
/**
|
|
3145
|
-
* One square icon action
|
|
3146
|
-
*
|
|
3147
|
-
*
|
|
3148
|
-
*
|
|
3386
|
+
* One square icon action. The glyph is decorative, so the label travels as
|
|
3387
|
+
* the accessible name and as the shell's own `Tooltip` above the button.
|
|
3388
|
+
* `danger` paints the error face; `leave` marks the button on the markup the
|
|
3389
|
+
* outside-click guard watches (see that guard) — it is not a visual state.
|
|
3149
3390
|
*/
|
|
3150
|
-
const action = (label, icon, onClick,
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3391
|
+
const action = (label, icon, onClick, marks) => {
|
|
3392
|
+
const button = react.createElement("button", {
|
|
3393
|
+
type: "button",
|
|
3394
|
+
className: marks?.danger ? "ct-list-btn ct-list-btn-danger" : "ct-list-btn",
|
|
3395
|
+
"aria-label": label,
|
|
3396
|
+
...marks?.leave ? {
|
|
3397
|
+
"data-ct-leave": "true",
|
|
3398
|
+
"data-ct-entry": entry.id
|
|
3399
|
+
} : {},
|
|
3400
|
+
onClick
|
|
3401
|
+
}, icon);
|
|
3402
|
+
return react.createElement(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
3403
|
+
label,
|
|
3404
|
+
side: "top",
|
|
3405
|
+
gap: 6,
|
|
3406
|
+
children: button
|
|
3407
|
+
});
|
|
3408
|
+
};
|
|
3161
3409
|
return react.createElement("div", {
|
|
3162
3410
|
className: "ct-list-row",
|
|
3163
3411
|
"data-ct-leave": "true",
|
|
@@ -3174,7 +3422,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3174
3422
|
}, entry.name)), react.createElement("div", {
|
|
3175
3423
|
className: "ct-list-actions",
|
|
3176
3424
|
onClick: (e) => e.stopPropagation()
|
|
3177
|
-
}, active ? react.createElement("span", { className: "ct-list-badge" }, t("custom.inUse")) : null, action(t("custom.edit"), react.createElement(
|
|
3425
|
+
}, 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
3426
|
}
|
|
3179
3427
|
/**
|
|
3180
3428
|
* Which appearance the colour dots edit. `system` resolves through the same
|
|
@@ -3190,7 +3438,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3190
3438
|
}
|
|
3191
3439
|
}
|
|
3192
3440
|
function ThemePanel(props) {
|
|
3193
|
-
const { theme, getSelection, setSelection, getCustom, setCustom, setCustomBase, resetCustom, saved,
|
|
3441
|
+
const { theme, getSelection, setSelection, getCustom, setCustom, setCustomBase, resetCustom, saved, t, onRequestClose } = props;
|
|
3194
3442
|
let initScheme = "system";
|
|
3195
3443
|
try {
|
|
3196
3444
|
const snap = theme?.getTheme();
|
|
@@ -3240,6 +3488,72 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3240
3488
|
text
|
|
3241
3489
|
});
|
|
3242
3490
|
}
|
|
3491
|
+
const [pickerDotKey, setPickerDotKey] = react.useState(null);
|
|
3492
|
+
const [pickerPos, setPickerPos] = react.useState(null);
|
|
3493
|
+
const pickerOpen = pickerDotKey !== null;
|
|
3494
|
+
const pickerOpenRef = react.useRef(false);
|
|
3495
|
+
pickerOpenRef.current = pickerOpen;
|
|
3496
|
+
/** The swatch the popover is anchored to; re-read on every reposition. */
|
|
3497
|
+
const pickerAnchorRef = react.useRef(null);
|
|
3498
|
+
/** The popover node itself; outside-pointerdown detection needs its bounds. */
|
|
3499
|
+
const pickerPopRef = react.useRef(null);
|
|
3500
|
+
/** Viewport coordinates that put the popover beside its anchor swatch. */
|
|
3501
|
+
function placePicker(anchor) {
|
|
3502
|
+
const WIDTH = 224;
|
|
3503
|
+
const HEIGHT = 240;
|
|
3504
|
+
const GAP = 8;
|
|
3505
|
+
const MARGIN = 8;
|
|
3506
|
+
const rect = anchor.getBoundingClientRect();
|
|
3507
|
+
const viewW = window.innerWidth;
|
|
3508
|
+
const viewH = window.innerHeight;
|
|
3509
|
+
return {
|
|
3510
|
+
left: Math.min(Math.max(MARGIN, rect.right - WIDTH), Math.max(MARGIN, viewW - WIDTH - MARGIN)),
|
|
3511
|
+
top: rect.bottom + GAP + HEIGHT <= viewH - MARGIN ? rect.bottom + GAP : Math.max(MARGIN, rect.top - GAP - HEIGHT)
|
|
3512
|
+
};
|
|
3513
|
+
}
|
|
3514
|
+
/** Toggle one seed's popover; `anchor` is the swatch that was clicked. */
|
|
3515
|
+
function togglePicker(key, anchor) {
|
|
3516
|
+
if (pickerDotKey === key) {
|
|
3517
|
+
closePicker();
|
|
3518
|
+
return;
|
|
3519
|
+
}
|
|
3520
|
+
pickerAnchorRef.current = anchor;
|
|
3521
|
+
setPickerDotKey(key);
|
|
3522
|
+
setPickerPos(placePicker(anchor));
|
|
3523
|
+
}
|
|
3524
|
+
function closePicker() {
|
|
3525
|
+
setPickerDotKey(null);
|
|
3526
|
+
setPickerPos(null);
|
|
3527
|
+
}
|
|
3528
|
+
react.useEffect(() => {
|
|
3529
|
+
if (!pickerOpen) return;
|
|
3530
|
+
function onPointerDown(e) {
|
|
3531
|
+
const target = e.target instanceof Element ? e.target : null;
|
|
3532
|
+
if (!target) return;
|
|
3533
|
+
if (pickerPopRef.current?.contains(target)) return;
|
|
3534
|
+
if (pickerAnchorRef.current?.contains(target)) return;
|
|
3535
|
+
closePicker();
|
|
3536
|
+
}
|
|
3537
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
3538
|
+
return () => document.removeEventListener("pointerdown", onPointerDown, true);
|
|
3539
|
+
}, [pickerOpen]);
|
|
3540
|
+
react.useEffect(() => {
|
|
3541
|
+
if (!pickerOpen) return;
|
|
3542
|
+
let raf = 0;
|
|
3543
|
+
const update = () => {
|
|
3544
|
+
const anchor = pickerAnchorRef.current;
|
|
3545
|
+
if (!anchor) return;
|
|
3546
|
+
cancelAnimationFrame(raf);
|
|
3547
|
+
raf = requestAnimationFrame(() => setPickerPos(placePicker(anchor)));
|
|
3548
|
+
};
|
|
3549
|
+
window.addEventListener("scroll", update, true);
|
|
3550
|
+
window.addEventListener("resize", update);
|
|
3551
|
+
return () => {
|
|
3552
|
+
window.removeEventListener("scroll", update, true);
|
|
3553
|
+
window.removeEventListener("resize", update);
|
|
3554
|
+
cancelAnimationFrame(raf);
|
|
3555
|
+
};
|
|
3556
|
+
}, [pickerOpen]);
|
|
3243
3557
|
/** Re-read both the list and the active pointer after any list mutation. */
|
|
3244
3558
|
function syncSaved() {
|
|
3245
3559
|
setList(saved.list());
|
|
@@ -3361,6 +3675,12 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3361
3675
|
}
|
|
3362
3676
|
function onKeyDown(e) {
|
|
3363
3677
|
if (e.key !== "Escape") return;
|
|
3678
|
+
if (pickerOpenRef.current) {
|
|
3679
|
+
e.preventDefault();
|
|
3680
|
+
e.stopPropagation();
|
|
3681
|
+
closePicker();
|
|
3682
|
+
return;
|
|
3683
|
+
}
|
|
3364
3684
|
if (confirmCloseRef.current || pendingLeaveRef.current) {
|
|
3365
3685
|
e.preventDefault();
|
|
3366
3686
|
e.stopPropagation();
|
|
@@ -3378,6 +3698,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3378
3698
|
const target = e.target instanceof Element ? e.target : null;
|
|
3379
3699
|
if (!target) return;
|
|
3380
3700
|
if (target.closest("[data-ct-editor]")) return;
|
|
3701
|
+
if (target.closest("[role=\"menu\"]")) return;
|
|
3381
3702
|
const panel = settingsPanel();
|
|
3382
3703
|
if (!!panel && !panel.contains(target) || isCloseButton(target)) {
|
|
3383
3704
|
if (!onRequestClose) return;
|
|
@@ -3414,6 +3735,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3414
3735
|
}, [onRequestClose]);
|
|
3415
3736
|
/** Open a fresh, unsaved theme seeded from the currently selected preset. */
|
|
3416
3737
|
function startAdd() {
|
|
3738
|
+
closePicker();
|
|
3417
3739
|
const origin = beginEditing(null, nextThemeName(t("custom.defaultName"), list.map((e) => e.name)), "", getCustom().theme);
|
|
3418
3740
|
setCustomBase(shownPreset);
|
|
3419
3741
|
const draft = resetCustom();
|
|
@@ -3422,6 +3744,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3422
3744
|
}
|
|
3423
3745
|
/** Open an existing card for editing; it also becomes the previewed theme. */
|
|
3424
3746
|
function startEdit(entry) {
|
|
3747
|
+
closePicker();
|
|
3425
3748
|
const next = beginEditing(entry.id, entry.name, entry.name, entry.theme);
|
|
3426
3749
|
setEditing(next);
|
|
3427
3750
|
onLoadSaved(entry.id);
|
|
@@ -3429,6 +3752,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3429
3752
|
/** Discard the open editor and put the previously applied theme back. */
|
|
3430
3753
|
function cancelEdit() {
|
|
3431
3754
|
if (!editing) return;
|
|
3755
|
+
closePicker();
|
|
3432
3756
|
revertEditing(editing);
|
|
3433
3757
|
setEditing(null);
|
|
3434
3758
|
syncSaved();
|
|
@@ -3491,6 +3815,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3491
3815
|
/** Commit the open editor: create a new entry, or update the one being edited. */
|
|
3492
3816
|
async function saveEdit() {
|
|
3493
3817
|
if (!editing) return;
|
|
3818
|
+
closePicker();
|
|
3494
3819
|
const name = editing.name.trim() || t("custom.defaultName");
|
|
3495
3820
|
const id = editing.id;
|
|
3496
3821
|
savingRef.current = true;
|
|
@@ -3547,6 +3872,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3547
3872
|
setCustomState(getCustom().theme);
|
|
3548
3873
|
return;
|
|
3549
3874
|
}
|
|
3875
|
+
closePicker();
|
|
3550
3876
|
if (editing) revertEditing(editing);
|
|
3551
3877
|
setEditing(null);
|
|
3552
3878
|
setSelectionState(shownPreset);
|
|
@@ -3593,7 +3919,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3593
3919
|
react.createElement("div", {
|
|
3594
3920
|
className: "ct-row ct-row-flush",
|
|
3595
3921
|
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, {
|
|
3922
|
+
}, 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
3923
|
checked: customOn,
|
|
3598
3924
|
label: t("custom.title"),
|
|
3599
3925
|
onChange: toggleCustom
|
|
@@ -3604,18 +3930,21 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3604
3930
|
const dotRow = (key, label, dots) => react.createElement("div", {
|
|
3605
3931
|
className: "ct-seed-row",
|
|
3606
3932
|
key
|
|
3607
|
-
}, react.createElement("div", { className: "ct-seed-label" }, label), react.createElement("div", { className: "ct-seed-dots" }, ...dots.map((d) => react.createElement(
|
|
3933
|
+
}, 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
3934
|
key: d.key,
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3935
|
+
label: d.name,
|
|
3936
|
+
side: "top",
|
|
3937
|
+
gap: 6,
|
|
3938
|
+
children: react.createElement("button", {
|
|
3939
|
+
type: "button",
|
|
3940
|
+
className: "ct-seed-dot",
|
|
3941
|
+
style: { background: d.value },
|
|
3942
|
+
"aria-haspopup": "dialog",
|
|
3943
|
+
"aria-expanded": pickerDotKey === d.key,
|
|
3944
|
+
"aria-label": `${d.name} — ${d.hint}`,
|
|
3945
|
+
onClick: (e) => togglePicker(d.key, e.currentTarget)
|
|
3946
|
+
})
|
|
3947
|
+
}))));
|
|
3619
3948
|
const pair = (key, title, desc) => ({
|
|
3620
3949
|
key,
|
|
3621
3950
|
name: t(title),
|
|
@@ -3672,21 +4001,24 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3672
4001
|
})
|
|
3673
4002
|
}));
|
|
3674
4003
|
/** The light/dark segmented control above the dots. */
|
|
3675
|
-
const
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
4004
|
+
const modeToggle = react.createElement(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
|
|
4005
|
+
id: SEED_MODE_CONTROL_ID,
|
|
4006
|
+
value: seedMode,
|
|
4007
|
+
options: [{
|
|
4008
|
+
value: "light",
|
|
4009
|
+
label: t("custom.seed.light")
|
|
4010
|
+
}, {
|
|
4011
|
+
value: "dark",
|
|
4012
|
+
label: t("custom.seed.dark")
|
|
4013
|
+
}],
|
|
4014
|
+
onChange: (next) => {
|
|
4015
|
+
const mode = next;
|
|
4016
|
+
setSeedMode(mode);
|
|
4017
|
+
previewAppearance(mode);
|
|
4018
|
+
},
|
|
4019
|
+
label: t("custom.mode.label"),
|
|
4020
|
+
className: "ct-mode"
|
|
4021
|
+
});
|
|
3690
4022
|
const editorName = react.createElement("input", {
|
|
3691
4023
|
className: "ct-editor-name",
|
|
3692
4024
|
type: "text",
|
|
@@ -3703,20 +4035,40 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3703
4035
|
else if (e.key === "Escape") cancelEdit();
|
|
3704
4036
|
}
|
|
3705
4037
|
});
|
|
3706
|
-
const editorActions = react.createElement("div", { className: "ct-editor-actions" }, react.createElement(
|
|
3707
|
-
|
|
3708
|
-
className: "ct-btn",
|
|
4038
|
+
const editorActions = react.createElement("div", { className: "ct-editor-actions" }, react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4039
|
+
variant: "outline",
|
|
3709
4040
|
onClick: cancelEdit
|
|
3710
|
-
}, t("custom.cancel")), react.createElement(
|
|
3711
|
-
|
|
3712
|
-
className: "ct-btn ct-btn-primary",
|
|
4041
|
+
}, t("custom.cancel")), react.createElement(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
4042
|
+
variant: "primary",
|
|
3713
4043
|
onClick: () => void saveEdit()
|
|
3714
4044
|
}, t("custom.save")));
|
|
4045
|
+
const pickerDot = pickerDotKey ? [...seedDots, ...shikiDots].find((d) => d.key === pickerDotKey) ?? null : null;
|
|
4046
|
+
const pickerPop = pickerDot && pickerPos ? react.createElement("div", {
|
|
4047
|
+
key: "color-picker",
|
|
4048
|
+
className: "ct-color-pop",
|
|
4049
|
+
ref: pickerPopRef,
|
|
4050
|
+
style: {
|
|
4051
|
+
left: pickerPos.left,
|
|
4052
|
+
top: pickerPos.top
|
|
4053
|
+
}
|
|
4054
|
+
}, react.createElement(Z, {
|
|
4055
|
+
color: pickerDot.value,
|
|
4056
|
+
onChange: (v) => pickerDot.onChange(v.toUpperCase())
|
|
4057
|
+
}), react.createElement(Oe, {
|
|
4058
|
+
className: "ct-hex-input",
|
|
4059
|
+
color: pickerDot.value,
|
|
4060
|
+
"aria-label": pickerDot.name,
|
|
4061
|
+
onChange: (v) => pickerDot.onChange(v.toUpperCase())
|
|
4062
|
+
})) : null;
|
|
3715
4063
|
const editorCard = (key) => react.createElement("div", {
|
|
3716
4064
|
className: "ct-editor",
|
|
3717
4065
|
key,
|
|
3718
4066
|
"data-ct-editor": "true"
|
|
3719
|
-
}, react.createElement("div", { className: "ct-editor-head" }, editorName, modeToggle),
|
|
4067
|
+
}, react.createElement("div", { className: "ct-editor-head" }, editorName, modeToggle), react.createElement("div", {
|
|
4068
|
+
role: "tabpanel",
|
|
4069
|
+
id: `${SEED_MODE_CONTROL_ID}-${seedMode}-panel`,
|
|
4070
|
+
"aria-labelledby": `${SEED_MODE_CONTROL_ID}-${seedMode}`
|
|
4071
|
+
}, dotRow("seeds", t("custom.group.seeds"), seedDots), dotRow("shiki", t("custom.group.shiki"), shikiDots)), editorActions, pickerPop);
|
|
3720
4072
|
const cards = list.map((entry) => editing && editing.id === entry.id ? editorCard(entry.id) : react.createElement(ThemeCard, {
|
|
3721
4073
|
key: entry.id,
|
|
3722
4074
|
entry,
|
|
@@ -3741,13 +4093,13 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3741
4093
|
className: "ct-add-btn",
|
|
3742
4094
|
disabled: importing,
|
|
3743
4095
|
onClick: startImport
|
|
3744
|
-
}, react.createElement(
|
|
4096
|
+
}, react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconDownloadOutlineRegular, { size: ICON_SIZE }), t("custom.import")), react.createElement("button", {
|
|
3745
4097
|
key: "add",
|
|
3746
4098
|
type: "button",
|
|
3747
4099
|
className: "ct-add-btn",
|
|
3748
4100
|
disabled: editing !== null,
|
|
3749
4101
|
onClick: startAdd
|
|
3750
|
-
}, react.createElement(
|
|
4102
|
+
}, react.createElement(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: ICON_SIZE }), t("custom.add")), react.createElement("input", {
|
|
3751
4103
|
key: "import-input",
|
|
3752
4104
|
ref: importInputRef,
|
|
3753
4105
|
type: "file",
|
|
@@ -3762,6 +4114,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3762
4114
|
description: t("custom.delete.desc").replace("{0}", pendingDelete.name),
|
|
3763
4115
|
confirmLabel: t("custom.delete"),
|
|
3764
4116
|
cancelLabel: t("custom.cancel"),
|
|
4117
|
+
danger: true,
|
|
3765
4118
|
onConfirm: onConfirmDelete,
|
|
3766
4119
|
onCancel: () => setPendingDelete(null)
|
|
3767
4120
|
}));
|
|
@@ -3794,20 +4147,12 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3794
4147
|
},
|
|
3795
4148
|
onCancel: () => setPendingLeave(null)
|
|
3796
4149
|
}));
|
|
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
|
-
}
|
|
4150
|
+
if (toast) children.push(react.createElement(_deepseek_ai_dsh_client_ui_primitives.Toast, {
|
|
4151
|
+
key: `toast-${String(toast.seq)}`,
|
|
4152
|
+
text: toast.text,
|
|
4153
|
+
tone: "success",
|
|
4154
|
+
onDone: () => setToast((cur) => cur?.seq === toast.seq ? null : cur)
|
|
4155
|
+
}));
|
|
3811
4156
|
return react.createElement("div", { style: {
|
|
3812
4157
|
display: "flex",
|
|
3813
4158
|
flexDirection: "column",
|
|
@@ -3978,19 +4323,6 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
3978
4323
|
".ct-select-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;}",
|
|
3979
4324
|
".ct-select-chevron{flex:none;color:var(--dsw-alias-label-tertiary);display:inline-flex;transition:transform 120ms ease;}",
|
|
3980
4325
|
".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
4326
|
".ct-row{border-bottom:1px solid var(--dsw-alias-border-l2);padding:16px 2px;display:flex;align-items:center;gap:16px;}",
|
|
3995
4327
|
".ct-row:last-child{border-bottom:none;}",
|
|
3996
4328
|
".ct-row-flush{border-bottom:none;}",
|
|
@@ -4000,13 +4332,12 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4000
4332
|
".ct-seed-row{display:flex;align-items:center;gap:16px;padding:12px 0;}",
|
|
4001
4333
|
".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
4334
|
".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;}}",
|
|
4335
|
+
".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;}",
|
|
4336
|
+
".ct-seed-dot:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
4337
|
+
".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;}",
|
|
4338
|
+
".ct-color-pop .react-colorful{width:198px;height:170px;}",
|
|
4339
|
+
".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;}",
|
|
4340
|
+
".ct-color-pop .ct-hex-input:focus{border-color:var(--dsw-alias-border-l3);}",
|
|
4010
4341
|
".ct-list{margin-top:4px;display:flex;flex-direction:column;gap:8px;}",
|
|
4011
4342
|
".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
4343
|
".ct-list-row:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
@@ -4016,7 +4347,7 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4016
4347
|
".ct-list-actions{display:inline-flex;align-items:center;gap:4px;flex:none;margin-left:auto;}",
|
|
4017
4348
|
".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
4349
|
".ct-list-badge + .ct-list-btn{margin-left:8px;}",
|
|
4019
|
-
".ct-list-btn{
|
|
4350
|
+
".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
4351
|
".ct-list-btn:hover{background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4021
4352
|
".ct-list-btn:active{background:var(--dsw-alias-interactive-bg-active);}",
|
|
4022
4353
|
".ct-list-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
@@ -4025,19 +4356,15 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4025
4356
|
".ct-list-btn-danger{color:var(--dsw-alias-state-error-primary);}",
|
|
4026
4357
|
".ct-list-btn-danger:hover{background:var(--dsw-alias-interactive-bg-hover-danger);}",
|
|
4027
4358
|
".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:
|
|
4359
|
+
".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
4360
|
".ct-editor-head{display:flex;align-items:center;gap:10px;padding-bottom:12px;}",
|
|
4030
4361
|
".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
4362
|
".ct-editor-name::placeholder{color:var(--dsw-alias-label-tertiary);}",
|
|
4032
4363
|
".ct-editor-name:hover{border-color:var(--dsw-alias-border-l3);}",
|
|
4033
4364
|
".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);}",
|
|
4365
|
+
".ct-mode{flex:none;}",
|
|
4039
4366
|
".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:
|
|
4367
|
+
".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
4368
|
".ct-add-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);}",
|
|
4042
4369
|
".ct-add-btn:disabled{opacity:.4;cursor:default;}",
|
|
4043
4370
|
".ct-add-btn:focus-visible{outline:none;box-shadow:0 0 0 2px var(--dsw-alias-border-l3);}",
|
|
@@ -4045,28 +4372,13 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4045
4372
|
".ct-add-row .ct-add-btn{flex:1 1 0;width:auto;margin-top:0;min-width:0;}",
|
|
4046
4373
|
".ct-modal-root{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:24px;}",
|
|
4047
4374
|
".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:
|
|
4375
|
+
".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
4376
|
".ct-modal-title{font-size:16px;line-height:24px;font-weight:600;color:var(--dsw-alias-label-primary);}",
|
|
4050
4377
|
".ct-modal-desc{font-size:13px;line-height:20px;color:var(--dsw-alias-label-tertiary);}",
|
|
4051
4378
|
".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;}}"
|
|
4379
|
+
".ct-action-cancel{min-width:72px}",
|
|
4380
|
+
".ct-action-confirm{min-width:136px}",
|
|
4381
|
+
"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
4382
|
].join("\n");
|
|
4071
4383
|
function isValidSelection(v) {
|
|
4072
4384
|
return !!v && (v === CUSTOM_SELECTION || NOOP_PRESET_IDS.has(v) || v in PRESETS);
|
|
@@ -4189,8 +4501,8 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4189
4501
|
/**
|
|
4190
4502
|
* Coalesce a burst of palette applications into one.
|
|
4191
4503
|
*
|
|
4192
|
-
* A
|
|
4193
|
-
*
|
|
4504
|
+
* A colour picker fires continuously while its slider is dragged. Each
|
|
4505
|
+
* application rebuilds both ramps, rewrites every token on
|
|
4194
4506
|
* `body` and forces a style flush in the shell's presenter, so applying once
|
|
4195
4507
|
* per event is what makes the colour editor stutter. The first change lands
|
|
4196
4508
|
* immediately and the rest are throttled to one per interval, newest request
|
|
@@ -4345,13 +4657,6 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4345
4657
|
if (env && isPresetId(env.base)) lastPreset = env.base;
|
|
4346
4658
|
}
|
|
4347
4659
|
apply(initialSelection);
|
|
4348
|
-
let sharedToast = null;
|
|
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 {}
|
|
4355
4660
|
ctx.effect(() => () => {
|
|
4356
4661
|
disposed = true;
|
|
4357
4662
|
cancelApply();
|
|
@@ -4379,7 +4684,6 @@ html[data-ds-dark-theme], body[data-ds-dark-theme] {
|
|
|
4379
4684
|
setCustomBase,
|
|
4380
4685
|
resetCustom,
|
|
4381
4686
|
saved,
|
|
4382
|
-
getHostToast: () => sharedToast,
|
|
4383
4687
|
onRequestClose: typeof props?.close === "function" ? props.close : null
|
|
4384
4688
|
}));
|
|
4385
4689
|
});
|