Skip to content

Commit 2a83137

Browse files
committedDec 22, 2023
fix: #379 ContextMenu not closing after using a custom button via onRenderContextMenu
1 parent 9aa8d76 commit 2a83137

File tree

5 files changed

+57
-184
lines changed

5 files changed

+57
-184
lines changed
 

‎src/lib/components/controls/contextmenu/ContextMenu.svelte

+11-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import ContextMenuDropDownButton from './ContextMenuDropDownButton.svelte'
2020
2121
export let items: ContextMenuItem[]
22+
export let onCloseContextMenu: () => void
2223
export let tip: string | undefined
2324
2425
let refContextMenu: HTMLDivElement
@@ -79,23 +80,27 @@
7980
>
8081
{#each items as item}
8182
{#if isMenuButton(item)}
82-
<ContextMenuButton {item} />
83+
<ContextMenuButton {item} {onCloseContextMenu} />
8384
{:else if isMenuDropDownButton(item)}
84-
<ContextMenuDropDownButton {item} />
85+
<ContextMenuDropDownButton {item} {onCloseContextMenu} />
8586
{:else if isContextMenuRow(item)}
8687
<div class="jse-row">
8788
{#each item.items as rowItem}
8889
{#if isMenuButton(rowItem)}
89-
<ContextMenuButton item={rowItem} />
90+
<ContextMenuButton item={rowItem} {onCloseContextMenu} />
9091
{:else if isMenuDropDownButton(rowItem)}
91-
<ContextMenuDropDownButton item={rowItem} />
92+
<ContextMenuDropDownButton item={rowItem} {onCloseContextMenu} />
9293
{:else if isContextMenuColumn(rowItem)}
9394
<div class="jse-column">
9495
{#each rowItem.items as columnItem}
9596
{#if isMenuButton(columnItem)}
96-
<ContextMenuButton className="left" item={columnItem} />
97+
<ContextMenuButton className="left" item={columnItem} {onCloseContextMenu} />
9798
{:else if isMenuDropDownButton(columnItem)}
98-
<ContextMenuDropDownButton className="left" item={columnItem} />
99+
<ContextMenuDropDownButton
100+
className="left"
101+
item={columnItem}
102+
{onCloseContextMenu}
103+
/>
99104
{:else if isMenuSeparator(columnItem)}
100105
<div class="jse-separator" />
101106
{:else if isMenuLabel(columnItem)}

‎src/lib/components/controls/contextmenu/ContextMenuButton.svelte

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
66
export let item: MenuButton
77
export let className: string | undefined = undefined
8+
export let onCloseContextMenu: () => void
89
</script>
910

1011
<button
1112
type="button"
1213
class={classnames('jse-context-menu-button', className, item.className)}
13-
on:click={item.onClick}
14+
on:click={(event) => {
15+
onCloseContextMenu()
16+
item.onClick(event)
17+
}}
1418
title={item.title}
1519
disabled={item.disabled || false}
1620
>

‎src/lib/components/controls/contextmenu/ContextMenuDropDownButton.svelte

+5-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
export let item: MenuDropDownButton
88
export let className: string | undefined = undefined
9+
export let onCloseContextMenu: () => void
910
</script>
1011

1112
<DropdownButton width={item.width} items={item.items}>
@@ -14,7 +15,10 @@
1415
type="button"
1516
slot="defaultItem"
1617
title={item.main.title}
17-
on:click={item.main.onClick}
18+
on:click={(event) => {
19+
onCloseContextMenu()
20+
item.main.onClick(event)
21+
}}
1822
disabled={item.main.disabled || false}
1923
>
2024
{#if item.main.icon}

‎src/lib/components/modes/tablemode/contextmenu/TableContextMenu.svelte

+17-81
Original file line numberDiff line numberDiff line change
@@ -72,71 +72,6 @@
7272
)
7373
: false
7474
75-
function handleEditValue() {
76-
onCloseContextMenu()
77-
onEditValue()
78-
}
79-
80-
function handleEditRow() {
81-
onCloseContextMenu()
82-
onEditRow()
83-
}
84-
85-
function handleToggleEnforceString() {
86-
onCloseContextMenu()
87-
onToggleEnforceString()
88-
}
89-
90-
function handleCut() {
91-
onCloseContextMenu()
92-
onCut(true)
93-
}
94-
95-
function handleCutCompact() {
96-
onCloseContextMenu()
97-
onCut(false)
98-
}
99-
100-
function handleCopy() {
101-
onCloseContextMenu()
102-
onCopy(true)
103-
}
104-
105-
function handleCopyCompact() {
106-
onCloseContextMenu()
107-
onCopy(false)
108-
}
109-
110-
function handlePaste() {
111-
onCloseContextMenu()
112-
onPaste()
113-
}
114-
115-
function handleRemove() {
116-
onCloseContextMenu()
117-
onRemove()
118-
}
119-
120-
function handleDuplicateRow() {
121-
onCloseContextMenu()
122-
onDuplicateRow()
123-
}
124-
125-
function handleInsertBeforeRow() {
126-
onCloseContextMenu()
127-
onInsertBeforeRow()
128-
}
129-
130-
function handleInsertAfterRow() {
131-
onCloseContextMenu()
132-
onInsertAfterRow()
133-
}
134-
135-
function handleRemoveRow() {
136-
onCloseContextMenu()
137-
onRemoveRow()
138-
}
139-
14075
let defaultItems: ContextMenuItem[]
14176
$: defaultItems = [
14277
{ type: 'separator' },
@@ -151,7 +86,7 @@
15186
type: 'dropdown-button',
15287
main: {
15388
type: 'button',
154-
onClick: handleEditValue,
89+
onClick: () => onEditValue(),
15590
icon: faPen,
15691
text: 'Edit',
15792
title: 'Edit the value (Double-click on the value)',
@@ -164,15 +99,15 @@
16499
icon: faPen,
165100
text: 'Edit',
166101
title: 'Edit the value (Double-click on the value)',
167-
onClick: handleEditValue,
102+
onClick: () => onEditValue(),
168103
disabled: !canEditValue
169104
},
170105
{
171106
type: 'button',
172107
icon: enforceString ? faCheckSquare : faSquare,
173108
text: 'Enforce string',
174109
title: 'Enforce keeping the value as string when it contains a numeric value',
175-
onClick: handleToggleEnforceString,
110+
onClick: () => onToggleEnforceString(),
176111
disabled: !canEnforceString
177112
}
178113
]
@@ -181,7 +116,7 @@
181116
type: 'dropdown-button',
182117
main: {
183118
type: 'button',
184-
onClick: handleCut,
119+
onClick: () => onCut(true),
185120
icon: faCut,
186121
text: 'Cut',
187122
title: 'Cut selected contents, formatted with indentation (Ctrl+X)',
@@ -194,15 +129,15 @@
194129
icon: faCut,
195130
text: 'Cut formatted',
196131
title: 'Cut selected contents, formatted with indentation (Ctrl+X)',
197-
onClick: handleCut,
132+
onClick: () => onCut(true),
198133
disabled: !hasSelectionContents
199134
},
200135
{
201136
type: 'button',
202137
icon: faCut,
203138
text: 'Cut compacted',
204139
title: 'Cut selected contents, without indentation (Ctrl+Shift+X)',
205-
onClick: handleCutCompact,
140+
onClick: () => onCut(false),
206141
disabled: !hasSelectionContents
207142
}
208143
]
@@ -211,7 +146,7 @@
211146
type: 'dropdown-button',
212147
main: {
213148
type: 'button',
214-
onClick: handleCopy,
149+
onClick: () => onCopy(true),
215150
icon: faCopy,
216151
text: 'Copy',
217152
title: 'Copy selected contents, formatted with indentation (Ctrl+C)',
@@ -224,30 +159,30 @@
224159
icon: faCopy,
225160
text: 'Copy formatted',
226161
title: 'Copy selected contents, formatted with indentation (Ctrl+C)',
227-
onClick: handleCopy,
162+
onClick: () => onCopy(false),
228163
disabled: !hasSelectionContents
229164
},
230165
{
231166
type: 'button',
232167
icon: faCopy,
233168
text: 'Copy compacted',
234169
title: 'Copy selected contents, without indentation (Ctrl+Shift+C)',
235-
onClick: handleCopyCompact,
170+
onClick: () => onCopy(false),
236171
disabled: !hasSelectionContents
237172
}
238173
]
239174
},
240175
{
241176
type: 'button',
242-
onClick: handlePaste,
177+
onClick: () => onPaste(),
243178
icon: faPaste,
244179
text: 'Paste',
245180
title: 'Paste clipboard contents (Ctrl+V)',
246181
disabled: !hasSelection
247182
},
248183
{
249184
type: 'button',
250-
onClick: handleRemove,
185+
onClick: () => onRemove(),
251186
icon: faTrashCan,
252187
text: 'Remove',
253188
title: 'Remove selected contents (Delete)',
@@ -261,39 +196,39 @@
261196
{ type: 'label', text: 'Table row:' },
262197
{
263198
type: 'button',
264-
onClick: handleEditRow,
199+
onClick: () => onEditRow(),
265200
icon: faPen,
266201
text: 'Edit row',
267202
title: 'Edit the current row',
268203
disabled: !hasSelectionContents
269204
},
270205
{
271206
type: 'button',
272-
onClick: handleDuplicateRow,
207+
onClick: () => onDuplicateRow(),
273208
icon: faClone,
274209
text: 'Duplicate row',
275210
title: 'Duplicate the current row',
276211
disabled: !hasSelection
277212
},
278213
{
279214
type: 'button',
280-
onClick: handleInsertBeforeRow,
215+
onClick: () => onInsertBeforeRow(),
281216
icon: faPlus,
282217
text: 'Insert before',
283218
title: 'Insert a row before the current row',
284219
disabled: !hasSelection
285220
},
286221
{
287222
type: 'button',
288-
onClick: handleInsertAfterRow,
223+
onClick: () => onInsertAfterRow(),
289224
icon: faPlus,
290225
text: 'Insert after',
291226
title: 'Insert a row after the current row',
292227
disabled: !hasSelection
293228
},
294229
{
295230
type: 'button',
296-
onClick: handleRemoveRow,
231+
onClick: () => onRemoveRow(),
297232
icon: faTrashCan,
298233
text: 'Remove row',
299234
title: 'Remove current row',
@@ -310,5 +245,6 @@
310245

311246
<ContextMenu
312247
{items}
248+
{onCloseContextMenu}
313249
tip={showTip ? 'Tip: you can open this context menu via right-click or with Ctrl+Q' : undefined}
314250
/>

‎src/lib/components/modes/treemode/contextmenu/TreeContextMenu.svelte

+19-95
Original file line numberDiff line numberDiff line change
@@ -119,99 +119,22 @@
119119
)
120120
: false
121121
122-
function handleEditKey() {
123-
onCloseContextMenu()
124-
onEditKey()
125-
}
126-
127-
function handleEditValue() {
128-
onCloseContextMenu()
129-
onEditValue()
130-
}
131-
132-
function handleToggleEnforceString() {
133-
onCloseContextMenu()
134-
onToggleEnforceString()
135-
}
136-
137-
function handleCut() {
138-
onCloseContextMenu()
139-
onCut(true)
140-
}
141-
142-
function handleCutCompact() {
143-
onCloseContextMenu()
144-
onCut(false)
145-
}
146-
147-
function handleCopy() {
148-
onCloseContextMenu()
149-
onCopy(true)
150-
}
151-
152-
function handleCopyCompact() {
153-
onCloseContextMenu()
154-
onCopy(false)
155-
}
156-
157-
function handlePaste() {
158-
onCloseContextMenu()
159-
onPaste()
160-
}
161-
162-
function handleRemove() {
163-
onCloseContextMenu()
164-
onRemove()
165-
}
166-
167-
function handleDuplicate() {
168-
onCloseContextMenu()
169-
onDuplicate()
170-
}
171-
172-
function handleExtract() {
173-
onCloseContextMenu()
174-
onExtract()
175-
}
176-
177122
function handleInsertOrConvert(type: InsertType) {
178-
onCloseContextMenu()
179-
180123
if (hasSelectionContents) {
181124
onConvert(type)
182125
} else {
183126
onInsert(type)
184127
}
185128
}
186129
187-
function handleSort() {
188-
onCloseContextMenu()
189-
onSort()
190-
}
191-
192-
function handleTransform() {
193-
onCloseContextMenu()
194-
onTransform()
195-
}
196-
197-
function handleInsertBefore() {
198-
onCloseContextMenu()
199-
onInsertBefore()
200-
}
201-
202-
function handleInsertAfter() {
203-
onCloseContextMenu()
204-
onInsertAfter()
205-
}
206-
207130
let defaultItems: ContextMenuItem[]
208131
$: defaultItems = [
209132
{
210133
type: 'row',
211134
items: [
212135
{
213136
type: 'button',
214-
onClick: handleEditKey,
137+
onClick: () => onEditKey(),
215138
icon: faPen,
216139
text: 'Edit key',
217140
title: 'Edit the key (Double-click on the key)',
@@ -221,7 +144,7 @@
221144
type: 'dropdown-button',
222145
main: {
223146
type: 'button',
224-
onClick: handleEditValue,
147+
onClick: () => onEditValue(),
225148
icon: faPen,
226149
text: editValueText,
227150
title: 'Edit the value (Double-click on the value)',
@@ -234,15 +157,15 @@
234157
icon: faPen,
235158
text: editValueText,
236159
title: 'Edit the value (Double-click on the value)',
237-
onClick: handleEditValue,
160+
onClick: () => onEditValue(),
238161
disabled: !canEditValue
239162
},
240163
{
241164
type: 'button',
242165
icon: enforceString ? faCheckSquare : faSquare,
243166
text: 'Enforce string',
244167
title: 'Enforce keeping the value as string when it contains a numeric value',
245-
onClick: handleToggleEnforceString,
168+
onClick: () => onToggleEnforceString(),
246169
disabled: !canEnforceString
247170
}
248171
]
@@ -257,7 +180,7 @@
257180
type: 'dropdown-button',
258181
main: {
259182
type: 'button',
260-
onClick: handleCut,
183+
onClick: () => onCut(true),
261184
icon: faCut,
262185
text: 'Cut',
263186
title: 'Cut selected contents, formatted with indentation (Ctrl+X)',
@@ -270,15 +193,15 @@
270193
icon: faCut,
271194
text: 'Cut formatted',
272195
title: 'Cut selected contents, formatted with indentation (Ctrl+X)',
273-
onClick: handleCut,
196+
onClick: () => onCut(true),
274197
disabled: !hasSelectionContents
275198
},
276199
{
277200
type: 'button',
278201
icon: faCut,
279202
text: 'Cut compacted',
280203
title: 'Cut selected contents, without indentation (Ctrl+Shift+X)',
281-
onClick: handleCutCompact,
204+
onClick: () => onCut(false),
282205
disabled: !hasSelectionContents
283206
}
284207
]
@@ -287,7 +210,7 @@
287210
type: 'dropdown-button',
288211
main: {
289212
type: 'button',
290-
onClick: handleCopy,
213+
onClick: () => onCopy(true),
291214
icon: faCopy,
292215
text: 'Copy',
293216
title: 'Copy selected contents, formatted with indentation (Ctrl+C)',
@@ -300,22 +223,22 @@
300223
icon: faCopy,
301224
text: 'Copy formatted',
302225
title: 'Copy selected contents, formatted with indentation (Ctrl+C)',
303-
onClick: handleCopy,
226+
onClick: () => onCopy(true),
304227
disabled: !hasSelectionContents
305228
},
306229
{
307230
type: 'button',
308231
icon: faCopy,
309232
text: 'Copy compacted',
310233
title: 'Copy selected contents, without indentation (Ctrl+Shift+C)',
311-
onClick: handleCopyCompact,
234+
onClick: () => onCopy(false),
312235
disabled: !hasSelectionContents
313236
}
314237
]
315238
},
316239
{
317240
type: 'button',
318-
onClick: handlePaste,
241+
onClick: () => onPaste(),
319242
icon: faPaste,
320243
text: 'Paste',
321244
title: 'Paste clipboard contents (Ctrl+V)',
@@ -332,39 +255,39 @@
332255
items: [
333256
{
334257
type: 'button',
335-
onClick: handleDuplicate,
258+
onClick: () => onDuplicate(),
336259
icon: faClone,
337260
text: 'Duplicate',
338261
title: 'Duplicate selected contents (Ctrl+D)',
339262
disabled: !canDuplicate
340263
},
341264
{
342265
type: 'button',
343-
onClick: handleExtract,
266+
onClick: () => onExtract(),
344267
icon: faCropAlt,
345268
text: 'Extract',
346269
title: 'Extract selected contents',
347270
disabled: !canExtract
348271
},
349272
{
350273
type: 'button',
351-
onClick: handleSort,
274+
onClick: () => onSort(),
352275
icon: faSortAmountDownAlt,
353276
text: 'Sort',
354277
title: 'Sort array or object contents',
355278
disabled: !hasSelectionContents
356279
},
357280
{
358281
type: 'button',
359-
onClick: handleTransform,
282+
onClick: () => onTransform(),
360283
icon: faFilter,
361284
text: 'Transform',
362285
title: 'Transform array or object contents (filter, sort, project)',
363286
disabled: !hasSelectionContents
364287
},
365288
{
366289
type: 'button',
367-
onClick: handleRemove,
290+
onClick: () => onRemove(),
368291
icon: faTrashCan,
369292
text: 'Remove',
370293
title: 'Remove selected contents (Delete)',
@@ -420,15 +343,15 @@
420343
items: [
421344
{
422345
type: 'button',
423-
onClick: handleInsertBefore,
346+
onClick: () => onInsertBefore(),
424347
icon: faCaretSquareUp,
425348
text: 'Insert before',
426349
title: 'Select area before current entry to insert or paste contents',
427350
disabled: !hasSelectionContents || rootSelected
428351
},
429352
{
430353
type: 'button',
431-
onClick: handleInsertAfter,
354+
onClick: () => onInsertAfter(),
432355
icon: faCaretSquareDown,
433356
text: 'Insert after',
434357
title: 'Select area after current entry to insert or paste contents',
@@ -443,5 +366,6 @@
443366

444367
<ContextMenu
445368
{items}
369+
{onCloseContextMenu}
446370
tip={showTip ? 'Tip: you can open this context menu via right-click or with Ctrl+Q' : undefined}
447371
/>

0 commit comments

Comments
 (0)
Please sign in to comment.