style: expand settings panel to 1180px via CSS and layoutEffect, fit 880px calendar with zero scrollbar

This commit is contained in:
katR 2026-10-11 09:47:55 +05:30
parent 4c32c0504a
commit dc73f2bbf5
4 changed files with 94 additions and 49 deletions

View file

@ -72,16 +72,20 @@ function HeatmapInnerView() {
const [hoveredDay, setHoveredDay] = (0, import_react.useState)(null); const [hoveredDay, setHoveredDay] = (0, import_react.useState)(null);
const [hoveredBar, setHoveredBar] = (0, import_react.useState)(null); const [hoveredBar, setHoveredBar] = (0, import_react.useState)(null);
const [tooltipPos, setTooltipPos] = (0, import_react.useState)(null); const [tooltipPos, setTooltipPos] = (0, import_react.useState)(null);
const rootRef = (0, import_react.useRef)(null);
(0, import_react.useEffect)(() => { (0, import_react.useEffect)(() => {
if (typeof document === "undefined") return; if (typeof document === "undefined") return;
const panel = document.querySelector('[class*="_panel"]'); const findPanel = () => {
return rootRef.current?.closest('[class*="_panel"]') || document.querySelector(".VOzbGW_panel") || document.querySelector('[class*="_panel"]');
};
const panel = findPanel();
if (panel) { if (panel) {
const prevWidth = panel.style.width; const prevWidth = panel.style.width;
const prevMaxWidth = panel.style.maxWidth; const prevMaxWidth = panel.style.maxWidth;
const prevTransition = panel.style.transition; const prevTransition = panel.style.transition;
panel.style.transition = "width 0.25s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.25s ease"; panel.style.transition = "width 0.25s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.25s ease";
panel.style.width = "min(1080px, calc(100vw - 32px))"; panel.style.setProperty("width", "min(1180px, calc(100vw - 32px))", "important");
panel.style.maxWidth = "calc(100vw - 32px)"; panel.style.setProperty("max-width", "calc(100vw - 32px)", "important");
return () => { return () => {
panel.style.width = prevWidth; panel.style.width = prevWidth;
panel.style.maxWidth = prevMaxWidth; panel.style.maxWidth = prevMaxWidth;
@ -294,6 +298,7 @@ function HeatmapInnerView() {
"div", "div",
{ {
"data-dsh-heatmap": "true", "data-dsh-heatmap": "true",
ref: rootRef,
style: { style: {
boxSizing: "border-box", boxSizing: "border-box",
width: "100%", width: "100%",
@ -447,10 +452,10 @@ function HeatmapInnerView() {
calendarGrid && /* @__PURE__ */ import_react.default.createElement("div", { style: { width: "100%", display: "flex", flexDirection: "column", alignItems: "center" } }, /* @__PURE__ */ import_react.default.createElement( calendarGrid && /* @__PURE__ */ import_react.default.createElement("div", { style: { width: "100%", display: "flex", flexDirection: "column", alignItems: "center" } }, /* @__PURE__ */ import_react.default.createElement(
"svg", "svg",
{ {
viewBox: "0 0 770 120", viewBox: "0 0 880 136",
style: { style: {
width: "100%", width: "100%",
maxWidth: "770px", maxWidth: "880px",
height: "auto", height: "auto",
display: "block", display: "block",
overflow: "visible" overflow: "visible"
@ -460,35 +465,35 @@ function HeatmapInnerView() {
"text", "text",
{ {
key: i, key: i,
x: 28 + m.col * 13.8, x: 32 + m.col * 15.6,
y: 10, y: 11,
fontSize: 10, fontSize: 11,
fill: "var(--dsw-alias-label-tertiary, #888888)", fill: "var(--dsw-alias-label-tertiary, #888888)",
fontFamily: "inherit" fontFamily: "inherit"
}, },
m.label m.label
)), )),
/* @__PURE__ */ import_react.default.createElement("text", { x: 2, y: 39, fontSize: 9, fill: "var(--dsw-alias-label-tertiary, #888888)", fontFamily: "inherit" }, "Mon"), /* @__PURE__ */ import_react.default.createElement("text", { x: 2, y: 45, fontSize: 10, fill: "var(--dsw-alias-label-tertiary, #888888)", fontFamily: "inherit" }, "Mon"),
/* @__PURE__ */ import_react.default.createElement("text", { x: 2, y: 67, fontSize: 9, fill: "var(--dsw-alias-label-tertiary, #888888)", fontFamily: "inherit" }, "Wed"), /* @__PURE__ */ import_react.default.createElement("text", { x: 2, y: 76, fontSize: 10, fill: "var(--dsw-alias-label-tertiary, #888888)", fontFamily: "inherit" }, "Wed"),
/* @__PURE__ */ import_react.default.createElement("text", { x: 2, y: 95, fontSize: 9, fill: "var(--dsw-alias-label-tertiary, #888888)", fontFamily: "inherit" }, "Fri"), /* @__PURE__ */ import_react.default.createElement("text", { x: 2, y: 107, fontSize: 10, fill: "var(--dsw-alias-label-tertiary, #888888)", fontFamily: "inherit" }, "Fri"),
calendarGrid.map((week, colIdx) => /* @__PURE__ */ import_react.default.createElement("g", { key: colIdx, transform: `translate(${28 + colIdx * 13.8}, 18)` }, week.map((day, rowIdx) => { calendarGrid.map((week, colIdx) => /* @__PURE__ */ import_react.default.createElement("g", { key: colIdx, transform: `translate(${32 + colIdx * 15.6}, 18)` }, week.map((day, rowIdx) => {
if (!day) return null; if (!day) return null;
const lvl = day.stats.level || 0; const lvl = day.stats.level || 0;
const bg = DEEPSEEK_LEVELS[lvl]; const bg = DEEPSEEK_LEVELS[lvl];
const isSelected = selectedDate === day.date; const isSelected = selectedDate === day.date;
const isHovered = hoveredDay?.date === day.date; const isHovered = hoveredDay?.date === day.date;
const strokeColor = isSelected ? "#ffffff" : isHovered ? "#5686fe" : lvl === 0 ? "rgba(255, 255, 255, 0.06)" : "transparent"; const strokeColor = isSelected ? "#ffffff" : isHovered ? "#5686fe" : lvl === 0 ? "rgba(255, 255, 255, 0.06)" : "transparent";
const strokeWidth = isSelected ? 1.6 : isHovered ? 1.3 : 1; const strokeWidth = isSelected ? 1.8 : isHovered ? 1.4 : 1;
return /* @__PURE__ */ import_react.default.createElement( return /* @__PURE__ */ import_react.default.createElement(
"rect", "rect",
{ {
key: rowIdx, key: rowIdx,
x: 0, x: 0,
y: rowIdx * 14, y: rowIdx * 15.6,
width: 11, width: 12,
height: 11, height: 12,
rx: 2, rx: 2.5,
ry: 2, ry: 2.5,
fill: bg, fill: bg,
stroke: strokeColor, stroke: strokeColor,
strokeWidth, strokeWidth,
@ -517,7 +522,7 @@ function HeatmapInnerView() {
{ {
style: { style: {
width: "100%", width: "100%",
maxWidth: "770px", maxWidth: "880px",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", justifyContent: "space-between",
@ -532,9 +537,9 @@ function HeatmapInnerView() {
{ {
key: i, key: i,
style: { style: {
width: 11, width: 12,
height: 11, height: 12,
borderRadius: 2, borderRadius: 2.5,
backgroundColor: c, backgroundColor: c,
border: i === 0 ? "1px solid rgba(255, 255, 255, 0.06)" : "none", border: i === 0 ? "1px solid rgba(255, 255, 255, 0.06)" : "none",
filter: i === 4 ? "drop-shadow(0 0 3px rgba(79, 133, 255, 0.5))" : "none" filter: i === 4 ? "drop-shadow(0 0 3px rgba(79, 133, 255, 0.5))" : "none"
@ -1145,6 +1150,20 @@ function apply(ctx) {
}, []); }, []);
return /* @__PURE__ */ import_react3.default.createElement(HeatmapModal, { open: isOpen, onClose: () => setIsOpen(false) }); return /* @__PURE__ */ import_react3.default.createElement(HeatmapModal, { open: isOpen, onClose: () => setIsOpen(false) });
}; };
if (!document.getElementById("dsh-token-heatmap-panel-resize")) {
const resizeStyle = document.createElement("style");
resizeStyle.id = "dsh-token-heatmap-panel-resize";
resizeStyle.textContent = `
/* Dynamically widen DSH Settings panel when Token Heatmap is active */
.VOzbGW_panel:has([data-dsh-heatmap]),
[class*="_panel"]:has([data-dsh-heatmap]) {
width: min(1180px, calc(100vw - 32px)) !important;
max-width: calc(100vw - 32px) !important;
transition: width 0.25s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.25s ease !important;
}
`;
document.head.appendChild(resizeStyle);
}
const modalContainer = document.createElement("div"); const modalContainer = document.createElement("div");
modalContainer.id = "dsh-token-heatmap-modal-root"; modalContainer.id = "dsh-token-heatmap-modal-root";
document.body.appendChild(modalContainer); document.body.appendChild(modalContainer);

File diff suppressed because one or more lines are too long

View file

@ -116,19 +116,28 @@ function HeatmapInnerView() {
turns: number; turns: number;
} | null>(null); } | null>(null);
const [tooltipPos, setTooltipPos] = useState<{ x: number; y: number } | null>(null); const [tooltipPos, setTooltipPos] = useState<{ x: number; y: number } | null>(null);
const rootRef = useRef<HTMLDivElement>(null);
// Auto-resize the settings dialog panel smoothly on mount so it comfortably fits the content // Dynamically enlarge the DSH Settings dialog panel so the calendar fits perfectly without a scrollbar
useEffect(() => { useEffect(() => {
if (typeof document === "undefined") return; if (typeof document === "undefined") return;
const panel = document.querySelector('[class*="_panel"]') as HTMLElement | null; const findPanel = () => {
return (
rootRef.current?.closest('[class*="_panel"]') ||
document.querySelector('.VOzbGW_panel') ||
document.querySelector('[class*="_panel"]')
) as HTMLElement | null;
};
const panel = findPanel();
if (panel) { if (panel) {
const prevWidth = panel.style.width; const prevWidth = panel.style.width;
const prevMaxWidth = panel.style.maxWidth; const prevMaxWidth = panel.style.maxWidth;
const prevTransition = panel.style.transition; const prevTransition = panel.style.transition;
panel.style.transition = "width 0.25s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.25s ease"; panel.style.transition = "width 0.25s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.25s ease";
panel.style.width = "min(1080px, calc(100vw - 32px))"; panel.style.setProperty("width", "min(1180px, calc(100vw - 32px))", "important");
panel.style.maxWidth = "calc(100vw - 32px)"; panel.style.setProperty("max-width", "calc(100vw - 32px)", "important");
return () => { return () => {
panel.style.width = prevWidth; panel.style.width = prevWidth;
@ -405,6 +414,7 @@ function HeatmapInnerView() {
return ( return (
<div <div
data-dsh-heatmap="true" data-dsh-heatmap="true"
ref={rootRef}
style={{ style={{
boxSizing: "border-box", boxSizing: "border-box",
width: "100%", width: "100%",
@ -570,14 +580,14 @@ function HeatmapInnerView() {
)} )}
</div> </div>
{/* Clean, centered SVG Calendar Grid (Fits panel smoothly) */} {/* Clean, centered SVG Calendar Grid (Fits 1180px panel with zero scrollbars) */}
{calendarGrid && ( {calendarGrid && (
<div style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "center" }}> <div style={{ width: "100%", display: "flex", flexDirection: "column", alignItems: "center" }}>
<svg <svg
viewBox="0 0 770 120" viewBox="0 0 880 136"
style={{ style={{
width: "100%", width: "100%",
maxWidth: "770px", maxWidth: "880px",
height: "auto", height: "auto",
display: "block", display: "block",
overflow: "visible", overflow: "visible",
@ -587,9 +597,9 @@ function HeatmapInnerView() {
{monthHeaders.map((m, i) => ( {monthHeaders.map((m, i) => (
<text <text
key={i} key={i}
x={28 + m.col * 13.8} x={32 + m.col * 15.6}
y={10} y={11}
fontSize={10} fontSize={11}
fill="var(--dsw-alias-label-tertiary, #888888)" fill="var(--dsw-alias-label-tertiary, #888888)"
fontFamily="inherit" fontFamily="inherit"
> >
@ -598,19 +608,19 @@ function HeatmapInnerView() {
))} ))}
{/* Day of week labels */} {/* Day of week labels */}
<text x={2} y={39} fontSize={9} fill="var(--dsw-alias-label-tertiary, #888888)" fontFamily="inherit"> <text x={2} y={45} fontSize={10} fill="var(--dsw-alias-label-tertiary, #888888)" fontFamily="inherit">
Mon Mon
</text> </text>
<text x={2} y={67} fontSize={9} fill="var(--dsw-alias-label-tertiary, #888888)" fontFamily="inherit"> <text x={2} y={76} fontSize={10} fill="var(--dsw-alias-label-tertiary, #888888)" fontFamily="inherit">
Wed Wed
</text> </text>
<text x={2} y={95} fontSize={9} fill="var(--dsw-alias-label-tertiary, #888888)" fontFamily="inherit"> <text x={2} y={107} fontSize={10} fill="var(--dsw-alias-label-tertiary, #888888)" fontFamily="inherit">
Fri Fri
</text> </text>
{/* Day Tiles: centered and proportioned */} {/* Day Tiles: comfortable 12px with 15.6px step */}
{calendarGrid.map((week, colIdx) => ( {calendarGrid.map((week, colIdx) => (
<g key={colIdx} transform={`translate(${28 + colIdx * 13.8}, 18)`}> <g key={colIdx} transform={`translate(${32 + colIdx * 15.6}, 18)`}>
{week.map((day, rowIdx) => { {week.map((day, rowIdx) => {
if (!day) return null; if (!day) return null;
@ -628,17 +638,17 @@ function HeatmapInnerView() {
? "rgba(255, 255, 255, 0.06)" ? "rgba(255, 255, 255, 0.06)"
: "transparent"; : "transparent";
const strokeWidth = isSelected ? 1.6 : isHovered ? 1.3 : 1; const strokeWidth = isSelected ? 1.8 : isHovered ? 1.4 : 1;
return ( return (
<rect <rect
key={rowIdx} key={rowIdx}
x={0} x={0}
y={rowIdx * 14} y={rowIdx * 15.6}
width={11} width={12}
height={11} height={12}
rx={2} rx={2.5}
ry={2} ry={2.5}
fill={bg} fill={bg}
stroke={strokeColor} stroke={strokeColor}
strokeWidth={strokeWidth} strokeWidth={strokeWidth}
@ -676,7 +686,7 @@ function HeatmapInnerView() {
<div <div
style={{ style={{
width: "100%", width: "100%",
maxWidth: "770px", maxWidth: "880px",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
justifyContent: "space-between", justifyContent: "space-between",
@ -695,9 +705,9 @@ function HeatmapInnerView() {
<div <div
key={i} key={i}
style={{ style={{
width: 11, width: 12,
height: 11, height: 12,
borderRadius: 2, borderRadius: 2.5,
backgroundColor: c, backgroundColor: c,
border: i === 0 ? "1px solid rgba(255, 255, 255, 0.06)" : "none", border: i === 0 ? "1px solid rgba(255, 255, 255, 0.06)" : "none",
filter: i === 4 ? "drop-shadow(0 0 3px rgba(79, 133, 255, 0.5))" : "none", filter: i === 4 ? "drop-shadow(0 0 3px rgba(79, 133, 255, 0.5))" : "none",

View file

@ -25,6 +25,22 @@ export function apply(ctx: any) {
// 2. Global Modal Host & In-Session Token Meter Integration // 2. Global Modal Host & In-Session Token Meter Integration
if (typeof document !== "undefined") { if (typeof document !== "undefined") {
// Inject dynamic resizing stylesheet for settings dialog
if (!document.getElementById("dsh-token-heatmap-panel-resize")) {
const resizeStyle = document.createElement("style");
resizeStyle.id = "dsh-token-heatmap-panel-resize";
resizeStyle.textContent = `
/* Dynamically widen DSH Settings panel when Token Heatmap is active */
.VOzbGW_panel:has([data-dsh-heatmap]),
[class*="_panel"]:has([data-dsh-heatmap]) {
width: min(1180px, calc(100vw - 32px)) !important;
max-width: calc(100vw - 32px) !important;
transition: width 0.25s cubic-bezier(0.16, 1, 0.3, 1), max-width 0.25s ease !important;
}
`;
document.head.appendChild(resizeStyle);
}
const modalContainer = document.createElement("div"); const modalContainer = document.createElement("div");
modalContainer.id = "dsh-token-heatmap-modal-root"; modalContainer.id = "dsh-token-heatmap-modal-root";
document.body.appendChild(modalContainer); document.body.appendChild(modalContainer);