[WEB-2045] dev: editor variable font sizes and styles support (#5340)
* chore: added variable font size and font style support * chore: remove font style switcher * chore: update typography
This commit is contained in:
parent
6d0cf1b4e9
commit
85f8fe9247
28 changed files with 419 additions and 145 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
EditorReadOnlyRefApi,
|
||||
EditorRefApi,
|
||||
IMarking,
|
||||
TDisplayConfig,
|
||||
} from "@plane/editor";
|
||||
// types
|
||||
import { IUserLite } from "@plane/types";
|
||||
|
|
@ -82,12 +83,16 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
|||
});
|
||||
// editor flaggings
|
||||
const { documentEditor } = useEditorFlagging();
|
||||
|
||||
// page filters
|
||||
const { isFullWidth } = usePageFilters();
|
||||
const { fontSize, fontStyle, isFullWidth } = usePageFilters();
|
||||
// issue-embed
|
||||
const { issueEmbedProps } = useIssueEmbed(workspaceSlug?.toString() ?? "", projectId?.toString() ?? "");
|
||||
|
||||
const displayConfig: TDisplayConfig = {
|
||||
fontSize,
|
||||
fontStyle,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
updateMarkings(pageDescription ?? "<p></p>");
|
||||
}, [pageDescription, updateMarkings]);
|
||||
|
|
@ -139,6 +144,7 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
|||
value={pageDescriptionYJS}
|
||||
ref={editorRef}
|
||||
containerClassName="p-0 pb-64"
|
||||
displayConfig={displayConfig}
|
||||
editorClassName="pl-10"
|
||||
onChange={handleDescriptionChange}
|
||||
mentionHandler={{
|
||||
|
|
@ -157,6 +163,7 @@ export const PageEditorBody: React.FC<Props> = observer((props) => {
|
|||
initialValue={pageDescription ?? "<p></p>"}
|
||||
handleEditorReady={handleReadOnlyEditorReady}
|
||||
containerClassName="p-0 pb-64 border-none"
|
||||
displayConfig={displayConfig}
|
||||
editorClassName="pl-10"
|
||||
mentionHandler={{
|
||||
highlights: mentionHighlights,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ export const PageOptionsDropdown: React.FC<Props> = observer((props) => {
|
|||
const { workspaceSlug, projectId } = useParams();
|
||||
// page filters
|
||||
const { isFullWidth, handleFullWidth } = usePageFilters();
|
||||
|
||||
const handleArchivePage = async () =>
|
||||
await archive().catch(() =>
|
||||
setToast({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { CSSProperties, useState } from "react";
|
||||
import { observer } from "mobx-react";
|
||||
// editor
|
||||
import { EditorRefApi } from "@plane/editor";
|
||||
|
|
@ -8,6 +8,8 @@ import { EditorRefApi } from "@plane/editor";
|
|||
import { TextArea } from "@plane/ui";
|
||||
// helpers
|
||||
import { cn } from "@/helpers/common.helper";
|
||||
// hooks
|
||||
import { usePageFilters } from "@/hooks/use-page-filters";
|
||||
|
||||
type Props = {
|
||||
editorRef: React.RefObject<EditorRefApi>;
|
||||
|
|
@ -20,25 +22,28 @@ export const PageEditorTitle: React.FC<Props> = observer((props) => {
|
|||
const { editorRef, readOnly, title, updateTitle } = props;
|
||||
// states
|
||||
const [isLengthVisible, setIsLengthVisible] = useState(false);
|
||||
// page filters
|
||||
const { fontSize, fontStyle } = usePageFilters();
|
||||
// ui
|
||||
const titleClassName = cn("bg-transparent tracking-[-2%] font-semibold", {
|
||||
"text-[1.6rem] leading-[1.8rem]": fontSize === "small-font",
|
||||
"text-[2rem] leading-[2.25rem]": fontSize === "large-font",
|
||||
});
|
||||
const titleStyle: CSSProperties = {
|
||||
fontFamily: fontStyle,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{readOnly ? (
|
||||
<h6
|
||||
className="break-words bg-transparent text-[1.75rem] font-semibold"
|
||||
style={{
|
||||
lineHeight: "1.2",
|
||||
}}
|
||||
>
|
||||
<h6 className={cn(titleClassName, "break-words")} style={titleStyle}>
|
||||
{title}
|
||||
</h6>
|
||||
) : (
|
||||
<>
|
||||
<TextArea
|
||||
className="w-full bg-custom-background text-[1.75rem] font-semibold outline-none p-0 border-none resize-none rounded-none"
|
||||
style={{
|
||||
lineHeight: "1.2",
|
||||
}}
|
||||
className={cn(titleClassName, "w-full outline-none p-0 border-none resize-none rounded-none")}
|
||||
style={titleStyle}
|
||||
placeholder="Untitled"
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") {
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ import {
|
|||
Underline,
|
||||
} from "lucide-react";
|
||||
// editor
|
||||
import { TEditorCommands } from "@plane/editor";
|
||||
import { TEditorCommands, TEditorFontStyle } from "@plane/editor";
|
||||
// ui
|
||||
import { MonospaceIcon, SansSerifIcon, SerifIcon } from "@plane/ui";
|
||||
|
||||
type TEditorTypes = "lite" | "document";
|
||||
|
||||
|
|
@ -107,3 +109,25 @@ export const TOOLBAR_ITEMS: {
|
|||
complex: COMPLEX_ITEMS.filter((item) => item.editors.includes("document")),
|
||||
},
|
||||
};
|
||||
|
||||
export const EDITOR_FONT_STYLES: {
|
||||
key: TEditorFontStyle;
|
||||
label: string;
|
||||
icon: any;
|
||||
}[] = [
|
||||
{
|
||||
key: "sans-serif",
|
||||
label: "Sans serif",
|
||||
icon: SansSerifIcon,
|
||||
},
|
||||
{
|
||||
key: "serif",
|
||||
label: "Serif",
|
||||
icon: SerifIcon,
|
||||
},
|
||||
{
|
||||
key: "monospace",
|
||||
label: "Mono",
|
||||
icon: MonospaceIcon,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,12 +1,67 @@
|
|||
// plane editor
|
||||
import { TEditorFontSize, TEditorFontStyle } from "@plane/editor";
|
||||
// hooks
|
||||
import useLocalStorage from "@/hooks/use-local-storage";
|
||||
|
||||
export type TPagesPersonalizationConfig = {
|
||||
full_width: boolean;
|
||||
font_size: TEditorFontSize;
|
||||
font_style: TEditorFontStyle;
|
||||
};
|
||||
|
||||
const DEFAULT_PERSONALIZATION_VALUES: TPagesPersonalizationConfig = {
|
||||
full_width: false,
|
||||
font_size: "large-font",
|
||||
font_style: "sans-serif",
|
||||
};
|
||||
|
||||
export const usePageFilters = () => {
|
||||
const { storedValue: isFullWidth, setValue: setFullWidth } = useLocalStorage<boolean>("page_full_width", true);
|
||||
const handleFullWidth = (value: boolean) => setFullWidth(value);
|
||||
// local storage
|
||||
const { storedValue: pagesConfig, setValue: setPagesConfig } = useLocalStorage<TPagesPersonalizationConfig>(
|
||||
"pages_config",
|
||||
DEFAULT_PERSONALIZATION_VALUES
|
||||
);
|
||||
// stored values
|
||||
const isFullWidth = !!pagesConfig?.full_width;
|
||||
const fontSize = pagesConfig?.font_size ?? DEFAULT_PERSONALIZATION_VALUES.font_size;
|
||||
const fontStyle = pagesConfig?.font_style ?? DEFAULT_PERSONALIZATION_VALUES.font_style;
|
||||
// update action
|
||||
const handleUpdateConfig = (payload: Partial<TPagesPersonalizationConfig>) =>
|
||||
setPagesConfig({
|
||||
...(pagesConfig ?? DEFAULT_PERSONALIZATION_VALUES),
|
||||
...payload,
|
||||
});
|
||||
/**
|
||||
* @description action to update full_width value
|
||||
* @param {boolean} value
|
||||
*/
|
||||
const handleFullWidth = (value: boolean) =>
|
||||
handleUpdateConfig({
|
||||
full_width: value,
|
||||
});
|
||||
/**
|
||||
* @description action to update font_size value
|
||||
* @param {TEditorFontSize} value
|
||||
*/
|
||||
const handleFontSize = (value: TEditorFontSize) =>
|
||||
handleUpdateConfig({
|
||||
font_size: value,
|
||||
});
|
||||
/**
|
||||
* @description action to update font_size value
|
||||
* @param {TEditorFontSize} value
|
||||
*/
|
||||
const handleFontStyle = (value: TEditorFontStyle) =>
|
||||
handleUpdateConfig({
|
||||
font_style: value,
|
||||
});
|
||||
|
||||
return {
|
||||
isFullWidth: !!isFullWidth,
|
||||
fontSize,
|
||||
handleFontSize,
|
||||
fontStyle,
|
||||
handleFontStyle,
|
||||
isFullWidth,
|
||||
handleFullWidth,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue