feat: Full width images (#4389)

* feat: Full width images

* lint

* fix: Enable TOC overlaid on full size images

* Vendorize react-medium-image-zoom

* tsc

* fix

* Remove body scroll lock
This commit is contained in:
Tom Moor
2022-12-17 17:17:15 -08:00
committed by GitHub
parent f8ba393f7c
commit acf74b83a8
19 changed files with 1415 additions and 104 deletions

View File

@@ -68,6 +68,7 @@ export default class ComponentView {
const children = this.component({
theme,
node: this.node,
view: this.view,
isSelected: this.isSelected,
isEditable: this.view.editable,
getPos: this.getPos,

View File

@@ -5,6 +5,7 @@ import {
AlignImageLeftIcon,
AlignImageRightIcon,
AlignImageCenterIcon,
AlignFullWidthIcon,
} from "outline-icons";
import { EditorState } from "prosemirror-state";
import * as React from "react";
@@ -23,6 +24,9 @@ export default function imageMenuItems(
const isRightAligned = isNodeActive(schema.nodes.image, {
layoutClass: "right-50",
});
const isFullWidthAligned = isNodeActive(schema.nodes.image, {
layoutClass: "full-width",
});
return [
{
@@ -40,7 +44,8 @@ export default function imageMenuItems(
active: (state) =>
isNodeActive(schema.nodes.image)(state) &&
!isLeftAligned(state) &&
!isRightAligned(state),
!isRightAligned(state) &&
!isFullWidthAligned(state),
},
{
name: "alignRight",
@@ -49,6 +54,13 @@ export default function imageMenuItems(
visible: true,
active: isRightAligned,
},
{
name: "alignFullWidth",
tooltip: dictionary.alignFullWidth,
icon: <AlignFullWidthIcon />,
visible: true,
active: isFullWidthAligned,
},
{
name: "separator",
visible: true,

View File

@@ -13,6 +13,7 @@ export default function useDictionary() {
alignCenter: t("Align center"),
alignLeft: t("Align left"),
alignRight: t("Align right"),
alignFullWidth: t("Full width"),
bulletList: t("Bulleted list"),
checkboxList: t("Todo list"),
codeBlock: t("Code block"),
@@ -28,9 +29,6 @@ export default function useDictionary() {
deleteImage: t("Delete image"),
downloadImage: t("Download image"),
replaceImage: t("Replace image"),
alignImageLeft: t("Float left"),
alignImageRight: t("Float right"),
alignImageDefault: t("Center large"),
em: t("Italic"),
embedInvalidLink: t("Sorry, that link wont work for this embed type"),
file: t("File attachment"),

View File

@@ -1,3 +1,4 @@
import { transparentize } from "polished";
import * as React from "react";
import { useTranslation } from "react-i18next";
import styled from "styled-components";
@@ -100,21 +101,27 @@ const Sticky = styled.div`
top: 80px;
max-height: calc(100vh - 80px);
box-shadow: 1px 0 0 ${(props) => props.theme.divider};
margin-top: 40px;
background: ${(props) => props.theme.background};
margin-top: 72px;
margin-right: 52px;
min-width: 204px;
width: 204px;
width: 228px;
min-height: 40px;
overflow-y: auto;
padding: 4px 16px;
border-radius: 8px;
@supports (backdrop-filter: blur(20px)) {
backdrop-filter: blur(20px);
background: ${(props) => transparentize(0.2, props.theme.background)};
}
`;
const Heading = styled.h3`
font-size: 11px;
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
color: ${(props) => props.theme.sidebarText};
letter-spacing: 0.04em;
color: ${(props) => props.theme.textTertiary};
letter-spacing: 0.03em;
`;
const Empty = styled(Text)`
@@ -128,10 +135,9 @@ const ListItem = styled.li<{ level: number; active?: boolean }>`
margin-bottom: 8px;
padding-right: 2em;
line-height: 1.3;
border-right: 3px solid
${(props) => (props.active ? props.theme.divider : "transparent")};
a {
font-weight: ${(props) => (props.active ? "600" : "inherit")};
color: ${(props) =>
props.active ? props.theme.primary : props.theme.text};
}

View File

@@ -481,7 +481,12 @@ class DocumentScene extends React.Component<Props> {
}
}}
/>
<Background key={revision ? revision.id : document.id} column auto>
<Background
id="full-width-container"
key={revision ? revision.id : document.id}
column
auto
>
<Route
path={`${document.url}/move`}
component={() => (
@@ -562,7 +567,7 @@ class DocumentScene extends React.Component<Props> {
>
<Notices document={document} readOnly={readOnly} />
<React.Suspense fallback={<PlaceholderDocument />}>
<Flex auto={!readOnly}>
<Flex auto={!readOnly} reverse>
{revision ? (
<RevisionViewer
isDraft={document.isDraft}
@@ -572,12 +577,6 @@ class DocumentScene extends React.Component<Props> {
/>
) : (
<>
{showContents && (
<Contents
headings={this.headings}
isFullWidth={document.fullWidth}
/>
)}
<Editor
id={document.id}
key={embedsDisabled ? "disabled" : "enabled"}
@@ -624,6 +623,13 @@ class DocumentScene extends React.Component<Props> {
</>
)}
</Editor>
{showContents && (
<Contents
headings={this.headings}
isFullWidth={document.fullWidth}
/>
)}
</>
)}
</Flex>

View File

@@ -287,7 +287,8 @@ function MultiplayerEditor({ onSynced, ...props }: Props, ref: any) {
style={
showCache
? {
display: "none",
opacity: 0,
pointerEvents: "none",
}
: undefined
}