mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 04:46:40 +07:00
made node use context providers
This commit is contained in:
parent
15095b3116
commit
f631f79654
8 changed files with 189 additions and 180 deletions
|
@ -6,53 +6,19 @@ import { NodeCommentsBlock } from '~/components/node/NodeCommentsBlock';
|
||||||
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
|
import { NodeCommentForm } from '~/components/node/NodeCommentForm';
|
||||||
import { NodeRelatedBlock } from '~/components/node/NodeRelatedBlock';
|
import { NodeRelatedBlock } from '~/components/node/NodeRelatedBlock';
|
||||||
import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks';
|
import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks';
|
||||||
import { IComment, IFile, INode, ITag } from '~/redux/types';
|
|
||||||
import { NodeTagsBlock } from '~/components/node/NodeTagsBlock';
|
import { NodeTagsBlock } from '~/components/node/NodeTagsBlock';
|
||||||
import { INodeRelated } from '~/redux/node/types';
|
|
||||||
import StickyBox from 'react-sticky-box/dist/esnext';
|
import StickyBox from 'react-sticky-box/dist/esnext';
|
||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
import { NodeAuthorBlock } from '~/components/node/NodeAuthorBlock';
|
import { NodeAuthorBlock } from '~/components/node/NodeAuthorBlock';
|
||||||
import { IUser } from '~/redux/auth/types';
|
import { useNodeContext } from '~/utils/providers/NodeProvider';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
node: INode;
|
|
||||||
user: IUser;
|
|
||||||
isUser: boolean;
|
isUser: boolean;
|
||||||
canEdit: boolean;
|
|
||||||
isLoading: boolean;
|
|
||||||
commentsOrder: 'ASC' | 'DESC';
|
commentsOrder: 'ASC' | 'DESC';
|
||||||
comments: IComment[];
|
|
||||||
commentsCount: number;
|
|
||||||
isLoadingComments: boolean;
|
|
||||||
related: INodeRelated;
|
|
||||||
lastSeenCurrent?: string;
|
|
||||||
onShowImageModal: (images: IFile[], index: number) => void;
|
|
||||||
onLoadMoreComments: () => void;
|
|
||||||
onDeleteComment: (id: IComment['id'], isLocked: boolean) => void;
|
|
||||||
onTagsChange: (tags: string[]) => void;
|
|
||||||
onTagClick: (tag: Partial<ITag>) => void;
|
|
||||||
onTagDelete: (id: ITag['ID']) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeBottomBlock: FC<IProps> = ({
|
const NodeBottomBlock: FC<IProps> = ({ commentsOrder }) => {
|
||||||
node,
|
const { node, related, isUser, isLoading } = useNodeContext();
|
||||||
user,
|
|
||||||
canEdit,
|
|
||||||
isLoading,
|
|
||||||
isUser,
|
|
||||||
isLoadingComments,
|
|
||||||
comments,
|
|
||||||
commentsCount,
|
|
||||||
commentsOrder,
|
|
||||||
related,
|
|
||||||
lastSeenCurrent,
|
|
||||||
onLoadMoreComments,
|
|
||||||
onDeleteComment,
|
|
||||||
onShowImageModal,
|
|
||||||
onTagsChange,
|
|
||||||
onTagClick,
|
|
||||||
onTagDelete,
|
|
||||||
}) => {
|
|
||||||
const { inline } = useNodeBlocks(node, isLoading);
|
const { inline } = useNodeBlocks(node, isLoading);
|
||||||
|
|
||||||
if (node.deleted_at) {
|
if (node.deleted_at) {
|
||||||
|
@ -66,19 +32,7 @@ const NodeBottomBlock: FC<IProps> = ({
|
||||||
<Group className={styles.comments}>
|
<Group className={styles.comments}>
|
||||||
{inline && <div className={styles.inline}>{inline}</div>}
|
{inline && <div className={styles.inline}>{inline}</div>}
|
||||||
|
|
||||||
<NodeCommentsBlock
|
<NodeCommentsBlock order={commentsOrder} />
|
||||||
lastSeenCurrent={lastSeenCurrent}
|
|
||||||
isLoading={isLoading}
|
|
||||||
isLoadingComments={isLoadingComments}
|
|
||||||
comments={comments}
|
|
||||||
count={commentsCount}
|
|
||||||
order={commentsOrder}
|
|
||||||
user={user}
|
|
||||||
node={node}
|
|
||||||
onShowImageModal={onShowImageModal}
|
|
||||||
onLoadMoreComments={onLoadMoreComments}
|
|
||||||
onDeleteComment={onDeleteComment}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isUser && !isLoading && <NodeCommentForm nodeId={node.id} />}
|
{isUser && !isLoading && <NodeCommentForm nodeId={node.id} />}
|
||||||
</Group>
|
</Group>
|
||||||
|
@ -89,16 +43,9 @@ const NodeBottomBlock: FC<IProps> = ({
|
||||||
<div className={styles.left_item}>
|
<div className={styles.left_item}>
|
||||||
<NodeAuthorBlock user={node?.user} />
|
<NodeAuthorBlock user={node?.user} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.left_item}>
|
<div className={styles.left_item}>
|
||||||
<NodeTagsBlock
|
<NodeTagsBlock />
|
||||||
tags={node.tags}
|
|
||||||
canDelete={canEdit}
|
|
||||||
canAppend={isUser}
|
|
||||||
isLoading={isLoading}
|
|
||||||
onChange={onTagsChange}
|
|
||||||
onTagClick={onTagClick}
|
|
||||||
onTagDelete={onTagDelete}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.left_item}>
|
<div className={styles.left_item}>
|
||||||
<NodeRelatedBlock isLoading={isLoading} node={node} related={related} />
|
<NodeRelatedBlock isLoading={isLoading} node={node} related={related} />
|
||||||
|
|
|
@ -1,40 +1,30 @@
|
||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import { NodeNoComments } from '~/components/node/NodeNoComments';
|
import { NodeNoComments } from '~/components/node/NodeNoComments';
|
||||||
import { NodeComments } from '~/components/node/NodeComments';
|
import { NodeComments } from '~/components/node/NodeComments';
|
||||||
import { IComment, IFile, INode } from '~/redux/types';
|
|
||||||
import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks';
|
import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks';
|
||||||
import { IUser } from '~/redux/auth/types';
|
import { useCommentContext } from '~/utils/providers/CommentProvider';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
order: 'ASC' | 'DESC';
|
order: 'ASC' | 'DESC';
|
||||||
node: INode;
|
|
||||||
user: IUser;
|
|
||||||
comments: IComment[];
|
|
||||||
count: number;
|
|
||||||
lastSeenCurrent?: string;
|
|
||||||
isLoading: boolean;
|
|
||||||
isLoadingComments: boolean;
|
|
||||||
onShowImageModal: (images: IFile[], index: number) => void;
|
|
||||||
onLoadMoreComments: () => void;
|
|
||||||
onDeleteComment: (id: IComment['id'], isLocked: boolean) => void;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NodeCommentsBlock: FC<IProps> = ({
|
const NodeCommentsBlock: FC<IProps> = () => {
|
||||||
|
const {
|
||||||
node,
|
node,
|
||||||
user,
|
user,
|
||||||
comments,
|
comments,
|
||||||
count,
|
count,
|
||||||
lastSeenCurrent,
|
lastSeenCurrent,
|
||||||
isLoading,
|
isLoadingNode,
|
||||||
isLoadingComments,
|
isLoadingComments,
|
||||||
onLoadMoreComments,
|
onLoadMoreComments,
|
||||||
onDeleteComment,
|
onDeleteComment,
|
||||||
onShowImageModal,
|
onShowImageModal,
|
||||||
}) => {
|
} = useCommentContext();
|
||||||
const { inline } = useNodeBlocks(node, isLoading);
|
const { inline } = useNodeBlocks(node, isLoadingNode);
|
||||||
|
|
||||||
return isLoading || isLoadingComments || (!comments.length && !inline) ? (
|
return isLoadingNode || isLoadingComments || (!comments.length && !inline) ? (
|
||||||
<NodeNoComments is_loading={isLoadingComments || isLoading} />
|
<NodeNoComments is_loading={isLoadingComments || isLoadingNode} />
|
||||||
) : (
|
) : (
|
||||||
<NodeComments
|
<NodeComments
|
||||||
count={count}
|
count={count}
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import { ITag } from '~/redux/types';
|
|
||||||
import { NodeTags } from '~/components/node/NodeTags';
|
import { NodeTags } from '~/components/node/NodeTags';
|
||||||
|
import { useTagContext } from '~/utils/providers/TagProvider';
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {}
|
||||||
tags: ITag[];
|
|
||||||
canAppend: boolean;
|
|
||||||
canDelete: boolean;
|
|
||||||
isLoading: boolean;
|
|
||||||
onChange: (tags: string[]) => void;
|
|
||||||
onTagClick: (tag: Partial<ITag>) => void;
|
|
||||||
onTagDelete: (id: ITag['ID']) => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
const NodeTagsBlock: FC<IProps> = ({
|
const NodeTagsBlock: FC<IProps> = ({}) => {
|
||||||
|
const {
|
||||||
tags,
|
tags,
|
||||||
canAppend,
|
canAppend,
|
||||||
canDelete,
|
canDelete,
|
||||||
|
@ -20,7 +13,8 @@ const NodeTagsBlock: FC<IProps> = ({
|
||||||
onChange,
|
onChange,
|
||||||
onTagClick,
|
onTagClick,
|
||||||
onTagDelete,
|
onTagDelete,
|
||||||
}) => {
|
} = useTagContext();
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,52 +12,18 @@ import { NodeBottomBlock } from '~/components/node/NodeBottomBlock';
|
||||||
import { useNodeCoverImage } from '~/utils/hooks/node/useNodeCoverImage';
|
import { useNodeCoverImage } from '~/utils/hooks/node/useNodeCoverImage';
|
||||||
import { URLS } from '~/constants/urls';
|
import { URLS } from '~/constants/urls';
|
||||||
import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog';
|
import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog';
|
||||||
import { useNodePermissions } from '~/utils/hooks/node/useNodePermissions';
|
|
||||||
import { IComment, IFile, INode, ITag } from '~/redux/types';
|
|
||||||
import { INodeRelated } from '~/redux/node/types';
|
|
||||||
|
|
||||||
import styles from './styles.module.scss';
|
import styles from './styles.module.scss';
|
||||||
import { IUser } from '~/redux/auth/types';
|
import { useNodeContext } from '~/utils/providers/NodeProvider';
|
||||||
|
|
||||||
type IProps = {
|
type IProps = {};
|
||||||
node: INode;
|
|
||||||
user: IUser;
|
const NodeLayout: FC<IProps> = () => {
|
||||||
lastSeenCurrent?: string;
|
const { node, isUser, isLoading } = useNodeContext();
|
||||||
related: INodeRelated;
|
|
||||||
comments: IComment[];
|
|
||||||
commentsCount: number;
|
|
||||||
isUser: boolean;
|
|
||||||
isLoading: boolean;
|
|
||||||
isLoadingComments: boolean;
|
|
||||||
onShowImageModal: (images: IFile[], index: number) => void;
|
|
||||||
onLoadMoreComments: () => void;
|
|
||||||
onDeleteComment: (id: IComment['id'], isLocked: boolean) => void;
|
|
||||||
onTagsChange: (tags: string[]) => void;
|
|
||||||
onTagClick: (tag: Partial<ITag>) => void;
|
|
||||||
onTagDelete: (id: ITag['ID']) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const NodeLayout: FC<IProps> = ({
|
|
||||||
node,
|
|
||||||
user,
|
|
||||||
comments,
|
|
||||||
commentsCount,
|
|
||||||
related,
|
|
||||||
lastSeenCurrent,
|
|
||||||
isUser,
|
|
||||||
isLoading,
|
|
||||||
isLoadingComments,
|
|
||||||
onLoadMoreComments,
|
|
||||||
onDeleteComment,
|
|
||||||
onShowImageModal,
|
|
||||||
onTagsChange,
|
|
||||||
onTagClick,
|
|
||||||
onTagDelete,
|
|
||||||
}) => {
|
|
||||||
useNodeCoverImage(node);
|
useNodeCoverImage(node);
|
||||||
|
|
||||||
const { head, block } = useNodeBlocks(node, isLoading);
|
const { head, block } = useNodeBlocks(node, isLoading);
|
||||||
const [canEdit] = useNodePermissions(node);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
|
@ -71,25 +37,7 @@ const NodeLayout: FC<IProps> = ({
|
||||||
<NodePanel node={node} isLoading={isLoading} />
|
<NodePanel node={node} isLoading={isLoading} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<NodeBottomBlock
|
<NodeBottomBlock isUser={isUser} commentsOrder="DESC" />
|
||||||
isUser={isUser}
|
|
||||||
user={user}
|
|
||||||
node={node}
|
|
||||||
canEdit={canEdit}
|
|
||||||
comments={comments}
|
|
||||||
commentsCount={commentsCount}
|
|
||||||
commentsOrder="DESC"
|
|
||||||
related={related}
|
|
||||||
isLoadingComments={isLoadingComments}
|
|
||||||
isLoading={isLoading}
|
|
||||||
lastSeenCurrent={lastSeenCurrent}
|
|
||||||
onShowImageModal={onShowImageModal}
|
|
||||||
onLoadMoreComments={onLoadMoreComments}
|
|
||||||
onDeleteComment={onDeleteComment}
|
|
||||||
onTagsChange={onTagsChange}
|
|
||||||
onTagClick={onTagClick}
|
|
||||||
onTagDelete={onTagDelete}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
@ -7,6 +7,10 @@ import { useImageModal } from '~/utils/hooks/useImageModal';
|
||||||
import { useNodeComments } from '~/utils/hooks/node/useNodeComments';
|
import { useNodeComments } from '~/utils/hooks/node/useNodeComments';
|
||||||
import { useUser } from '~/utils/hooks/user/userUser';
|
import { useUser } from '~/utils/hooks/user/userUser';
|
||||||
import { useNodeTags } from '~/utils/hooks/node/useNodeTags';
|
import { useNodeTags } from '~/utils/hooks/node/useNodeTags';
|
||||||
|
import { NodeProvider } from '~/utils/providers/NodeProvider';
|
||||||
|
import { CommentProvider } from '~/utils/providers/CommentProvider';
|
||||||
|
import { TagProvider } from '~/utils/providers/TagProvider';
|
||||||
|
import { useNodePermissions } from '~/utils/hooks/node/useNodePermissions';
|
||||||
|
|
||||||
type Props = RouteComponentProps<{ id: string }> & {};
|
type Props = RouteComponentProps<{ id: string }> & {};
|
||||||
|
|
||||||
|
@ -31,26 +35,37 @@ const NodePage: FC<Props> = ({
|
||||||
parseInt(id, 10)
|
parseInt(id, 10)
|
||||||
);
|
);
|
||||||
const user = useUser();
|
const user = useUser();
|
||||||
|
const [canEdit] = useNodePermissions(node);
|
||||||
|
|
||||||
useScrollToTop([id, isLoadingComments]);
|
useScrollToTop([id, isLoadingComments]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NodeLayout
|
<NodeProvider node={node} related={related} isUser={user.is_user} isLoading={isLoading}>
|
||||||
|
<CommentProvider
|
||||||
node={node}
|
node={node}
|
||||||
user={user}
|
user={user}
|
||||||
related={related}
|
|
||||||
lastSeenCurrent={lastSeenCurrent}
|
|
||||||
comments={comments}
|
comments={comments}
|
||||||
commentsCount={commentsCount}
|
count={commentsCount}
|
||||||
isUser={user.is_user}
|
lastSeenCurrent={lastSeenCurrent}
|
||||||
isLoading={isLoading}
|
isLoadingNode={isLoading}
|
||||||
isLoadingComments={isLoadingComments}
|
isLoadingComments={isLoadingComments}
|
||||||
onShowImageModal={onShowImageModal}
|
onShowImageModal={onShowImageModal}
|
||||||
onLoadMoreComments={onLoadMoreComments}
|
onLoadMoreComments={onLoadMoreComments}
|
||||||
onDeleteComment={onDeleteComment}
|
onDeleteComment={onDeleteComment}
|
||||||
onTagDelete={onTagDelete}
|
>
|
||||||
|
<TagProvider
|
||||||
|
tags={node.tags}
|
||||||
|
canAppend={user.is_user}
|
||||||
|
canDelete={canEdit}
|
||||||
|
isLoading={isLoading}
|
||||||
|
onChange={onTagsChange}
|
||||||
onTagClick={onTagClick}
|
onTagClick={onTagClick}
|
||||||
onTagsChange={onTagsChange}
|
onTagDelete={onTagDelete}
|
||||||
/>
|
>
|
||||||
|
<NodeLayout />
|
||||||
|
</TagProvider>
|
||||||
|
</CommentProvider>
|
||||||
|
</NodeProvider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
37
src/utils/providers/CommentProvider.tsx
Normal file
37
src/utils/providers/CommentProvider.tsx
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { IComment, IFile, INode } from '~/redux/types';
|
||||||
|
import { IUser } from '~/redux/auth/types';
|
||||||
|
import React, { createContext, FC, useContext } from 'react';
|
||||||
|
import { EMPTY_USER } from '~/redux/auth/constants';
|
||||||
|
import { EMPTY_NODE } from '~/redux/node/constants';
|
||||||
|
|
||||||
|
export interface CommentProviderProps {
|
||||||
|
node: INode;
|
||||||
|
user: IUser;
|
||||||
|
comments: IComment[];
|
||||||
|
count: number;
|
||||||
|
lastSeenCurrent?: string;
|
||||||
|
isLoadingNode: boolean;
|
||||||
|
isLoadingComments: boolean;
|
||||||
|
onShowImageModal: (images: IFile[], index: number) => void;
|
||||||
|
onLoadMoreComments: () => void;
|
||||||
|
onDeleteComment: (id: IComment['id'], isLocked: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommentContext = createContext<CommentProviderProps>({
|
||||||
|
node: EMPTY_NODE,
|
||||||
|
user: EMPTY_USER,
|
||||||
|
comments: [],
|
||||||
|
count: 0,
|
||||||
|
lastSeenCurrent: undefined,
|
||||||
|
isLoadingNode: false,
|
||||||
|
isLoadingComments: false,
|
||||||
|
onShowImageModal: () => {},
|
||||||
|
onLoadMoreComments: () => {},
|
||||||
|
onDeleteComment: () => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const CommentProvider: FC<CommentProviderProps> = ({ children, ...contextValue }) => {
|
||||||
|
return <CommentContext.Provider value={contextValue}>{children}</CommentContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useCommentContext = () => useContext(CommentContext);
|
50
src/utils/providers/NodeProvider.tsx
Normal file
50
src/utils/providers/NodeProvider.tsx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { INode } from '~/redux/types';
|
||||||
|
import { INodeRelated } from '~/redux/node/types';
|
||||||
|
import { EMPTY_NODE } from '~/redux/node/constants';
|
||||||
|
import React, { createContext, FC, useContext } from 'react';
|
||||||
|
|
||||||
|
export interface NodeContextProps {
|
||||||
|
node: INode;
|
||||||
|
related: INodeRelated;
|
||||||
|
isUser: boolean;
|
||||||
|
isLoading: boolean;
|
||||||
|
// user: IUser;
|
||||||
|
// isLoadingComments: boolean;
|
||||||
|
// lastSeenCurrent?: string;
|
||||||
|
// commentsCount: number;
|
||||||
|
// comments: IComment[];
|
||||||
|
// onShowImageModal: (images: IFile[], index: number) => void;
|
||||||
|
// onLoadMoreComments: () => void;
|
||||||
|
// onDeleteComment: (id: IComment['id'], isLocked: boolean) => void;
|
||||||
|
// onTagsChange: (tags: string[]) => void;
|
||||||
|
// onTagClick: (tag: Partial<ITag>) => void;
|
||||||
|
// onTagDelete: (id: ITag['ID']) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NodeContext = createContext<NodeContextProps>({
|
||||||
|
node: EMPTY_NODE,
|
||||||
|
related: { albums: {}, similar: [] },
|
||||||
|
isUser: false,
|
||||||
|
isLoading: false,
|
||||||
|
|
||||||
|
// CommentContext
|
||||||
|
// user: EMPTY_USER,
|
||||||
|
// lastSeenCurrent: undefined,
|
||||||
|
// comments: [],
|
||||||
|
// commentsCount: 0,
|
||||||
|
// onLoadMoreComments: () => {},
|
||||||
|
// onShowImageModal: () => {},
|
||||||
|
// onDeleteComment: () => {},
|
||||||
|
// isLoadingComments: false,
|
||||||
|
|
||||||
|
// TagContext
|
||||||
|
// onTagsChange: () => {},
|
||||||
|
// onTagClick: () => {},
|
||||||
|
// onTagDelete: () => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NodeProvider: FC<NodeContextProps> = ({ children, ...contextValue }) => {
|
||||||
|
return <NodeContext.Provider value={contextValue}>{children}</NodeContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useNodeContext = () => useContext(NodeContext);
|
28
src/utils/providers/TagProvider.tsx
Normal file
28
src/utils/providers/TagProvider.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import React, { createContext, FC, useContext } from 'react';
|
||||||
|
import { ITag } from '~/redux/types';
|
||||||
|
|
||||||
|
export interface TagContextProps {
|
||||||
|
tags: ITag[];
|
||||||
|
canAppend: boolean;
|
||||||
|
canDelete: boolean;
|
||||||
|
isLoading: boolean;
|
||||||
|
onChange: (tags: string[]) => void;
|
||||||
|
onTagClick: (tag: Partial<ITag>) => void;
|
||||||
|
onTagDelete: (id: ITag['ID']) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TagContext = createContext<TagContextProps>({
|
||||||
|
tags: [],
|
||||||
|
canDelete: false,
|
||||||
|
canAppend: false,
|
||||||
|
isLoading: false,
|
||||||
|
onChange: () => {},
|
||||||
|
onTagClick: () => {},
|
||||||
|
onTagDelete: () => {},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const TagProvider: FC<TagContextProps> = ({ children, ...contextValue }) => {
|
||||||
|
return <TagContext.Provider value={contextValue}>{children}</TagContext.Provider>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useTagContext = () => useContext(TagContext);
|
Loading…
Add table
Add a link
Reference in a new issue