Skip to content

Commit

Permalink
feat: support folding text fragments in code editor (#4676)
Browse files Browse the repository at this point in the history
Closes #3636

Enabled folding for dialog editors only to avoid bloating space in
settings panel.

<img width="905" alt="Screenshot 2024-12-30 at 19 42 03"
src="https://github.com/user-attachments/assets/39a500f1-7d4f-407d-a7df-a1f47e15f69c"
/>
<img width="918" alt="Screenshot 2024-12-30 at 19 42 55"
src="https://github.com/user-attachments/assets/fe3b4c65-ec95-40c5-a114-e5fef2e02584"
/>
  • Loading branch information
TrySound authored Dec 30, 2024
1 parent ed36cf8 commit 8e4ef3e
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 104 deletions.
18 changes: 17 additions & 1 deletion apps/builder/app/builder/shared/code-editor-base.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
historyKeymap,
indentWithTab,
} from "@codemirror/commands";
import { syntaxHighlighting } from "@codemirror/language";
import { foldGutter, syntaxHighlighting } from "@codemirror/language";
import {
theme,
textVariants,
Expand All @@ -40,6 +40,7 @@ import {
FloatingPanel,
} from "@webstudio-is/design-system";
import { MaximizeIcon } from "@webstudio-is/icons";
import { ChevronDownIcon, ChevronRightIcon } from "@webstudio-is/icons/svg";
import { solarizedLight } from "./code-highlight";

// This undocumented flag is required to keep contenteditable fields editable after the first activation of EditorView.
Expand Down Expand Up @@ -121,6 +122,10 @@ const editorContentStyle = css({
textDecoration: "underline wavy red",
backgroundColor: "rgba(255, 0, 0, 0.1)",
},
".cm-gutters": {
backgroundColor: "transparent",
border: 0,
},
});

const shortcutStyle = css({
Expand Down Expand Up @@ -188,6 +193,17 @@ const keyBindings = [
indentWithTab,
];

export const foldGutterExtension = foldGutter({
markerDOM: (isOpen) => {
const div = document.createElement("div");
div.style.width = "16px";
div.style.height = "16px";
div.style.cursor = "pointer";
div.innerHTML = isOpen ? ChevronDownIcon : ChevronRightIcon;
return div;
},
});

export type EditorApi = {
replaceSelection: (string: string) => void;
focus: () => void;
Expand Down
21 changes: 16 additions & 5 deletions apps/builder/app/builder/shared/code-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
EditorDialog,
EditorDialogButton,
EditorDialogControl,
foldGutterExtension,
getMinMaxHeightVars,
} from "./code-editor-base";

Expand Down Expand Up @@ -96,6 +97,11 @@ export const CodeEditor = forwardRef<
return [];
}, [lang]);

const dialogExtensions = useMemo(
() => [...extensions, foldGutterExtension],
[extensions]
);

// prevent clicking on autocomplete options propagating to body
// and closing dialogs and popovers
useEffect(() => {
Expand All @@ -113,14 +119,19 @@ export const CodeEditor = forwardRef<
document.removeEventListener("pointerdown", handlePointerDown, options);
};
}, []);
const content = (
<EditorContent {...editorContentProps} extensions={extensions} />
);
return (
<div className={wrapperStyle()} ref={ref}>
<EditorDialogControl>
{content}
<EditorDialog title={title} content={content}>
{<EditorContent {...editorContentProps} extensions={extensions} />}
<EditorDialog
title={title}
content={
<EditorContent
{...editorContentProps}
extensions={dialogExtensions}
/>
}
>
<EditorDialogButton />
</EditorDialog>
</EditorDialogControl>
Expand Down
3 changes: 2 additions & 1 deletion apps/builder/app/builder/shared/expression-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
EditorDialog,
EditorDialogButton,
EditorDialogControl,
foldGutterExtension,
type EditorApi,
} from "./code-editor-base";

Expand Down Expand Up @@ -518,7 +519,7 @@ export const ExpressionEditor = ({
// by spliting into separate component which is invoked
// only when dialog content is rendered
const ValuePreviewEditor = ({ value }: { value: unknown }) => {
const extensions = useMemo(() => [javascript({})], []);
const extensions = useMemo(() => [javascript({}), foldGutterExtension], []);
return (
<EditorContent
readOnly={true}
Expand Down
14 changes: 7 additions & 7 deletions apps/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@
},
"dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.4.0",
"@codemirror/autocomplete": "^6.18.1",
"@codemirror/autocomplete": "^6.18.4",
"@codemirror/commands": "^6.7.1",
"@codemirror/lang-css": "^6.3.0",
"@codemirror/lang-css": "^6.3.1",
"@codemirror/lang-html": "^6.4.9",
"@codemirror/lang-javascript": "^6.2.2",
"@codemirror/lang-markdown": "^6.3.0",
"@codemirror/language": "^6.10.3",
"@codemirror/lint": "^6.8.2",
"@codemirror/state": "^6.4.1",
"@codemirror/view": "^6.34.1",
"@codemirror/lang-markdown": "^6.3.1",
"@codemirror/language": "^6.10.8",
"@codemirror/lint": "^6.8.4",
"@codemirror/state": "^6.5.0",
"@codemirror/view": "^6.36.1",
"@floating-ui/dom": "^1.6.11",
"@fontsource-variable/inter": "^5.0.20",
"@fontsource-variable/manrope": "^5.0.20",
Expand Down
2 changes: 1 addition & 1 deletion packages/jsx-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@webstudio-is/css-data": "workspace:*",
"@webstudio-is/react-sdk": "workspace:*",
"@webstudio-is/sdk": "workspace:*",
"acorn": "^8.12.1",
"acorn": "^8.14.0",
"acorn-jsx": "^5.3.2",
"json5": "^2.2.3",
"zod": "^3.22.4"
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"dependencies": {
"@webstudio-is/css-engine": "workspace:*",
"@webstudio-is/fonts": "workspace:*",
"acorn": "^8.12.1",
"acorn": "^8.14.0",
"acorn-walk": "^8.3.4",
"reserved-identifiers": "^1.0.0",
"type-fest": "^4.31.0",
Expand Down
Loading

0 comments on commit 8e4ef3e

Please sign in to comment.