mirror of
https://github.com/docmost/docmost.git
synced 2026-05-16 14:14:06 +08:00
feat(tree): replace sidebar tree (react-aborist) with custom tree implementation (#2199)
* feat(tree): replace react-arborist with custom tree implementation * feat(tree): keyboard arrow navigation between rows * feat(emoji-picker): focus search input on open * refactor(emoji): switch to @slidoapp/emoji-mart fork for accessibility * feat(tree): Home/End and typeahead keyboard navigation * feat(tree): roving tabindex and * to expand sibling subtrees * feat(tree): Space activation and ARIA refinements * fix(tree): move treeitem role to focusable row + aria-current
This commit is contained in:
@@ -21,7 +21,7 @@ let _emojiIndex: EmojiIndexEntry[] | null = null;
|
||||
|
||||
export const buildEmojiIndex = async (): Promise<EmojiIndexEntry[]> => {
|
||||
if (_emojiIndex) return _emojiIndex;
|
||||
const { default: data } = await import("@emoji-mart/data");
|
||||
const { default: data } = await import('@slidoapp/emoji-mart-data');
|
||||
_emojiIndex = (Object.values((data as any).emojis) as any[])
|
||||
.filter((e) => e.id && e.name && e.skins?.[0]?.native)
|
||||
.map((e) => ({
|
||||
@@ -74,7 +74,7 @@ let _cats: EmojiCategory[] | null = null;
|
||||
export const getEmojiCategories = async (): Promise<EmojiCategory[]> => {
|
||||
if (_cats) return _cats;
|
||||
const [{ default: data }, index] = await Promise.all([
|
||||
import("@emoji-mart/data"),
|
||||
import("@slidoapp/emoji-mart-data"),
|
||||
buildEmojiIndex(),
|
||||
]);
|
||||
const byId = new Map(index.map((e) => [e.id, e]));
|
||||
|
||||
@@ -3,7 +3,6 @@ import React, {
|
||||
useCallback,
|
||||
useEffect,
|
||||
useImperativeHandle,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
@@ -36,7 +35,7 @@ import {
|
||||
usePageQuery,
|
||||
} from "@/features/page/queries/page-query";
|
||||
import { treeDataAtom } from "@/features/page/tree/atoms/tree-data-atom";
|
||||
import { SimpleTree } from "react-arborist";
|
||||
import { treeModel } from "@/features/page/tree/model/tree-model";
|
||||
import { SpaceTreeNode } from "@/features/page/tree/types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useQueryEmit } from "@/features/websocket/use-query-emit";
|
||||
@@ -53,7 +52,6 @@ const MentionList = forwardRef<any, MentionListProps>((props, ref) => {
|
||||
const [renderItems, setRenderItems] = useState<MentionSuggestionItem[]>([]);
|
||||
const { t } = useTranslation();
|
||||
const [data, setData] = useAtom(treeDataAtom);
|
||||
const tree = useMemo(() => new SimpleTree<SpaceTreeNode>(data), [data]);
|
||||
const createPageMutation = useCreatePageMutation();
|
||||
const emit = useQueryEmit();
|
||||
const isInCommentContext = props.isInCommentContext ?? false;
|
||||
@@ -220,20 +218,20 @@ const MentionList = forwardRef<any, MentionListProps>((props, ref) => {
|
||||
try {
|
||||
createdPage = await createPageMutation.mutateAsync(payload);
|
||||
const parentId = page.id || null;
|
||||
const data = {
|
||||
const newNode: SpaceTreeNode = {
|
||||
id: createdPage.id,
|
||||
slugId: createdPage.slugId,
|
||||
name: createdPage.title,
|
||||
position: createdPage.position,
|
||||
spaceId: createdPage.spaceId,
|
||||
parentPageId: createdPage.parentPageId,
|
||||
hasChildren: false,
|
||||
children: [],
|
||||
} as any;
|
||||
};
|
||||
|
||||
const lastIndex = tree.data.length;
|
||||
const lastIndex = data.length;
|
||||
|
||||
tree.create({ parentId, index: lastIndex, data });
|
||||
setData(tree.data);
|
||||
setData(treeModel.insert(data, parentId, newNode, lastIndex));
|
||||
|
||||
props.command({
|
||||
id: uuid7(),
|
||||
@@ -251,7 +249,7 @@ const MentionList = forwardRef<any, MentionListProps>((props, ref) => {
|
||||
payload: {
|
||||
parentId,
|
||||
index: lastIndex,
|
||||
data,
|
||||
data: newNode,
|
||||
},
|
||||
});
|
||||
}, 50);
|
||||
|
||||
Reference in New Issue
Block a user