🐛(frontend) fix dnd conflict with tree and Blocknote

We have different DND system in the page, one on the
menu tree and one in the Blocknote editor.
The menu tree was adding a transparent layer
when user were dragging element on the Blocknote
editor, blocking the Blocknote DND.
We update the ui-kit to add the prop dndRootElement,
dndRootElement is now used to specify the root element
for DND, this transparent layer is now only applied
when a drag is made from the menu tree.

It stabilize as well the drop position, making it easier to drop element.
This commit is contained in:
Anthony LC
2025-09-02 10:36:37 +02:00
parent 474e5ac0c0
commit 648528499c
4 changed files with 37 additions and 56 deletions

View File

@@ -35,6 +35,7 @@ and this project adheres to
- 🐛(frontend) fix export when quote block and inline code #1319 - 🐛(frontend) fix export when quote block and inline code #1319
- 🐛(frontend) fix base64 font #1324 - 🐛(frontend) fix base64 font #1324
- 🐛(backend) allow editor to delete subpages #1296 - 🐛(backend) allow editor to delete subpages #1296
- 🐛(frontend) fix dnd conflict with tree and Blocknote #1328
## [3.5.0] - 2025-07-31 ## [3.5.0] - 2025-07-31

View File

@@ -29,7 +29,7 @@
"@emoji-mart/react": "1.1.1", "@emoji-mart/react": "1.1.1",
"@fontsource/material-icons": "5.2.5", "@fontsource/material-icons": "5.2.5",
"@gouvfr-lasuite/integration": "1.0.3", "@gouvfr-lasuite/integration": "1.0.3",
"@gouvfr-lasuite/ui-kit": "0.16.0", "@gouvfr-lasuite/ui-kit": "0.16.1",
"@hocuspocus/provider": "2.15.2", "@hocuspocus/provider": "2.15.2",
"@openfun/cunningham-react": "3.2.3", "@openfun/cunningham-react": "3.2.3",
"@react-pdf/renderer": "4.3.0", "@react-pdf/renderer": "4.3.0",

View File

@@ -30,6 +30,7 @@ export const DocTree = ({ currentDoc }: DocTreeProps) => {
const treeContext = useTreeContext<Doc | null>(); const treeContext = useTreeContext<Doc | null>();
const router = useRouter(); const router = useRouter();
const { isDesktop } = useResponsive(); const { isDesktop } = useResponsive();
const [treeRoot, setTreeRoot] = useState<HTMLElement | null>(null);
const [initialOpenState, setInitialOpenState] = useState<OpenMap | undefined>( const [initialOpenState, setInitialOpenState] = useState<OpenMap | undefined>(
undefined, undefined,
@@ -148,6 +149,7 @@ export const DocTree = ({ currentDoc }: DocTreeProps) => {
return ( return (
<Box <Box
ref={setTreeRoot}
data-testid="doc-tree" data-testid="doc-tree"
$height="100%" $height="100%"
$css={css` $css={css`
@@ -232,30 +234,33 @@ export const DocTree = ({ currentDoc }: DocTreeProps) => {
</Box> </Box>
</Box> </Box>
{initialOpenState && treeContext.treeData.nodes.length > 0 && ( {initialOpenState &&
<TreeView treeContext.treeData.nodes.length > 0 &&
initialOpenState={initialOpenState} treeRoot && (
afterMove={handleMove} <TreeView
selectedNodeId={ dndRootElement={treeRoot}
treeContext.treeData.selectedNode?.id ?? initialOpenState={initialOpenState}
treeContext.initialTargetId ?? afterMove={handleMove}
undefined selectedNodeId={
} treeContext.treeData.selectedNode?.id ??
canDrop={({ parentNode }) => { treeContext.initialTargetId ??
const parentDoc = parentNode?.data.value as Doc; undefined
if (!parentDoc) {
return currentDoc.abilities.move && isDesktop;
} }
return parentDoc.abilities.move && isDesktop; canDrop={({ parentNode }) => {
}} const parentDoc = parentNode?.data.value as Doc;
canDrag={(node) => { if (!parentDoc) {
const doc = node.value as Doc; return currentDoc.abilities.move && isDesktop;
return doc.abilities.move && isDesktop; }
}} return parentDoc.abilities.move && isDesktop;
rootNodeId={treeContext.root.id} }}
renderNode={DocSubPageItem} canDrag={(node) => {
/> const doc = node.value as Doc;
)} return doc.abilities.move && isDesktop;
}}
rootNodeId={treeContext.root.id}
renderNode={DocSubPageItem}
/>
)}
</Box> </Box>
); );
}; };

View File

@@ -1734,10 +1734,10 @@
resolved "https://registry.yarnpkg.com/@gouvfr-lasuite/integration/-/integration-1.0.3.tgz#7aca824ba61d343a7905dc90c8a8bbdbce8f9a09" resolved "https://registry.yarnpkg.com/@gouvfr-lasuite/integration/-/integration-1.0.3.tgz#7aca824ba61d343a7905dc90c8a8bbdbce8f9a09"
integrity sha512-OgP28CqlPi35wQPul1Dr52SngACXAk8buLGqHYXDp23fbTOJThqarrZE/pgJHoc9Ndwiu7ngwBSO4rZ7OPyMpA== integrity sha512-OgP28CqlPi35wQPul1Dr52SngACXAk8buLGqHYXDp23fbTOJThqarrZE/pgJHoc9Ndwiu7ngwBSO4rZ7OPyMpA==
"@gouvfr-lasuite/ui-kit@0.16.0": "@gouvfr-lasuite/ui-kit@0.16.1":
version "0.16.0" version "0.16.1"
resolved "https://registry.yarnpkg.com/@gouvfr-lasuite/ui-kit/-/ui-kit-0.16.0.tgz#6cf2f786759384904ac1b4c99b4082b0508aa71f" resolved "https://registry.yarnpkg.com/@gouvfr-lasuite/ui-kit/-/ui-kit-0.16.1.tgz#3dfac5c38ea31c292f38cd25b5372b4633661f37"
integrity sha512-VLjDLxuBM647OOD66ylJEnfcQrcO8fWyrfVSvhk/3QLMu9UImqSIE62RGh9PbeZ0+fXso9I8xI/wamkvyujXCQ== integrity sha512-mx2gM1vv7NvL0LOOd3zqtT4H58rR9ogmmswYV6ocDFx7hoMWE/gA6i1R2grktFrJP/Pt3JgcvDET8iKbp+56VQ==
dependencies: dependencies:
"@dnd-kit/core" "6.3.1" "@dnd-kit/core" "6.3.1"
"@dnd-kit/modifiers" "9.0.0" "@dnd-kit/modifiers" "9.0.0"
@@ -14712,16 +14712,7 @@ string-length@^4.0.2:
char-regex "^1.0.2" char-regex "^1.0.2"
strip-ansi "^6.0.0" strip-ansi "^6.0.0"
"string-width-cjs@npm:string-width@^4.2.0": "string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -14847,14 +14838,7 @@ stringify-object@^3.3.0:
is-obj "^1.0.1" is-obj "^1.0.1"
is-regexp "^1.0.0" is-regexp "^1.0.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1": "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1" version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -16389,16 +16373,7 @@ workbox-window@7.1.0:
"@types/trusted-types" "^2.0.2" "@types/trusted-types" "^2.0.2"
workbox-core "7.1.0" workbox-core "7.1.0"
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
wrap-ansi@^7.0.0:
version "7.0.0" version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==