1
1
'use client'
2
2
3
- import type { ElementNode , LexicalNode } from 'lexical'
3
+ import type { BaseSelection , ElementNode , LexicalNode } from 'lexical'
4
4
5
5
import { $findMatchingParent } from '@lexical/utils'
6
6
import {
@@ -15,10 +15,11 @@ import type { ToolbarGroup } from '../../toolbars/types.js'
15
15
import { IndentDecreaseIcon } from '../../../lexical/ui/icons/IndentDecrease/index.js'
16
16
import { IndentIncreaseIcon } from '../../../lexical/ui/icons/IndentIncrease/index.js'
17
17
import { createClientFeature } from '../../../utilities/createClientFeature.js'
18
+ import { type IndentFeatureProps } from '../server/index.js'
18
19
import { IndentPlugin } from './IndentPlugin.js'
19
20
import { toolbarIndentGroupWithItems } from './toolbarIndentGroup.js'
20
21
21
- const toolbarGroups : ToolbarGroup [ ] = [
22
+ const toolbarGroups = ( { disabledNodes } : IndentFeatureProps ) : ToolbarGroup [ ] => [
22
23
toolbarIndentGroupWithItems ( [
23
24
{
24
25
ChildComponent : IndentDecreaseIcon ,
@@ -40,16 +41,10 @@ const toolbarGroups: ToolbarGroup[] = [
40
41
}
41
42
}
42
43
}
43
- if ( ! atLeastOneNodeCanOutdent && $isRangeSelection ( selection ) ) {
44
- const anchorNode = selection . anchor . getNode ( )
45
- if (
46
- $findMatchingParent ( anchorNode , ( node ) => isIndentable ( node ) && node . getIndent ( ) > 0 )
47
- ) {
48
- return true
49
- }
50
- const focusNode = selection . focus . getNode ( )
44
+
45
+ if ( ! atLeastOneNodeCanOutdent ) {
51
46
if (
52
- $findMatchingParent ( focusNode , ( node ) => isIndentable ( node ) && node . getIndent ( ) > 0 )
47
+ $pointsAncestorMatch ( selection , ( node ) => isIndentable ( node ) && node . getIndent ( ) > 0 )
53
48
) {
54
49
return true
55
50
}
@@ -68,6 +63,18 @@ const toolbarGroups: ToolbarGroup[] = [
68
63
{
69
64
ChildComponent : IndentIncreaseIcon ,
70
65
isActive : ( ) => false ,
66
+ isEnabled : ( { selection } ) => {
67
+ const nodes = selection ?. getNodes ( )
68
+ if ( ! nodes ?. length ) {
69
+ return false
70
+ }
71
+ if ( nodes . some ( ( node ) => disabledNodes ?. includes ( node . getType ( ) ) ) ) {
72
+ return false
73
+ }
74
+ return ! $pointsAncestorMatch ( selection , ( node ) =>
75
+ ( disabledNodes ?? [ ] ) . includes ( node . getType ( ) ) ,
76
+ )
77
+ } ,
71
78
key : 'indentIncrease' ,
72
79
label : ( { i18n } ) => {
73
80
return i18n . t ( 'lexical:indent:increaseLabel' )
@@ -80,17 +87,32 @@ const toolbarGroups: ToolbarGroup[] = [
80
87
] ) ,
81
88
]
82
89
83
- export const IndentFeatureClient = createClientFeature ( {
84
- plugins : [
85
- {
86
- Component : IndentPlugin ,
87
- position : 'normal' ,
90
+ export const IndentFeatureClient = createClientFeature < IndentFeatureProps > ( ( { props } ) => {
91
+ const disabledNodes = props . disabledNodes ?? [ ]
92
+ return {
93
+ plugins : [
94
+ {
95
+ Component : IndentPlugin ,
96
+ position : 'normal' ,
97
+ } ,
98
+ ] ,
99
+ sanitizedClientFeatureProps : props ,
100
+ toolbarFixed : {
101
+ groups : toolbarGroups ( { disabledNodes } ) ,
88
102
} ,
89
- ] ,
90
- toolbarFixed : {
91
- groups : toolbarGroups ,
92
- } ,
93
- toolbarInline : {
94
- groups : toolbarGroups ,
95
- } ,
103
+ toolbarInline : {
104
+ groups : toolbarGroups ( { disabledNodes } ) ,
105
+ } ,
106
+ }
96
107
} )
108
+
109
+ function $pointsAncestorMatch (
110
+ selection : BaseSelection ,
111
+ fn : ( node : LexicalNode ) => boolean ,
112
+ ) : boolean {
113
+ return (
114
+ $isRangeSelection ( selection ) &&
115
+ ( ! ! $findMatchingParent ( selection . anchor . getNode ( ) , fn ) ||
116
+ ! ! $findMatchingParent ( selection . focus . getNode ( ) , fn ) )
117
+ )
118
+ }
0 commit comments