1
1
import { App , Modal , Setting } from 'obsidian' ;
2
2
import { SelectModalElement } from './SelectModalElement' ;
3
+ import { mod } from '../utils/Utils' ;
3
4
4
5
export abstract class SelectModal < T > extends Modal {
5
6
allowMultiSelect : boolean ;
@@ -22,6 +23,17 @@ export abstract class SelectModal<T> extends Modal {
22
23
23
24
this . elements = elements ;
24
25
this . selectModalElements = [ ] ;
26
+
27
+ this . scope . register ( [ ] , 'ArrowUp' , ( ) => {
28
+ this . highlightUp ( ) ;
29
+ } ) ;
30
+ this . scope . register ( [ ] , 'ArrowDown' , ( ) => {
31
+ this . highlightDown ( ) ;
32
+ } ) ;
33
+ this . scope . register ( [ ] , 'ArrowRight' , ( ) => {
34
+ this . activateHighlighted ( ) ;
35
+ } ) ;
36
+ this . scope . register ( [ ] , 'Enter' , ( ) => this . submit ( ) ) ;
25
37
}
26
38
27
39
abstract renderElement ( value : T , el : HTMLElement ) : any ;
@@ -38,6 +50,14 @@ export abstract class SelectModal<T> extends Modal {
38
50
}
39
51
}
40
52
53
+ deHighlightAllOtherElements ( elementId : number ) {
54
+ for ( const selectModalElement of this . selectModalElements ) {
55
+ if ( selectModalElement . id !== elementId ) {
56
+ selectModalElement . setHighlighted ( false ) ;
57
+ }
58
+ }
59
+ }
60
+
41
61
async onOpen ( ) {
42
62
const { contentEl} = this ;
43
63
@@ -72,4 +92,54 @@ export abstract class SelectModal<T> extends Modal {
72
92
}
73
93
bottomSetting . addButton ( btn => btn . setButtonText ( 'Ok' ) . setCta ( ) . onClick ( ( ) => this . submit ( ) ) ) ;
74
94
}
95
+
96
+ activateHighlighted ( ) {
97
+ for ( const selectModalElement of this . selectModalElements ) {
98
+ if ( selectModalElement . isHighlighted ( ) ) {
99
+ selectModalElement . setActive ( ! selectModalElement . isActive ( ) ) ;
100
+ if ( ! this . allowMultiSelect ) {
101
+ this . disableAllOtherElements ( selectModalElement . id ) ;
102
+ }
103
+ }
104
+ }
105
+ }
106
+
107
+ highlightUp ( ) {
108
+ for ( const selectModalElement of this . selectModalElements ) {
109
+ if ( selectModalElement . isHighlighted ( ) ) {
110
+ this . getPreviousSelectModalElement ( selectModalElement ) . setHighlighted ( true ) ;
111
+ return ;
112
+ }
113
+ }
114
+
115
+ // nothing is highlighted
116
+ this . selectModalElements . last ( ) . setHighlighted ( true ) ;
117
+ }
118
+
119
+ highlightDown ( ) {
120
+ for ( const selectModalElement of this . selectModalElements ) {
121
+ if ( selectModalElement . isHighlighted ( ) ) {
122
+ this . getNextSelectModalElement ( selectModalElement ) . setHighlighted ( true ) ;
123
+ return ;
124
+ }
125
+ }
126
+
127
+ // nothing is highlighted
128
+ this . selectModalElements . first ( ) . setHighlighted ( true ) ;
129
+ }
130
+
131
+ private getNextSelectModalElement ( selectModalElement : SelectModalElement < T > ) : SelectModalElement < T > {
132
+ let nextId = selectModalElement . id + 1 ;
133
+ nextId = mod ( nextId , this . selectModalElements . length ) ;
134
+
135
+ return this . selectModalElements . filter ( x => x . id === nextId ) . first ( ) ;
136
+ }
137
+
138
+ private getPreviousSelectModalElement ( selectModalElement : SelectModalElement < T > ) : SelectModalElement < T > {
139
+ let nextId = selectModalElement . id - 1 ;
140
+ nextId = mod ( nextId , this . selectModalElements . length ) ;
141
+
142
+ return this . selectModalElements . filter ( x => x . id === nextId ) . first ( ) ;
143
+ }
144
+
75
145
}
0 commit comments