mirror of https://github.com/buster-so/buster.git
globall key press
This commit is contained in:
parent
fd2e61808c
commit
7787a72061
|
@ -33,7 +33,6 @@ export const MentionInputSuggestionsMentionsInput = forwardRef<
|
|||
autoFocus={false}
|
||||
disabled={props.disabled}
|
||||
className="sr-only hidden h-0 border-0 p-0 pointer-events-none w-full"
|
||||
// className="absolute -top-1 left-0 w-full h-full border border-red-500"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</React.Fragment>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Command } from 'cmdk';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { createContext, useContextSelector } from 'use-context-selector';
|
||||
import { SearchEmptyState } from './SearchEmptyState';
|
||||
import { SearchFooter } from './SearchFooter';
|
||||
import { SearchInput } from './SearchInput';
|
||||
import { SearchModalContentItems } from './SearchModalContentItems';
|
||||
import type { SearchModalContentProps } from './search-modal.types';
|
||||
import type { SearchItem, SearchModalContentProps } from './search-modal.types';
|
||||
import { useViewSearchItem } from './useViewSearchItem';
|
||||
|
||||
export const SearchModalContent = <M, T extends string>({
|
||||
|
@ -26,18 +27,40 @@ export const SearchModalContent = <M, T extends string>({
|
|||
onViewSearchItem,
|
||||
});
|
||||
const [searchValue, setSearchValue] = useState<string>(defaulSearchValue);
|
||||
const isCommandKeyPressedRef = useRef(false);
|
||||
|
||||
const onSearchChangePreflight = (searchValue: string) => {
|
||||
setSearchValue(searchValue);
|
||||
onSearchChange(searchValue);
|
||||
};
|
||||
|
||||
const handleKeyDownGlobal = (e: React.KeyboardEvent) => {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
isCommandKeyPressedRef.current = true;
|
||||
}
|
||||
handleKeyDown(e);
|
||||
};
|
||||
|
||||
const handleKeyUpGlobal = (e: React.KeyboardEvent) => {
|
||||
if (!e.metaKey && !e.ctrlKey) {
|
||||
isCommandKeyPressedRef.current = false;
|
||||
}
|
||||
};
|
||||
|
||||
const onSelectGlobal = (item: SearchItem<M, T>) => {
|
||||
if (item?.onSelect) {
|
||||
item.onSelect();
|
||||
}
|
||||
onSelect(item, isCommandKeyPressedRef.current ? 'navigate' : 'select');
|
||||
};
|
||||
|
||||
return (
|
||||
<Command
|
||||
className="min-w-[650px] min-h-[450px] max-h-[75vh] bg-background flex flex-col"
|
||||
value={focusedValue}
|
||||
onValueChange={setFocusedValue}
|
||||
onKeyDown={handleKeyDown}
|
||||
onKeyDown={handleKeyDownGlobal}
|
||||
onKeyUp={handleKeyUpGlobal}
|
||||
>
|
||||
<SearchInput
|
||||
searchValue={searchValue}
|
||||
|
@ -48,7 +71,7 @@ export const SearchModalContent = <M, T extends string>({
|
|||
<div className="border-b" />
|
||||
<SearchModalContentItems
|
||||
searchItems={searchItems}
|
||||
onSelect={onSelect}
|
||||
onSelectGlobal={onSelectGlobal}
|
||||
onViewSearchItem={onViewSearchItem}
|
||||
/>
|
||||
<SearchEmptyState emptyState={emptyState} />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Command } from 'cmdk';
|
||||
import { Command, useCommandState } from 'cmdk';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type {
|
||||
SearchItem,
|
||||
|
@ -8,15 +8,24 @@ import type {
|
|||
SearchModalContentProps,
|
||||
} from './search-modal.types';
|
||||
|
||||
type CommonProps<M, T extends string> = {
|
||||
onSelectGlobal: (d: SearchItem<M, T>) => void;
|
||||
};
|
||||
|
||||
export const SearchModalContentItems = <M, T extends string>({
|
||||
searchItems,
|
||||
onSelect,
|
||||
onViewSearchItem,
|
||||
}: Pick<SearchModalContentProps<M, T>, 'searchItems' | 'onSelect' | 'onViewSearchItem'>) => {
|
||||
onSelectGlobal,
|
||||
}: Pick<SearchModalContentProps<M, T>, 'searchItems' | 'onViewSearchItem'> & CommonProps<M, T>) => {
|
||||
const hasResults = useCommandState((x) => x.filtered.count) > 0;
|
||||
|
||||
return (
|
||||
<Command.List className="flex flex-col overflow-y-auto flex-1">
|
||||
<Command.List className={cn('flex flex-col overflow-y-auto flex-1', !hasResults && 'hidden')}>
|
||||
{searchItems.map((item, index) => (
|
||||
<ItemsSelecter key={keyExtractor(item, index)} item={item} />
|
||||
<ItemsSelecter
|
||||
key={keyExtractor(item, index)}
|
||||
item={item}
|
||||
onSelectGlobal={onSelectGlobal}
|
||||
/>
|
||||
))}
|
||||
</Command.List>
|
||||
);
|
||||
|
@ -29,14 +38,20 @@ const keyExtractor = <M, T extends string>(item: SearchItems<M, T>, index: numbe
|
|||
return item.type + index;
|
||||
};
|
||||
|
||||
const ItemsSelecter = <M, T extends string>({ item }: { item: SearchItems<M, T> }) => {
|
||||
const ItemsSelecter = <M, T extends string>({
|
||||
item,
|
||||
onSelectGlobal,
|
||||
}: {
|
||||
item: SearchItems<M, T>;
|
||||
onSelectGlobal: (d: SearchItem<M, T>) => void;
|
||||
}) => {
|
||||
const type = item.type;
|
||||
if (type === 'item') {
|
||||
return <SearchItemComponent {...item} />;
|
||||
return <SearchItemComponent {...item} onSelectGlobal={onSelectGlobal} />;
|
||||
}
|
||||
|
||||
if (type === 'group') {
|
||||
return <SearchItemGroupComponent item={item} />;
|
||||
return <SearchItemGroupComponent item={item} onSelectGlobal={onSelectGlobal} />;
|
||||
}
|
||||
|
||||
if (type === 'seperator') {
|
||||
|
@ -48,16 +63,8 @@ const ItemsSelecter = <M, T extends string>({ item }: { item: SearchItems<M, T>
|
|||
return null;
|
||||
};
|
||||
|
||||
const SearchItemComponent = <M, T extends string>({
|
||||
value,
|
||||
label,
|
||||
secondaryLabel,
|
||||
tertiaryLabel,
|
||||
icon,
|
||||
onSelect,
|
||||
loading,
|
||||
disabled,
|
||||
}: SearchItem<M, T>) => {
|
||||
const SearchItemComponent = <M, T extends string>(item: SearchItem<M, T> & CommonProps<M, T>) => {
|
||||
const { value, label, secondaryLabel, tertiaryLabel, icon, disabled, onSelectGlobal } = item;
|
||||
return (
|
||||
<Command.Item
|
||||
className={cn(
|
||||
|
@ -68,10 +75,7 @@ const SearchItemComponent = <M, T extends string>({
|
|||
)}
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
onSelect={() => {
|
||||
console.log('onSelect', value);
|
||||
onSelect?.();
|
||||
}}
|
||||
onSelect={() => onSelectGlobal(item)}
|
||||
>
|
||||
{label}
|
||||
</Command.Item>
|
||||
|
@ -80,18 +84,24 @@ const SearchItemComponent = <M, T extends string>({
|
|||
|
||||
const SearchItemGroupComponent = <M, T extends string>({
|
||||
item,
|
||||
onSelectGlobal,
|
||||
}: {
|
||||
item: SearchItemGroup<M, T>;
|
||||
onSelectGlobal: (d: SearchItem<M, T>) => void;
|
||||
}) => {
|
||||
return (
|
||||
<Command.Group>
|
||||
{item.items.map((item, index) => (
|
||||
<ItemsSelecter key={keyExtractor(item, index)} item={item} />
|
||||
<ItemsSelecter
|
||||
key={keyExtractor(item, index)}
|
||||
item={item}
|
||||
onSelectGlobal={onSelectGlobal}
|
||||
/>
|
||||
))}
|
||||
</Command.Group>
|
||||
);
|
||||
};
|
||||
|
||||
const SearchItemSeperatorComponent = ({ item }: { item: SearchItemSeperator }) => {
|
||||
const SearchItemSeperatorComponent = ({ item: _item }: { item: SearchItemSeperator }) => {
|
||||
return <Command.Separator className="border-t w-full" />;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue