fix: Consistent menus in editor (#3363)

* Use scrollable in context menu

* fix: Remove old blockToolbar styles
This commit is contained in:
Tom Moor
2022-04-12 20:12:45 -07:00
committed by GitHub
parent 86f1645199
commit abbc3bdb30
7 changed files with 35 additions and 58 deletions

View File

@@ -5,6 +5,7 @@ import { Menu } from "reakit/Menu";
import styled, { DefaultTheme } from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { depths } from "@shared/styles";
import Scrollable from "~/components/Scrollable";
import useMenuContext from "~/hooks/useMenuContext";
import useMenuHeight from "~/hooks/useMenuHeight";
import usePrevious from "~/hooks/usePrevious";
@@ -116,6 +117,7 @@ const ContextMenu: React.FC<Props> = ({
topAnchor={topAnchor}
rightAnchor={rightAnchor}
ref={backgroundRef}
hiddenScrollbars
style={
maxHeight && topAnchor
? {
@@ -180,7 +182,7 @@ type BackgroundProps = {
theme: DefaultTheme;
};
export const Background = styled.div<BackgroundProps>`
export const Background = styled(Scrollable)<BackgroundProps>`
animation: ${mobileContextMenu} 200ms ease;
transform-origin: 50% 100%;
max-width: 100%;
@@ -189,8 +191,6 @@ export const Background = styled.div<BackgroundProps>`
padding: 6px 0;
min-width: 180px;
min-height: 44px;
overflow: hidden;
overflow-y: auto;
max-height: 75vh;
pointer-events: all;
font-weight: normal;

View File

@@ -3,16 +3,17 @@ import * as React from "react";
import styled from "styled-components";
import useWindowSize from "~/hooks/useWindowSize";
type Props = {
type Props = React.HTMLAttributes<HTMLDivElement> & {
shadow?: boolean;
topShadow?: boolean;
bottomShadow?: boolean;
hiddenScrollbars?: boolean;
flex?: boolean;
children: React.ReactNode;
};
function Scrollable(
{ shadow, topShadow, bottomShadow, flex, ...rest }: Props,
{ shadow, topShadow, bottomShadow, hiddenScrollbars, flex, ...rest }: Props,
ref: React.RefObject<HTMLDivElement>
) {
const fallbackRef = React.useRef<HTMLDivElement>();
@@ -55,6 +56,7 @@ function Scrollable(
ref={ref || fallbackRef}
onScroll={updateShadows}
$flex={flex}
$hiddenScrollbars={hiddenScrollbars}
$topShadowVisible={topShadowVisible}
$bottomShadowVisible={bottomShadowVisible}
{...rest}
@@ -66,6 +68,7 @@ const Wrapper = styled.div<{
$flex?: boolean;
$topShadowVisible?: boolean;
$bottomShadowVisible?: boolean;
$hiddenScrollbars?: boolean;
}>`
display: ${(props) => (props.$flex ? "flex" : "block")};
flex-direction: column;
@@ -90,6 +93,17 @@ const Wrapper = styled.div<{
return "none";
}};
transition: all 100ms ease-in-out;
${(props) =>
props.$hiddenScrollbars &&
`
-ms-overflow-style: none;
overflow: -moz-scrollbars-none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
`}
`;
export default observer(React.forwardRef(Scrollable));

View File

@@ -1,6 +1,6 @@
import * as React from "react";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import styled, { useTheme } from "styled-components";
import styled from "styled-components";
export type Props = {
selected: boolean;
@@ -22,7 +22,6 @@ function BlockMenuItem({
containerId = "block-menu-container",
}: Props) {
const Icon = icon;
const theme = useTheme();
const ref = React.useCallback(
(node) => {
@@ -50,11 +49,7 @@ function BlockMenuItem({
>
{Icon && (
<>
<Icon
color={
selected ? theme.blockToolbarIconSelected : theme.blockToolbarIcon
}
/>
<Icon color="currentColor" />
&nbsp;&nbsp;
</>
)}
@@ -85,24 +80,14 @@ const MenuItem = styled.button<{
border: none;
opacity: ${(props) => (props.disabled ? ".5" : "1")};
color: ${(props) =>
props.selected
? props.theme.blockToolbarTextSelected
: props.theme.blockToolbarText};
background: ${(props) =>
props.selected
? props.theme.blockToolbarSelectedBackground ||
props.theme.blockToolbarTrigger
: "none"};
props.selected ? props.theme.white : props.theme.textSecondary};
background: ${(props) => (props.selected ? props.theme.primary : "none")};
padding: 0 16px;
outline: none;
&:active {
color: ${(props) => props.theme.blockToolbarTextSelected};
background: ${(props) =>
props.selected
? props.theme.blockToolbarSelectedBackground ||
props.theme.blockToolbarTrigger
: props.theme.blockToolbarHoverBackground};
color: ${(props) => props.theme.white};
background: ${(props) => (props.selected ? props.theme.primary : "none")};
${Shortcut} {
color: ${(props) => props.theme.textSecondary};

View File

@@ -13,6 +13,7 @@ import { EmbedDescriptor, MenuItem } from "@shared/editor/types";
import { depths } from "@shared/styles";
import { supportedImageMimeTypes } from "@shared/utils/files";
import getDataTransferFiles from "@shared/utils/getDataTransferFiles";
import Scrollable from "~/components/Scrollable";
import { Dictionary } from "~/hooks/useDictionary";
import Input from "./Input";
@@ -488,6 +489,7 @@ class CommandMenu<T = MenuItem> extends React.Component<Props<T>, State> {
id={this.props.id || "block-menu-container"}
active={isActive}
ref={this.menuRef}
hiddenScrollbars
{...positioning}
>
{insertItem ? (
@@ -570,7 +572,7 @@ const LinkInputWrapper = styled.div`
const LinkInput = styled(Input)`
height: 36px;
width: 100%;
color: ${(props) => props.theme.blockToolbarText};
color: ${(props) => props.theme.textSecondary};
`;
const List = styled.ol`
@@ -596,22 +598,22 @@ const Empty = styled.div`
padding: 0 16px;
`;
export const Wrapper = styled.div<{
export const Wrapper = styled(Scrollable)<{
active: boolean;
top?: number;
bottom?: number;
left?: number;
isAbove: boolean;
}>`
color: ${(props) => props.theme.text};
color: ${(props) => props.theme.textSecondary};
font-family: ${(props) => props.theme.fontFamily};
position: absolute;
z-index: ${depths.editorToolbar};
${(props) => props.top !== undefined && `top: ${props.top}px`};
${(props) => props.bottom !== undefined && `bottom: ${props.bottom}px`};
left: ${(props) => props.left}px;
background-color: ${(props) => props.theme.blockToolbarBackground};
border-radius: 4px;
background: ${(props) => props.theme.menuBackground};
border-radius: 6px;
box-shadow: rgba(0, 0, 0, 0.05) 0px 0px 0px 1px,
rgba(0, 0, 0, 0.08) 0px 4px 8px, rgba(0, 0, 0, 0.08) 0px 2px 4px;
opacity: 0;
@@ -625,8 +627,6 @@ export const Wrapper = styled.div<{
white-space: nowrap;
width: 300px;
max-height: 324px;
overflow: hidden;
overflow-y: auto;
* {
box-sizing: border-box;
@@ -635,7 +635,7 @@ export const Wrapper = styled.div<{
hr {
border: 0;
height: 0;
border-top: 1px solid ${(props) => props.theme.blockToolbarDivider};
border-top: 1px solid ${(props) => props.theme.divider};
}
${({ active, isAbove }) =>

View File

@@ -756,8 +756,8 @@ const EditorStyles = styled.div<{
select,
button {
background: ${(props) => props.theme.blockToolbarBackground};
color: ${(props) => props.theme.blockToolbarItem};
background: ${(props) => props.theme.background};
color: ${(props) => props.theme.text};
border-width: 1px;
font-size: 13px;
display: none;

View File

@@ -47,17 +47,6 @@ declare module "styled-components" {
codePlaceholder: string;
codeInserted: string;
codeImportant: string;
blockToolbarBackground: string;
blockToolbarTrigger: string;
blockToolbarTriggerIcon: string;
blockToolbarItem: string;
blockToolbarIcon: undefined;
blockToolbarIconSelected: string;
blockToolbarText: string;
blockToolbarTextSelected: string;
blockToolbarSelectedBackground: string;
blockToolbarHoverBackground: string;
blockToolbarDivider: string;
noticeInfoBackground: string;
noticeInfoText: string;
noticeTipBackground: string;

View File

@@ -81,17 +81,6 @@ export const base = {
codePlaceholder: "#3d8fd1",
codeInserted: "#202746",
codeImportant: "#c94922",
blockToolbarBackground: colors.white,
blockToolbarTrigger: colors.slate,
blockToolbarTriggerIcon: colors.white,
blockToolbarItem: colors.almostBlack,
blockToolbarText: colors.almostBlack,
blockToolbarTextSelected: colors.black,
blockToolbarSelectedBackground: colors.slateLight,
blockToolbarHoverBackground: colors.slateLight,
blockToolbarDivider: colors.slateLight,
blockToolbarIcon: undefined,
blockToolbarIconSelected: colors.black,
noticeInfoBackground: colors.warmGrey,
noticeInfoText: colors.almostBlack,
noticeTipBackground: "#fce5bb",