diff --git a/packages/web/src/components/ui/ContextMenuRenderer.tsx b/packages/web/src/components/ui/ContextMenuRenderer.tsx index cc7b7123..7dae29c7 100644 --- a/packages/web/src/components/ui/ContextMenuRenderer.tsx +++ b/packages/web/src/components/ui/ContextMenuRenderer.tsx @@ -1,9 +1,10 @@ -import React, { useEffect, useLayoutEffect, useRef, useCallback, useState } from 'react'; +import React, { useEffect, useLayoutEffect, useRef, useCallback, useState, useSyncExternalStore } from 'react'; import { createPortal } from 'react-dom'; import { useContextMenuStore, filterMenuItems, type ContextMenuItem, + type ContextMenuCheckbox, type ContextMenuLeafItem, type ContextMenuSubmenu, } from '../../stores/contextMenuStore'; @@ -41,6 +42,35 @@ function CheckboxIndicator({ checked }: { checked: boolean }) { ); } +// ── Reactive checkbox wrapper ─────────────────────────────────────────────── + +interface ReactiveCheckboxItemProps { + item: ContextMenuCheckbox; + isMobile?: boolean; +} + +function ReactiveCheckboxItem({ item, isMobile }: ReactiveCheckboxItemProps) { + const checked = useSyncExternalStore(item.subscribe, item.getChecked); + + const className = isMobile + ? `${MOBILE_ITEM_CLASS} text-txt-primary` + : ITEM_CLASS; + + return ( + + ); +} + // ── Desktop submenu flyout ─────────────────────────────────────────────────── interface SubmenuFlyoutProps { @@ -115,19 +145,7 @@ function DesktopLeafItem({ item, close }: DesktopLeafItemProps) { return