fix: Mispositioned TOC control on mobile due to merge conflict
fix: Show message in mobile TOC when no headings in document fix: MenuItem with level should still have background edge-to-edge fix: Show developer warning when creating incorrect menu item type
This commit is contained in:
parent
587a0e0517
commit
5cd4dbd9d7
|
@ -87,9 +87,9 @@ const Spacer = styled.svg`
|
|||
export const MenuAnchor = styled.a`
|
||||
display: flex;
|
||||
margin: 0;
|
||||
margin-left: ${(props) => props.level * 10}px;
|
||||
border: 0;
|
||||
padding: 12px;
|
||||
padding-left: ${(props) => 12 + props.level * 10}px;
|
||||
width: 100%;
|
||||
min-height: 32px;
|
||||
background: none;
|
||||
|
|
|
@ -13,47 +13,7 @@ import Header from "./Header";
|
|||
import MenuItem, { MenuAnchor } from "./MenuItem";
|
||||
import Separator from "./Separator";
|
||||
import ContextMenu from ".";
|
||||
|
||||
type TMenuItem =
|
||||
| {|
|
||||
title: React.Node,
|
||||
to: string,
|
||||
visible?: boolean,
|
||||
selected?: boolean,
|
||||
disabled?: boolean,
|
||||
|}
|
||||
| {|
|
||||
title: React.Node,
|
||||
onClick: (event: SyntheticEvent<>) => void | Promise<void>,
|
||||
visible?: boolean,
|
||||
selected?: boolean,
|
||||
disabled?: boolean,
|
||||
|}
|
||||
| {|
|
||||
title: React.Node,
|
||||
href: string,
|
||||
visible?: boolean,
|
||||
selected?: boolean,
|
||||
disabled?: boolean,
|
||||
level?: number,
|
||||
|}
|
||||
| {|
|
||||
title: React.Node,
|
||||
visible?: boolean,
|
||||
disabled?: boolean,
|
||||
style?: Object,
|
||||
hover?: boolean,
|
||||
items: TMenuItem[],
|
||||
|}
|
||||
| {|
|
||||
type: "separator",
|
||||
visible?: boolean,
|
||||
|}
|
||||
| {|
|
||||
type: "heading",
|
||||
visible?: boolean,
|
||||
title: React.Node,
|
||||
|};
|
||||
import { type MenuItem as TMenuItem } from "types";
|
||||
|
||||
type Props = {|
|
||||
items: TMenuItem[],
|
||||
|
@ -174,6 +134,7 @@ function Template({ items, ...menu }: Props): React.Node {
|
|||
return <Header>{item.title}</Header>;
|
||||
}
|
||||
|
||||
console.warn("Unrecognized menu item", item);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
|
|
@ -72,8 +72,6 @@ const Actions = styled(Flex)`
|
|||
flex-basis: 0;
|
||||
min-width: auto;
|
||||
padding-left: 8px;
|
||||
position: fixed;
|
||||
right: 12px;
|
||||
|
||||
${breakpoint("tablet")`
|
||||
position: unset;
|
||||
|
|
|
@ -7,6 +7,7 @@ import { MenuButton, useMenuState } from "reakit/Menu";
|
|||
import Button from "components/Button";
|
||||
import ContextMenu from "components/ContextMenu";
|
||||
import Template from "components/ContextMenu/Template";
|
||||
import { type MenuItem } from "types";
|
||||
|
||||
type Props = {|
|
||||
headings: { title: string, level: number, id: string }[],
|
||||
|
@ -27,6 +28,31 @@ function TableOfContentsMenu({ headings }: Props) {
|
|||
Infinity
|
||||
);
|
||||
|
||||
const items: MenuItem[] = React.useMemo(() => {
|
||||
let i = [
|
||||
{
|
||||
type: "heading",
|
||||
visible: true,
|
||||
title: t("Contents"),
|
||||
},
|
||||
...headings.map((heading) => ({
|
||||
href: `#${heading.id}`,
|
||||
title: t(heading.title),
|
||||
level: heading.level - minHeading,
|
||||
})),
|
||||
];
|
||||
|
||||
if (i.length === 1) {
|
||||
i.push({
|
||||
href: "#",
|
||||
title: t("Headings you add to the document will appear here"),
|
||||
disabled: true,
|
||||
});
|
||||
}
|
||||
|
||||
return i;
|
||||
}, [t, headings, minHeading]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MenuButton {...menu}>
|
||||
|
@ -41,23 +67,7 @@ function TableOfContentsMenu({ headings }: Props) {
|
|||
)}
|
||||
</MenuButton>
|
||||
<ContextMenu {...menu} aria-label={t("Table of contents")}>
|
||||
<Template
|
||||
{...menu}
|
||||
items={[
|
||||
{
|
||||
type: "heading",
|
||||
visible: true,
|
||||
title: t("Contents"),
|
||||
},
|
||||
...headings.map((heading) => {
|
||||
return {
|
||||
href: `#${heading.id}`,
|
||||
title: t(heading.title),
|
||||
level: heading.level - minHeading,
|
||||
};
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
<Template {...menu} items={items} />
|
||||
</ContextMenu>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -58,3 +58,44 @@ export type SearchResult = {
|
|||
context: string,
|
||||
document: Document,
|
||||
};
|
||||
|
||||
export type MenuItem =
|
||||
| {|
|
||||
title: React.Node,
|
||||
to: string,
|
||||
visible?: boolean,
|
||||
selected?: boolean,
|
||||
disabled?: boolean,
|
||||
|}
|
||||
| {|
|
||||
title: React.Node,
|
||||
onClick: (event: SyntheticEvent<>) => void | Promise<void>,
|
||||
visible?: boolean,
|
||||
selected?: boolean,
|
||||
disabled?: boolean,
|
||||
|}
|
||||
| {|
|
||||
title: React.Node,
|
||||
href: string,
|
||||
visible?: boolean,
|
||||
selected?: boolean,
|
||||
disabled?: boolean,
|
||||
level?: number,
|
||||
|}
|
||||
| {|
|
||||
title: React.Node,
|
||||
visible?: boolean,
|
||||
disabled?: boolean,
|
||||
style?: Object,
|
||||
hover?: boolean,
|
||||
items: MenuItem[],
|
||||
|}
|
||||
| {|
|
||||
type: "separator",
|
||||
visible?: boolean,
|
||||
|}
|
||||
| {|
|
||||
type: "heading",
|
||||
visible?: boolean,
|
||||
title: React.Node,
|
||||
|};
|
||||
|
|
|
@ -206,8 +206,9 @@
|
|||
"Share options": "Share options",
|
||||
"Go to document": "Go to document",
|
||||
"Revoke link": "Revoke link",
|
||||
"Table of contents": "Table of contents",
|
||||
"Contents": "Contents",
|
||||
"Headings you add to the document will appear here": "Headings you add to the document will appear here",
|
||||
"Table of contents": "Table of contents",
|
||||
"By {{ author }}": "By {{ author }}",
|
||||
"Are you sure you want to make {{ userName }} an admin? Admins can modify team and billing information.": "Are you sure you want to make {{ userName }} an admin? Admins can modify team and billing information.",
|
||||
"Are you sure you want to make {{ userName }} a member?": "Are you sure you want to make {{ userName }} a member?",
|
||||
|
|
Reference in New Issue