Fix item pane section button icons in light and dark themes.

Wire stroke context properties for Lucide SVG toolbar icons and set light/dark icon URLs on open-in-window and adaptive-height buttons.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
yhy
2026-08-29 23:54:45 +08:00
co-authored by Cursor
parent 36b806378f
commit 54f004a56c
4 changed files with 75 additions and 25 deletions
+28
View File
@@ -14,6 +14,34 @@
min-height: 0 !important; min-height: 0 !important;
} }
/*
* Item pane section header buttons (open in window, adaptive height).
* Lucide-style icons are stroke-based (context-stroke); Zotero only enables
* fill context on .section-custom-button by default, so strokes stay invisible
* in light and dark themes until stroke is wired to currentColor.
*/
collapsible-section.chatpapers-adaptive-height > .head toolbarbutton.section-custom-button,
collapsible-section.chatpapers-fixed-height > .head toolbarbutton.section-custom-button {
-moz-context-properties: fill, fill-opacity, stroke, stroke-opacity;
fill: currentColor;
stroke: currentColor;
color: inherit;
}
@media (prefers-color-scheme: light) {
collapsible-section.chatpapers-adaptive-height > .head toolbarbutton.section-custom-button,
collapsible-section.chatpapers-fixed-height > .head toolbarbutton.section-custom-button {
list-style-image: var(--custom-button-icon-light);
}
}
@media (prefers-color-scheme: dark) {
collapsible-section.chatpapers-adaptive-height > .head toolbarbutton.section-custom-button,
collapsible-section.chatpapers-fixed-height > .head toolbarbutton.section-custom-button {
list-style-image: var(--custom-button-icon-dark);
}
}
collapsible-section.chatpapers-adaptive-height[open] { collapsible-section.chatpapers-adaptive-height[open] {
--open-height: auto; --open-height: auto;
} }
@@ -4,6 +4,7 @@ import { findPdfAttachment } from "../../pdf/extractor";
import { ensureChatPapersStyles } from "../../ui/readerPane"; import { ensureChatPapersStyles } from "../../ui/readerPane";
import { import {
applyAdaptiveHeight, applyAdaptiveHeight,
applyItemPaneSectionButtonIcons,
buildItemPaneSectionButtons, buildItemPaneSectionButtons,
onItemPaneSectionToggle, onItemPaneSectionToggle,
prepareItemPaneBody, prepareItemPaneBody,
@@ -71,6 +72,7 @@ export function registerLecturePane() {
body.append(err); body.append(err);
} }
applyAdaptiveHeight(body, "lecture"); applyAdaptiveHeight(body, "lecture");
applyItemPaneSectionButtonIcons(body);
const section = body.closest("collapsible-section"); const section = body.closest("collapsible-section");
if (section?.hasAttribute("open")) { if (section?.hasAttribute("open")) {
refreshSectionOpenHeight(body); refreshSectionOpenHeight(body);
+43 -25
View File
@@ -37,6 +37,48 @@ export function isAdaptiveHeight(kind: ItemPaneKind): boolean {
return val !== false; return val !== false;
} }
function setSectionButtonIcons(btn: HTMLElement, icon: string): void {
const url = `url('${icon}')`;
btn.style.setProperty("--custom-button-icon-light", url);
btn.style.setProperty("--custom-button-icon-dark", url);
}
function applyOpenInWindowButtonIcon(body: HTMLElement): void {
const section = resolveCollapsibleSection(body);
const btn = section?.querySelector(
".open-in-window.section-custom-button",
) as HTMLElement | null;
if (!btn) return;
setSectionButtonIcons(btn, OPEN_WINDOW_ICON);
}
export function updateAdaptiveButtonState(
body: HTMLElement,
adaptive: boolean,
): void {
const section = resolveCollapsibleSection(body);
const btn = section?.querySelector(
".adaptive-height.section-custom-button",
) as HTMLElement | null;
if (!btn) return;
btn.setAttribute("aria-pressed", adaptive ? "true" : "false");
btn.classList.toggle("chatpapers-adaptive-active", adaptive);
setSectionButtonIcons(btn, adaptive ? ADAPTIVE_ICON : ADAPTIVE_ICON_OFF);
btn.title = getString(
adaptive ? "item-pane-adaptive-height-on" : "item-pane-adaptive-height-off",
);
}
export function applyItemPaneSectionButtonIcons(
body: HTMLElement,
adaptive = isAdaptiveHeight(
(body.dataset.chatpapersPaneKind || "chat") as ItemPaneKind,
),
): void {
applyOpenInWindowButtonIcon(body);
updateAdaptiveButtonState(body, adaptive);
}
export function applyAdaptiveHeight( export function applyAdaptiveHeight(
body: HTMLElement, body: HTMLElement,
kind: ItemPaneKind, kind: ItemPaneKind,
@@ -49,7 +91,7 @@ export function applyAdaptiveHeight(
const section = resolveCollapsibleSection(body); const section = resolveCollapsibleSection(body);
section?.classList.toggle("chatpapers-adaptive-height", adaptive); section?.classList.toggle("chatpapers-adaptive-height", adaptive);
section?.classList.toggle("chatpapers-fixed-height", !adaptive); section?.classList.toggle("chatpapers-fixed-height", !adaptive);
updateAdaptiveButtonState(body, adaptive); applyItemPaneSectionButtonIcons(body, adaptive);
} }
export function toggleAdaptiveHeight( export function toggleAdaptiveHeight(
@@ -81,30 +123,6 @@ export function refreshSectionOpenHeight(body: HTMLElement): void {
section.style.setProperty("--open-height", `${maxH}px`); section.style.setProperty("--open-height", `${maxH}px`);
} }
export function updateAdaptiveButtonState(
body: HTMLElement,
adaptive: boolean,
): void {
const section = resolveCollapsibleSection(body);
const btn = section?.querySelector(
".adaptive-height.section-custom-button",
) as HTMLElement | null;
if (!btn) return;
btn.setAttribute("aria-pressed", adaptive ? "true" : "false");
btn.classList.toggle("chatpapers-adaptive-active", adaptive);
btn.style.setProperty(
"--custom-button-icon-light",
`url('${adaptive ? ADAPTIVE_ICON : ADAPTIVE_ICON_OFF}')`,
);
btn.style.setProperty(
"--custom-button-icon-dark",
`url('${adaptive ? ADAPTIVE_ICON : ADAPTIVE_ICON_OFF}')`,
);
btn.title = getString(
adaptive ? "item-pane-adaptive-height-on" : "item-pane-adaptive-height-off",
);
}
export function onItemPaneSectionToggle(options: { export function onItemPaneSectionToggle(options: {
body: HTMLElement; body: HTMLElement;
event?: Event; event?: Event;
+2
View File
@@ -3,6 +3,7 @@ import { getLocaleID, getString } from "../../utils/locale";
import { ChatView } from "./chatView"; import { ChatView } from "./chatView";
import { import {
applyAdaptiveHeight, applyAdaptiveHeight,
applyItemPaneSectionButtonIcons,
buildItemPaneSectionButtons, buildItemPaneSectionButtons,
onItemPaneSectionToggle, onItemPaneSectionToggle,
prepareItemPaneBody, prepareItemPaneBody,
@@ -62,6 +63,7 @@ export function registerChatPane() {
views.set(body, view); views.set(body, view);
await view.mount(); await view.mount();
applyAdaptiveHeight(body, "chat"); applyAdaptiveHeight(body, "chat");
applyItemPaneSectionButtonIcons(body);
const section = body.closest("collapsible-section"); const section = body.closest("collapsible-section");
if (section?.hasAttribute("open")) { if (section?.hasAttribute("open")) {
refreshSectionOpenHeight(body); refreshSectionOpenHeight(body);