Skip to content

Commit

Permalink
#772: Made hamburger menu button able to take an offset instead of a …
Browse files Browse the repository at this point in the history
…containerRef to determine position of menu.

Added some "dummy" web view menu data for resourceViewer.react
Modified createRCDockTabFromTabInfo to pass web view type to the title and made the title's icon into a menu button (instead of the hamburger icon).
  • Loading branch information
tombogle committed Mar 6, 2024
1 parent 2283b38 commit aa4c3dd
Show file tree
Hide file tree
Showing 11 changed files with 721 additions and 638 deletions.
6 changes: 0 additions & 6 deletions lib/papi-dts/papi.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2978,7 +2978,6 @@ declare module 'shared/models/docking-framework.model' {
WebViewDefinition,
WebViewDefinitionUpdateInfo,
} from 'shared/models/web-view.model';
import { HamburgerMenuButtonProps } from 'platform-bible-react';
/**
* Saved information used to recreate a tab.
*
Expand All @@ -3003,11 +3002,6 @@ declare module 'shared/models/docking-framework.model' {
* - {@link TabSaver} saves this into {@link SavedTabInfo}
*/
export type TabInfo = SavedTabInfo & {
/**
* Optional multi-column menu definition. If provided, the "hamburger" menu icon will be shown on
* the leading side of the icon and/or text label.
*/
menuInfo?: HamburgerMenuButtonProps;
/**
* Url of image to show on the title bar of the tab
*
Expand Down
362 changes: 181 additions & 181 deletions lib/platform-bible-react/dist/index.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/platform-bible-react/dist/index.cjs.map

Large diffs are not rendered by default.

13 changes: 9 additions & 4 deletions lib/platform-bible-react/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,15 @@ export type HamburgerMenuButtonProps = React$1.PropsWithChildren & {
/** The handler to use for menu commands (and eventually toolbar commands). */
commandHandler: CommandHandler;
/**
* Reference to the "div" container that determines the top of the area in which the menu should
* appear.
* Optional reference to the "div" container that determines the top of the area in which the menu should
* appear. If not defined, then the offsetFromBottomOfMenuToTopOfMenu is used.
*/
containerRef: React$1.MutableRefObject<HTMLDivElement>;
containerRef?: React$1.MutableRefObject<HTMLDivElement>;
/**
* If containerRef is not defined, this is the desired offset in pixels from the bottom of the
* button to the top of menu. Defaults to 1.
*/
offsetFromBottomOfButtonToTopOfMenu?: number;
/** The menu data to show when the menu is opened. */
normalMenu: MultiColumnMenu;
/**
Expand All @@ -416,7 +421,7 @@ export type HamburgerMenuButtonProps = React$1.PropsWithChildren & {
/** Value to use as prefix for ARIA labels on interactive sub-components */
ariaLabelPrefix?: string;
};
export function HamburgerMenuButton({ normalMenu, fullMenu, commandHandler, containerRef, className, ariaLabelPrefix, children, }: HamburgerMenuButtonProps): import("react/jsx-runtime").JSX.Element;
export function HamburgerMenuButton({ normalMenu, fullMenu, commandHandler, containerRef, offsetFromBottomOfButtonToTopOfMenu, className, ariaLabelPrefix, children, }: HamburgerMenuButtonProps): import("react/jsx-runtime").JSX.Element;
export type IconButtonProps = React$1.PropsWithChildren<{
/** Optional unique identifier */
id?: string;
Expand Down
843 changes: 422 additions & 421 deletions lib/platform-bible-react/dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion lib/platform-bible-react/dist/index.js.map

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,16 @@ export type HamburgerMenuButtonProps = PropsWithChildren & {
commandHandler: CommandHandler;

/**
* Reference to the "div" container that determines the top of the area in which the menu should
* appear.
* Optional reference to the "div" container that determines the top of the area in which the menu
* should appear. If not defined, then the offsetFromBottomOfMenuToTopOfMenu is used.
*/
containerRef: MutableRefObject<HTMLDivElement>;
containerRef?: MutableRefObject<HTMLDivElement>;

/**
* If containerRef is not defined, this is the desired offset in pixels from the bottom of the
* button to the top of menu. Defaults to 1.
*/
offsetFromBottomOfButtonToTopOfMenu?: number;

/** The menu data to show when the menu is opened. */
normalMenu: MultiColumnMenu;
Expand All @@ -43,6 +49,7 @@ export default function HamburgerMenuButton({
fullMenu,
commandHandler,
containerRef,
offsetFromBottomOfButtonToTopOfMenu,
className,
ariaLabelPrefix,
children,
Expand Down Expand Up @@ -81,10 +88,14 @@ export default function HamburgerMenuButton({
const [topOfMenu, setTopOfMenu] = useState(0);

useEffect(() => {
if (isMenuOpen && containerRef.current) {
setTopOfMenu(containerRef.current.clientHeight);
if (isMenuOpen) {
if (containerRef?.current) {
setTopOfMenu(containerRef.current.clientHeight);
} else {
setTopOfMenu(offsetFromBottomOfButtonToTopOfMenu ?? 1);
}
}
}, [isMenuOpen, containerRef]);
}, [isMenuOpen, containerRef, offsetFromBottomOfButtonToTopOfMenu]);

return (
<>
Expand Down
51 changes: 51 additions & 0 deletions src/extension-host/data/menu.data.json
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,57 @@
"groups": {},
"items": []
}
},

"resourceViewer.react": {
"includeDefaults": true,
"topMenu": {
"columns": {
"resourceViewer.options": { "label": "%options%", "order": 2 },
"resourceViewer.info": { "label": "%info%", "order": 3 }
},
"groups": {
"resourceViewer.colors": { "column": "resourceViewer.options", "order": 1 },
"resourceViewer.layout": { "column": "resourceViewer.options", "order": 2 },
"resourceViewer.general": { "column": "resourceViewer.info", "order": 2 }
},
"items": [
{
"label": "%backgroundColor%",
"group": "resourceViewer.colors",
"order": 2,
"command": "resourceViewer.changeBackgroundColor"
},
{
"label": "%textColor%",
"group": "resourceViewer.colors",
"order": 1,
"command": "resourceViewer.changeTextColor"
},
{
"label": "%thickBorders%",
"group": "resourceViewer.layout",
"order": 1,
"command": "resourceViewer.showThickBorders"
},
{
"label": "%publisherInfo%",
"group": "resourceViewer.general",
"order": 1,
"command": "resourceViewer.showPublisherInfo"
},
{
"label": "%copyrightInfo%",
"group": "resourceViewer.general",
"order": 2,
"command": "resourceViewer.showCopyrightInfo"
}
]
},
"contextMenu": {
"groups": {},
"items": []
}
}
}
}
10 changes: 9 additions & 1 deletion src/renderer/components/docking/platform-dock-tab.component.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { TabInfo } from '@shared/models/docking-framework.model';

import { WebViewDefinition } from '@shared/models/web-view.model';
import { TAB_GROUP } from './platform-dock-layout-positioning.util';
import PlatformPanel from './platform-panel.component';
import PlatformTabTitle from './platform-tab-title.component';
Expand All @@ -12,11 +13,18 @@ import PlatformTabTitle from './platform-tab-title.component';
*/
export default function createRCDockTabFromTabInfo(tabInfo: TabInfo) {
// Translate the data from the loaded tab to be in the form needed by rc-dock
const webViewData =
// If the tab is for a web view, then its data should be a WebViewDefinition
// eslint-disable-next-line no-type-assertion/no-type-assertion
tabInfo.tabType === 'webView' ? (tabInfo.data as WebViewDefinition) : undefined;
// Assume the webViewType is correctly formatted because it should have already been checked
// eslint-disable-next-line no-type-assertion/no-type-assertion
const webViewType = webViewData?.webViewType as `${string}.${string}`;
return {
...tabInfo,
title: (
<PlatformTabTitle
menuInfo={tabInfo.menuInfo}
webViewType={webViewType}
iconUrl={tabInfo.tabIconUrl}
text={tabInfo.tabTitle}
tooltip={tabInfo.tabTooltip}
Expand Down
41 changes: 30 additions & 11 deletions src/renderer/components/docking/platform-tab-title.component.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Tooltip } from '@mui/material';
import { HamburgerMenuButton, HamburgerMenuButtonProps } from 'platform-bible-react';
import { HamburgerMenuButton } from 'platform-bible-react';
import './platform-tab-title.component.scss';
import menuDataService from '@shared/services/menu-data.service';
import { useData } from '@renderer/hooks/papi-hooks';
import { handleMenuCommand } from '../platform-bible-menu.commands';

type PlatformTabTitleProps = {
/**
* Optional information about the menu to display. If provided, the "hamburger" menu icon will be
* shown on the leading side of the icon and/or text label.
*/
menuInfo?: HamburgerMenuButtonProps;
/** What type of WebView this is. Unique to all other WebView definitions */
webViewType?: `${string}.${string}`;
/** Url to image to show on the tab. Defaults to Platform.Bible logo */
iconUrl?: string;
/** Text to show on the tab */
Expand All @@ -24,11 +24,24 @@ type PlatformTabTitleProps = {
* @param tooltip Text to show when hovering over the tab. Defaults to empty string
*/
export default function PlatformTabTitle({
menuInfo,
webViewType,
iconUrl,
text,
tooltip,
}: PlatformTabTitleProps) {
const menuSelector = webViewType ?? 'invalid.invalid';

const menuInfo = useData(webViewType ? menuDataService.dataProviderName : undefined).WebViewMenu(
menuSelector,
{
topMenu: undefined,
includeDefaults: true,
contextMenu: undefined,
},
);

const [webViewMenu, , isLoading] = menuInfo;

const tooltipDiv = tooltip ? <div className="tooltip">{tooltip}</div> : '';

const icon = (
Expand All @@ -47,12 +60,18 @@ export default function PlatformTabTitle({
return (
<Tooltip title={tooltipDiv}>
<div className="title">
{menuInfo ? (
<HamburgerMenuButton className="tab-menu-button" aria-label="Tab" {...menuInfo}>
{isLoading || !webViewMenu?.topMenu ? (
icon
) : (
<HamburgerMenuButton
commandHandler={handleMenuCommand}
normalMenu={webViewMenu.topMenu}
className="tab-menu-button"
aria-label="Tab"
offsetFromBottomOfButtonToTopOfMenu={20}
>
{icon}
</HamburgerMenuButton>
) : (
icon
)}
<span>{text}</span>
</div>
Expand Down
6 changes: 0 additions & 6 deletions src/shared/models/docking-framework.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
WebViewDefinition,
WebViewDefinitionUpdateInfo,
} from '@shared/models/web-view.model';
import { HamburgerMenuButtonProps } from 'platform-bible-react';

/**
* Saved information used to recreate a tab.
Expand All @@ -32,11 +31,6 @@ export type SavedTabInfo = {
* - {@link TabSaver} saves this into {@link SavedTabInfo}
*/
export type TabInfo = SavedTabInfo & {
/**
* Optional multi-column menu definition. If provided, the "hamburger" menu icon will be shown on
* the leading side of the icon and/or text label.
*/
menuInfo?: HamburgerMenuButtonProps;
/**
* Url of image to show on the title bar of the tab
*
Expand Down

0 comments on commit aa4c3dd

Please sign in to comment.