Refactor StatusActionButton
This commit is contained in:
parent
82130a1612
commit
bd98842434
6 changed files with 174 additions and 195 deletions
|
@ -223,12 +223,12 @@ const RouterDropdownMenu = withRouter(DropdownMenu);
|
||||||
|
|
||||||
export interface IDropdown extends RouteComponentProps {
|
export interface IDropdown extends RouteComponentProps {
|
||||||
icon?: string,
|
icon?: string,
|
||||||
src: string,
|
src?: string,
|
||||||
items: Menu,
|
items: Menu,
|
||||||
size?: number,
|
size?: number,
|
||||||
active?: boolean,
|
active?: boolean,
|
||||||
pressed?: boolean,
|
pressed?: boolean,
|
||||||
title: string,
|
title?: string,
|
||||||
disabled?: boolean,
|
disabled?: boolean,
|
||||||
status?: Status,
|
status?: Status,
|
||||||
isUserTouching?: () => boolean,
|
isUserTouching?: () => boolean,
|
||||||
|
@ -245,6 +245,7 @@ export interface IDropdown extends RouteComponentProps {
|
||||||
openedViaKeyboard?: boolean,
|
openedViaKeyboard?: boolean,
|
||||||
text?: string,
|
text?: string,
|
||||||
onShiftClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>,
|
onShiftClick?: React.EventHandler<React.MouseEvent | React.KeyboardEvent>,
|
||||||
|
children?: JSX.Element,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IDropdownState {
|
interface IDropdownState {
|
||||||
|
@ -355,11 +356,21 @@ class Dropdown extends React.PureComponent<IDropdown, IDropdownState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { src, items, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard = false, pressed, text } = this.props;
|
const { src = require('@tabler/icons/icons/dots.svg'), items, title, disabled, dropdownPlacement, openDropdownId, openedViaKeyboard = false, pressed, text, children } = this.props;
|
||||||
const open = this.state.id === openDropdownId;
|
const open = this.state.id === openDropdownId;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
{children ? (
|
||||||
|
React.cloneElement(children, {
|
||||||
|
disabled,
|
||||||
|
onClick: this.handleClick,
|
||||||
|
onMouseDown: this.handleMouseDown,
|
||||||
|
onKeyDown: this.handleButtonKeyDown,
|
||||||
|
onKeyPress: this.handleKeyPress,
|
||||||
|
ref: this.setTargetRef,
|
||||||
|
})
|
||||||
|
) : (
|
||||||
<IconButton
|
<IconButton
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
className={classNames({
|
className={classNames({
|
||||||
|
@ -376,6 +387,7 @@ class Dropdown extends React.PureComponent<IDropdown, IDropdownState> {
|
||||||
onKeyPress={this.handleKeyPress}
|
onKeyPress={this.handleKeyPress}
|
||||||
ref={this.setTargetRef}
|
ref={this.setTargetRef}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
|
<Overlay show={open} placement={dropdownPlacement} target={this.findTarget}>
|
||||||
<RouterDropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} />
|
<RouterDropdownMenu items={items} onClose={this.handleClose} openedViaKeyboard={openedViaKeyboard} />
|
||||||
|
|
|
@ -3,7 +3,7 @@ import React, { useState, useRef } from 'react';
|
||||||
import { usePopper } from 'react-popper';
|
import { usePopper } from 'react-popper';
|
||||||
|
|
||||||
interface IHoverable {
|
interface IHoverable {
|
||||||
component: React.Component,
|
component: JSX.Element,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wrapper to render a given component when hovered */
|
/** Wrapper to render a given component when hovered */
|
81
app/soapbox/components/status-action-button.tsx
Normal file
81
app/soapbox/components/status-action-button.tsx
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import React from 'react';
|
||||||
|
import InlineSVG from 'react-inlinesvg';
|
||||||
|
|
||||||
|
import { Text } from 'soapbox/components/ui';
|
||||||
|
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
||||||
|
|
||||||
|
const COLORS = {
|
||||||
|
accent: 'text-accent-300 hover:text-accent-300 dark:hover:text-accent-300',
|
||||||
|
success: 'text-success-600 hover:text-success-600 dark:hover:text-success-600',
|
||||||
|
'': '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const FILL_COLORS = {
|
||||||
|
accent: 'fill-accent-300 hover:fill-accent-300',
|
||||||
|
'': '',
|
||||||
|
};
|
||||||
|
|
||||||
|
type Color = keyof typeof COLORS;
|
||||||
|
type FillColor = keyof typeof FILL_COLORS;
|
||||||
|
|
||||||
|
interface IStatusActionCounter {
|
||||||
|
count: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Action button numerical counter, eg "5" likes */
|
||||||
|
const StatusActionCounter: React.FC<IStatusActionCounter> = ({ count = 0 }): JSX.Element => {
|
||||||
|
return (
|
||||||
|
<Text size='xs' weight='semibold' theme='inherit'>
|
||||||
|
{shortNumberFormat(count)}
|
||||||
|
</Text>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface IStatusActionButton extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
iconClassName?: string,
|
||||||
|
icon: string,
|
||||||
|
count?: number,
|
||||||
|
active?: boolean,
|
||||||
|
color?: Color,
|
||||||
|
fill?: FillColor,
|
||||||
|
}
|
||||||
|
|
||||||
|
const StatusActionButton = React.forwardRef((props: IStatusActionButton, ref: React.ForwardedRef<HTMLButtonElement>): JSX.Element => {
|
||||||
|
const { icon, className, iconClassName, active, color = '', fill = '', count = 0, ...filteredProps } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
ref={ref}
|
||||||
|
type='button'
|
||||||
|
className={classNames(
|
||||||
|
'group flex items-center p-1 space-x-0.5 rounded-full',
|
||||||
|
'text-gray-400 hover:text-gray-600 dark:hover:text-white',
|
||||||
|
'bg-white dark:bg-transparent',
|
||||||
|
{
|
||||||
|
[COLORS[color]]: active,
|
||||||
|
},
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
{...filteredProps}
|
||||||
|
>
|
||||||
|
<InlineSVG
|
||||||
|
src={icon}
|
||||||
|
className={classNames(
|
||||||
|
'p-1 rounded-full box-content',
|
||||||
|
'group-focus:outline-none group-focus:ring-2 group-focus:ring-offset-2 dark:ring-offset-0 group-focus:ring-primary-500',
|
||||||
|
{
|
||||||
|
[FILL_COLORS[fill]]: active,
|
||||||
|
},
|
||||||
|
iconClassName,
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{(count || null) && (
|
||||||
|
<StatusActionCounter count={count} />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default StatusActionButton;
|
|
@ -1,4 +1,3 @@
|
||||||
import classNames from 'classnames';
|
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
|
@ -8,11 +7,8 @@ import { withRouter } from 'react-router-dom';
|
||||||
|
|
||||||
import { simpleEmojiReact } from 'soapbox/actions/emoji_reacts';
|
import { simpleEmojiReact } from 'soapbox/actions/emoji_reacts';
|
||||||
import EmojiSelector from 'soapbox/components/emoji_selector';
|
import EmojiSelector from 'soapbox/components/emoji_selector';
|
||||||
import {
|
import Hoverable from 'soapbox/components/hoverable';
|
||||||
StatusAction,
|
import StatusActionButton from 'soapbox/components/status-action-button';
|
||||||
StatusActionButton,
|
|
||||||
StatusActionCounter,
|
|
||||||
} from 'soapbox/components/ui/status/status-action-button';
|
|
||||||
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
|
import DropdownMenuContainer from 'soapbox/containers/dropdown_menu_container';
|
||||||
import { isUserTouching } from 'soapbox/is_mobile';
|
import { isUserTouching } from 'soapbox/is_mobile';
|
||||||
import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji_reacts';
|
import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji_reacts';
|
||||||
|
@ -20,8 +16,6 @@ import { getFeatures } from 'soapbox/utils/features';
|
||||||
|
|
||||||
import { openModal } from '../actions/modals';
|
import { openModal } from '../actions/modals';
|
||||||
|
|
||||||
import { IconButton, Hoverable } from './ui';
|
|
||||||
|
|
||||||
import type { History } from 'history';
|
import type { History } from 'history';
|
||||||
import type { AnyAction, Dispatch } from 'redux';
|
import type { AnyAction, Dispatch } from 'redux';
|
||||||
import type { Menu } from 'soapbox/components/dropdown_menu';
|
import type { Menu } from 'soapbox/components/dropdown_menu';
|
||||||
|
@ -171,7 +165,7 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleLikeButtonClick = () => {
|
handleLikeButtonClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
const { features } = this.props;
|
const { features } = this.props;
|
||||||
|
|
||||||
const reactForStatus = getReactForStatus(this.props.status, this.props.allowedEmoji);
|
const reactForStatus = getReactForStatus(this.props.status, this.props.allowedEmoji);
|
||||||
|
@ -186,6 +180,8 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
} else {
|
} else {
|
||||||
this.handleReact(meEmojiReact);
|
this.handleReact(meEmojiReact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReact = (emoji: string): void => {
|
handleReact = (emoji: string): void => {
|
||||||
|
@ -204,13 +200,15 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
handleFavouriteClick: React.EventHandler<React.MouseEvent> = () => {
|
handleFavouriteClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
const { me, onFavourite, onOpenUnauthorizedModal, status } = this.props;
|
const { me, onFavourite, onOpenUnauthorizedModal, status } = this.props;
|
||||||
if (me) {
|
if (me) {
|
||||||
onFavourite(status);
|
onFavourite(status);
|
||||||
} else {
|
} else {
|
||||||
onOpenUnauthorizedModal('FAVOURITE');
|
onOpenUnauthorizedModal('FAVOURITE');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => {
|
handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
|
@ -589,9 +587,6 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
reblogIcon = require('@tabler/icons/icons/lock.svg');
|
reblogIcon = require('@tabler/icons/icons/lock.svg');
|
||||||
}
|
}
|
||||||
|
|
||||||
let reblogButton;
|
|
||||||
|
|
||||||
if (me && features.quotePosts) {
|
|
||||||
const reblogMenu = [
|
const reblogMenu = [
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(status.reblogged ? messages.cancel_reblog_private : messages.reblog),
|
text: intl.formatMessage(status.reblogged ? messages.cancel_reblog_private : messages.reblog),
|
||||||
|
@ -605,31 +600,17 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
reblogButton = (
|
const reblogButton = (
|
||||||
<DropdownMenuContainer
|
<StatusActionButton
|
||||||
items={reblogMenu}
|
icon={reblogIcon}
|
||||||
|
color='success'
|
||||||
disabled={!publicStatus}
|
disabled={!publicStatus}
|
||||||
|
title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)}
|
||||||
active={status.reblogged}
|
active={status.reblogged}
|
||||||
pressed={status.reblogged}
|
|
||||||
title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)}
|
|
||||||
src={reblogIcon}
|
|
||||||
onShiftClick={this.handleReblogClick}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
reblogButton = (
|
|
||||||
<IconButton
|
|
||||||
disabled={!publicStatus}
|
|
||||||
className={classNames({
|
|
||||||
'text-gray-400 group-hover:text-gray-600 dark:group-hover:text-white': !status.reblogged,
|
|
||||||
'text-success-600 group-hover:text-success-600': status.reblogged,
|
|
||||||
})}
|
|
||||||
title={!publicStatus ? intl.formatMessage(messages.cannot_reblog) : intl.formatMessage(messages.reblog)}
|
|
||||||
src={reblogIcon}
|
|
||||||
onClick={this.handleReblogClick}
|
onClick={this.handleReblogClick}
|
||||||
|
count={reblogCount}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (!status.in_reply_to_id) {
|
if (!status.in_reply_to_id) {
|
||||||
replyTitle = intl.formatMessage(messages.reply);
|
replyTitle = intl.formatMessage(messages.reply);
|
||||||
|
@ -648,55 +629,40 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
count={replyCount}
|
count={replyCount}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<StatusAction>
|
{features.quotePosts && me ? (
|
||||||
|
<DropdownMenuContainer items={reblogMenu} onShiftClick={this.handleReblogClick}>
|
||||||
{reblogButton}
|
{reblogButton}
|
||||||
{reblogCount > 0 && (
|
</DropdownMenuContainer>
|
||||||
<StatusActionCounter count={reblogCount} />
|
) : (
|
||||||
|
reblogButton
|
||||||
)}
|
)}
|
||||||
</StatusAction>
|
|
||||||
|
|
||||||
{features.emojiReacts ? (
|
{features.emojiReacts ? (
|
||||||
<div
|
|
||||||
ref={this.setRef}
|
|
||||||
className='group flex relative items-center space-x-0.5 p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500'
|
|
||||||
>
|
|
||||||
<Hoverable
|
<Hoverable
|
||||||
component={(
|
component={(
|
||||||
<EmojiSelector
|
<EmojiSelector
|
||||||
onReact={this.handleReact}
|
onReact={this.handleReact}
|
||||||
focused={emojiSelectorFocused}
|
focused={emojiSelectorFocused}
|
||||||
onUnfocus={handleEmojiSelectorUnfocus}
|
onUnfocus={handleEmojiSelectorUnfocus}
|
||||||
/> as any
|
/>
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<IconButton
|
<StatusActionButton
|
||||||
className={classNames({
|
|
||||||
'text-gray-400 group-hover:text-gray-600 dark:group-hover:text-white': !meEmojiReact,
|
|
||||||
'text-accent-300 group-hover:text-accent-300': Boolean(meEmojiReact),
|
|
||||||
})}
|
|
||||||
title={meEmojiTitle}
|
title={meEmojiTitle}
|
||||||
src={require('@tabler/icons/icons/heart.svg')}
|
icon={require('@tabler/icons/icons/thumb-up.svg')}
|
||||||
iconClassName={classNames({
|
color='accent'
|
||||||
'fill-accent-300': Boolean(meEmojiReact),
|
|
||||||
})}
|
|
||||||
// emoji={meEmojiReact}
|
|
||||||
onClick={this.handleLikeButtonClick}
|
onClick={this.handleLikeButtonClick}
|
||||||
|
active={Boolean(meEmojiReact)}
|
||||||
|
count={emojiReactCount}
|
||||||
/>
|
/>
|
||||||
</Hoverable>
|
</Hoverable>
|
||||||
|
|
||||||
{emojiReactCount > 0 && (
|
|
||||||
(features.exposableReactions && !features.emojiReacts) ? (
|
|
||||||
<StatusActionCounter count={emojiReactCount} />
|
|
||||||
) : (
|
|
||||||
<StatusActionCounter count={emojiReactCount} />
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
): (
|
): (
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={intl.formatMessage(messages.favourite)}
|
title={intl.formatMessage(messages.favourite)}
|
||||||
icon={require('@tabler/icons/icons/heart.svg')}
|
icon={require('@tabler/icons/icons/heart.svg')}
|
||||||
onClick={this.handleLikeButtonClick}
|
color='accent'
|
||||||
|
fill='accent'
|
||||||
|
onClick={this.handleFavouriteClick}
|
||||||
active={Boolean(meEmojiReact)}
|
active={Boolean(meEmojiReact)}
|
||||||
count={favouriteCount}
|
count={favouriteCount}
|
||||||
/>
|
/>
|
||||||
|
@ -710,14 +676,12 @@ class StatusActionBar extends ImmutablePureComponent<IStatusActionBar, IStatusAc
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<StatusAction>
|
<DropdownMenuContainer items={menu} status={status}>
|
||||||
<DropdownMenuContainer
|
<StatusActionButton
|
||||||
items={menu}
|
|
||||||
title={intl.formatMessage(messages.more)}
|
title={intl.formatMessage(messages.more)}
|
||||||
status={status}
|
icon={require('@tabler/icons/icons/dots.svg')}
|
||||||
src={require('@tabler/icons/icons/dots.svg')}
|
|
||||||
/>
|
/>
|
||||||
</StatusAction>
|
</DropdownMenuContainer>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ export { default as EmojiSelector } from './emoji-selector/emoji-selector';
|
||||||
export { default as Form } from './form/form';
|
export { default as Form } from './form/form';
|
||||||
export { default as FormActions } from './form-actions/form-actions';
|
export { default as FormActions } from './form-actions/form-actions';
|
||||||
export { default as FormGroup } from './form-group/form-group';
|
export { default as FormGroup } from './form-group/form-group';
|
||||||
export { default as Hoverable } from './hoverable/hoverable';
|
|
||||||
export { default as HStack } from './hstack/hstack';
|
export { default as HStack } from './hstack/hstack';
|
||||||
export { default as Icon } from './icon/icon';
|
export { default as Icon } from './icon/icon';
|
||||||
export { default as IconButton } from './icon-button/icon-button';
|
export { default as IconButton } from './icon-button/icon-button';
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
import classNames from 'classnames';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
import { IconButton } from 'soapbox/components/ui';
|
|
||||||
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
|
||||||
|
|
||||||
interface IStatusActionCounter {
|
|
||||||
count: number,
|
|
||||||
className?: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Action button numerical counter, eg "5" likes */
|
|
||||||
const StatusActionCounter: React.FC<IStatusActionCounter> = ({ count = 0, className }): JSX.Element => {
|
|
||||||
return (
|
|
||||||
<span className={classNames('text-xs font-semibold text-gray-400 group-hover:text-gray-600 dark:group-hover:text-white', className)}>
|
|
||||||
{shortNumberFormat(count)}
|
|
||||||
</span>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface IStatusAction {
|
|
||||||
title?: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Status action container element */
|
|
||||||
const StatusAction: React.FC<IStatusAction> = ({ title, children }) => {
|
|
||||||
return (
|
|
||||||
<div title={title} className='group flex items-center space-x-0.5 p-1 rounded-full focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500'>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
interface IStatusActionButton {
|
|
||||||
icon: string,
|
|
||||||
onClick: () => void,
|
|
||||||
count?: number,
|
|
||||||
active?: boolean,
|
|
||||||
title?: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Action button (eg "Like") for a Status */
|
|
||||||
const StatusActionButton: React.FC<IStatusActionButton> = ({ icon, title, active = false, onClick, count = 0 }): JSX.Element => {
|
|
||||||
|
|
||||||
const handleClick: React.EventHandler<React.MouseEvent> = (e) => {
|
|
||||||
onClick();
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StatusAction title={title}>
|
|
||||||
<IconButton
|
|
||||||
title={title}
|
|
||||||
src={icon}
|
|
||||||
onClick={handleClick}
|
|
||||||
className={classNames('text-gray-400 group-hover:text-gray-600 dark:group-hover:text-white', {
|
|
||||||
'text-accent-300 group-hover:text-accent-300 dark:group-hover:text-accent-300': active,
|
|
||||||
// TODO: repost button
|
|
||||||
// 'text-success-600 hover:text-success-600': active,
|
|
||||||
})}
|
|
||||||
iconClassName={classNames({
|
|
||||||
'fill-accent-300': active,
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{(count || null) && (
|
|
||||||
<StatusActionCounter
|
|
||||||
className={classNames({ 'text-accent-300 group-hover:text-accent-300': active })}
|
|
||||||
count={count}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</StatusAction>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { StatusAction, StatusActionButton, StatusActionCounter };
|
|
Loading…
Reference in a new issue