@tanstack/hotkeys-devtools 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/HotkeysContextProvider.js +1 -2
- package/dist/_registrations.js +1 -2
- package/dist/components/ActionButtons.js +2 -3
- package/dist/components/DetailsPanel.js +16 -3
- package/dist/components/HeldKeysTopbar.js +5 -3
- package/dist/components/HotkeyList.js +13 -3
- package/dist/components/Shell.js +5 -4
- package/dist/components/index.js +1 -2
- package/dist/core.d.ts +3 -6
- package/dist/core.js +1 -2
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -2
- package/dist/sequence-progress.js +1 -2
- package/dist/styles/tokens.js +1 -2
- package/dist/styles/use-styles.js +5 -4
- package/package.json +11 -11
- package/dist/HotkeysContextProvider.js.map +0 -1
- package/dist/_registrations.js.map +0 -1
- package/dist/components/ActionButtons.js.map +0 -1
- package/dist/components/DetailsPanel.js.map +0 -1
- package/dist/components/HeldKeysTopbar.js.map +0 -1
- package/dist/components/HotkeyList.js.map +0 -1
- package/dist/components/Shell.js.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/core.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/sequence-progress.js.map +0 -1
- package/dist/styles/tokens.js.map +0 -1
- package/dist/styles/use-styles.js.map +0 -1
- package/src/HotkeysContextProvider.tsx +0 -130
- package/src/_registrations.ts +0 -59
- package/src/components/ActionButtons.tsx +0 -38
- package/src/components/DetailsPanel.tsx +0 -685
- package/src/components/HeldKeysTopbar.tsx +0 -46
- package/src/components/HotkeyList.tsx +0 -473
- package/src/components/Shell.tsx +0 -171
- package/src/components/index.tsx +0 -19
- package/src/core.tsx +0 -11
- package/src/index.ts +0 -11
- package/src/production.ts +0 -5
- package/src/sequence-progress.ts +0 -29
- package/src/styles/tokens.ts +0 -305
- package/src/styles/use-styles.ts +0 -687
|
@@ -1,685 +0,0 @@
|
|
|
1
|
-
import { For, Show, createMemo } from 'solid-js'
|
|
2
|
-
import clsx from 'clsx'
|
|
3
|
-
import {
|
|
4
|
-
detectPlatform,
|
|
5
|
-
formatForDisplay,
|
|
6
|
-
normalizeHotkeyFromParsed,
|
|
7
|
-
parseHotkey,
|
|
8
|
-
} from '@tanstack/hotkeys'
|
|
9
|
-
import { useStyles } from '../styles/use-styles'
|
|
10
|
-
import { useHotkeysDevtoolsState } from '../HotkeysContextProvider'
|
|
11
|
-
import { effectiveSequenceMatchedSteps } from '../sequence-progress'
|
|
12
|
-
import {
|
|
13
|
-
formatRegistration,
|
|
14
|
-
getBindingKind,
|
|
15
|
-
useRegistrationConflicts,
|
|
16
|
-
} from '../_registrations'
|
|
17
|
-
import { ActionButtons } from './ActionButtons'
|
|
18
|
-
import type {
|
|
19
|
-
ConflictBehavior,
|
|
20
|
-
HotkeyRegistration,
|
|
21
|
-
ParsedHotkey,
|
|
22
|
-
SequenceRegistrationView,
|
|
23
|
-
} from '@tanstack/hotkeys'
|
|
24
|
-
|
|
25
|
-
const PLATFORM_ROWS = [
|
|
26
|
-
{ id: 'mac' as const, label: 'macOS' },
|
|
27
|
-
{ id: 'windows' as const, label: 'Windows' },
|
|
28
|
-
{ id: 'linux' as const, label: 'Linux' },
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
function KeyBreakdownPlatformTable(props: {
|
|
32
|
-
getParsed: () => ParsedHotkey
|
|
33
|
-
/** Platform used when the parsed hotkey was produced (registration `options.platform`). */
|
|
34
|
-
getCanonicalPlatform: () => 'mac' | 'windows' | 'linux'
|
|
35
|
-
styles: ReturnType<typeof useStyles>
|
|
36
|
-
}) {
|
|
37
|
-
const st = () => props.styles()
|
|
38
|
-
return (
|
|
39
|
-
<div class={st().platformBreakdown}>
|
|
40
|
-
<For each={PLATFORM_ROWS}>
|
|
41
|
-
{(row) => (
|
|
42
|
-
<div class={st().platformBreakdownRow}>
|
|
43
|
-
<span class={st().platformBreakdownLabel}>{row.label}</span>
|
|
44
|
-
<span class={st().platformBreakdownPretty}>
|
|
45
|
-
{formatForDisplay(
|
|
46
|
-
normalizeHotkeyFromParsed(
|
|
47
|
-
props.getParsed(),
|
|
48
|
-
props.getCanonicalPlatform(),
|
|
49
|
-
),
|
|
50
|
-
{
|
|
51
|
-
platform: row.id,
|
|
52
|
-
},
|
|
53
|
-
)}
|
|
54
|
-
</span>
|
|
55
|
-
</div>
|
|
56
|
-
)}
|
|
57
|
-
</For>
|
|
58
|
-
</div>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function isSequenceRegistration(
|
|
63
|
-
reg: HotkeyRegistration | SequenceRegistrationView,
|
|
64
|
-
): reg is SequenceRegistrationView {
|
|
65
|
-
return 'sequence' in reg && Array.isArray(reg.sequence)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type DetailsPanelProps = {
|
|
69
|
-
selectedRegistration: () =>
|
|
70
|
-
| HotkeyRegistration
|
|
71
|
-
| SequenceRegistrationView
|
|
72
|
-
| null
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function getTargetDescription(target: HTMLElement | Document | Window): string {
|
|
76
|
-
if (typeof document !== 'undefined' && target === document) {
|
|
77
|
-
return 'document'
|
|
78
|
-
}
|
|
79
|
-
if (typeof window !== 'undefined' && target === window) {
|
|
80
|
-
return 'window'
|
|
81
|
-
}
|
|
82
|
-
if (target instanceof HTMLElement) {
|
|
83
|
-
const tag = target.tagName.toLowerCase()
|
|
84
|
-
const id = target.id ? `#${target.id}` : ''
|
|
85
|
-
const cls = target.className
|
|
86
|
-
? `.${target.className.split(' ').join('.')}`
|
|
87
|
-
: ''
|
|
88
|
-
return `${tag}${id}${cls}`
|
|
89
|
-
}
|
|
90
|
-
return 'element'
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function HotkeyDetails(props: {
|
|
94
|
-
registration: HotkeyRegistration
|
|
95
|
-
getTargetDescription: (t: HTMLElement | Document | Window) => string
|
|
96
|
-
styles: ReturnType<typeof useStyles>
|
|
97
|
-
}) {
|
|
98
|
-
const reg = () => props.registration
|
|
99
|
-
const parsed = () => reg().parsedHotkey
|
|
100
|
-
const conflicts = useRegistrationConflicts(reg)
|
|
101
|
-
const targetConflicts = () => conflicts().overlapping
|
|
102
|
-
const scopeConflicts = () => conflicts().separate
|
|
103
|
-
const allConflicts = () => [...targetConflicts(), ...scopeConflicts()]
|
|
104
|
-
const conflictBehavior = (): ConflictBehavior =>
|
|
105
|
-
reg().options.conflictBehavior ?? 'warn'
|
|
106
|
-
|
|
107
|
-
const registrationPlatform = () => reg().options.platform ?? detectPlatform()
|
|
108
|
-
|
|
109
|
-
const keyParts = createMemo(() =>
|
|
110
|
-
formatForDisplay(parsed(), {
|
|
111
|
-
platform: registrationPlatform(),
|
|
112
|
-
parts: true,
|
|
113
|
-
}),
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
const styles = props.styles
|
|
117
|
-
|
|
118
|
-
return (
|
|
119
|
-
<>
|
|
120
|
-
<div class={styles().stateHeader}>
|
|
121
|
-
<div class={styles().stateTitle}>{formatRegistration(reg())}</div>
|
|
122
|
-
<div class={styles().infoGrid}>
|
|
123
|
-
<div class={styles().infoLabel}>ID</div>
|
|
124
|
-
<div class={styles().infoValueMono}>{reg().id}</div>
|
|
125
|
-
<div class={styles().infoLabel}>Matches</div>
|
|
126
|
-
<div class={styles().infoValueMono}>{getBindingKind(reg())}</div>
|
|
127
|
-
<div class={styles().infoLabel}>Raw</div>
|
|
128
|
-
<div class={styles().infoValueMono}>{reg().hotkey}</div>
|
|
129
|
-
<div class={styles().infoLabel}>Target</div>
|
|
130
|
-
<div class={styles().infoValueMono}>
|
|
131
|
-
{props.getTargetDescription(reg().target)}
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<div class={styles().detailsGrid}>
|
|
137
|
-
<div class={styles().detailSection}>
|
|
138
|
-
<div class={styles().detailSectionHeader}>Key Breakdown</div>
|
|
139
|
-
<div class={styles().keyBreakdownSplitRow}>
|
|
140
|
-
<div class={styles().keyBreakdownSplitLeft}>
|
|
141
|
-
<div class={styles().keyBreakdown}>
|
|
142
|
-
<For each={keyParts()}>
|
|
143
|
-
{(part, i) => (
|
|
144
|
-
<>
|
|
145
|
-
<Show when={i() > 0}>
|
|
146
|
-
<span class={styles().keyBreakdownPlus}>+</span>
|
|
147
|
-
</Show>
|
|
148
|
-
<span class={styles().keyCapLarge}>{part}</span>
|
|
149
|
-
</>
|
|
150
|
-
)}
|
|
151
|
-
</For>
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
<span class={styles().keyBreakdownSplitArrow} aria-hidden="true">
|
|
155
|
-
{'->'}
|
|
156
|
-
</span>
|
|
157
|
-
<div class={styles().keyBreakdownSplitRight}>
|
|
158
|
-
<KeyBreakdownPlatformTable
|
|
159
|
-
getParsed={() => parsed()}
|
|
160
|
-
getCanonicalPlatform={registrationPlatform}
|
|
161
|
-
styles={props.styles}
|
|
162
|
-
/>
|
|
163
|
-
</div>
|
|
164
|
-
</div>
|
|
165
|
-
</div>
|
|
166
|
-
|
|
167
|
-
<div class={styles().detailSection}>
|
|
168
|
-
<div class={styles().detailSectionHeader}>Actions</div>
|
|
169
|
-
<ActionButtons registration={reg()} />
|
|
170
|
-
</div>
|
|
171
|
-
|
|
172
|
-
<div class={styles().detailSection}>
|
|
173
|
-
<div class={styles().detailSectionHeader}>Meta</div>
|
|
174
|
-
<div>
|
|
175
|
-
<div class={styles().optionRow}>
|
|
176
|
-
<span class={styles().optionLabel}>name</span>
|
|
177
|
-
<span class={styles().optionValue}>
|
|
178
|
-
{reg().options.meta?.name ?? '—'}
|
|
179
|
-
</span>
|
|
180
|
-
</div>
|
|
181
|
-
<div class={styles().optionRow}>
|
|
182
|
-
<span class={styles().optionLabel}>description</span>
|
|
183
|
-
<span class={styles().optionValue}>
|
|
184
|
-
{reg().options.meta?.description ?? '—'}
|
|
185
|
-
</span>
|
|
186
|
-
</div>
|
|
187
|
-
<Show
|
|
188
|
-
when={
|
|
189
|
-
reg().options.meta &&
|
|
190
|
-
Object.keys(reg().options.meta!).filter(
|
|
191
|
-
(k) => k !== 'name' && k !== 'description',
|
|
192
|
-
).length > 0
|
|
193
|
-
}
|
|
194
|
-
>
|
|
195
|
-
<For
|
|
196
|
-
each={Object.entries(reg().options.meta ?? {}).filter(
|
|
197
|
-
([k]) => k !== 'name' && k !== 'description',
|
|
198
|
-
)}
|
|
199
|
-
>
|
|
200
|
-
{([key, value]) => (
|
|
201
|
-
<div class={styles().optionRow}>
|
|
202
|
-
<span class={styles().optionLabel}>{key}</span>
|
|
203
|
-
<span class={styles().optionValue}>{String(value)}</span>
|
|
204
|
-
</div>
|
|
205
|
-
)}
|
|
206
|
-
</For>
|
|
207
|
-
</Show>
|
|
208
|
-
</div>
|
|
209
|
-
</div>
|
|
210
|
-
|
|
211
|
-
<div class={styles().detailSection}>
|
|
212
|
-
<div class={styles().detailSectionHeader}>Options</div>
|
|
213
|
-
<div>
|
|
214
|
-
<div class={styles().optionRow}>
|
|
215
|
-
<span class={styles().optionLabel}>enabled</span>
|
|
216
|
-
<span
|
|
217
|
-
class={
|
|
218
|
-
reg().options.enabled !== false
|
|
219
|
-
? styles().optionValueTrue
|
|
220
|
-
: styles().optionValueFalse
|
|
221
|
-
}
|
|
222
|
-
>
|
|
223
|
-
{String(reg().options.enabled !== false)}
|
|
224
|
-
</span>
|
|
225
|
-
</div>
|
|
226
|
-
<div class={styles().optionRow}>
|
|
227
|
-
<span class={styles().optionLabel}>eventType</span>
|
|
228
|
-
<span class={styles().optionValue}>
|
|
229
|
-
{reg().options.eventType ?? 'keydown'}
|
|
230
|
-
</span>
|
|
231
|
-
</div>
|
|
232
|
-
<div class={styles().optionRow}>
|
|
233
|
-
<span class={styles().optionLabel}>preventDefault</span>
|
|
234
|
-
<span
|
|
235
|
-
class={
|
|
236
|
-
reg().options.preventDefault
|
|
237
|
-
? styles().optionValueTrue
|
|
238
|
-
: styles().optionValueFalse
|
|
239
|
-
}
|
|
240
|
-
>
|
|
241
|
-
{String(!!reg().options.preventDefault)}
|
|
242
|
-
</span>
|
|
243
|
-
</div>
|
|
244
|
-
<div class={styles().optionRow}>
|
|
245
|
-
<span class={styles().optionLabel}>stopPropagation</span>
|
|
246
|
-
<span
|
|
247
|
-
class={
|
|
248
|
-
reg().options.stopPropagation
|
|
249
|
-
? styles().optionValueTrue
|
|
250
|
-
: styles().optionValueFalse
|
|
251
|
-
}
|
|
252
|
-
>
|
|
253
|
-
{String(!!reg().options.stopPropagation)}
|
|
254
|
-
</span>
|
|
255
|
-
</div>
|
|
256
|
-
<div class={styles().optionRow}>
|
|
257
|
-
<span class={styles().optionLabel}>ignoreInputs</span>
|
|
258
|
-
<span
|
|
259
|
-
class={
|
|
260
|
-
reg().options.ignoreInputs !== false
|
|
261
|
-
? styles().optionValueTrue
|
|
262
|
-
: styles().optionValueFalse
|
|
263
|
-
}
|
|
264
|
-
>
|
|
265
|
-
{String(reg().options.ignoreInputs !== false)}
|
|
266
|
-
</span>
|
|
267
|
-
</div>
|
|
268
|
-
<div class={styles().optionRow}>
|
|
269
|
-
<span class={styles().optionLabel}>requireReset</span>
|
|
270
|
-
<span
|
|
271
|
-
class={
|
|
272
|
-
reg().options.requireReset
|
|
273
|
-
? styles().optionValueTrue
|
|
274
|
-
: styles().optionValueFalse
|
|
275
|
-
}
|
|
276
|
-
>
|
|
277
|
-
{String(!!reg().options.requireReset)}
|
|
278
|
-
</span>
|
|
279
|
-
</div>
|
|
280
|
-
<div class={styles().optionRow}>
|
|
281
|
-
<span class={styles().optionLabel}>conflictBehavior</span>
|
|
282
|
-
<span class={styles().optionValue}>{conflictBehavior()}</span>
|
|
283
|
-
</div>
|
|
284
|
-
<div class={styles().optionRow}>
|
|
285
|
-
<span class={styles().optionLabel}>hasFired</span>
|
|
286
|
-
<span
|
|
287
|
-
class={
|
|
288
|
-
reg().hasFired
|
|
289
|
-
? styles().optionValueTrue
|
|
290
|
-
: styles().optionValueFalse
|
|
291
|
-
}
|
|
292
|
-
>
|
|
293
|
-
{String(reg().hasFired)}
|
|
294
|
-
</span>
|
|
295
|
-
</div>
|
|
296
|
-
</div>
|
|
297
|
-
</div>
|
|
298
|
-
|
|
299
|
-
<Show when={allConflicts().length > 0}>
|
|
300
|
-
<div class={styles().detailSection}>
|
|
301
|
-
<div class={styles().detailSectionHeader}>
|
|
302
|
-
Conflicts ({allConflicts().length})
|
|
303
|
-
</div>
|
|
304
|
-
<div class={styles().conflictList}>
|
|
305
|
-
<For each={targetConflicts()}>
|
|
306
|
-
{(conflict) => {
|
|
307
|
-
return (
|
|
308
|
-
<div class={styles().conflictItem}>
|
|
309
|
-
<span>overlap</span> {conflict.id}:{' '}
|
|
310
|
-
{formatRegistration(conflict)} (
|
|
311
|
-
{conflict.options.eventType ?? 'keydown'}) on{' '}
|
|
312
|
-
{props.getTargetDescription(conflict.target)}
|
|
313
|
-
</div>
|
|
314
|
-
)
|
|
315
|
-
}}
|
|
316
|
-
</For>
|
|
317
|
-
<For each={scopeConflicts()}>
|
|
318
|
-
{(conflict) => (
|
|
319
|
-
<div class={styles().conflictItemScope}>
|
|
320
|
-
<span>scope</span> {conflict.id}:{' '}
|
|
321
|
-
{formatRegistration(conflict)} (
|
|
322
|
-
{conflict.options.eventType ?? 'keydown'}) on{' '}
|
|
323
|
-
{props.getTargetDescription(conflict.target)}
|
|
324
|
-
</div>
|
|
325
|
-
)}
|
|
326
|
-
</For>
|
|
327
|
-
</div>
|
|
328
|
-
</div>
|
|
329
|
-
</Show>
|
|
330
|
-
</div>
|
|
331
|
-
</>
|
|
332
|
-
)
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
function SequenceDetails(props: {
|
|
336
|
-
registration: SequenceRegistrationView
|
|
337
|
-
state: ReturnType<typeof useHotkeysDevtoolsState>
|
|
338
|
-
getTargetDescription: (t: HTMLElement | Document | Window) => string
|
|
339
|
-
styles: ReturnType<typeof useStyles>
|
|
340
|
-
}) {
|
|
341
|
-
const reg = () => props.registration
|
|
342
|
-
const liveReg = createMemo(
|
|
343
|
-
() =>
|
|
344
|
-
props.state.sequenceRegistrations().find((r) => r.id === reg().id) ??
|
|
345
|
-
reg(),
|
|
346
|
-
)
|
|
347
|
-
const matchedSteps = createMemo(() =>
|
|
348
|
-
effectiveSequenceMatchedSteps(liveReg(), props.state.sequenceProgressNow()),
|
|
349
|
-
)
|
|
350
|
-
const conflicts = useRegistrationConflicts(liveReg)
|
|
351
|
-
const targetConflicts = () => conflicts().overlapping
|
|
352
|
-
const scopeConflicts = () => conflicts().separate
|
|
353
|
-
const allConflicts = () => [...targetConflicts(), ...scopeConflicts()]
|
|
354
|
-
const conflictBehavior = (): ConflictBehavior =>
|
|
355
|
-
liveReg().options.conflictBehavior ?? 'warn'
|
|
356
|
-
|
|
357
|
-
const sequenceCanonicalPlatform = createMemo(
|
|
358
|
-
() => liveReg().options.platform ?? detectPlatform(),
|
|
359
|
-
)
|
|
360
|
-
|
|
361
|
-
const styles = props.styles
|
|
362
|
-
|
|
363
|
-
return (
|
|
364
|
-
<>
|
|
365
|
-
<div class={styles().stateHeader}>
|
|
366
|
-
<div class={styles().stateTitle}>
|
|
367
|
-
<For each={liveReg().sequence}>
|
|
368
|
-
{(step, i) => (
|
|
369
|
-
<span>
|
|
370
|
-
<Show when={i() > 0}> </Show>
|
|
371
|
-
<span
|
|
372
|
-
class={
|
|
373
|
-
i() < matchedSteps()
|
|
374
|
-
? styles().sequenceStepMatched
|
|
375
|
-
: undefined
|
|
376
|
-
}
|
|
377
|
-
>
|
|
378
|
-
{formatForDisplay(step, {
|
|
379
|
-
platform: sequenceCanonicalPlatform(),
|
|
380
|
-
})}
|
|
381
|
-
</span>
|
|
382
|
-
</span>
|
|
383
|
-
)}
|
|
384
|
-
</For>
|
|
385
|
-
</div>
|
|
386
|
-
<div class={styles().infoGrid}>
|
|
387
|
-
<div class={styles().infoLabel}>ID</div>
|
|
388
|
-
<div class={styles().infoValueMono}>{liveReg().id}</div>
|
|
389
|
-
<div class={styles().infoLabel}>Matches</div>
|
|
390
|
-
<div class={styles().infoValueMono}>{getBindingKind(liveReg())}</div>
|
|
391
|
-
<div class={styles().infoLabel}>Raw</div>
|
|
392
|
-
<div class={styles().infoValueMono}>
|
|
393
|
-
{liveReg().sequence.join(' → ')}
|
|
394
|
-
</div>
|
|
395
|
-
<div class={styles().infoLabel}>Sequence</div>
|
|
396
|
-
<div class={styles().infoValueMono}>
|
|
397
|
-
<For each={liveReg().sequence}>
|
|
398
|
-
{(step, i) => (
|
|
399
|
-
<span>
|
|
400
|
-
<Show when={i() > 0}> </Show>
|
|
401
|
-
<span
|
|
402
|
-
class={
|
|
403
|
-
i() < matchedSteps()
|
|
404
|
-
? styles().sequenceStepMatched
|
|
405
|
-
: undefined
|
|
406
|
-
}
|
|
407
|
-
>
|
|
408
|
-
{formatForDisplay(step, {
|
|
409
|
-
platform: sequenceCanonicalPlatform(),
|
|
410
|
-
})}
|
|
411
|
-
</span>
|
|
412
|
-
</span>
|
|
413
|
-
)}
|
|
414
|
-
</For>
|
|
415
|
-
</div>
|
|
416
|
-
<div class={styles().infoLabel}>Target</div>
|
|
417
|
-
<div class={styles().infoValueMono}>
|
|
418
|
-
{props.getTargetDescription(liveReg().target)}
|
|
419
|
-
</div>
|
|
420
|
-
</div>
|
|
421
|
-
</div>
|
|
422
|
-
|
|
423
|
-
<div class={styles().detailsGrid}>
|
|
424
|
-
<div class={styles().detailSection}>
|
|
425
|
-
<div class={styles().detailSectionHeader}>Key Breakdown</div>
|
|
426
|
-
<div class={styles().keyBreakdown}>
|
|
427
|
-
<For each={liveReg().sequence}>
|
|
428
|
-
{(step, i) => (
|
|
429
|
-
<>
|
|
430
|
-
<Show when={i() > 0}>
|
|
431
|
-
<span class={styles().keyBreakdownPlus}>→</span>
|
|
432
|
-
</Show>
|
|
433
|
-
<span
|
|
434
|
-
class={clsx(
|
|
435
|
-
styles().keyCapLarge,
|
|
436
|
-
i() < matchedSteps() && styles().keyCapLargeInProgress,
|
|
437
|
-
)}
|
|
438
|
-
>
|
|
439
|
-
{formatForDisplay(step, {
|
|
440
|
-
platform: sequenceCanonicalPlatform(),
|
|
441
|
-
})}
|
|
442
|
-
</span>
|
|
443
|
-
</>
|
|
444
|
-
)}
|
|
445
|
-
</For>
|
|
446
|
-
</div>
|
|
447
|
-
|
|
448
|
-
<div class={styles().keyBreakdownSubHeader}>Each chord</div>
|
|
449
|
-
<For each={liveReg().sequence}>
|
|
450
|
-
{(step, stepIdx) => {
|
|
451
|
-
const stepParsed = () =>
|
|
452
|
-
parseHotkey(step, sequenceCanonicalPlatform())
|
|
453
|
-
const stepParts = () =>
|
|
454
|
-
formatForDisplay(stepParsed(), {
|
|
455
|
-
platform: sequenceCanonicalPlatform(),
|
|
456
|
-
parts: true,
|
|
457
|
-
})
|
|
458
|
-
return (
|
|
459
|
-
<div class={styles().sequenceChordDetail}>
|
|
460
|
-
<div class={styles().keyBreakdownSubHeader}>
|
|
461
|
-
Step {stepIdx() + 1} —{' '}
|
|
462
|
-
{stepParsed().code !== undefined ? 'Code' : 'Key'}
|
|
463
|
-
</div>
|
|
464
|
-
<div class={styles().keyBreakdownSplitRow}>
|
|
465
|
-
<div class={styles().keyBreakdownSplitLeft}>
|
|
466
|
-
<div class={styles().keyBreakdown}>
|
|
467
|
-
<For each={stepParts()}>
|
|
468
|
-
{(part, i) => (
|
|
469
|
-
<>
|
|
470
|
-
<Show when={i() > 0}>
|
|
471
|
-
<span class={styles().keyBreakdownPlus}>+</span>
|
|
472
|
-
</Show>
|
|
473
|
-
<span class={styles().keyCapLarge}>{part}</span>
|
|
474
|
-
</>
|
|
475
|
-
)}
|
|
476
|
-
</For>
|
|
477
|
-
</div>
|
|
478
|
-
</div>
|
|
479
|
-
<span
|
|
480
|
-
class={styles().keyBreakdownSplitArrow}
|
|
481
|
-
aria-hidden="true"
|
|
482
|
-
>
|
|
483
|
-
{'->'}
|
|
484
|
-
</span>
|
|
485
|
-
<div class={styles().keyBreakdownSplitRight}>
|
|
486
|
-
<KeyBreakdownPlatformTable
|
|
487
|
-
getParsed={stepParsed}
|
|
488
|
-
getCanonicalPlatform={() => sequenceCanonicalPlatform()}
|
|
489
|
-
styles={props.styles}
|
|
490
|
-
/>
|
|
491
|
-
</div>
|
|
492
|
-
</div>
|
|
493
|
-
</div>
|
|
494
|
-
)
|
|
495
|
-
}}
|
|
496
|
-
</For>
|
|
497
|
-
</div>
|
|
498
|
-
|
|
499
|
-
<div class={styles().detailSection}>
|
|
500
|
-
<div class={styles().detailSectionHeader}>Actions</div>
|
|
501
|
-
<ActionButtons registration={liveReg()} />
|
|
502
|
-
</div>
|
|
503
|
-
|
|
504
|
-
<div class={styles().detailSection}>
|
|
505
|
-
<div class={styles().detailSectionHeader}>Meta</div>
|
|
506
|
-
<div>
|
|
507
|
-
<div class={styles().optionRow}>
|
|
508
|
-
<span class={styles().optionLabel}>name</span>
|
|
509
|
-
<span class={styles().optionValue}>
|
|
510
|
-
{liveReg().options.meta?.name ?? '—'}
|
|
511
|
-
</span>
|
|
512
|
-
</div>
|
|
513
|
-
<div class={styles().optionRow}>
|
|
514
|
-
<span class={styles().optionLabel}>description</span>
|
|
515
|
-
<span class={styles().optionValue}>
|
|
516
|
-
{liveReg().options.meta?.description ?? '—'}
|
|
517
|
-
</span>
|
|
518
|
-
</div>
|
|
519
|
-
<Show
|
|
520
|
-
when={
|
|
521
|
-
liveReg().options.meta &&
|
|
522
|
-
Object.keys(liveReg().options.meta!).filter(
|
|
523
|
-
(k) => k !== 'name' && k !== 'description',
|
|
524
|
-
).length > 0
|
|
525
|
-
}
|
|
526
|
-
>
|
|
527
|
-
<For
|
|
528
|
-
each={Object.entries(liveReg().options.meta ?? {}).filter(
|
|
529
|
-
([k]) => k !== 'name' && k !== 'description',
|
|
530
|
-
)}
|
|
531
|
-
>
|
|
532
|
-
{([key, value]) => (
|
|
533
|
-
<div class={styles().optionRow}>
|
|
534
|
-
<span class={styles().optionLabel}>{key}</span>
|
|
535
|
-
<span class={styles().optionValue}>{String(value)}</span>
|
|
536
|
-
</div>
|
|
537
|
-
)}
|
|
538
|
-
</For>
|
|
539
|
-
</Show>
|
|
540
|
-
</div>
|
|
541
|
-
</div>
|
|
542
|
-
|
|
543
|
-
<div class={styles().detailSection}>
|
|
544
|
-
<div class={styles().detailSectionHeader}>Options</div>
|
|
545
|
-
<div>
|
|
546
|
-
<div class={styles().optionRow}>
|
|
547
|
-
<span class={styles().optionLabel}>enabled</span>
|
|
548
|
-
<span
|
|
549
|
-
class={
|
|
550
|
-
liveReg().options.enabled !== false
|
|
551
|
-
? styles().optionValueTrue
|
|
552
|
-
: styles().optionValueFalse
|
|
553
|
-
}
|
|
554
|
-
>
|
|
555
|
-
{String(liveReg().options.enabled !== false)}
|
|
556
|
-
</span>
|
|
557
|
-
</div>
|
|
558
|
-
<div class={styles().optionRow}>
|
|
559
|
-
<span class={styles().optionLabel}>eventType</span>
|
|
560
|
-
<span class={styles().optionValue}>
|
|
561
|
-
{liveReg().options.eventType ?? 'keydown'}
|
|
562
|
-
</span>
|
|
563
|
-
</div>
|
|
564
|
-
<div class={styles().optionRow}>
|
|
565
|
-
<span class={styles().optionLabel}>timeout</span>
|
|
566
|
-
<span class={styles().optionValue}>
|
|
567
|
-
{liveReg().options.timeout ?? 1000}ms
|
|
568
|
-
</span>
|
|
569
|
-
</div>
|
|
570
|
-
<div class={styles().optionRow}>
|
|
571
|
-
<span class={styles().optionLabel}>preventDefault</span>
|
|
572
|
-
<span
|
|
573
|
-
class={
|
|
574
|
-
liveReg().options.preventDefault
|
|
575
|
-
? styles().optionValueTrue
|
|
576
|
-
: styles().optionValueFalse
|
|
577
|
-
}
|
|
578
|
-
>
|
|
579
|
-
{String(!!liveReg().options.preventDefault)}
|
|
580
|
-
</span>
|
|
581
|
-
</div>
|
|
582
|
-
<div class={styles().optionRow}>
|
|
583
|
-
<span class={styles().optionLabel}>stopPropagation</span>
|
|
584
|
-
<span
|
|
585
|
-
class={
|
|
586
|
-
liveReg().options.stopPropagation
|
|
587
|
-
? styles().optionValueTrue
|
|
588
|
-
: styles().optionValueFalse
|
|
589
|
-
}
|
|
590
|
-
>
|
|
591
|
-
{String(!!liveReg().options.stopPropagation)}
|
|
592
|
-
</span>
|
|
593
|
-
</div>
|
|
594
|
-
<div class={styles().optionRow}>
|
|
595
|
-
<span class={styles().optionLabel}>ignoreInputs</span>
|
|
596
|
-
<span
|
|
597
|
-
class={
|
|
598
|
-
liveReg().options.ignoreInputs !== false
|
|
599
|
-
? styles().optionValueTrue
|
|
600
|
-
: styles().optionValueFalse
|
|
601
|
-
}
|
|
602
|
-
>
|
|
603
|
-
{String(liveReg().options.ignoreInputs !== false)}
|
|
604
|
-
</span>
|
|
605
|
-
</div>
|
|
606
|
-
<div class={styles().optionRow}>
|
|
607
|
-
<span class={styles().optionLabel}>conflictBehavior</span>
|
|
608
|
-
<span class={styles().optionValue}>{conflictBehavior()}</span>
|
|
609
|
-
</div>
|
|
610
|
-
</div>
|
|
611
|
-
</div>
|
|
612
|
-
|
|
613
|
-
<Show when={allConflicts().length > 0}>
|
|
614
|
-
<div class={styles().detailSection}>
|
|
615
|
-
<div class={styles().detailSectionHeader}>
|
|
616
|
-
Conflicts ({allConflicts().length})
|
|
617
|
-
</div>
|
|
618
|
-
<div class={styles().conflictList}>
|
|
619
|
-
<For each={targetConflicts()}>
|
|
620
|
-
{(conflict) => {
|
|
621
|
-
return (
|
|
622
|
-
<div class={styles().conflictItem}>
|
|
623
|
-
<span>overlap</span> {conflict.id}:{' '}
|
|
624
|
-
{formatRegistration(conflict)} (
|
|
625
|
-
{conflict.options.eventType ?? 'keydown'}) on{' '}
|
|
626
|
-
{props.getTargetDescription(conflict.target)}
|
|
627
|
-
</div>
|
|
628
|
-
)
|
|
629
|
-
}}
|
|
630
|
-
</For>
|
|
631
|
-
<For each={scopeConflicts()}>
|
|
632
|
-
{(conflict) => (
|
|
633
|
-
<div class={styles().conflictItemScope}>
|
|
634
|
-
<span>scope</span> {conflict.id}:{' '}
|
|
635
|
-
{formatRegistration(conflict)} (
|
|
636
|
-
{conflict.options.eventType ?? 'keydown'}) on{' '}
|
|
637
|
-
{props.getTargetDescription(conflict.target)}
|
|
638
|
-
</div>
|
|
639
|
-
)}
|
|
640
|
-
</For>
|
|
641
|
-
</div>
|
|
642
|
-
</div>
|
|
643
|
-
</Show>
|
|
644
|
-
</div>
|
|
645
|
-
</>
|
|
646
|
-
)
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
export function DetailsPanel(props: DetailsPanelProps) {
|
|
650
|
-
const styles = useStyles()
|
|
651
|
-
const state = useHotkeysDevtoolsState()
|
|
652
|
-
|
|
653
|
-
return (
|
|
654
|
-
<div class={styles().stateDetails}>
|
|
655
|
-
<Show
|
|
656
|
-
when={props.selectedRegistration()}
|
|
657
|
-
fallback={
|
|
658
|
-
<div class={styles().noSelection}>
|
|
659
|
-
Select a hotkey or sequence from the list to view its details
|
|
660
|
-
</div>
|
|
661
|
-
}
|
|
662
|
-
>
|
|
663
|
-
{(reg) => (
|
|
664
|
-
<Show
|
|
665
|
-
when={isSequenceRegistration(reg())}
|
|
666
|
-
fallback={
|
|
667
|
-
<HotkeyDetails
|
|
668
|
-
registration={reg() as HotkeyRegistration}
|
|
669
|
-
getTargetDescription={getTargetDescription}
|
|
670
|
-
styles={styles}
|
|
671
|
-
/>
|
|
672
|
-
}
|
|
673
|
-
>
|
|
674
|
-
<SequenceDetails
|
|
675
|
-
registration={reg() as SequenceRegistrationView}
|
|
676
|
-
state={state}
|
|
677
|
-
getTargetDescription={getTargetDescription}
|
|
678
|
-
styles={styles}
|
|
679
|
-
/>
|
|
680
|
-
</Show>
|
|
681
|
-
)}
|
|
682
|
-
</Show>
|
|
683
|
-
</div>
|
|
684
|
-
)
|
|
685
|
-
}
|