fix: Consistent menus in editor (#3363)
* Use scrollable in context menu * fix: Remove old blockToolbar styles
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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" />
|
||||
|
||||
</>
|
||||
)}
|
||||
@@ -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};
|
||||
|
||||
@@ -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 }) =>
|
||||
|
||||
@@ -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;
|
||||
|
||||
11
app/typings/styled-components.d.ts
vendored
11
app/typings/styled-components.d.ts
vendored
@@ -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;
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user