Skip to content

Commit bb9b707

Browse files
Merge pull request #16 from xiaoluoboding/feat/update-search
fix: fixed the bug #14
2 parents 59c0e81 + f26308f commit bb9b707

File tree

9 files changed

+62
-44
lines changed

9 files changed

+62
-44
lines changed

packages/CommandDialog.vue

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,14 @@ const emit = defineEmits<{
4848
(e: 'select-item', item: ItemInfo): void
4949
}>()
5050
51-
const { search, filtered } = useCommandState()
51+
const { resetStore } = useCommandState()
5252
const { emitter } = useCommandEvent()
5353
const dialogRef = ref<HTMLDivElement>()
5454
5555
emitter.on('selectItem', (item) => {
5656
emit('select-item', item)
5757
})
5858
59-
const resetStore = () => {
60-
// reset the command state
61-
search.value = ''
62-
filtered.value.count = 0
63-
filtered.value.items = new Map()
64-
filtered.value.groups = new Set()
65-
}
66-
6759
whenever(() => props.visible, resetStore)
6860
6961
onBeforeUnmount(resetStore)

packages/CommandList.vue

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<div command-list="" role="listbox" aria-label="Suggestions" ref="listRef">
3-
<div command-list-sizer ref="heightRef">
3+
<div command-list-sizer="" ref="heightRef">
44
<slot />
55
</div>
66
</div>
@@ -34,12 +34,11 @@ let sizer: HTMLDivElement | undefined
3434
watchEffect(() => {
3535
sizer = heightRef.value
3636
const wrapper = listRef.value
37-
37+
let animationFrame: any
3838
if (sizer && wrapper) {
3939
observer = new ResizeObserver((entries) => {
40-
nextTick(() => {
40+
animationFrame = requestAnimationFrame(() => {
4141
const height = sizer?.offsetHeight
42-
4342
wrapper?.style.setProperty(
4443
'--command-list-height',
4544
`${height?.toFixed(1)}px`
@@ -48,6 +47,11 @@ watchEffect(() => {
4847
})
4948
})
5049
observer.observe(sizer)
50+
51+
return () => {
52+
cancelAnimationFrame(animationFrame)
53+
observer?.unobserve(sizer!)
54+
}
5155
}
5256
})
5357

packages/CommandRoot.vue

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const emit = defineEmits<{
6060
}>()
6161
6262
provide('theme', props.theme || 'default')
63-
const { selectedNode, search, dataValue, filtered } = useCommandState()
63+
const { selectedNode, search, filtered } = useCommandState()
6464
const { emitter } = useCommandEvent()
6565
6666
const commandRef = ref<HTMLDivElement>()
@@ -110,6 +110,20 @@ const getSelectedItem = () => {
110110
return commandRef.value?.querySelector(SELECTED_ITEM_SELECTOR)
111111
}
112112
113+
const getAllGroups = () => {
114+
const allGroupEl = commandRef.value?.querySelectorAll(
115+
GROUP_SELECTOR
116+
) as NodeListOf<HTMLElement>
117+
return allGroupEl ? Array.from(allGroupEl) : []
118+
}
119+
120+
const getAllItems = (rootNode: HTMLElement | undefined = commandRef.value) => {
121+
const allItemEl = rootNode?.querySelectorAll(
122+
ITEM_SELECTOR
123+
) as NodeListOf<HTMLElement>
124+
return allItemEl ? Array.from(allItemEl) : []
125+
}
126+
113127
const getValidItems = (
114128
rootNode: HTMLElement | undefined = commandRef.value
115129
) => {
@@ -119,13 +133,6 @@ const getValidItems = (
119133
return allItemEl ? Array.from(allItemEl) : []
120134
}
121135
122-
const getValidGroups = () => {
123-
const allGroupEl = commandRef.value?.querySelectorAll(
124-
GROUP_SELECTOR
125-
) as NodeListOf<HTMLElement>
126-
return allGroupEl ? Array.from(allGroupEl) : []
127-
}
128-
129136
const selectedFirstItem = () => {
130137
const [firstItem] = getValidItems()
131138
if (firstItem && firstItem.getAttribute(ITEM_KEY_SELECTOR)) {
@@ -279,7 +286,7 @@ const filterItems = () => {
279286
}
280287
281288
// Reset the groups
282-
filtered.value.groups = new Set('')
289+
filtered.value.groups = new Set()
283290
284291
const items = new Map()
285292
@@ -299,15 +306,13 @@ const filterItems = () => {
299306
}
300307
}
301308
302-
nextTick(() => {
303-
filtered.value.count = items.size
304-
filtered.value.items = items
305-
})
309+
filtered.value.count = items.size
310+
filtered.value.items = items
306311
}
307312
308313
const initStore = () => {
309-
const items = getValidItems()
310-
const groups = getValidGroups()
314+
const groups = getAllGroups()
315+
const items = getAllItems()
311316
312317
for (const item of items) {
313318
const itemKey = item.getAttribute(ITEM_KEY_SELECTOR) || ''
@@ -319,7 +324,7 @@ const initStore = () => {
319324
320325
// map the items in group
321326
for (const group of groups) {
322-
const itemsInGroup = getValidItems(group)
327+
const itemsInGroup = getAllItems(group)
323328
const groupId = group.getAttribute(GROUP_KEY_SELECTOR) || ''
324329
const itemIds = new Set('')
325330
@@ -343,12 +348,13 @@ watch(
343348
},
344349
{ deep: true }
345350
)
351+
346352
/**
347353
* when search's value is changed, trigger filter action
348354
*/
349355
watch(
350356
() => search.value,
351-
(newVal) => {
357+
() => {
352358
filterItems()
353359
nextTick(selectedFirstItem)
354360
}
@@ -361,14 +367,17 @@ emitter.on('selectItem', (item) => {
361367
const debouncedEmit = useDebounceFn((isRerender: Boolean) => {
362368
if (isRerender) {
363369
initStore()
364-
nextTick(selectedFirstItem)
370+
nextTick(() => {
371+
filterItems()
372+
selectedFirstItem()
373+
})
365374
}
366375
}, 100)
367376
368377
emitter.on('rerenderList', debouncedEmit)
369378
370379
onMounted(() => {
371380
initStore()
372-
selectedFirstItem()
381+
nextTick(selectedFirstItem)
373382
})
374383
</script>

packages/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,4 @@ const Command = Object.assign(Root, {
9393
readonly Separator: typeof Separator
9494
}
9595

96-
export { Command }
96+
export { Command, useCommandState }

packages/useCommandState.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,38 @@ type State = {
1212
selectedGroup: string
1313
// Input State
1414
search: string
15-
dataValue: string
1615
filtered: FilteredItem
1716
}
1817

1918
const state = reactive<State>({
2019
selectedNode: '',
2120
selectedGroup: '',
21+
/** Value of the search query. */
2222
search: '',
23-
dataValue: '',
2423
filtered: {
24+
/** The count of all visible items. */
2525
count: 0,
26+
/** Map from visible item id. */
2627
items: new Map(),
28+
/** Set of groups with at least one visible item. */
2729
groups: new Set()
2830
}
2931
})
3032

3133
const useCommandState = () => {
3234
const isSearching = computed(() => state.search !== '')
35+
36+
const resetStore = () => {
37+
// reset the command state
38+
state.search = ''
39+
state.filtered.count = 0
40+
state.filtered.items = new Map()
41+
state.filtered.groups = new Set()
42+
}
43+
3344
return {
3445
isSearching,
46+
resetStore,
3547
...toRefs(state)
3648
}
3749
}

src/App.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</div>
99
<div class="flex-center gap-4">
1010
<button
11-
class="opacity-50 hover:opacity-100 transition"
11+
class="bg-transparent opacity-50 hover:opacity-100 transition"
1212
@click="(e) => toggleDarkmode()"
1313
>
1414
<MoonIcon class="w-6 h-6" v-if="isDark" />

src/components/command/Self.vue

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,15 +143,14 @@
143143
import { ref, computed } from 'vue'
144144
import { useMagicKeys, whenever, onClickOutside } from '@vueuse/core'
145145
146-
import { Command } from '@/index'
146+
import { Command, useCommandState } from '@/index'
147147
import { isDark, toggleDarkmode } from '~/composables/useDarkmode'
148148
import RaycastIcon from '~/components/icons/RaycastIcon.vue'
149149
import LinearIcon from '~/components/icons/LinearIcon.vue'
150150
import VercelIcon from '~/components/icons/VercelIcon.vue'
151151
import SunIcon from '~/components/icons/SunIcon.vue'
152152
import MoonIcon from '~/components/icons/MoonIcon.vue'
153153
import Logo from '~/components/icons/Logo.vue'
154-
import { ItemInfo } from '@/types'
155154
156155
defineProps<{
157156
visible: boolean
@@ -196,6 +195,7 @@ const inputValue = ref('')
196195
const isHomePage = computed(() => activePage.value === 'home')
197196
198197
const { current } = useMagicKeys()
198+
const { search } = useCommandState()
199199
200200
const togglePage = () => {
201201
activePage.value = 'home'
@@ -220,6 +220,7 @@ whenever(
220220
221221
const handleSelectTheme = (item: any) => {
222222
activePage.value = item.value
223+
search.value = ''
223224
emit('select', item.value)
224225
}
225226
onClickOutside(el, (e: Event) => {

src/components/command/vercel/Projects.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
<template>
2-
<div>
3-
<Item v-for="n in 6" :data-value="`Project ${n}`">
4-
{{ `Project ${n}` }}
5-
</Item>
6-
</div>
2+
<Item v-for="n in 6" :data-value="`Project ${n}`">
3+
{{ `Project ${n}` }}
4+
</Item>
75
</template>
86

97
<script lang="ts" setup>

src/components/command/vercel/Vercel.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@ import { ref, computed } from 'vue'
3434
import { useMagicKeys, whenever } from '@vueuse/core'
3535
3636
import { toggleDarkmode } from '~/composables/useDarkmode'
37-
import { Command } from '@/index'
37+
import { Command, useCommandState } from '@/index'
3838
import { ItemInfo } from '@/types'
3939
4040
import Home from './Home.vue'
4141
import Projects from './Projects.vue'
4242
4343
const { current } = useMagicKeys()
44+
const { search } = useCommandState()
4445
4546
const activePage = ref('home')
4647
const inputValue = ref('')
@@ -63,6 +64,7 @@ const pageTree = computed(() => {
6364
6465
const togglePage = () => {
6566
activePage.value = isHomePage.value ? 'projects' : 'home'
67+
search.value = ''
6668
}
6769
6870
const handleKeyDown = () => {

0 commit comments

Comments
 (0)