fix: Inset icon in collection headers, minor ContentEditable refactor (#3168)
This commit is contained in:
@@ -9,6 +9,8 @@ import {
|
||||
useHistory,
|
||||
useRouteMatch,
|
||||
} from "react-router-dom";
|
||||
import styled from "styled-components";
|
||||
import breakpoint from "styled-components-breakpoint";
|
||||
import Collection from "~/models/Collection";
|
||||
import Search from "~/scenes/Search";
|
||||
import Badge from "~/components/Badge";
|
||||
@@ -107,8 +109,7 @@ function CollectionScene() {
|
||||
title={
|
||||
<>
|
||||
<CollectionIcon collection={collection} expanded />
|
||||
|
||||
{collection.name}
|
||||
{collection.name}
|
||||
</>
|
||||
}
|
||||
actions={<Actions collection={collection} />}
|
||||
@@ -123,9 +124,9 @@ function CollectionScene() {
|
||||
<Empty collection={collection} />
|
||||
) : (
|
||||
<>
|
||||
<Heading>
|
||||
<CollectionIcon collection={collection} size={40} expanded />{" "}
|
||||
{collection.name}{" "}
|
||||
<HeadingWithIcon>
|
||||
<HeadingIcon collection={collection} size={40} expanded />
|
||||
{collection.name}
|
||||
{!collection.permission && (
|
||||
<Tooltip
|
||||
tooltip={t(
|
||||
@@ -136,7 +137,7 @@ function CollectionScene() {
|
||||
<Badge>{t("Private")}</Badge>
|
||||
</Tooltip>
|
||||
)}
|
||||
</Heading>
|
||||
</HeadingWithIcon>
|
||||
<CollectionDescription collection={collection} />
|
||||
|
||||
<PinnedDocuments
|
||||
@@ -243,4 +244,18 @@ function CollectionScene() {
|
||||
);
|
||||
}
|
||||
|
||||
const HeadingWithIcon = styled(Heading)`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
${breakpoint("tablet")`
|
||||
margin-left: -40px;
|
||||
`};
|
||||
`;
|
||||
|
||||
const HeadingIcon = styled(CollectionIcon)`
|
||||
align-self: flex-start;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
export default observer(CollectionScene);
|
||||
|
||||
@@ -7,6 +7,7 @@ import { light } from "@shared/theme";
|
||||
import Document from "~/models/Document";
|
||||
import ContentEditable from "~/components/ContentEditable";
|
||||
import Star, { AnimatedStar } from "~/components/Star";
|
||||
import useEmojiWidth from "~/hooks/useEmojiWidth";
|
||||
import usePolicy from "~/hooks/usePolicy";
|
||||
import { isModKey } from "~/utils/keyboard";
|
||||
|
||||
@@ -51,17 +52,6 @@ const EditableTitle = React.forwardRef(
|
||||
ref.current?.focus();
|
||||
}, [ref]);
|
||||
|
||||
// Ensure only plain text can be pasted into title when pasting from another
|
||||
// rich text editor
|
||||
const handlePaste = React.useCallback(
|
||||
(event: React.ClipboardEvent<HTMLSpanElement>) => {
|
||||
event.preventDefault();
|
||||
const text = event.clipboardData.getData("text/plain");
|
||||
window.document.execCommand("insertText", false, text);
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleKeyDown = React.useCallback(
|
||||
(event: React.KeyboardEvent) => {
|
||||
if (event.key === "Enter") {
|
||||
@@ -102,34 +92,16 @@ const EditableTitle = React.forwardRef(
|
||||
[onGoToNextInput, onSave]
|
||||
);
|
||||
|
||||
/**
|
||||
* Measures the width of the document's emoji in the title
|
||||
*/
|
||||
const emojiWidth = React.useMemo(() => {
|
||||
const element = window.document.createElement("span");
|
||||
if (!document.emoji) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
element.innerText = `${document.emoji}\u00A0`;
|
||||
element.style.visibility = "hidden";
|
||||
element.style.position = "absolute";
|
||||
element.style.left = "-9999px";
|
||||
element.style.lineHeight = lineHeight;
|
||||
element.style.fontSize = fontSize;
|
||||
element.style.width = "max-content";
|
||||
window.document.body?.appendChild(element);
|
||||
const width = window.getComputedStyle(element).width;
|
||||
window.document.body?.removeChild(element);
|
||||
return parseInt(width, 10);
|
||||
}, [document.emoji]);
|
||||
const emojiWidth = useEmojiWidth(document.emoji, {
|
||||
fontSize,
|
||||
lineHeight,
|
||||
});
|
||||
|
||||
return (
|
||||
<Title
|
||||
onClick={handleClick}
|
||||
onChange={onChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onPaste={handlePaste}
|
||||
placeholder={placeholder}
|
||||
value={normalizedTitle}
|
||||
$emojiWidth={emojiWidth}
|
||||
@@ -170,17 +142,10 @@ const Title = styled(ContentEditable)<TitleProps>`
|
||||
line-height: ${lineHeight};
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
background: ${(props) => props.theme.background};
|
||||
transition: ${(props) => props.theme.backgroundTransition};
|
||||
color: ${(props) => props.theme.text};
|
||||
-webkit-text-fill-color: ${(props) => props.theme.text};
|
||||
font-size: ${fontSize};
|
||||
font-weight: 500;
|
||||
outline: none;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
resize: none;
|
||||
cursor: text;
|
||||
|
||||
> span {
|
||||
outline: none;
|
||||
|
||||
Reference in New Issue
Block a user