Added basic inbox view
This commit is contained in:
parent
8cbdecfc7f
commit
6530cd535e
@ -6,7 +6,7 @@ import NiceModal from '@ebay/nice-modal-react';
|
|||||||
import React, {useState} from 'react';
|
import React, {useState} from 'react';
|
||||||
import {Activity} from './activities/ActivityItem';
|
import {Activity} from './activities/ActivityItem';
|
||||||
import {ActorProperties, ObjectProperties} from '@tryghost/admin-x-framework/api/activitypub';
|
import {ActorProperties, ObjectProperties} from '@tryghost/admin-x-framework/api/activitypub';
|
||||||
import {Button, Heading} from '@tryghost/admin-x-design-system';
|
import {Button, Heading, Select, SelectOption, Tooltip} from '@tryghost/admin-x-design-system';
|
||||||
import {useBrowseInboxForUser} from '../MainContent';
|
import {useBrowseInboxForUser} from '../MainContent';
|
||||||
|
|
||||||
interface InboxProps {}
|
interface InboxProps {}
|
||||||
@ -15,6 +15,7 @@ const Inbox: React.FC<InboxProps> = ({}) => {
|
|||||||
const {data: activities = []} = useBrowseInboxForUser('index');
|
const {data: activities = []} = useBrowseInboxForUser('index');
|
||||||
const [, setArticleContent] = useState<ObjectProperties | null>(null);
|
const [, setArticleContent] = useState<ObjectProperties | null>(null);
|
||||||
const [, setArticleActor] = useState<ActorProperties | null>(null);
|
const [, setArticleActor] = useState<ActorProperties | null>(null);
|
||||||
|
const [layout, setLayout] = useState('inbox');
|
||||||
|
|
||||||
const inboxTabActivities = activities.filter((activity: Activity) => {
|
const inboxTabActivities = activities.filter((activity: Activity) => {
|
||||||
const isCreate = activity.type === 'Create' && ['Article', 'Note'].includes(activity.object.type);
|
const isCreate = activity.type === 'Create' && ['Article', 'Note'].includes(activity.object.type);
|
||||||
@ -32,13 +33,47 @@ const Inbox: React.FC<InboxProps> = ({}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const selectOptions: SelectOption[] = [
|
||||||
|
{value: 'option-1', label: 'Home'},
|
||||||
|
{value: 'option-2', label: 'Posts'},
|
||||||
|
{value: 'option-3', label: 'Notes'},
|
||||||
|
{value: 'option-4', label: 'Media'}
|
||||||
|
];
|
||||||
|
|
||||||
|
const defaultValue: SelectOption = {
|
||||||
|
value: 'option-1', label: 'Home'
|
||||||
|
};
|
||||||
|
|
||||||
|
const controlClasses = {
|
||||||
|
control: '!bg-transparent !hidden mr-2 !pl-0 text-xl font-bold',
|
||||||
|
menu: '!min-w-[120px]'
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MainNavigation />
|
<MainNavigation />
|
||||||
|
<div className='mx-auto mt-4 flex w-full max-w-[640px] items-center justify-between border-b border-grey-200 pb-4'>
|
||||||
|
<div>
|
||||||
|
<Select controlClasses={controlClasses} defaultValue={defaultValue} options={selectOptions} unstyled onSelect={() => {}} />
|
||||||
|
<h2 className='text-xl font-bold'>Home</h2>
|
||||||
|
</div>
|
||||||
|
<div className=''>
|
||||||
|
<Tooltip content="Inbox">
|
||||||
|
<Button className='!px-2' icon='listview' iconColorClass={layout === 'inbox' ? 'text-black' : 'text-grey-400'} size='sm' onClick={() => {
|
||||||
|
setLayout('inbox');
|
||||||
|
}} />
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip content="Feed">
|
||||||
|
<Button className='!px-2' icon='cardview' iconColorClass={layout === 'feed' ? 'text-black' : 'text-grey-400'} size='sm' onClick={() => {
|
||||||
|
setLayout('feed');
|
||||||
|
}} />
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className='z-0 flex w-full flex-col'>
|
<div className='z-0 flex w-full flex-col'>
|
||||||
<div className='w-full'>
|
<div className='w-full'>
|
||||||
{inboxTabActivities.length > 0 ? (
|
{inboxTabActivities.length > 0 ? (
|
||||||
<ul className='mx-auto flex max-w-[560px] flex-col py-8'>
|
<ul className='mx-auto flex max-w-[640px] flex-col'>
|
||||||
{inboxTabActivities.reverse().map(activity => (
|
{inboxTabActivities.reverse().map(activity => (
|
||||||
<li
|
<li
|
||||||
key={activity.id}
|
key={activity.id}
|
||||||
@ -47,7 +82,7 @@ const Inbox: React.FC<InboxProps> = ({}) => {
|
|||||||
>
|
>
|
||||||
<FeedItem
|
<FeedItem
|
||||||
actor={activity.actor}
|
actor={activity.actor}
|
||||||
layout='feed'
|
layout={layout}
|
||||||
object={activity.object}
|
object={activity.object}
|
||||||
type={activity.type}
|
type={activity.type}
|
||||||
/>
|
/>
|
||||||
|
@ -5,7 +5,7 @@ import getUsername from '../../utils/get-username';
|
|||||||
import {ActorProperties, ObjectProperties} from '@tryghost/admin-x-framework/api/activitypub';
|
import {ActorProperties, ObjectProperties} from '@tryghost/admin-x-framework/api/activitypub';
|
||||||
import {Button, Heading, Icon} from '@tryghost/admin-x-design-system';
|
import {Button, Heading, Icon} from '@tryghost/admin-x-design-system';
|
||||||
|
|
||||||
export function renderAttachment(object: ObjectProperties, layout: string) {
|
export function renderFeedAttachment(object: ObjectProperties, layout: string) {
|
||||||
let attachment;
|
let attachment;
|
||||||
if (object.image) {
|
if (object.image) {
|
||||||
attachment = object.image;
|
attachment = object.image;
|
||||||
@ -61,6 +61,71 @@ export function renderAttachment(object: ObjectProperties, layout: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderInboxAttachment(object: ObjectProperties) {
|
||||||
|
let attachment;
|
||||||
|
if (object.image) {
|
||||||
|
attachment = object.image;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object.type === 'Note' && !attachment) {
|
||||||
|
attachment = object.attachment;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attachment) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(attachment)) {
|
||||||
|
const attachmentCount = attachment.length;
|
||||||
|
// let gridClass = '';
|
||||||
|
// if (attachmentCount === 2) {
|
||||||
|
// gridClass = 'grid-cols-2 auto-rows-[150px]'; // Two images, side by side
|
||||||
|
// } else if (attachmentCount === 3 || attachmentCount === 4) {
|
||||||
|
// gridClass = 'grid-cols-2 auto-rows-[150px]'; // Three or four images, two per row
|
||||||
|
// }
|
||||||
|
return (
|
||||||
|
<div className='min-w-[160px]'>
|
||||||
|
<div className='relative'>
|
||||||
|
<img className={`h-[100px] w-[160px] rounded-md object-cover`} src={attachment[0].url} />
|
||||||
|
<div className='absolute bottom-1 right-1 z-10 rounded-full border border-[rgba(255,255,255,0.25)] bg-black px-2 py-0.5 font-semibold text-white'>+ {attachmentCount - 1}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (attachment.mediaType) {
|
||||||
|
case 'image/jpeg':
|
||||||
|
case 'image/png':
|
||||||
|
case 'image/gif':
|
||||||
|
return (
|
||||||
|
<div className='min-w-[160px]'>
|
||||||
|
<img className={`h-[100px] w-[160px] rounded-md object-cover`} src={attachment.url} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case 'video/mp4':
|
||||||
|
case 'video/webm':
|
||||||
|
return (
|
||||||
|
<div className='min-w-[160px]'>
|
||||||
|
<div className='relative mb-4 mt-2'>
|
||||||
|
<video className='h-[300px] w-full rounded object-cover' src={attachment.url} controls/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
case 'audio/mpeg':
|
||||||
|
case 'audio/ogg':
|
||||||
|
return (
|
||||||
|
<div className='min-w-[160px]'>
|
||||||
|
<div className='relative mb-4 mt-2 w-full'>
|
||||||
|
<audio className='w-full' src={attachment.url} controls/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
interface FeedItemProps {
|
interface FeedItemProps {
|
||||||
actor: ActorProperties;
|
actor: ActorProperties;
|
||||||
object: ObjectProperties;
|
object: ObjectProperties;
|
||||||
@ -89,47 +154,117 @@ const FeedItem: React.FC<FeedItemProps> = ({actor, object, layout, type}) => {
|
|||||||
author = typeof object.attributedTo === 'object' ? object.attributedTo as ActorProperties : actor;
|
author = typeof object.attributedTo === 'object' ? object.attributedTo as ActorProperties : actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
if (layout === 'feed') {
|
||||||
<>
|
return (
|
||||||
{object && (
|
<>
|
||||||
<div className={`group/article relative cursor-pointer ${(layout === 'feed') ? 'pt-5' : ''}`}>
|
{object && (
|
||||||
{(type === 'Announce' && object.type === 'Note') && <div className='z-10 mb-2 flex items-center gap-3 text-grey-700'>
|
<div className={`group/article relative cursor-pointer pt-5`}>
|
||||||
<div className='z-10 flex w-10 justify-end'><Icon colorClass='text-grey-700' name='reload' size={'sm'}></Icon></div>
|
{(type === 'Announce' && object.type === 'Note') && <div className='z-10 mb-2 flex items-center gap-3 text-grey-700'>
|
||||||
<span className='z-10'>{actor.name} reposted</span>
|
<div className='z-10 flex w-10 justify-end'><Icon colorClass='text-grey-700' name='reload' size={'sm'}></Icon></div>
|
||||||
</div>}
|
<span className='z-10'>{actor.name} reposted</span>
|
||||||
<div className={`border-1 z-10 -my-1 grid grid-cols-[auto_1fr] grid-rows-[auto_1fr] gap-x-3 ${(layout === 'modal') ? 'gap-y-2' : 'gap-y-1'} border-b border-b-grey-200 pb-4`} data-test-activity>
|
</div>}
|
||||||
<div className='relative z-10 pt-[3px]'>
|
<div className={`border-1 z-10 -my-1 grid grid-cols-[auto_1fr] grid-rows-[auto_1fr] gap-x-3 gap-y-2 border-b border-b-grey-200 pb-4`} data-test-activity>
|
||||||
<APAvatar author={author}/>
|
<div className='relative z-10 pt-[3px]'>
|
||||||
</div>
|
<APAvatar author={author}/>
|
||||||
{/* <div className='border-1 z-10 -mt-1 flex w-full flex-col items-start justify-between border-b border-b-grey-200 pb-4' data-test-activity> */}
|
|
||||||
<div className='relative z-10 flex w-full flex-col overflow-visible text-[1.5rem]'>
|
|
||||||
<div className='flex'>
|
|
||||||
<span className='truncate whitespace-nowrap font-bold' data-test-activity-heading>{author.name}</span>
|
|
||||||
<span className='whitespace-nowrap text-grey-700 before:mx-1 before:content-["·"]' title={`${timestamp}`}>{getRelativeTimestamp(date)}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className='flex'>
|
{/* <div className='border-1 z-10 -mt-1 flex w-full flex-col items-start justify-between border-b border-b-grey-200 pb-4' data-test-activity> */}
|
||||||
<span className='truncate text-grey-700'>{getUsername(author)}</span>
|
<div className='relative z-10 flex w-full flex-col overflow-visible text-[1.5rem]'>
|
||||||
|
<div className='flex'>
|
||||||
|
<span className='truncate whitespace-nowrap font-bold' data-test-activity-heading>{author.name}</span>
|
||||||
|
<span className='whitespace-nowrap text-grey-700 before:mx-1 before:content-["·"]' title={`${timestamp}`}>{getRelativeTimestamp(date)}</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex'>
|
||||||
|
<span className='truncate text-grey-700'>{getUsername(author)}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className={`relative z-10 col-start-2 col-end-3 w-full gap-4`}>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
{object.name && <Heading className='mb-1 leading-tight' level={4} data-test-activity-heading>{object.name}</Heading>}
|
||||||
|
<div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content text-pretty text-[1.5rem] text-grey-900'></div>
|
||||||
|
{renderFeedAttachment(object, layout)}
|
||||||
|
<div className='mt-3 flex gap-2'>
|
||||||
|
<Button className={`self-start text-grey-500 transition-all hover:text-grey-800 ${isClicked ? 'bump' : ''} ${isLiked ? 'ap-red-heart text-red *:!fill-red hover:text-red' : ''}`} hideLabel={true} icon='heart' id='like' size='md' unstyled={true} onClick={handleLikeClick}/>
|
||||||
|
<span className={`text-grey-800 ${isLiked ? 'opacity-100' : 'opacity-0'}`}>1</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* </div> */}
|
||||||
</div>
|
</div>
|
||||||
<div className={`relative z-10 ${(layout === 'modal') ? 'col-start-1' : 'col-start-2'} col-end-3 w-full gap-4`}>
|
<div className={`absolute -inset-x-3 -inset-y-0 z-0 rounded transition-colors ${(layout === 'feed') ? 'group-hover/article:bg-grey-75' : ''} `}></div>
|
||||||
<div className='flex flex-col'>
|
</div>
|
||||||
{object.name && <Heading className='mb-1 leading-tight' level={4} data-test-activity-heading>{object.name}</Heading>}
|
)}
|
||||||
<div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content text-pretty text-[1.5rem] text-grey-900'></div>
|
</>
|
||||||
{/* <p className='text-pretty text-md text-grey-900'>{object.content}</p> */}
|
);
|
||||||
{renderAttachment(object, layout)}
|
} else if (layout === 'modal') {
|
||||||
<div className='mt-3 flex gap-2'>
|
return (
|
||||||
<Button className={`self-start text-grey-500 transition-all hover:text-grey-800 ${isClicked ? 'bump' : ''} ${isLiked ? 'ap-red-heart text-red *:!fill-red hover:text-red' : ''}`} hideLabel={true} icon='heart' id='like' size='md' unstyled={true} onClick={handleLikeClick}/>
|
<>
|
||||||
<span className={`text-grey-800 ${isLiked ? 'opacity-100' : 'opacity-0'}`}>1</span>
|
{object && (
|
||||||
|
<div className={`group/article relative cursor-pointer`}>
|
||||||
|
{(type === 'Announce' && object.type === 'Note') && <div className='z-10 mb-2 flex items-center gap-3 text-grey-700'>
|
||||||
|
<div className='z-10 flex w-10 justify-end'><Icon colorClass='text-grey-700' name='reload' size={'sm'}></Icon></div>
|
||||||
|
<span className='z-10'>{actor.name} reposted</span>
|
||||||
|
</div>}
|
||||||
|
<div className={`border-1 z-10 -my-1 grid grid-cols-[auto_1fr] grid-rows-[auto_1fr] gap-x-3 gap-y-2 border-b border-b-grey-200 pb-4`} data-test-activity>
|
||||||
|
<div className='relative z-10 pt-[3px]'>
|
||||||
|
<APAvatar author={author}/>
|
||||||
|
</div>
|
||||||
|
{/* <div className='border-1 z-10 -mt-1 flex w-full flex-col items-start justify-between border-b border-b-grey-200 pb-4' data-test-activity> */}
|
||||||
|
<div className='relative z-10 flex w-full flex-col overflow-visible text-[1.5rem]'>
|
||||||
|
<div className='flex'>
|
||||||
|
<span className='truncate whitespace-nowrap font-bold' data-test-activity-heading>{author.name}</span>
|
||||||
|
<span className='whitespace-nowrap text-grey-700 before:mx-1 before:content-["·"]' title={`${timestamp}`}>{getRelativeTimestamp(date)}</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex'>
|
||||||
|
<span className='truncate text-grey-700'>{getUsername(author)}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={`relative z-10 col-start-1 col-end-3 w-full gap-4`}>
|
||||||
|
<div className='flex flex-col'>
|
||||||
|
{object.name && <Heading className='mb-1 leading-tight' level={4} data-test-activity-heading>{object.name}</Heading>}
|
||||||
|
<div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content text-pretty text-[1.5rem] text-grey-900'></div>
|
||||||
|
{renderFeedAttachment(object, layout)}
|
||||||
|
<div className='mt-3 flex gap-2'>
|
||||||
|
<Button className={`self-start text-grey-500 transition-all hover:text-grey-800 ${isClicked ? 'bump' : ''} ${isLiked ? 'ap-red-heart text-red *:!fill-red hover:text-red' : ''}`} hideLabel={true} icon='heart' id='like' size='md' unstyled={true} onClick={handleLikeClick}/>
|
||||||
|
<span className={`text-grey-800 ${isLiked ? 'opacity-100' : 'opacity-0'}`}>1</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/* </div> */}
|
||||||
|
</div>
|
||||||
|
<div className={`absolute -inset-x-3 -inset-y-0 z-0 rounded transition-colors`}></div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if (layout === 'inbox') {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{object && (
|
||||||
|
<div className='group/article relative -mx-4 -mt-px cursor-pointer rounded-md px-4 hover:bg-grey-75'>
|
||||||
|
<div className='z-10 flex items-start gap-3 border-b border-grey-200 py-4 group-hover/article:border-transparent'>
|
||||||
|
<APAvatar author={author} size='xs'/>
|
||||||
|
<div className='z-10 w-full'>
|
||||||
|
<div className='mb-1'>
|
||||||
|
<span className='truncate whitespace-nowrap font-semibold' data-test-activity-heading>{author.name}</span>
|
||||||
|
<span className='truncate text-grey-700'> {getUsername(author)}</span>
|
||||||
|
<span className='whitespace-nowrap text-grey-700 before:mx-1 before:content-["·"]' title={`${timestamp}`}>{getRelativeTimestamp(date)}</span>
|
||||||
|
</div>
|
||||||
|
<div className='flex w-full items-start justify-between gap-5'>
|
||||||
|
<div className='grow'>
|
||||||
|
{object.name && <Heading className='leading-tight' level={5} data-test-activity-heading>{object.name}</Heading>}
|
||||||
|
<div dangerouslySetInnerHTML={({__html: object.content})} className='ap-note-content mt-1 line-clamp-3 text-pretty text-[1.5rem] text-grey-900'></div>
|
||||||
|
</div>
|
||||||
|
{renderInboxAttachment(object)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* </div> */}
|
|
||||||
</div>
|
</div>
|
||||||
<div className={`absolute -inset-x-3 -inset-y-0 z-0 rounded transition-colors ${(layout === 'feed') ? 'group-hover/article:bg-grey-75' : ''} `}></div>
|
)}
|
||||||
</div>
|
</>
|
||||||
)}
|
);
|
||||||
</>
|
}
|
||||||
);
|
|
||||||
|
return (<></>);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FeedItem;
|
export default FeedItem;
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import {ActorProperties} from '@tryghost/admin-x-framework/api/activitypub';
|
import {ActorProperties} from '@tryghost/admin-x-framework/api/activitypub';
|
||||||
import {Icon} from '@tryghost/admin-x-design-system';
|
import {Icon} from '@tryghost/admin-x-design-system';
|
||||||
|
|
||||||
type AvatarSize = 'sm' | 'lg';
|
type AvatarSize = 'xs' | 'sm' | 'lg';
|
||||||
|
|
||||||
interface APAvatarProps {
|
interface APAvatarProps {
|
||||||
author?: ActorProperties;
|
author?: ActorProperties;
|
||||||
@ -10,23 +10,30 @@ interface APAvatarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const APAvatar: React.FC<APAvatarProps> = ({author, size}) => {
|
const APAvatar: React.FC<APAvatarProps> = ({author, size}) => {
|
||||||
let avatarSize = '';
|
let iconSize = 18;
|
||||||
|
let containerClass = '';
|
||||||
|
let imageClass = 'z-10 rounded w-10 h-10';
|
||||||
|
|
||||||
switch (size) {
|
switch (size) {
|
||||||
|
case 'xs':
|
||||||
|
iconSize = 12;
|
||||||
|
containerClass = 'z-10 rounded bg-grey-100 flex items-center justify-center p-[3px] w-6 h-6';
|
||||||
|
imageClass = 'z-10 rounded w-6 h-6';
|
||||||
|
break;
|
||||||
case 'sm':
|
case 'sm':
|
||||||
avatarSize = ' w-10 h-10 ';
|
containerClass = 'z-10 rounded bg-grey-100 flex items-center justify-center p-[10px] w-10 h-10';
|
||||||
break;
|
break;
|
||||||
case 'lg':
|
case 'lg':
|
||||||
avatarSize = ' w-22 h-22 ';
|
containerClass = 'z-10 rounded bg-grey-100 flex items-center justify-center p-[10px] w-22 h-22';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
avatarSize = ' w-10 h-10 ';
|
containerClass = 'z-10 rounded bg-grey-100 flex items-center justify-center p-[10px] w-10 h-10';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{author && author!.icon?.url ? <img className={`z-10 ${avatarSize} rounded`} src={author!.icon?.url}/> : <div className={`z-10 rounded bg-grey-100 ${avatarSize} flex items-center justify-center p-[10px]`}><Icon colorClass='text-grey-600' name='user' size={18} /></div>}
|
{author && author!.icon?.url ? <img className={imageClass} src={author!.icon?.url}/> : <div className={containerClass}><Icon colorClass='text-grey-600' name='user' size={iconSize} /></div>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -18,7 +18,7 @@ const Tooltip: React.FC<TooltipProps> = ({content, size = 'sm', children, contai
|
|||||||
);
|
);
|
||||||
|
|
||||||
tooltipClassName = clsx(
|
tooltipClassName = clsx(
|
||||||
'select-none rounded-sm bg-black px-2 py-0.5 leading-normal text-white will-change-[transform,opacity]',
|
'z-[9999] select-none rounded-sm bg-black px-2 py-0.5 leading-normal text-white will-change-[transform,opacity]',
|
||||||
size === 'sm' && 'text-xs',
|
size === 'sm' && 'text-xs',
|
||||||
size === 'md' && 'text-sm'
|
size === 'md' && 'text-sm'
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user