Skip to content

Commit

Permalink
experimental: Rich Text add list item support
Browse files Browse the repository at this point in the history
  • Loading branch information
istarkov committed Dec 21, 2024
1 parent e877b1f commit e7dbc8e
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,75 @@ const getInsertionIndex = (
return insertBefore ? index : index + 1;
};

export const insertListItemAt = (listItemSelector: InstanceSelector) => {
const instances = $instances.get();

const parentSelector = listItemSelector.slice(1);

const parentInstance = instances.get(parentSelector[0]);

if (parentInstance === undefined) {
return;
}

const position =
1 +
parentInstance.children.findIndex(
(child) => child.type === "id" && child.value === listItemSelector[0]
);

if (position === 0) {
return;
}

const target: DroppableTarget = {
parentSelector,
position,
};

const fragment = extractWebstudioFragment(
getWebstudioData(),
listItemSelector[0]
);

fragment.instances = structuredClone(fragment.instances);
fragment.instances.splice(1);
fragment.instances[0].children = [];

updateWebstudioData((data) => {
const { newInstanceIds } = insertWebstudioFragmentCopy({
data,
fragment,
availableDataSources: findAvailableDataSources(
data.dataSources,
data.instances,
target.parentSelector
),
});
const newRootInstanceId = newInstanceIds.get(fragment.instances[0].id);
if (newRootInstanceId === undefined) {
return;
}
const children: Instance["children"] = [
{ type: "id", value: newRootInstanceId },
];

insertInstanceChildrenMutable(data, children, target);

const selectedInstanceSelector = [
newRootInstanceId,
...target.parentSelector,
];

$textEditingInstanceSelector.set({
selector: selectedInstanceSelector,
reason: "new",
});

selectInstance(selectedInstanceSelector);
});
};

export const insertTemplateAt = (
templateSelector: InstanceSelector,
anchor: InstanceSelector,
Expand Down
36 changes: 33 additions & 3 deletions apps/builder/app/canvas/features/text-editor/text-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ import {
selectInstance,
} from "~/shared/awareness";
import { shallowEqual } from "shallow-equal";
import { insertTemplateAt } from "~/builder/features/workspace/canvas-tools/outline/block-utils";
import {
insertListItemAt,
insertTemplateAt,
} from "~/builder/features/workspace/canvas-tools/outline/block-utils";

const BindInstanceToNodePlugin = ({
refs,
Expand Down Expand Up @@ -1075,16 +1078,31 @@ const RichTextContentPluginInternal = ({

if (event.key === "Backspace" || event.key === "Delete") {
const rootNodeContent = $getRoot().getTextContent().trim();
// Delete current

if (rootNodeContent.length === 0) {
const currentInstance = $instances
.get()
.get(rootInstanceSelector[0]);

if (currentInstance?.component === "ListItem") {
onNext(editor.getEditorState(), { reason: "left" });

updateWebstudioData((data) => {
deleteInstanceMutable(data, rootInstanceSelector);
});

event.preventDefault();
return true;
}

const blockChildSelector =
findBlockChildSelector(rootInstanceSelector);

if (blockChildSelector) {
onNext(editor.getEditorState(), { reason: "left" });

updateWebstudioData((data) => {
deleteInstanceMutable(data, rootInstanceSelector);
deleteInstanceMutable(data, blockChildSelector);
});

event.preventDefault();
Expand All @@ -1095,6 +1113,18 @@ const RichTextContentPluginInternal = ({

if (menuState === "closed") {
if (event.key === "Enter" && !event.shiftKey) {
// Custom logic if we are editing ListItem
const currentInstance = $instances
.get()
.get(rootInstanceSelector[0]);

if (currentInstance?.component === "ListItem") {
// Instead of creating block component we need to add a new ListItem
insertListItemAt(rootInstanceSelector);
event.preventDefault();
return true;
}

// Check if it pressed on the last line, last symbol

const allowedComponents = ["Paragraph", "Text", "Heading"];
Expand Down

0 comments on commit e7dbc8e

Please sign in to comment.