Skip to content

Commit 996b95d

Browse files
committed
feat: prompt slot
1 parent 15e8356 commit 996b95d

File tree

3 files changed

+59
-48
lines changed

3 files changed

+59
-48
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,19 @@ and `title` property have no effect. Example:
224224
</vue-command>
225225
```
226226

227+
### Prompt
228+
229+
You can overwrite the prompt with the prompt slot. If you use this slot,
230+
`hidePrompt` and `prompt` property have no effect. Example:
231+
232+
```vue
233+
<vue-command>
234+
<template #prompt>
235+
~$
236+
</template>
237+
</vue-command>
238+
```
239+
227240
## Library
228241

229242
Library provides helper methods to render terminal related content.
@@ -292,6 +305,7 @@ import { listFormatter } from "vue-command";
292305
| `setQuery` | `Function` | `query` |
293306
| `showHelp` | `Boolean` | |
294307
| `signals` | `Object` | |
308+
| `slots` | `Object` | |
295309
| `terminal` | `Object` | |
296310

297311
Provider can be injected into your component by name:
@@ -349,6 +363,9 @@ to subscribe to the signal.
349363
signals.off("SIGINT", sigint);
350364
```
351365

366+
The libraries query component makes usage of that and allows to cancel a query
367+
with `SIGIN`.
368+
352369
## Nice-to-haves
353370

354371
These features didn't make it into the last release. If you would like to

src/components/VueCommand.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ import {
104104
computed,
105105
onMounted,
106106
nextTick,
107-
getCurrentInstance
107+
getCurrentInstance,
108+
useSlots
108109
} from 'vue'
109110
import {
110111
createCommandNotFound,
@@ -132,6 +133,8 @@ import {
132133
lt
133134
} from 'lodash'
134135
136+
const slots = useSlots()
137+
135138
const props = defineProps({
136139
commands: {
137140
default: () => ({}),
@@ -526,17 +529,17 @@ provide('helpText', props.helpText)
526529
provide('helpTimeout', props.helpTimeout)
527530
provide('hidePrompt', props.hidePrompt)
528531
provide('incrementHistory', incrementHistory)
529-
provide('invert', props.invert)
530532
provide('optionsResolver', props.optionsResolver)
531533
provide('parser', props.parser)
532534
provide('programs', programs)
533535
provide('sendSignal', sendSignal)
534536
provide('setCursorPosition', setCursorPosition)
535537
provide('setFullscreen', setFullscreen)
536538
provide('setHistoryPosition', setHistoryPosition)
539+
provide('setQuery', setQuery)
537540
provide('showHelp', props.showHelp)
538541
provide('signals', signals)
539-
provide('setQuery', setQuery)
542+
provide('slots', slots)
540543
provide('terminal', terminal)
541544
542545
defineExpose({

src/components/VueCommandQuery.vue

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,16 @@
33
<!-- Query -->
44
<div
55
v-show="shouldShowQuery"
6-
:class="{
7-
'vue-command__query': !invert,
8-
'vue-command__query--invert': invert
9-
}">
10-
<span
11-
v-if="!hidePrompt"
12-
:class="{
13-
'vue-command__query__prompt': !invert,
14-
'vue-command__query__prompt--invert': invert
15-
}">
16-
{{ local.prompt }}
17-
</span>
18-
19-
<!-- TODO Make textarea to enforce word break -->
6+
class="vue-command__query">
7+
<!-- Prompt -->
8+
<VueCommandPrompt />
9+
10+
<!-- Query -->
11+
<!-- TODO Convert to textarea to enforce word breaks -->
2012
<input
2113
ref="queryRef"
2214
v-model="local.query"
23-
:class="{
24-
'vue-command__query__input': !invert,
25-
'vue-command__query__input--invert': invert
26-
}"
15+
class="vue-command__query__input"
2716
:disabled="isOutdatedQuery"
2817
:placeholder="placeholder"
2918
autocapitalize="none"
@@ -43,21 +32,12 @@
4332
v-for="(multilineQuery, index) in multilineQueries"
4433
v-show="isBeforeReverseISearch(index)"
4534
:key="index"
46-
:class="{
47-
'vue-command__multiline-query': !invert,
48-
'vue-command__multiline-query--invert': invert
49-
}">
35+
class="vue-command__multiline-query">
5036
<span
51-
:class="{
52-
'vue-command__multiline-query__prompt': !invert,
53-
'vue-command__multiline-query__prompt--invert': invert
54-
}">></span>
37+
class="vue-command__multiline-query__prompt">></span>
5538
<input
5639
ref="multilineQueryRefs"
57-
:class="{
58-
'vue-command__multiline-query__input': !invert,
59-
'vue-command__multiline-query__input--invert': invert
60-
}"
40+
class="vue-command__multiline-query__input"
6141
:disabled="isOutdatedMultilineQuery(index)"
6242
:value="multilineQuery"
6343
autocapitalize="none"
@@ -75,21 +55,12 @@
7555
<!-- Reverse I search -->
7656
<div
7757
v-if="isReverseISearch"
78-
:class="{
79-
'vue-command__reverse-i-search': !invert,
80-
'vue-command__reverse-i-search--invert': invert
81-
}">
58+
class="vue-command__reverse-i-search">
8259
<span
83-
:class="{
84-
'vue-command__reverse-i-search-status': !invert,
85-
'vue-command__reverse-i-search-status--invert': invert
86-
}">({{ reverseISearchStatus }})`</span><input
60+
class="vue-command__reverse-i-search-status">({{ reverseISearchStatus }})`</span><input
8761
ref="reverseISearchRef"
8862
v-model="reverseISearch"
89-
:class="{
90-
'vue-command__reverse-i-search__input': !invert,
91-
'vue-command__reverse-i-search__input--invert': invert
92-
}"
63+
class="vue-command__reverse-i-search__input"
9364
:disabled="isOutdated"
9465
autocapitalize="none"
9566
autocorrect="off"
@@ -116,7 +87,9 @@ import {
11687
onBeforeUnmount,
11788
reactive,
11889
nextTick,
119-
computed
90+
computed,
91+
Fragment,
92+
h
12093
} from 'vue'
12194
import {
12295
and,
@@ -140,13 +113,13 @@ import {
140113
set,
141114
trimStart,
142115
lt,
143-
join
116+
join,
117+
isUndefined
144118
} from 'lodash'
145119
146120
const appendToHistory = inject('appendToHistory')
147121
const dispatch = inject('dispatch')
148122
const hidePrompt = inject('hidePrompt')
149-
const invert = inject('invert')
150123
const helpText = inject('helpText')
151124
const helpTimeout = inject('helpTimeout')
152125
const optionsResolver = inject('optionsResolver')
@@ -156,6 +129,7 @@ const setCursorPosition = inject('setCursorPosition')
156129
const setQuery = inject('setQuery')
157130
const showHelp = inject('showHelp')
158131
const signals = inject('signals')
132+
const slots = inject('slots')
159133
const terminal = inject('terminal')
160134
161135
// Indicates if the query, including multiline queries and reverse I search, is
@@ -169,6 +143,23 @@ const reverseISearchRef = ref(null)
169143
const reverseISearchStatus = ref('reverse-i-search')
170144
const queryRef = ref(null)
171145
146+
// Prompt slot with fallback
147+
const VueCommandPrompt = computed(() => {
148+
if (hidePrompt) {
149+
return h(Fragment)
150+
}
151+
152+
// Render prompt slot if given
153+
if (!isUndefined(slots.prompt)) {
154+
return h(Fragment, slots.prompt())
155+
}
156+
157+
// Show default prompt slot
158+
return h(Fragment, h('span', {
159+
class: 'vue-command__query__prompt'
160+
}, terminal.value.prompt))
161+
})
162+
172163
const local = reactive({
173164
prompt: terminal.value.prompt,
174165
query: ''

0 commit comments

Comments
 (0)