File tree Expand file tree Collapse file tree 8 files changed +86
-14
lines changed Expand file tree Collapse file tree 8 files changed +86
-14
lines changed Original file line number Diff line number Diff line change 1
1
import { assertEmpty , mergeCSSClasses } from "@blocknote/core" ;
2
- import { ComponentProps } from "@blocknote/react" ;
3
- import { forwardRef } from "react" ;
2
+ import { ComponentProps , elementOverflow , mergeRefs } from "@blocknote/react" ;
3
+ import { forwardRef , useEffect , useRef } from "react" ;
4
4
5
5
export const SuggestionMenuItem = forwardRef <
6
6
HTMLDivElement ,
@@ -10,10 +10,26 @@ export const SuggestionMenuItem = forwardRef<
10
10
11
11
assertEmpty ( rest ) ;
12
12
13
+ const itemRef = useRef < HTMLDivElement > ( null ) ;
14
+
15
+ useEffect ( ( ) => {
16
+ if ( ! itemRef . current || ! isSelected ) {
17
+ return ;
18
+ }
19
+
20
+ const overflow = elementOverflow ( itemRef . current ) ;
21
+
22
+ if ( overflow === "top" ) {
23
+ itemRef . current . scrollIntoView ( true ) ;
24
+ } else if ( overflow === "bottom" ) {
25
+ itemRef . current . scrollIntoView ( false ) ;
26
+ }
27
+ } , [ isSelected ] ) ;
28
+
13
29
return (
14
30
< div
15
31
className = { mergeCSSClasses ( "bn-ak-menu-item" , className || "" ) }
16
- ref = { ref }
32
+ ref = { mergeRefs ( [ ref , itemRef ] ) }
17
33
id = { id }
18
34
onClick = { onClick }
19
35
role = "option"
Original file line number Diff line number Diff line change 322
322
323
323
.bn-mt-suggestion-menu-item-body {
324
324
align-items : stretch;
325
- color : var (--bn-colors-menu-text );
326
325
display : flex;
327
326
flex : 1 ;
328
327
flex-direction : column;
331
330
}
332
331
333
332
.bn-mt-suggestion-menu-item-title {
333
+ color : var (--bn-colors-menu-text );
334
334
line-height : 20px ;
335
335
font-weight : 500 ;
336
336
font-size : 14px ;
339
339
}
340
340
341
341
.bn-mt-suggestion-menu-item-subtitle {
342
+ color : var (--bn-colors-menu-text );
342
343
line-height : 16px ;
343
344
font-size : 10px ;
344
345
margin : 0 ;
Original file line number Diff line number Diff line change @@ -14,7 +14,7 @@ export const SuggestionMenuEmptyItem = forwardRef<
14
14
15
15
return (
16
16
< MantineGroup className = { className } ref = { ref } >
17
- < MantineGroup className = "bn-mt-suggestion-menu-item-label " >
17
+ < MantineGroup className = "bn-mt-suggestion-menu-item-title " >
18
18
{ children }
19
19
</ MantineGroup >
20
20
</ MantineGroup >
Original file line number Diff line number Diff line change @@ -4,10 +4,11 @@ import {
4
4
Stack as MantineStack ,
5
5
Text as MantineText ,
6
6
} from "@mantine/core" ;
7
+ import { mergeRefs } from "@mantine/hooks" ;
7
8
8
9
import { assertEmpty } from "@blocknote/core" ;
9
- import { ComponentProps } from "@blocknote/react" ;
10
- import { forwardRef } from "react" ;
10
+ import { ComponentProps , elementOverflow } from "@blocknote/react" ;
11
+ import { forwardRef , useEffect , useRef } from "react" ;
11
12
12
13
export const SuggestionMenuItem = forwardRef <
13
14
HTMLDivElement ,
@@ -17,11 +18,27 @@ export const SuggestionMenuItem = forwardRef<
17
18
18
19
assertEmpty ( rest ) ;
19
20
21
+ const itemRef = useRef < HTMLDivElement > ( null ) ;
22
+
23
+ useEffect ( ( ) => {
24
+ if ( ! itemRef . current || ! isSelected ) {
25
+ return ;
26
+ }
27
+
28
+ const overflow = elementOverflow ( itemRef . current ) ;
29
+
30
+ if ( overflow === "top" ) {
31
+ itemRef . current . scrollIntoView ( true ) ;
32
+ } else if ( overflow === "bottom" ) {
33
+ itemRef . current . scrollIntoView ( false ) ;
34
+ }
35
+ } , [ isSelected ] ) ;
36
+
20
37
return (
21
38
< MantineGroup
22
39
gap = { 0 }
23
40
className = { className }
24
- ref = { ref }
41
+ ref = { mergeRefs ( ref , itemRef ) }
25
42
id = { id }
26
43
role = "option"
27
44
onClick = { onClick }
Original file line number Diff line number Diff line change @@ -79,3 +79,6 @@ export * from "./hooks/useSelectedBlocks";
79
79
export * from "./schema/ReactBlockSpec" ;
80
80
export * from "./schema/ReactInlineContentSpec" ;
81
81
export * from "./schema/ReactStyleSpec" ;
82
+
83
+ export * from "./util/mergeRefs" ;
84
+ export * from "./util/elementOverflow" ;
Original file line number Diff line number Diff line change
1
+ export function elementOverflow ( element : HTMLElement ) {
2
+ if ( ! element . parentElement ) {
3
+ return "none" ;
4
+ }
5
+
6
+ const elementRect = element . getBoundingClientRect ( ) ;
7
+ const parentRect = element . parentElement . getBoundingClientRect ( ) ;
8
+
9
+ const topOverflow = elementRect . top < parentRect . top ;
10
+ const bottomOverflow = elementRect . bottom > parentRect . bottom ;
11
+
12
+ return topOverflow && bottomOverflow
13
+ ? "both"
14
+ : topOverflow
15
+ ? "top"
16
+ : bottomOverflow
17
+ ? "bottom"
18
+ : "none" ;
19
+ }
Original file line number Diff line number Diff line change 1
- import { type ClassValue , clsx } from "clsx"
2
- import { twMerge } from "tailwind-merge"
1
+ import { type ClassValue , clsx } from "clsx" ;
2
+ import { twMerge } from "tailwind-merge" ;
3
3
4
4
export function cn ( ...inputs : ClassValue [ ] ) {
5
- return twMerge ( clsx ( inputs ) )
5
+ return twMerge ( clsx ( inputs ) ) ;
6
6
}
Original file line number Diff line number Diff line change 1
1
import { assertEmpty } from "@blocknote/core" ;
2
- import { ComponentProps } from "@blocknote/react" ;
3
- import { forwardRef } from "react" ;
2
+ import { ComponentProps , elementOverflow , mergeRefs } from "@blocknote/react" ;
3
+ import { forwardRef , useEffect , useRef } from "react" ;
4
4
5
5
import { cn } from "../lib/utils" ;
6
6
import { useShadCNComponentsContext } from "../ShadCNComponentsContext" ;
@@ -15,14 +15,30 @@ export const SuggestionMenuItem = forwardRef<
15
15
16
16
assertEmpty ( rest ) ;
17
17
18
+ const itemRef = useRef < HTMLDivElement > ( null ) ;
19
+
20
+ useEffect ( ( ) => {
21
+ if ( ! itemRef . current || ! isSelected ) {
22
+ return ;
23
+ }
24
+
25
+ const overflow = elementOverflow ( itemRef . current ) ;
26
+
27
+ if ( overflow === "top" ) {
28
+ itemRef . current . scrollIntoView ( true ) ;
29
+ } else if ( overflow === "bottom" ) {
30
+ itemRef . current . scrollIntoView ( false ) ;
31
+ }
32
+ } , [ isSelected ] ) ;
33
+
18
34
return (
19
35
< div
20
36
// Styles from ShadCN DropdownMenuItem component
21
37
className = { cn (
22
38
"relative flex cursor-pointer select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50" ,
23
39
className
24
40
) }
25
- ref = { ref }
41
+ ref = { mergeRefs ( [ ref , itemRef ] ) }
26
42
id = { id }
27
43
onClick = { onClick }
28
44
role = "option"
You can’t perform that action at this time.
0 commit comments