From 54f004a56ccf01e70ad78a7b004fb0a4d1852a68 Mon Sep 17 00:00:00 2001 From: yhy Date: Sat, 29 Aug 2026 23:54:45 +0800 Subject: [PATCH] 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 --- addon/content/chatpapers.css | 28 ++++++++ src/modules/lecture/ui/registerLecturePane.ts | 2 + src/modules/ui/itemPaneSection.ts | 68 ++++++++++++------- src/modules/ui/readerPane.ts | 2 + 4 files changed, 75 insertions(+), 25 deletions(-) diff --git a/addon/content/chatpapers.css b/addon/content/chatpapers.css index 5d4b806..489751c 100644 --- a/addon/content/chatpapers.css +++ b/addon/content/chatpapers.css @@ -14,6 +14,34 @@ 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] { --open-height: auto; } diff --git a/src/modules/lecture/ui/registerLecturePane.ts b/src/modules/lecture/ui/registerLecturePane.ts index 8da8503..dab6892 100644 --- a/src/modules/lecture/ui/registerLecturePane.ts +++ b/src/modules/lecture/ui/registerLecturePane.ts @@ -4,6 +4,7 @@ import { findPdfAttachment } from "../../pdf/extractor"; import { ensureChatPapersStyles } from "../../ui/readerPane"; import { applyAdaptiveHeight, + applyItemPaneSectionButtonIcons, buildItemPaneSectionButtons, onItemPaneSectionToggle, prepareItemPaneBody, @@ -71,6 +72,7 @@ export function registerLecturePane() { body.append(err); } applyAdaptiveHeight(body, "lecture"); + applyItemPaneSectionButtonIcons(body); const section = body.closest("collapsible-section"); if (section?.hasAttribute("open")) { refreshSectionOpenHeight(body); diff --git a/src/modules/ui/itemPaneSection.ts b/src/modules/ui/itemPaneSection.ts index c51219a..92c2adb 100644 --- a/src/modules/ui/itemPaneSection.ts +++ b/src/modules/ui/itemPaneSection.ts @@ -37,6 +37,48 @@ export function isAdaptiveHeight(kind: ItemPaneKind): boolean { 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( body: HTMLElement, kind: ItemPaneKind, @@ -49,7 +91,7 @@ export function applyAdaptiveHeight( const section = resolveCollapsibleSection(body); section?.classList.toggle("chatpapers-adaptive-height", adaptive); section?.classList.toggle("chatpapers-fixed-height", !adaptive); - updateAdaptiveButtonState(body, adaptive); + applyItemPaneSectionButtonIcons(body, adaptive); } export function toggleAdaptiveHeight( @@ -81,30 +123,6 @@ export function refreshSectionOpenHeight(body: HTMLElement): void { 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: { body: HTMLElement; event?: Event; diff --git a/src/modules/ui/readerPane.ts b/src/modules/ui/readerPane.ts index 8369f8a..b064cb8 100644 --- a/src/modules/ui/readerPane.ts +++ b/src/modules/ui/readerPane.ts @@ -3,6 +3,7 @@ import { getLocaleID, getString } from "../../utils/locale"; import { ChatView } from "./chatView"; import { applyAdaptiveHeight, + applyItemPaneSectionButtonIcons, buildItemPaneSectionButtons, onItemPaneSectionToggle, prepareItemPaneBody, @@ -62,6 +63,7 @@ export function registerChatPane() { views.set(body, view); await view.mount(); applyAdaptiveHeight(body, "chat"); + applyItemPaneSectionButtonIcons(body); const section = body.closest("collapsible-section"); if (section?.hasAttribute("open")) { refreshSectionOpenHeight(body);