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:
Philip Okugbe
2026-05-13 23:01:04 +01:00
committed by GitHub
parent a689cca7a0
commit 31ed0df3f7
32 changed files with 3816 additions and 1429 deletions
+7 -4
View File
@@ -54,7 +54,7 @@ export class WsService {
return;
}
await this.broadcastToAuthorizedUsers(room, client.data.userId, pageId, data);
await this.broadcastToAuthorizedUsers(room, client.id, pageId, data);
}
async invalidateSpaceRestrictionCache(spaceId: string): Promise<void> {
@@ -115,14 +115,17 @@ export class WsService {
private async broadcastToAuthorizedUsers(
room: string,
excludeUserId: string | null,
excludeSocketId: string | null,
pageId: string,
data: any,
): Promise<void> {
const sockets = await this.server.in(room).fetchSockets();
const otherSockets = excludeUserId
? sockets.filter((s) => s.data.userId !== excludeUserId)
// Exclude only the originating socket, not every socket of the originating
// user. Excluding by userId silently dropped the originator's other tabs
// from receiving restricted-space tree events.
const otherSockets = excludeSocketId
? sockets.filter((s) => s.id !== excludeSocketId)
: sockets;
if (otherSockets.length === 0) return;