mirror of https://github.com/buster-so/buster.git
set empty state
This commit is contained in:
parent
e6531430f5
commit
109e2f6398
|
@ -0,0 +1,6 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { MentionInputSuggestions } from '@/components/ui/inputs/MentionInputSuggestions';
|
||||||
|
|
||||||
|
export const BusterChatInput = () => {
|
||||||
|
return <div>BusterChatInput</div>;
|
||||||
|
};
|
|
@ -45,8 +45,9 @@ export const MentionInputSuggestions = ({
|
||||||
}: MentionInputSuggestionsProps) => {
|
}: MentionInputSuggestionsProps) => {
|
||||||
const [hasClickedSelect, setHasClickedSelect] = useState(false);
|
const [hasClickedSelect, setHasClickedSelect] = useState(false);
|
||||||
const [value, setValue] = useState(valueProp ?? defaultValue);
|
const [value, setValue] = useState(valueProp ?? defaultValue);
|
||||||
const commandListNavigatedRef = useRef(false);
|
const [hasResults, setHasResults] = useState(false);
|
||||||
|
|
||||||
|
const commandListNavigatedRef = useRef(false);
|
||||||
const commandRef = useRef<HTMLDivElement>(null);
|
const commandRef = useRef<HTMLDivElement>(null);
|
||||||
const mentionsInputRef = useRef<MentionInputRef>(null);
|
const mentionsInputRef = useRef<MentionInputRef>(null);
|
||||||
|
|
||||||
|
@ -83,6 +84,7 @@ export const MentionInputSuggestions = ({
|
||||||
onClick?.();
|
onClick?.();
|
||||||
if (closeSuggestionOnSelect) setHasClickedSelect(true);
|
if (closeSuggestionOnSelect) setHasClickedSelect(true);
|
||||||
onSuggestionItemClick?.(params);
|
onSuggestionItemClick?.(params);
|
||||||
|
setHasResults(false);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -135,6 +137,8 @@ export const MentionInputSuggestions = ({
|
||||||
value={value}
|
value={value}
|
||||||
label={ariaLabel}
|
label={ariaLabel}
|
||||||
className={cn('relative border rounded overflow-hidden bg-background shadow', className)}
|
className={cn('relative border rounded overflow-hidden bg-background shadow', className)}
|
||||||
|
shouldFilter={shouldFilter}
|
||||||
|
filter={filter}
|
||||||
>
|
>
|
||||||
<MentionInputSuggestionsContainer className={inputContainerClassName}>
|
<MentionInputSuggestionsContainer className={inputContainerClassName}>
|
||||||
<MentionInputSuggestionsMentionsInput
|
<MentionInputSuggestionsMentionsInput
|
||||||
|
@ -146,27 +150,30 @@ export const MentionInputSuggestions = ({
|
||||||
mentions={mentions}
|
mentions={mentions}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={onChangeInputValue}
|
onChange={onChangeInputValue}
|
||||||
shouldFilter={shouldFilter}
|
|
||||||
filter={filter}
|
|
||||||
onMentionItemClick={onMentionItemClick}
|
onMentionItemClick={onMentionItemClick}
|
||||||
onPressEnter={onPressEnter || onSubmit}
|
onPressEnter={onPressEnter || onSubmit}
|
||||||
commandListNavigatedRef={commandListNavigatedRef}
|
commandListNavigatedRef={commandListNavigatedRef}
|
||||||
/>
|
/>
|
||||||
{children}
|
{children}
|
||||||
</MentionInputSuggestionsContainer>
|
</MentionInputSuggestionsContainer>
|
||||||
|
{hasResults && <div className="border-b mb-1.5" />}
|
||||||
<MentionInputSuggestionsList
|
<MentionInputSuggestionsList
|
||||||
show={showSuggestionList}
|
show={showSuggestionList}
|
||||||
className={suggestionsContainerClassName}
|
className={cn(suggestionsContainerClassName, hasResults && 'pb-1.5')}
|
||||||
>
|
>
|
||||||
<MentionInputSuggestionsItemsSelector
|
<MentionInputSuggestionsItemsSelector
|
||||||
suggestionItems={suggestionItems}
|
suggestionItems={suggestionItems}
|
||||||
onSelect={onSelectItem}
|
onSelect={onSelectItem}
|
||||||
addValueToInput={addSuggestionValueToInput}
|
addValueToInput={addSuggestionValueToInput}
|
||||||
closeOnSelect={closeSuggestionOnSelect}
|
closeOnSelect={closeSuggestionOnSelect}
|
||||||
|
hasResults={hasResults}
|
||||||
|
setHasResults={setHasResults}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<MentionInputSuggestionsEmpty
|
||||||
|
setHasResults={setHasResults}
|
||||||
|
emptyComponent={emptyComponent}
|
||||||
/>
|
/>
|
||||||
{emptyComponent && (
|
|
||||||
<MentionInputSuggestionsEmpty>{emptyComponent}</MentionInputSuggestionsEmpty>
|
|
||||||
)}
|
|
||||||
</MentionInputSuggestionsList>
|
</MentionInputSuggestionsList>
|
||||||
</Command>
|
</Command>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,17 +1,35 @@
|
||||||
import { Command } from 'cmdk';
|
import { Command } from 'cmdk';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
|
import { useMount } from '@/hooks/useMount';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
export const MentionInputSuggestionsEmpty = ({
|
export const MentionInputSuggestionsEmpty = ({
|
||||||
children,
|
emptyComponent,
|
||||||
...props
|
setHasResults,
|
||||||
}: React.ComponentPropsWithoutRef<typeof Command.Empty>) => {
|
className,
|
||||||
|
}: {
|
||||||
|
setHasResults: (hasResults: boolean) => void;
|
||||||
|
className?: string;
|
||||||
|
emptyComponent: React.ReactNode;
|
||||||
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Command.Empty
|
<Command.Empty
|
||||||
className={cn('text-gray-light py-6 text-center text-base', props.className)}
|
className={cn(
|
||||||
{...props}
|
'text-gray-light py-6 text-center text-base',
|
||||||
|
!emptyComponent && 'hidden',
|
||||||
|
className
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
{children}
|
{emptyComponent}
|
||||||
|
<SetHasResults setHasResults={setHasResults} />
|
||||||
</Command.Empty>
|
</Command.Empty>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SetHasResults = ({ setHasResults }: { setHasResults: (hasResults: boolean) => void }) => {
|
||||||
|
useMount(() => {
|
||||||
|
setHasResults(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
import { Command } from 'cmdk';
|
import { Command } from 'cmdk';
|
||||||
import type React from 'react';
|
import type React from 'react';
|
||||||
|
import { useMount } from '@/hooks/useMount';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
import type { MentionInputSuggestionsDropdownItem, MentionInputSuggestionsOnSelectParams } from './MentionInputSuggestions.types';
|
import type {
|
||||||
|
MentionInputSuggestionsDropdownItem,
|
||||||
|
MentionInputSuggestionsOnSelectParams,
|
||||||
|
} from './MentionInputSuggestions.types';
|
||||||
|
|
||||||
export type MentionInputSuggestionsItemProps = {
|
export type MentionInputSuggestionsItemProps = {
|
||||||
onSelect: (d: MentionInputSuggestionsOnSelectParams) => void;
|
onSelect: (d: MentionInputSuggestionsOnSelectParams) => void;
|
||||||
} & MentionInputSuggestionsDropdownItem & {
|
} & MentionInputSuggestionsDropdownItem & {
|
||||||
className?: string;
|
className?: string;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
|
hasResults: boolean;
|
||||||
|
setHasResults: (hasResults: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MentionInputSuggestionsItem = ({
|
export const MentionInputSuggestionsItem = ({
|
||||||
|
@ -23,6 +29,8 @@ export const MentionInputSuggestionsItem = ({
|
||||||
type,
|
type,
|
||||||
addValueToInput,
|
addValueToInput,
|
||||||
onSelect,
|
onSelect,
|
||||||
|
hasResults,
|
||||||
|
setHasResults,
|
||||||
...props
|
...props
|
||||||
}: MentionInputSuggestionsItemProps) => {
|
}: MentionInputSuggestionsItemProps) => {
|
||||||
return (
|
return (
|
||||||
|
@ -47,6 +55,21 @@ export const MentionInputSuggestionsItem = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
|
{!hasResults && <SetHasResults hasResults={hasResults} setHasResults={setHasResults} />}
|
||||||
</Command.Item>
|
</Command.Item>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SetHasResults = ({
|
||||||
|
hasResults,
|
||||||
|
setHasResults,
|
||||||
|
}: {
|
||||||
|
hasResults: boolean;
|
||||||
|
setHasResults: (hasResults: boolean) => void;
|
||||||
|
}) => {
|
||||||
|
useMount(() => {
|
||||||
|
if (!hasResults) setHasResults(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import type {
|
import type {
|
||||||
MentionInputSuggestionsProps,
|
|
||||||
MentionInputSuggestionsOnSelectParams,
|
|
||||||
GroupOverrideProps,
|
GroupOverrideProps,
|
||||||
|
MentionInputSuggestionsOnSelectParams,
|
||||||
|
MentionInputSuggestionsProps,
|
||||||
} from './MentionInputSuggestions.types';
|
} from './MentionInputSuggestions.types';
|
||||||
import { MentionInputSuggestionsGroup } from './MentionInputSuggestionsGroup';
|
import { MentionInputSuggestionsGroup } from './MentionInputSuggestionsGroup';
|
||||||
import { MentionInputSuggestionsItem } from './MentionInputSuggestionsItem';
|
import { MentionInputSuggestionsItem } from './MentionInputSuggestionsItem';
|
||||||
|
@ -12,16 +12,19 @@ export const MentionInputSuggestionsItemSelector = ({
|
||||||
onSelect,
|
onSelect,
|
||||||
addValueToInput,
|
addValueToInput,
|
||||||
closeOnSelect,
|
closeOnSelect,
|
||||||
|
...rest
|
||||||
}: {
|
}: {
|
||||||
item: MentionInputSuggestionsProps['suggestionItems'][number];
|
item: MentionInputSuggestionsProps['suggestionItems'][number];
|
||||||
onSelect: (params: MentionInputSuggestionsOnSelectParams) => void;
|
onSelect: (params: MentionInputSuggestionsOnSelectParams) => void;
|
||||||
|
hasResults: boolean;
|
||||||
|
setHasResults: (hasResults: boolean) => void;
|
||||||
} & GroupOverrideProps) => {
|
} & GroupOverrideProps) => {
|
||||||
if (item.type === 'separator') {
|
if (item.type === 'separator') {
|
||||||
return <MentionInputSuggestionsSeparator />;
|
return <MentionInputSuggestionsSeparator />;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.type === 'group') {
|
if (item.type === 'group') {
|
||||||
return <MentionInputSuggestionsGroup {...item} onSelect={onSelect} />;
|
return <MentionInputSuggestionsGroup {...item} onSelect={onSelect} {...rest} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -30,28 +33,23 @@ export const MentionInputSuggestionsItemSelector = ({
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
addValueToInput={item?.addValueToInput ?? addValueToInput}
|
addValueToInput={item?.addValueToInput ?? addValueToInput}
|
||||||
closeOnSelect={item?.closeOnSelect ?? closeOnSelect}
|
closeOnSelect={item?.closeOnSelect ?? closeOnSelect}
|
||||||
|
{...rest}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const MentionInputSuggestionsItemsSelector = ({
|
export const MentionInputSuggestionsItemsSelector = ({
|
||||||
suggestionItems,
|
suggestionItems,
|
||||||
onSelect,
|
...rest
|
||||||
addValueToInput,
|
|
||||||
closeOnSelect,
|
|
||||||
}: {
|
}: {
|
||||||
suggestionItems: MentionInputSuggestionsProps['suggestionItems'];
|
suggestionItems: MentionInputSuggestionsProps['suggestionItems'];
|
||||||
onSelect: (params: MentionInputSuggestionsOnSelectParams) => void;
|
onSelect: (params: MentionInputSuggestionsOnSelectParams) => void;
|
||||||
|
hasResults: boolean;
|
||||||
|
setHasResults: (hasResults: boolean) => void;
|
||||||
} & GroupOverrideProps) => {
|
} & GroupOverrideProps) => {
|
||||||
if (!suggestionItems) return null;
|
if (!suggestionItems) return null;
|
||||||
return suggestionItems.map((item, index) => (
|
return suggestionItems.map((item, index) => (
|
||||||
<MentionInputSuggestionsItemSelector
|
<MentionInputSuggestionsItemSelector key={keySelector(item, index)} item={item} {...rest} />
|
||||||
key={keySelector(item, index)}
|
|
||||||
item={item}
|
|
||||||
onSelect={onSelect}
|
|
||||||
addValueToInput={addValueToInput}
|
|
||||||
closeOnSelect={closeOnSelect}
|
|
||||||
/>
|
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,9 @@ export const MentionInputSuggestionsList = ({
|
||||||
show = true,
|
show = true,
|
||||||
}: MentionInputSuggestionsListProps) => {
|
}: MentionInputSuggestionsListProps) => {
|
||||||
if (!show) return null;
|
if (!show) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Command.List className={cn('border-t px-3 py-1.5', className)} style={style}>
|
<Command.List className={cn('px-3', className)} style={style}>
|
||||||
{children}
|
{children}
|
||||||
</Command.List>
|
</Command.List>
|
||||||
);
|
);
|
||||||
|
|
|
@ -6,13 +6,7 @@ import type { MentionInputSuggestionsProps } from './MentionInputSuggestions.typ
|
||||||
|
|
||||||
export type MentionInputSuggestionsMentionsInputProps = Pick<
|
export type MentionInputSuggestionsMentionsInputProps = Pick<
|
||||||
MentionInputSuggestionsProps,
|
MentionInputSuggestionsProps,
|
||||||
| 'mentions'
|
'mentions' | 'value' | 'placeholder' | 'defaultValue' | 'onMentionItemClick'
|
||||||
| 'value'
|
|
||||||
| 'placeholder'
|
|
||||||
| 'defaultValue'
|
|
||||||
| 'shouldFilter'
|
|
||||||
| 'filter'
|
|
||||||
| 'onMentionItemClick'
|
|
||||||
> & {
|
> & {
|
||||||
onChange: MentionInputProps['onChange'];
|
onChange: MentionInputProps['onChange'];
|
||||||
onPressEnter: MentionInputProps['onPressEnter'];
|
onPressEnter: MentionInputProps['onPressEnter'];
|
||||||
|
@ -26,10 +20,11 @@ export type MentionInputSuggestionsMentionsInputProps = Pick<
|
||||||
export const MentionInputSuggestionsMentionsInput = forwardRef<
|
export const MentionInputSuggestionsMentionsInput = forwardRef<
|
||||||
MentionInputRef,
|
MentionInputRef,
|
||||||
MentionInputSuggestionsMentionsInputProps
|
MentionInputSuggestionsMentionsInputProps
|
||||||
>(({ value: valueProp, placeholder, defaultValue, mentions, value, ...props }, ref) => {
|
>(({ mentions, ...props }, ref) => {
|
||||||
|
const { value } = props;
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<MentionInput ref={ref} mentions={mentions} defaultValue={value} {...props} />
|
<MentionInput ref={ref} mentions={mentions} {...props} />
|
||||||
<Command.Input
|
<Command.Input
|
||||||
value={value}
|
value={value}
|
||||||
autoFocus={false}
|
autoFocus={false}
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './MentionInputSuggestions';
|
Loading…
Reference in New Issue