mirror of https://github.com/buster-so/buster.git
finalized pill api
This commit is contained in:
parent
c53b3749ba
commit
4ac600e4bb
|
@ -25,6 +25,8 @@ export const MentionExtension = (suggestions: MentionSuggestionExtension[]) =>
|
|||
label: '',
|
||||
value: '',
|
||||
trigger: '',
|
||||
pillLabel: '',
|
||||
doNotAddPipeOnSelect: false,
|
||||
} satisfies MentionPillAttributes;
|
||||
},
|
||||
addCommands() {
|
||||
|
|
|
@ -42,6 +42,17 @@ const looneyTunesCharacters: MentionInputTriggerItem[] = [
|
|||
value: 'Tweety Bird',
|
||||
label: 'Tweety Bird',
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
value: 'Taz',
|
||||
label: 'Taz',
|
||||
},
|
||||
{
|
||||
value: 'Sylvester',
|
||||
label: 'Sylvester',
|
||||
},
|
||||
];
|
||||
|
||||
const theSimpsonsCharacters: MentionInputTriggerItem[] = [
|
||||
|
@ -72,16 +83,16 @@ const theSimpsonsCharacters: MentionInputTriggerItem[] = [
|
|||
].map((item) => ({
|
||||
...item,
|
||||
label: (
|
||||
<span className="inline gap-x-1 space-x-1">
|
||||
<span className="gap-x-1 space-x-1">
|
||||
<img
|
||||
src={faker.image.url({
|
||||
width: 16,
|
||||
height: 16,
|
||||
})}
|
||||
alt=""
|
||||
className="w-3 h-3 rounded-full bg-item-active inline align-middle"
|
||||
className="w-3 h-3 rounded-full bg-item-active inline-block align-middle"
|
||||
/>
|
||||
<span>{item.label}</span>
|
||||
<span className="inline-block">{item.label}</span>
|
||||
</span>
|
||||
),
|
||||
}));
|
||||
|
@ -101,13 +112,14 @@ const arthurCharacters: MentionInputTriggerItem[] = [
|
|||
},
|
||||
].map((item) => ({
|
||||
...item,
|
||||
pillLabel: item.label,
|
||||
label: (
|
||||
<span className="flex flex-col justify-between space-y-2 min-w-72 py-2">
|
||||
<span className="flex flex-col justify-between space-y-2 py-2 overflow-hidden">
|
||||
<h3 className="font-semibold text-gray-900 text-base leading-tight">{item.label}</h3>
|
||||
<div className="flex flex-col space-y-2">
|
||||
<div className="flex items-center text-sm text-gray-600">
|
||||
<span className="w-16 text-gray-500 font-medium">Address:</span>
|
||||
<span>
|
||||
<div className="flex items-center text-sm text-gray-600 overflow-hidden">
|
||||
<span className="w-16 text-gray-500 font-medium truncate">Address:</span>
|
||||
<span className="truncate">
|
||||
{faker.location.streetAddress()}, {faker.location.city()}
|
||||
</span>
|
||||
</div>
|
||||
|
@ -168,9 +180,124 @@ const arthurSuggestions = createMentionSuggestionExtension({
|
|||
},
|
||||
});
|
||||
|
||||
const spongebobCharacters: MentionInputTriggerItem[] = [
|
||||
{
|
||||
type: 'group',
|
||||
items: [
|
||||
{
|
||||
value: 'SpongeBob SquarePants',
|
||||
label: 'SpongeBob SquarePants',
|
||||
},
|
||||
{
|
||||
value: 'Patrick Star',
|
||||
label: 'Patrick Star',
|
||||
},
|
||||
{
|
||||
value: 'Squidward Tentacles',
|
||||
label: 'Squidward Tentacles',
|
||||
},
|
||||
{
|
||||
value: 'Mr. Krabs',
|
||||
label: 'Mr. Krabs',
|
||||
},
|
||||
],
|
||||
label: 'SpongeBob SquarePants Characters',
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
items: [
|
||||
{
|
||||
value: 'Courage the Cowardly Dog',
|
||||
label: 'Courage the Cowardly Dog',
|
||||
},
|
||||
{
|
||||
value: 'Muriel Bagge',
|
||||
label: 'Muriel Bagge',
|
||||
},
|
||||
{
|
||||
value: 'Shaggy',
|
||||
label: 'Shaggy',
|
||||
},
|
||||
{
|
||||
value: 'Snake',
|
||||
label: 'Snake',
|
||||
},
|
||||
],
|
||||
label: 'Courage the Cowardly Dog Characters',
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
label: 'Foster`s Home',
|
||||
items: [
|
||||
{
|
||||
value: 'Bloo',
|
||||
label: 'Bloo',
|
||||
},
|
||||
{
|
||||
value: 'Mac',
|
||||
label: 'Mac',
|
||||
},
|
||||
{
|
||||
value: 'Wilt',
|
||||
label: 'Wilt',
|
||||
},
|
||||
{
|
||||
value: 'Eduardo',
|
||||
label: 'Eduardo',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
type: 'group',
|
||||
label: 'Scooby-Doo Characters',
|
||||
items: [
|
||||
{
|
||||
value: 'Scooby-Doo',
|
||||
label: 'Scooby-Doo',
|
||||
},
|
||||
{
|
||||
value: 'Shaggy',
|
||||
label: 'Shaggy',
|
||||
},
|
||||
{
|
||||
value: 'Velma',
|
||||
label: 'Velma',
|
||||
},
|
||||
{
|
||||
value: 'Daphne',
|
||||
label: 'Daphne',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const spongebobSuggestions = createMentionSuggestionExtension({
|
||||
trigger: '%',
|
||||
items: spongebobCharacters,
|
||||
pillStyling: {
|
||||
className: () => {
|
||||
return 'bg-yellow-100 border-yellow-300 text-yellow-500 hover:bg-yellow-200';
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
mentions: [looneyTunesSuggestions, theSimpsonsSuggestions, arthurSuggestions],
|
||||
mentions: [
|
||||
looneyTunesSuggestions,
|
||||
theSimpsonsSuggestions,
|
||||
arthurSuggestions,
|
||||
spongebobSuggestions,
|
||||
],
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import type { SuggestionProps } from '@tiptap/suggestion';
|
||||
import React, { useEffect, useImperativeHandle, useState } from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type {
|
||||
MentionInputTriggerItem,
|
||||
MentionOnSelectParams,
|
||||
|
@ -19,10 +20,10 @@ export interface MentionListImperativeHandle {
|
|||
export type MentionListProps<T = string> = SuggestionProps<
|
||||
MentionInputTriggerItem<T>,
|
||||
MentionTriggerItem<T> & { trigger: string }
|
||||
> & { trigger: string; emptyState?: React.ReactNode };
|
||||
> & { trigger: string; emptyState?: React.ReactNode; className?: string };
|
||||
|
||||
function MentionListInner<T = string>(
|
||||
{ trigger, emptyState, items, command }: MentionListProps<T>,
|
||||
{ trigger, emptyState, items, command, className }: MentionListProps<T>,
|
||||
ref: React.ForwardedRef<MentionListImperativeHandle>
|
||||
) {
|
||||
const [selectedItem, setSelectedItem] = useState<T | undefined>(undefined);
|
||||
|
@ -97,7 +98,13 @@ function MentionListInner<T = string>(
|
|||
}));
|
||||
|
||||
return (
|
||||
<div className="flex flex-col p-1 bg-background rounded border w-full min-w-[200px] max-w-[280px] overflow-hidden">
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col p-1 bg-background rounded border w-full min-w-[200px] max-w-[280px] overflow-x-auto',
|
||||
'max-h-[300px] overflow-y-auto',
|
||||
className
|
||||
)}
|
||||
>
|
||||
{items.length ? (
|
||||
items.map((item, index: number) => (
|
||||
<MentionListSelector<T>
|
||||
|
|
|
@ -4,16 +4,16 @@ import { Popover } from '@/components/ui/popover';
|
|||
import { cn } from '@/lib/utils';
|
||||
import type { MentionTriggerItem } from './MentionInput.types';
|
||||
|
||||
export type MentionPillAttributes<T = string> = Pick<
|
||||
MentionTriggerItem<T>,
|
||||
'label' | 'value' | 'doNotAddPipeOnSelect'
|
||||
export type MentionPillAttributes<T = string> = Required<
|
||||
Pick<MentionTriggerItem<T>, 'label' | 'value' | 'doNotAddPipeOnSelect' | 'pillLabel'>
|
||||
> & { trigger: string };
|
||||
|
||||
export const MentionPill = <T extends string>({
|
||||
node,
|
||||
editor,
|
||||
}: ReactNodeViewProps<MentionTriggerItem<T>>) => {
|
||||
const { trigger, label, value } = node.attrs as MentionPillAttributes;
|
||||
const { trigger, label, value, pillLabel } = node.attrs as MentionPillAttributes;
|
||||
console.log('node', node);
|
||||
const pillStyling = editor.storage.mention.pillStylingByTrigger.get(trigger);
|
||||
const pillClassName =
|
||||
typeof pillStyling?.className === 'function'
|
||||
|
@ -36,7 +36,7 @@ export const MentionPill = <T extends string>({
|
|||
)}
|
||||
style={pillStyle}
|
||||
>
|
||||
{label}
|
||||
{pillLabel || label}
|
||||
</span>
|
||||
</PopoverWrapper>
|
||||
</NodeViewWrapper>
|
||||
|
|
Loading…
Reference in New Issue