mirror of
https://github.com/makeplane/plane
synced 2025-08-07 19:59:33 +00:00
style: page editor width and layout updates (#6826)
This commit is contained in:
committed by
GitHub
parent
993713925a
commit
a25cd426a9
@@ -1,5 +1,7 @@
|
||||
import { Extensions } from "@tiptap/core";
|
||||
import React from "react";
|
||||
// plane imports
|
||||
import { cn } from "@plane/utils";
|
||||
// components
|
||||
import { DocumentContentLoader, PageRenderer } from "@/components/editors";
|
||||
// constants
|
||||
@@ -73,7 +75,11 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
||||
|
||||
if (!editor) return null;
|
||||
|
||||
if (!hasServerSynced && !hasServerConnectionFailed) return <DocumentContentLoader />;
|
||||
const blockWidthClassName = cn("w-full max-w-[720px] mx-auto transition-all duration-200 ease-in-out", {
|
||||
"max-w-[1152px]": displayConfig.wideLayout,
|
||||
});
|
||||
|
||||
if (!hasServerSynced && !hasServerConnectionFailed) return <DocumentContentLoader className={blockWidthClassName} />;
|
||||
|
||||
return (
|
||||
<PageRenderer
|
||||
@@ -81,7 +87,7 @@ const CollaborativeDocumentEditor = (props: ICollaborativeDocumentEditor) => {
|
||||
bubbleMenuEnabled={bubbleMenuEnabled}
|
||||
displayConfig={displayConfig}
|
||||
editor={editor}
|
||||
editorContainerClassName={editorContainerClassNames}
|
||||
editorContainerClassName={cn(editorContainerClassNames, "document-editor")}
|
||||
id={id}
|
||||
tabIndex={tabIndex}
|
||||
/>
|
||||
|
||||
@@ -1,42 +1,51 @@
|
||||
// ui
|
||||
// plane imports
|
||||
import { Loader } from "@plane/ui";
|
||||
import { cn } from "@plane/utils";
|
||||
|
||||
export const DocumentContentLoader = () => (
|
||||
<div className="size-full px-5">
|
||||
<Loader className="relative space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="py-2">
|
||||
<Loader.Item width="100%" height="36px" />
|
||||
</div>
|
||||
<Loader.Item width="80%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
<div className="py-2">
|
||||
<Loader.Item width="60%" height="36px" />
|
||||
</div>
|
||||
<Loader.Item width="70%" height="22px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
<div className="py-2">
|
||||
<Loader.Item width="50%" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="100%" height="22px" />
|
||||
<div className="py-2">
|
||||
<Loader.Item width="30%" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
type Props = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export const DocumentContentLoader = (props: Props) => {
|
||||
const { className } = props;
|
||||
|
||||
return (
|
||||
<div className={cn("size-full", className)}>
|
||||
<Loader className="relative space-y-4">
|
||||
<div className="space-y-2">
|
||||
<div className="py-2">
|
||||
<Loader.Item width="100%" height="36px" />
|
||||
</div>
|
||||
<Loader.Item width="80%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
<div className="py-2">
|
||||
<Loader.Item width="60%" height="36px" />
|
||||
</div>
|
||||
<Loader.Item width="70%" height="22px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
<div className="py-2">
|
||||
<Loader.Item width="50%" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="100%" height="22px" />
|
||||
<div className="py-2">
|
||||
<Loader.Item width="30%" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
<div className="relative flex items-center gap-2">
|
||||
<div className="py-2">
|
||||
<Loader.Item width="30px" height="30px" />
|
||||
</div>
|
||||
<Loader.Item width="30%" height="22px" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Loader>
|
||||
</div>
|
||||
);
|
||||
</Loader>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -132,7 +132,7 @@ export const PageRenderer = (props: IPageRenderer) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="frame-renderer flex-grow w-full -mx-5" onMouseOver={handleLinkHover}>
|
||||
<div className="frame-renderer flex-grow w-full" onMouseOver={handleLinkHover}>
|
||||
<EditorContainer
|
||||
displayConfig={displayConfig}
|
||||
editor={editor}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Extensions } from "@tiptap/core";
|
||||
import { forwardRef, MutableRefObject } from "react";
|
||||
// plane imports
|
||||
import { cn } from "@plane/utils";
|
||||
// components
|
||||
import { PageRenderer } from "@/components/editors";
|
||||
// constants
|
||||
@@ -79,7 +81,7 @@ const DocumentReadOnlyEditor = (props: IDocumentReadOnlyEditor) => {
|
||||
bubbleMenuEnabled={false}
|
||||
displayConfig={displayConfig}
|
||||
editor={editor}
|
||||
editorContainerClassName={editorContainerClassName}
|
||||
editorContainerClassName={cn(editorContainerClassName, "document-editor")}
|
||||
id={id}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -74,6 +74,7 @@ export const EditorContainer: FC<EditorContainerProps> = (props) => {
|
||||
`editor-container cursor-text relative line-spacing-${displayConfig.lineSpacing ?? DEFAULT_DISPLAY_CONFIG.lineSpacing}`,
|
||||
{
|
||||
"active-editor": editor?.isFocused && editor?.isEditable,
|
||||
"wide-layout": displayConfig.wideLayout,
|
||||
},
|
||||
displayConfig.fontSize ?? DEFAULT_DISPLAY_CONFIG.fontSize,
|
||||
displayConfig.fontStyle ?? DEFAULT_DISPLAY_CONFIG.fontStyle,
|
||||
|
||||
@@ -5,6 +5,7 @@ export const DEFAULT_DISPLAY_CONFIG: TDisplayConfig = {
|
||||
fontSize: "large-font",
|
||||
fontStyle: "sans-serif",
|
||||
lineSpacing: "regular",
|
||||
wideLayout: false,
|
||||
};
|
||||
|
||||
export const ACCEPTED_FILE_MIME_TYPES = ["image/jpeg", "image/jpg", "image/png", "image/webp", "image/gif"];
|
||||
|
||||
@@ -49,7 +49,7 @@ export const isValidHttpUrl = (string: string): boolean => {
|
||||
|
||||
try {
|
||||
url = new URL(string);
|
||||
} catch (_) {
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,4 +29,5 @@ export type TDisplayConfig = {
|
||||
fontStyle?: TEditorFontStyle;
|
||||
fontSize?: TEditorFontSize;
|
||||
lineSpacing?: TEditorLineSpacing;
|
||||
wideLayout?: boolean;
|
||||
};
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
-moz-user-select: text;
|
||||
-ms-user-select: text;
|
||||
user-select: text;
|
||||
outline: none;
|
||||
outline: none !important;
|
||||
cursor: text;
|
||||
font-family: var(--font-style);
|
||||
font-size: var(--font-size-regular);
|
||||
|
||||
@@ -1,3 +1,47 @@
|
||||
:root {
|
||||
/* text colors */
|
||||
--editor-colors-gray-text: #5c5e63;
|
||||
--editor-colors-peach-text: #ff5b59;
|
||||
--editor-colors-pink-text: #f65385;
|
||||
--editor-colors-orange-text: #fd9038;
|
||||
--editor-colors-green-text: #0fc27b;
|
||||
--editor-colors-light-blue-text: #17bee9;
|
||||
--editor-colors-dark-blue-text: #266df0;
|
||||
--editor-colors-purple-text: #9162f9;
|
||||
/* end text colors */
|
||||
|
||||
/* layout */
|
||||
--normal-content-width: 720px;
|
||||
--wide-content-width: 1152px;
|
||||
--normal-content-margin: 20px;
|
||||
--wide-content-margin: 96px;
|
||||
/* end layout */
|
||||
}
|
||||
|
||||
/* text background colors */
|
||||
[data-theme*="light"] {
|
||||
--editor-colors-gray-background: #d6d6d8;
|
||||
--editor-colors-peach-background: #ffd5d7;
|
||||
--editor-colors-pink-background: #fdd4e3;
|
||||
--editor-colors-orange-background: #ffe3cd;
|
||||
--editor-colors-green-background: #c3f0de;
|
||||
--editor-colors-light-blue-background: #c5eff9;
|
||||
--editor-colors-dark-blue-background: #c9dafb;
|
||||
--editor-colors-purple-background: #e3d8fd;
|
||||
}
|
||||
[data-theme*="dark"] {
|
||||
--editor-colors-gray-background: #404144;
|
||||
--editor-colors-peach-background: #593032;
|
||||
--editor-colors-pink-background: #562e3d;
|
||||
--editor-colors-orange-background: #583e2a;
|
||||
--editor-colors-green-background: #1d4a3b;
|
||||
--editor-colors-light-blue-background: #1f495c;
|
||||
--editor-colors-dark-blue-background: #223558;
|
||||
--editor-colors-purple-background: #3d325a;
|
||||
}
|
||||
/* end text background colors */
|
||||
|
||||
/* font size and style */
|
||||
.editor-container {
|
||||
--color-placeholder: rgba(var(--color-text-100), 0.5);
|
||||
|
||||
@@ -47,6 +91,8 @@
|
||||
/* end font sizes and line heights */
|
||||
|
||||
/* font styles */
|
||||
--font-style: "Inter", sans-serif;
|
||||
|
||||
&.sans-serif {
|
||||
--font-style: "Inter", sans-serif;
|
||||
}
|
||||
@@ -102,3 +148,94 @@
|
||||
}
|
||||
/* end spacing */
|
||||
}
|
||||
/* end font size and style */
|
||||
|
||||
/* layout config */
|
||||
#page-header-container {
|
||||
container-name: page-header-container;
|
||||
container-type: inline-size;
|
||||
|
||||
.page-header-content {
|
||||
--header-width: var(--normal-content-width);
|
||||
|
||||
&.wide-layout {
|
||||
--header-width: var(--wide-content-width);
|
||||
}
|
||||
|
||||
padding-left: calc(((100% - var(--header-width)) / 2) - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
#page-content-container {
|
||||
container-name: page-content-container;
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.editor-container.document-editor {
|
||||
--editor-content-width: var(--normal-content-width);
|
||||
|
||||
&.wide-layout {
|
||||
--editor-content-width: var(--wide-content-width);
|
||||
}
|
||||
|
||||
.ProseMirror {
|
||||
max-width: var(--editor-content-width);
|
||||
margin: 0 auto;
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* keep a static padding of 96px for wide layouts for container width >912px and <1344px */
|
||||
@container page-header-container (min-width: 912px) and (max-width: 1344px) {
|
||||
.page-header-content.wide-layout {
|
||||
padding-left: var(--wide-content-margin) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* keep a static padding of 96px for wide layouts for container width <912px */
|
||||
@container page-header-container (max-width: 912) {
|
||||
.page-header-content.wide-layout {
|
||||
padding-left: var(--wide-content-margin) !important;
|
||||
}
|
||||
}
|
||||
/* end layout config */
|
||||
|
||||
/* keep a static padding of 20px for wide layouts for container width <760px */
|
||||
@container page-header-container (max-width: 760px) {
|
||||
.page-header-content {
|
||||
padding-left: var(--normal-content-margin) !important;
|
||||
}
|
||||
}
|
||||
/* end layout config */
|
||||
|
||||
/* keep a static padding of 96px for wide layouts for container width >912px and <1344px */
|
||||
@container page-content-container (min-width: 912px) and (max-width: 1344px) {
|
||||
.editor-container.wide-layout,
|
||||
.page-title-container {
|
||||
padding-left: var(--wide-content-margin);
|
||||
padding-right: var(--wide-content-margin);
|
||||
}
|
||||
}
|
||||
|
||||
/* keep a static padding of 20px for wide layouts for container width <912px */
|
||||
@container page-content-container (max-width: 912px) {
|
||||
.editor-container.wide-layout,
|
||||
.page-title-container {
|
||||
padding-left: var(--normal-content-margin);
|
||||
padding-right: var(--normal-content-margin);
|
||||
}
|
||||
}
|
||||
|
||||
/* keep a static padding of 20px for normal layouts for container width <760px */
|
||||
@container page-content-container (max-width: 760px) {
|
||||
.editor-container:not(.wide-layout),
|
||||
.page-title-container {
|
||||
padding-left: var(--normal-content-margin);
|
||||
padding-right: var(--normal-content-margin);
|
||||
}
|
||||
|
||||
.page-summary-container {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
/* end layout config */
|
||||
|
||||
Reference in New Issue
Block a user