diff --git a/.github/workflows/version-dump.yml b/.github/workflows/version-dump.yml index 00827ede..bacb11da 100644 --- a/.github/workflows/version-dump.yml +++ b/.github/workflows/version-dump.yml @@ -34,7 +34,7 @@ jobs: cache: 'pnpm' - name: Install dependencies - run: pnpm install + run: pnpm -w install - name: Check for changeset files run: | @@ -47,7 +47,9 @@ jobs: ls -la .changeset/*.md - name: Version bump - run: pnpm changeset version + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: pnpm -w changeset version - name: Commit and push run: | diff --git a/apps/client/CHANGELOG.md b/apps/client/CHANGELOG.md index fcb80d69..27c21324 100644 --- a/apps/client/CHANGELOG.md +++ b/apps/client/CHANGELOG.md @@ -1,5 +1,16 @@ # @bofit/client +## 2.0.0 + +### Major Changes + +- [#375](https://github.com/team-bofit/bofit-client/pull/375) [`cc2d41d`](https://github.com/team-bofit/bofit-client/commit/cc2d41de09b3e95c4c5bd015b174c940655d7c8c) Thanks [@minjeoong](https://github.com/minjeoong)! - refactoring 1th + +### Patch Changes + +- Updated dependencies [[`cc2d41d`](https://github.com/team-bofit/bofit-client/commit/cc2d41de09b3e95c4c5bd015b174c940655d7c8c)]: + - @bds/ui@1.1.0 + ## 1.0.0 ### Major Changes diff --git a/apps/client/package.json b/apps/client/package.json index 73b207ed..fd5c92ab 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -1,6 +1,6 @@ { "name": "@bofit/client", - "version": "1.0.0", + "version": "2.0.0", "type": "module", "scripts": { "dev": "vite", @@ -14,15 +14,15 @@ "@tanstack/react-query": "^5.83.0", "@tanstack/react-query-devtools": "^5.83.0", "@toss/ky": "^1.2.1", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.1.6", "lottie-react": "^2.4.1", - "react": "^19.1.0", - "react-dom": "^19.1.0", + "react": "catalog:react-core", + "react-dom": "catalog:react-core", "react-error-boundary": "^6.0.0", "react-router": "^7.6.3", "react-router-dom": "^7.6.3", - "swiper": "^11.2.10" + "swiper": "^11.2.10", + "@types/react": "catalog:react-core", + "@types/react-dom": "catalog:react-core" }, "devDependencies": { "@bofit/eslint": "workspace:*", @@ -30,16 +30,17 @@ "@pivanov/vite-plugin-svg-sprite": "^3.0.0", "@typescript-eslint/eslint-plugin": "^5.59.0", "@typescript-eslint/parser": "^5.59.0", - "@vanilla-extract/css": "*", - "@vanilla-extract/recipes": "^0.5.7", - "@vanilla-extract/sprinkles": "*", - "@vanilla-extract/vite-plugin": "*", - "@vitejs/plugin-react": "*", + "@vanilla-extract/css": "catalog:vanilla-extract-core", + "@vanilla-extract/recipes": "catalog:vanilla-extract-core", + "@vanilla-extract/sprinkles": "catalog:vanilla-extract-utils", + "@vanilla-extract/vite-plugin": "catalog:vanilla-extract-utils", + "vite": "catalog:vite-core", + "@vitejs/plugin-react": "catalog:vite-plugins", "eslint": "^8.44.0", "globals": "^16.2.0", "openapi-typescript": "^7.8.0", - "typescript": "~5.8.3", - "vite": "*", + "typescript": "catalog:typescript-core", + "@types/node": "catalog:typescript-core", "vite-tsconfig-paths": "^5.1.4" } } diff --git a/apps/client/src/pages/community/community-detail.tsx b/apps/client/src/pages/community/community-detail.tsx new file mode 100644 index 00000000..94393a2d --- /dev/null +++ b/apps/client/src/pages/community/community-detail.tsx @@ -0,0 +1,33 @@ +import { useParams } from 'react-router'; + +import { Navigation } from '@bds/ui'; +import { Icon } from '@bds/ui/icons'; + +import DetailSection from '@widgets/community/components/detail-section/detail-section'; + +import { useNavigateTo } from '@shared/hooks/use-navigate-to'; +import { routePath } from '@shared/router/path'; + +const CommunityDetail = () => { + const { postId } = useParams<{ postId: string }>(); + + if (!postId) { + throw new Error('postId가 존재하지 않습니다.'); + } + + return ( + <> + } + onClickLeft={useNavigateTo(-1)} + rightIcon={} + onClickRight={useNavigateTo(routePath.HOME)} + /> + + + + ); +}; + +export default CommunityDetail; diff --git a/apps/client/src/pages/community/community-detail/community-detail.tsx b/apps/client/src/pages/community/community-detail/community-detail.tsx deleted file mode 100644 index 25097abb..00000000 --- a/apps/client/src/pages/community/community-detail/community-detail.tsx +++ /dev/null @@ -1,284 +0,0 @@ -import { useState } from 'react'; -import { - useInfiniteQuery, - useMutation, - useQueryClient, - useSuspenseQuery, -} from '@tanstack/react-query'; -import { useParams } from 'react-router'; -import { useNavigate } from 'react-router-dom'; - -import { Button, Modal, Navigation, useModal } from '@bds/ui'; -import { Icon } from '@bds/ui/icons'; - -import CommentBox from '@widgets/community/components/comment-box/comment-box'; -import EmptyPlaceholder from '@widgets/community/components/empty-placeholder/empty-placeholder'; -import PostDetailInfo from '@widgets/community/components/post-detail-info/post-detail-info'; -import UserComment from '@widgets/community/components/user-comment/user-comment'; -import { EMPTY_COMMENT } from '@widgets/community/constant/empty-content'; - -import { - COMMUNITY_MUTATION_OPTIONS, - COMMUNITY_QUERY_OPTIONS, -} from '@shared/api/domain/community/queries'; -import { USER_QUERY_OPTIONS } from '@shared/api/domain/onboarding/queries'; -import { COMMUNITY_QUERY_KEY } from '@shared/api/keys/query-key'; -import { LIMIT_MEDIUM_TEXT } from '@shared/constants/text-limits'; -import { useIntersectionObserver } from '@shared/hooks/use-intersection-observer'; -import { useLimitedInput } from '@shared/hooks/use-limited-input'; -import { routePath } from '@shared/router/path'; -import { getTimeAgo } from '@shared/utils/get-time-ago'; - -import * as styles from './community-detail.css'; -import { virtualRef } from '@widgets/mypage/preview.css'; - -const DELETE_MODAL = { - FEED: { - title: '이 글을 삭제할까요?', - content: '삭제한 글/댓글은 복원되지 않습니다.', - }, - COMMENT: { - title: '이 댓글을 삭제할까요?', - content: '삭제한 댓글은 복원되지 않습니다.', - }, -}; - -const CommunityDetail = () => { - const navigate = useNavigate(); - const [content, setContent] = useState(''); - const { postId } = useParams<{ postId: string }>(); - const { isErrorState } = useLimitedInput(LIMIT_MEDIUM_TEXT, content.length); - const queryClient = useQueryClient(); - - if (!postId) { - throw new Error('postId가 존재하지 않습니다.'); - } - - const { data: feedDetailData } = useSuspenseQuery( - COMMUNITY_QUERY_OPTIONS.FEED_DETAIL(postId), - ); - const { - data: comments, - fetchNextPage, - hasNextPage, - isFetchingNextPage, - } = useInfiniteQuery({ - ...COMMUNITY_QUERY_OPTIONS.COMMENTS(postId), - }); - - const { data: profileData } = useSuspenseQuery(USER_QUERY_OPTIONS.PROFILE()); - const { mutate: createCommentMutate } = useMutation({ - ...COMMUNITY_MUTATION_OPTIONS.POST_COMMENT(), - onSuccess: (_data, variables) => { - queryClient.invalidateQueries({ - queryKey: COMMUNITY_QUERY_KEY.COMMENTS(variables.postId), - }); - queryClient.invalidateQueries({ - queryKey: COMMUNITY_QUERY_KEY.FEED_DETAIL(variables.postId), - }); - }, - }); - - const { mutate: deleteFeedMutate } = useMutation({ - ...COMMUNITY_MUTATION_OPTIONS.DELETE_FEED(postId), - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: COMMUNITY_QUERY_KEY.FEED_PREVIEW(), - }); - navigate(routePath.COMMUNITY); - }, - }); - - const { mutate: deleteCommentMutate } = useMutation({ - ...COMMUNITY_MUTATION_OPTIONS.DELETE_COMMENT(postId), - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: COMMUNITY_QUERY_KEY.COMMENTS(postId), - }); - queryClient.invalidateQueries({ - queryKey: COMMUNITY_QUERY_KEY.FEED_DETAIL(postId), - }); - }, - }); - - const handleDeleteFeed = () => { - deleteFeedMutate(); - closeModal(); - }; - - const handleChange = (e: React.ChangeEvent) => { - if (e.target.value.length <= 30) { - setContent(e.target.value); - } - }; - - const allComments = - comments?.pages.flatMap((page) => page?.data?.content ?? []) ?? []; - - const commentsObserverRef = useIntersectionObserver(() => { - if (hasNextPage && !isFetchingNextPage) { - fetchNextPage(); - } - }, true); - - const userData = profileData?.data; - const isPostOwner = feedDetailData?.writerId === userData?.userId; - - const handleNavigate = (path: string) => { - navigate(path); - }; - - const onSubmitComment = () => { - if (!content.trim()) { - return; - } - createCommentMutate( - { postId, content: content.trim() }, - { - onSuccess: () => { - setContent(''); - }, - }, - ); - }; - - const handleGoBack = () => { - navigate(-1); - }; - - const handleGoEdit = () => { - navigate(routePath.COMMUNITY_EDIT.replace(':postId', String(postId)), { - state: { - title: feedDetailData?.title, - content: feedDetailData?.content, - }, - }); - }; - - const { openModal, closeModal } = useModal(); - type ModalType = 'feed' | 'comment' | null; - - const showDeleteModal = (type: ModalType, commentId?: string) => { - openModal(renderModal(type, commentId)); - }; - - const renderModal = (type: ModalType, commentId?: string) => { - const isFeed = type === 'feed'; - return ( - - - {isFeed ? DELETE_MODAL.FEED.title : DELETE_MODAL.COMMENT.title} - - - - - - - - - - ); - }; - - const handleDeleteComment = (commentId: string) => { - deleteCommentMutate(commentId); - closeModal(); - }; - - if (!comments) { - return null; - } - - return ( - <> - } - onClickLeft={handleGoBack} - rightIcon={} - onClickRight={() => handleNavigate(routePath.HOME)} - /> - -
- showDeleteModal('feed')} - /> - -
-
- -

- 댓글 {feedDetailData?.commentCount} -

-
- -
- {allComments.length > 0 ? ( - allComments.map((comment) => { - const isCommentOwner = comment.writerId === userData?.userId; - - return ( - - showDeleteModal('comment', String(comment.commentId)) - } - /> - ); - }) - ) : ( -
-
- -
-
- )} -
-
-
-
- - - ); -}; - -export default CommunityDetail; diff --git a/apps/client/src/pages/community/community-page.tsx b/apps/client/src/pages/community/community-page.tsx index fac5f6b8..09aa5cd0 100644 --- a/apps/client/src/pages/community/community-page.tsx +++ b/apps/client/src/pages/community/community-page.tsx @@ -1,91 +1,22 @@ -import { useInfiniteQuery } from '@tanstack/react-query'; -import { useNavigate } from 'react-router'; - -import { Alert, Floating, Navigation } from '@bds/ui'; +import { Navigation } from '@bds/ui'; import { Icon } from '@bds/ui/icons'; -import DetailComment from '@widgets/community/components/detail-comment/detail-comment'; -import EmptyPlaceholder from '@widgets/community/components/empty-placeholder/empty-placeholder'; -import { ALERT_CONTENT_BODY } from '@widgets/community/constant/alert-content'; -import { EMPTY_POST } from '@widgets/community/constant/empty-content'; +import CommunityPreview from '@widgets/community/components/community-preview/community-preview'; -import { COMMUNITY_QUERY_OPTIONS } from '@shared/api/domain/community/queries'; -import { useIntersectionObserver } from '@shared/hooks/use-intersection-observer'; +import { useNavigateTo } from '@shared/hooks/use-navigate-to'; import { routePath } from '@shared/router/path'; -import * as styles from './community-page.css'; -import { virtualRef } from '@widgets/mypage/preview.css'; - const CommunityPage = () => { - const navigate = useNavigate(); - const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = - useInfiniteQuery({ - ...COMMUNITY_QUERY_OPTIONS.POSTS(), - }); - - const feedObserverRef = useIntersectionObserver(() => { - if (hasNextPage && !isFetchingNextPage) { - fetchNextPage(); - } - }, true); - - const onClickWrite = () => { - navigate(routePath.COMMUNITY_WRITE); - }; - - const onClickHome = () => { - navigate(routePath.HOME); - }; - return ( -
+ <> } - onClickRight={onClickHome} + onClickRight={useNavigateTo(routePath.HOME)} title="커뮤니티" /> - -
- {data?.pages.some((page) => (page?.content ?? []).length > 0) ? ( - data.pages - .flatMap((page) => page?.content ?? []) - .map((post) => ( - navigate(`/community/detail/${post.postId}`)} - /> - )) - ) : ( -
-
- -
-
- )} -
-
- -
- } - state="default" - onClick={onClickWrite} - /> -
-
+ + ); }; diff --git a/apps/client/src/shared/hooks/use-navigate-to.tsx b/apps/client/src/shared/hooks/use-navigate-to.tsx new file mode 100644 index 00000000..258b6c08 --- /dev/null +++ b/apps/client/src/shared/hooks/use-navigate-to.tsx @@ -0,0 +1,13 @@ +import { useNavigate } from 'react-router-dom'; + +export const useNavigateTo = (path: string | number) => { + const navigate = useNavigate(); + + return () => { + if (typeof path === 'string') { + navigate(path); + } else { + navigate(path); + } + }; +}; diff --git a/apps/client/src/shared/router/lazy.ts b/apps/client/src/shared/router/lazy.ts index 35fcf674..9375d2fc 100644 --- a/apps/client/src/shared/router/lazy.ts +++ b/apps/client/src/shared/router/lazy.ts @@ -13,7 +13,7 @@ export const CommunityWrite = lazy( () => import('@pages/community/community-write/community-write'), ); export const CommunityDetail = lazy( - () => import('@pages/community/community-detail/community-detail'), + () => import('@pages/community/community-detail'), ); export const MyPage = lazy(() => import('@pages/my/my-page')); diff --git a/apps/client/src/widgets/community/components/comment-box/comment-box.css.ts b/apps/client/src/widgets/community/components/comment-input-box/comment-input-box.css.ts similarity index 100% rename from apps/client/src/widgets/community/components/comment-box/comment-box.css.ts rename to apps/client/src/widgets/community/components/comment-input-box/comment-input-box.css.ts diff --git a/apps/client/src/widgets/community/components/comment-box/comment-box.tsx b/apps/client/src/widgets/community/components/comment-input-box/comment-input-box.tsx similarity index 85% rename from apps/client/src/widgets/community/components/comment-box/comment-box.tsx rename to apps/client/src/widgets/community/components/comment-input-box/comment-input-box.tsx index 301c3662..0c4b253d 100644 --- a/apps/client/src/widgets/community/components/comment-box/comment-box.tsx +++ b/apps/client/src/widgets/community/components/comment-input-box/comment-input-box.tsx @@ -5,21 +5,21 @@ import { Icon } from '@bds/ui/icons'; import { PLACEHOLDER } from '@widgets/community/constant/input-placeholder'; -import * as styles from './comment-box.css'; +import * as styles from './comment-input-box.css'; -interface CommentBoxProps { +interface CommentInputBoxProps { value: string; onChange: (e: ChangeEvent) => void; errorState?: boolean; onSubmit: () => void; } -const CommentBox = ({ +const CommentInputBox = ({ value, onChange, errorState, onSubmit, -}: CommentBoxProps) => { +}: CommentInputBoxProps) => { const handleKeyDown = (e: KeyboardEvent) => { if (e.nativeEvent.isComposing) { return; @@ -52,4 +52,4 @@ const CommentBox = ({ ); }; -export default CommentBox; +export default CommentInputBox; diff --git a/apps/client/src/widgets/community/components/community-modal/community-modal.tsx b/apps/client/src/widgets/community/components/community-modal/community-modal.tsx new file mode 100644 index 00000000..573ab487 --- /dev/null +++ b/apps/client/src/widgets/community/components/community-modal/community-modal.tsx @@ -0,0 +1,59 @@ +import { Button, Modal } from '@bds/ui'; + +import { DELETE_MODAL } from '@widgets/community/constant/modal-delete-content'; + +interface CommunityModalProps { + type: 'feed' | 'comment'; + commentId?: string; + onClose: () => void; + onConfirmDeleteFeed: () => void; + onConfirmDeleteComment: (commentId: string) => void; +} + +const BUTTON_STATUS = { + CLOSE: '취소', + DELETE: '삭제', +}; + +const CommunityModal = ({ + type, + commentId, + onClose, + onConfirmDeleteFeed, + onConfirmDeleteComment, +}: CommunityModalProps) => { + const isFeed = type === 'feed'; + + const handleModalAction = () => { + if (isFeed) { + onConfirmDeleteFeed(); + } else if (commentId) { + onConfirmDeleteComment(commentId); + } + }; + + return ( + + + {isFeed ? DELETE_MODAL.FEED.title : DELETE_MODAL.COMMENT.title} + + + + + + + + + + ); +}; + +export default CommunityModal; diff --git a/apps/client/src/widgets/community/components/community-preview/community-preview.css.ts b/apps/client/src/widgets/community/components/community-preview/community-preview.css.ts new file mode 100644 index 00000000..b3208f87 --- /dev/null +++ b/apps/client/src/widgets/community/components/community-preview/community-preview.css.ts @@ -0,0 +1,15 @@ +import { style } from '@vanilla-extract/css'; + +export const bottomFloating = style({ + position: 'fixed', + bottom: '2.4rem', + right: '50%', + transform: 'translateX(199px)', + + '@media': { + 'screen and (max-width: 430px)': { + right: '1.6rem', + transform: 'none', + }, + }, +}); diff --git a/apps/client/src/widgets/community/components/community-preview/community-preview.tsx b/apps/client/src/widgets/community/components/community-preview/community-preview.tsx new file mode 100644 index 00000000..8f626b9b --- /dev/null +++ b/apps/client/src/widgets/community/components/community-preview/community-preview.tsx @@ -0,0 +1,48 @@ +import { useInfiniteQuery } from '@tanstack/react-query'; + +import { Alert, Floating } from '@bds/ui'; +import { Icon } from '@bds/ui/icons'; + +import FeedList from '@widgets/community/components/feed-list/feed-list'; +import { ALERT_CONTENT_BODY } from '@widgets/community/constant/alert-content'; + +import { COMMUNITY_QUERY_OPTIONS } from '@shared/api/domain/community/queries'; +import { useNavigateTo } from '@shared/hooks/use-navigate-to'; +import { routePath } from '@shared/router/path'; + +import * as styles from './community-preview.css'; +const CommunityPreview = () => { + const { data, fetchNextPage, hasNextPage, isFetchingNextPage } = + useInfiniteQuery({ + ...COMMUNITY_QUERY_OPTIONS.POSTS(), + }); + + return ( + <> + + + + +
+ } + state="default" + onClick={useNavigateTo(routePath.COMMUNITY_WRITE)} + /> +
+ + ); +}; + +export default CommunityPreview; diff --git a/apps/client/src/widgets/community/components/detail-section/detail-section.tsx b/apps/client/src/widgets/community/components/detail-section/detail-section.tsx new file mode 100644 index 00000000..5ecf8372 --- /dev/null +++ b/apps/client/src/widgets/community/components/detail-section/detail-section.tsx @@ -0,0 +1,69 @@ +import { useState } from 'react'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; + +import CommentInputBox from '@widgets/community/components/comment-input-box/comment-input-box'; +import FeedContent from '@widgets/community/components/feed-content/feed-content'; + +import { COMMUNITY_MUTATION_OPTIONS } from '@shared/api/domain/community/queries'; +import { COMMUNITY_QUERY_KEY } from '@shared/api/keys/query-key'; +import { + LIMIT_MEDIUM_TEXT, + LIMIT_SHORT_TEXT, +} from '@shared/constants/text-limits'; +import { useLimitedInput } from '@shared/hooks/use-limited-input'; + +interface DetailSectionProps { + postId: string; +} + +const DetailSection = ({ postId }: DetailSectionProps) => { + const [content, setContent] = useState(''); + const { isErrorState } = useLimitedInput(LIMIT_MEDIUM_TEXT, content.length); + const queryClient = useQueryClient(); + const { mutate: createCommentMutate } = useMutation({ + ...COMMUNITY_MUTATION_OPTIONS.POST_COMMENT(), + onSuccess: (_data, variables) => { + queryClient.invalidateQueries({ + queryKey: COMMUNITY_QUERY_KEY.COMMENTS(variables.postId), + }); + queryClient.invalidateQueries({ + queryKey: COMMUNITY_QUERY_KEY.FEED_DETAIL(variables.postId), + }); + }, + }); + + const handleChange = (e: React.ChangeEvent) => { + if (e.target.value.length <= LIMIT_SHORT_TEXT) { + setContent(e.target.value); + } + }; + + const onSubmitComment = () => { + if (!content.trim()) { + return; + } + createCommentMutate( + { postId, content: content.trim() }, + { + onSuccess: () => { + setContent(''); + }, + }, + ); + }; + + return ( + <> + + + + + ); +}; + +export default DetailSection; diff --git a/apps/client/src/widgets/community/components/feed-content/feed-content.css.ts b/apps/client/src/widgets/community/components/feed-content/feed-content.css.ts new file mode 100644 index 00000000..9f5a63c1 --- /dev/null +++ b/apps/client/src/widgets/community/components/feed-content/feed-content.css.ts @@ -0,0 +1,8 @@ +import { style } from '@vanilla-extract/css'; + +export const container = style({ + display: 'flex', + flexDirection: 'column', + padding: '2.4rem 1.6rem 0 1.6rem', + gap: '1.6rem', +}); diff --git a/apps/client/src/widgets/community/components/feed-content/feed-content.tsx b/apps/client/src/widgets/community/components/feed-content/feed-content.tsx new file mode 100644 index 00000000..4d0f6273 --- /dev/null +++ b/apps/client/src/widgets/community/components/feed-content/feed-content.tsx @@ -0,0 +1,116 @@ +import { useMutation, useSuspenseQuery } from '@tanstack/react-query'; +import { useNavigate } from 'react-router-dom'; + +import { useModal } from '@bds/ui'; + +import CommunityModal from '@widgets/community/components/community-modal/community-modal'; +import FeedDetailInfo from '@widgets/community/components/feed-detail-info/feed-detail-info'; +import UserCommentList from '@widgets/community/components/user-comment-list/user-comment-list'; +import { ModalType } from '@widgets/community/types/community-modal.type'; + +import { + COMMUNITY_MUTATION_OPTIONS, + COMMUNITY_QUERY_OPTIONS, +} from '@shared/api/domain/community/queries'; +import { USER_QUERY_OPTIONS } from '@shared/api/domain/onboarding/queries'; +import { COMMUNITY_QUERY_KEY } from '@shared/api/keys/query-key'; +import { routePath } from '@shared/router/path'; +import { getTimeAgo } from '@shared/utils/get-time-ago'; +import { queryClient } from '@shared/utils/query-client'; + +import * as styles from './feed-content.css'; + +interface FeedContentProps { + postId: string; +} + +const FeedContent = ({ postId }: FeedContentProps) => { + const navigate = useNavigate(); + const { openModal, closeModal } = useModal(); + + const { data: feedDetailData } = useSuspenseQuery( + COMMUNITY_QUERY_OPTIONS.FEED_DETAIL(postId), + ); + + const { data: profileData } = useSuspenseQuery(USER_QUERY_OPTIONS.PROFILE()); + + const userData = profileData?.data; + const isPostOwner = feedDetailData?.writerId === userData?.userId; + + const { mutate: deleteFeedMutate } = useMutation({ + ...COMMUNITY_MUTATION_OPTIONS.DELETE_FEED(postId), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: COMMUNITY_QUERY_KEY.FEED_PREVIEW(), + }); + navigate(routePath.COMMUNITY); + }, + }); + + const { mutate: deleteCommentMutate } = useMutation({ + ...COMMUNITY_MUTATION_OPTIONS.DELETE_COMMENT(postId), + onSuccess: () => { + queryClient.invalidateQueries({ + queryKey: COMMUNITY_QUERY_KEY.COMMENTS(postId), + }); + queryClient.invalidateQueries({ + queryKey: COMMUNITY_QUERY_KEY.FEED_DETAIL(postId), + }); + }, + }); + + const showDeleteModal = (type: ModalType, commentId?: string) => { + openModal( + , + ); + }; + + const handleDeleteFeed = () => { + deleteFeedMutate(); + closeModal(); + }; + + const handleDeleteComment = (commentId: string) => { + deleteCommentMutate(commentId); + closeModal(); + }; + + const handleGoEdit = () => { + navigate(routePath.COMMUNITY_EDIT.replace(':postId', String(postId)), { + state: { + title: feedDetailData?.title, + content: feedDetailData?.content, + }, + }); + }; + + return ( +
+ showDeleteModal('feed')} + /> + + showDeleteModal('comment', commentId)} + /> +
+ ); +}; + +export default FeedContent; diff --git a/apps/client/src/widgets/community/components/post-detail-info/post-detail-info.css.ts b/apps/client/src/widgets/community/components/feed-detail-info/feed-detail-info.css.ts similarity index 100% rename from apps/client/src/widgets/community/components/post-detail-info/post-detail-info.css.ts rename to apps/client/src/widgets/community/components/feed-detail-info/feed-detail-info.css.ts diff --git a/apps/client/src/widgets/community/components/post-detail-info/post-detail-info.tsx b/apps/client/src/widgets/community/components/feed-detail-info/feed-detail-info.tsx similarity index 83% rename from apps/client/src/widgets/community/components/post-detail-info/post-detail-info.tsx rename to apps/client/src/widgets/community/components/feed-detail-info/feed-detail-info.tsx index 8e1ba96d..0c7500fc 100644 --- a/apps/client/src/widgets/community/components/post-detail-info/post-detail-info.tsx +++ b/apps/client/src/widgets/community/components/feed-detail-info/feed-detail-info.tsx @@ -2,9 +2,9 @@ import { Content, Title } from '@bds/ui'; import UserDetailMeta from '@widgets/community/components/user-detail-meta/user-detail-meta'; -import * as styles from './post-detail-info.css'; +import * as styles from './feed-detail-info.css'; -interface PostDetailInfoProps { +interface FeedDetailInfoProps { nickname: string; createdAt: string; profileImage: string; @@ -15,7 +15,7 @@ interface PostDetailInfoProps { onDeleteClick: () => void; } -export const PostDetailInfo = ({ +export const FeedDetailInfo = ({ nickname, createdAt, profileImage, @@ -24,7 +24,7 @@ export const PostDetailInfo = ({ content, onEditClick, onDeleteClick, -}: PostDetailInfoProps) => { +}: FeedDetailInfoProps) => { return (
{ +}: FeedListItemProps) => { return (
@@ -49,4 +49,4 @@ const DetailComment = ({ ); }; -export default DetailComment; +export default FeedListItem; diff --git a/apps/client/src/pages/community/community-page.css.ts b/apps/client/src/widgets/community/components/feed-list/feed-list.css.ts similarity index 56% rename from apps/client/src/pages/community/community-page.css.ts rename to apps/client/src/widgets/community/components/feed-list/feed-list.css.ts index da5154f6..87d55a73 100644 --- a/apps/client/src/pages/community/community-page.css.ts +++ b/apps/client/src/widgets/community/components/feed-list/feed-list.css.ts @@ -1,8 +1,14 @@ import { style } from '@vanilla-extract/css'; -export const container = style({ +export const mapCommunityListContainer = style({ display: 'flex', flexDirection: 'column', + padding: '2.4rem 1.6rem 0', + gap: '1.6rem', +}); + +export const placeholder = style({ + height: 'calc(100svh - 20rem)', }); export const emptyPlaceholder = style({ @@ -13,28 +19,3 @@ export const emptyPlaceholder = style({ alignItems: 'center', justifyContent: 'center', }); - -export const mapCommunityListContainer = style({ - display: 'flex', - flexDirection: 'column', - padding: '2.4rem 1.6rem 0', - gap: '1.6rem', -}); - -export const bottomFloating = style({ - position: 'fixed', - bottom: '2.4rem', - right: '50%', - transform: 'translateX(199px)', - - '@media': { - 'screen and (max-width: 430px)': { - right: '1.6rem', - transform: 'none', - }, - }, -}); - -export const placeholder = style({ - height: 'calc(100svh - 20rem)', -}); diff --git a/apps/client/src/widgets/community/components/feed-list/feed-list.tsx b/apps/client/src/widgets/community/components/feed-list/feed-list.tsx new file mode 100644 index 00000000..6e2b054e --- /dev/null +++ b/apps/client/src/widgets/community/components/feed-list/feed-list.tsx @@ -0,0 +1,62 @@ +import { InfiniteData } from '@tanstack/react-query'; +import { useNavigate } from 'react-router-dom'; + +import EmptyPlaceholder from '@widgets/community/components/empty-placeholder/empty-placeholder'; +import FeedListItem from '@widgets/community/components/feed-list-item/feed-list-item'; +import { EMPTY_POST } from '@widgets/community/constant/empty-content'; + +import { FeedPreviewResponse } from '@shared/api/types/types'; +import { useIntersectionObserver } from '@shared/hooks/use-intersection-observer'; + +import * as styles from './feed-list.css'; +import { virtualRef } from '@widgets/mypage/preview.css'; + +interface FeedListProps { + data?: InfiniteData; + fetchNextPage: () => void; + hasNextPage: boolean; + isFetchingNextPage: boolean; +} + +const FeedList = ({ + data, + fetchNextPage, + hasNextPage, + isFetchingNextPage, +}: FeedListProps) => { + const navigate = useNavigate(); + const feedObserverRef = useIntersectionObserver(() => { + if (hasNextPage && !isFetchingNextPage) { + fetchNextPage(); + } + }, true); + return ( +
+ {data?.pages.some((page) => (page?.content ?? []).length > 0) ? ( + data.pages + .flatMap((page) => page?.content ?? []) + .map((post) => ( + navigate(`/community/detail/${post.postId}`)} + /> + )) + ) : ( +
+
+ +
+
+ )} +
+
+ ); +}; + +export default FeedList; diff --git a/apps/client/src/pages/community/community-detail/community-detail.css.ts b/apps/client/src/widgets/community/components/user-comment-list/user-comment-list.css.ts similarity index 85% rename from apps/client/src/pages/community/community-detail/community-detail.css.ts rename to apps/client/src/widgets/community/components/user-comment-list/user-comment-list.css.ts index 274a9ae1..2d878994 100644 --- a/apps/client/src/pages/community/community-detail/community-detail.css.ts +++ b/apps/client/src/widgets/community/components/user-comment-list/user-comment-list.css.ts @@ -2,13 +2,6 @@ import { style } from '@vanilla-extract/css'; import { themeVars } from '@bds/ui/styles'; -export const container = style({ - display: 'flex', - flexDirection: 'column', - padding: '2.4rem 1.6rem 0 1.6rem', - gap: '1.6rem', -}); - export const commentMapContainer = style({ display: 'flex', flexDirection: 'column', @@ -46,3 +39,10 @@ export const emptyPlaceholder = style({ export const placeholder = style({ height: 'calc(100svh - 50rem)', }); + +export const virtualRef = style({ + display: 'block', + height: '2rem', + width: '1px', + flexShrink: 0, +}); diff --git a/apps/client/src/widgets/community/components/user-comment-list/user-comment-list.tsx b/apps/client/src/widgets/community/components/user-comment-list/user-comment-list.tsx new file mode 100644 index 00000000..96764f58 --- /dev/null +++ b/apps/client/src/widgets/community/components/user-comment-list/user-comment-list.tsx @@ -0,0 +1,91 @@ +import { useInfiniteQuery } from '@tanstack/react-query'; + +import { Icon } from '@bds/ui/icons'; + +import EmptyPlaceholder from '@widgets/community/components/empty-placeholder/empty-placeholder'; +import UserComment from '@widgets/community/components/user-comment/user-comment'; +import { EMPTY_COMMENT } from '@widgets/community/constant/empty-content'; + +import { COMMUNITY_QUERY_OPTIONS } from '@shared/api/domain/community/queries'; +import { FeedDetailResponse } from '@shared/api/types/types'; +import { useIntersectionObserver } from '@shared/hooks/use-intersection-observer'; +import { getTimeAgo } from '@shared/utils/get-time-ago'; + +import * as styles from './user-comment-list.css'; + +interface UserCommentListProps { + postId: string; + commentOwnerId?: number; + feedDetailData?: FeedDetailResponse | null; + onDeleteClick: (commentId: string) => void; +} + +const UserCommentList = ({ + postId, + commentOwnerId, + feedDetailData, + onDeleteClick, +}: UserCommentListProps) => { + const { + data: comments, + fetchNextPage, + hasNextPage, + isFetchingNextPage, + } = useInfiniteQuery({ + ...COMMUNITY_QUERY_OPTIONS.COMMENTS(postId), + }); + + const allComments = + comments?.pages.flatMap((page) => page?.data?.content ?? []) ?? []; + + const commentsObserverRef = useIntersectionObserver(() => { + if (hasNextPage && !isFetchingNextPage) { + fetchNextPage(); + } + }, true); + + if (!comments) { + return null; + } + return ( +
+
+
+ +

+ 댓글 {feedDetailData?.commentCount} +

+
+ +
+ {allComments.length > 0 ? ( + allComments.map((comment) => { + const isCommentOwner = comment.writerId === commentOwnerId; + + return ( + onDeleteClick(String(comment.commentId))} + /> + ); + }) + ) : ( +
+
+ +
+
+ )} +
+
+
+
+ ); +}; + +export default UserCommentList; diff --git a/apps/client/src/widgets/community/constant/detail-content.ts b/apps/client/src/widgets/community/constant/detail-content.ts deleted file mode 100644 index d9bdd3bb..00000000 --- a/apps/client/src/widgets/community/constant/detail-content.ts +++ /dev/null @@ -1 +0,0 @@ -export const POINT = '•'; diff --git a/apps/client/src/widgets/community/constant/modal-delete-content.ts b/apps/client/src/widgets/community/constant/modal-delete-content.ts new file mode 100644 index 00000000..ce9e36d2 --- /dev/null +++ b/apps/client/src/widgets/community/constant/modal-delete-content.ts @@ -0,0 +1,10 @@ +export const DELETE_MODAL = { + FEED: { + title: '이 글을 삭제할까요?', + content: '삭제한 글/댓글은 복원되지 않습니다.', + }, + COMMENT: { + title: '이 댓글을 삭제할까요?', + content: '삭제한 댓글은 복원되지 않습니다.', + }, +}; diff --git a/apps/client/src/widgets/community/types/community-modal.type.ts b/apps/client/src/widgets/community/types/community-modal.type.ts new file mode 100644 index 00000000..246765a8 --- /dev/null +++ b/apps/client/src/widgets/community/types/community-modal.type.ts @@ -0,0 +1 @@ +export type ModalType = 'feed' | 'comment'; diff --git a/apps/client/src/widgets/report/components/accordion/accordion.css.ts b/apps/client/src/widgets/report/components/accordion/accordion.css.ts index 1a800509..d2dba897 100644 --- a/apps/client/src/widgets/report/components/accordion/accordion.css.ts +++ b/apps/client/src/widgets/report/components/accordion/accordion.css.ts @@ -34,25 +34,36 @@ export const icon = style({ transition: 'transform 0.3s ease', }); -export const panelContainer = recipe({ +export const panelAllContainer = recipe({ base: { overflow: 'hidden', - transition: 'max-height 0.2s ease, opacity 0.25s ease, padding 0.3s ease', - display: 'flex', - flexDirection: 'column', - gap: '2.4rem', + transition: 'max-height 300ms ease, opacity 300ms ease', }, variants: { - expanded: { - true: { - maxHeight: '90rem', + state: { + hidden: { + transition: 'none', + maxHeight: '0', + opacity: '0', + }, + open: { + maxHeight: 'var(--accordion-height, 0)', opacity: 1, - paddingTop: '2.4rem ', }, - false: { + closed: { maxHeight: '0', opacity: '0', }, }, }, + defaultVariants: { + state: 'hidden', + }, +}); + +export const panelContainer = style({ + display: 'flex', + flexDirection: 'column', + gap: '2.4rem', + paddingTop: '1.6rem', }); diff --git a/apps/client/src/widgets/report/components/accordion/accordion.tsx b/apps/client/src/widgets/report/components/accordion/accordion.tsx index db15a5b9..d4760743 100644 --- a/apps/client/src/widgets/report/components/accordion/accordion.tsx +++ b/apps/client/src/widgets/report/components/accordion/accordion.tsx @@ -8,6 +8,7 @@ import Chip from '../chip/chip'; import Title from '../title/title'; import { AccordionContextProvider } from './context-provider'; import { useAccordionContext } from './hooks/use-context'; +import { useMeasureHeight } from './hooks/use-measure-height'; import * as styles from './accordion.css'; @@ -27,10 +28,13 @@ interface accordionPanelProps { children: ReactNode; } -export const Accordion = ({ - children, - defaultExpanded = false, -}: accordionProps) => { +interface AccordionPanelStyle extends React.CSSProperties { + '--accordion-height'?: string; +} + +export const Accordion = ({ children }: accordionProps) => { + const defaultExpanded = false; + return (
{children}
@@ -44,15 +48,14 @@ export const AccordionHeader = ({ accordionCategory, onClick, }: accordionHeaderProps) => { - const { expanded, handleClick } = useAccordionContext(); + const { isOpen, handleClick } = useAccordionContext(); const handleAccordionClick = () => { - handleClick(); if (accordionCategory) { onClick?.(accordionCategory); } + handleClick(); }; - return (
@@ -65,7 +68,7 @@ export const AccordionHeader = ({ name="caret_up_lg" size="2.4rem" color="gray800" - rotate={expanded ? undefined : 180} + rotate={isOpen ? undefined : 180} />
@@ -73,9 +76,31 @@ export const AccordionHeader = ({ }; export const AccordionPanel = ({ children }: accordionPanelProps) => { - const { expanded } = useAccordionContext(); + const { isOpen } = useAccordionContext(); + const { ref, height } = useMeasureHeight(); - return
{children}
; + const ready = height > 0; + const state: 'hidden' | 'open' | 'closed' = ready + ? isOpen + ? 'open' + : 'closed' + : 'hidden'; + + const panelStyle: AccordionPanelStyle = { + '--accordion-height': `${height}px`, + }; + + return ( +
+
+ {children} +
+
+ ); }; Accordion.Header = AccordionHeader; diff --git a/apps/client/src/widgets/report/components/accordion/context-provider.tsx b/apps/client/src/widgets/report/components/accordion/context-provider.tsx index d491d6dd..2ec3c9b7 100644 --- a/apps/client/src/widgets/report/components/accordion/context-provider.tsx +++ b/apps/client/src/widgets/report/components/accordion/context-provider.tsx @@ -8,15 +8,16 @@ interface AccordionContextProviderProps { } export const AccordionContextProvider = ({ children, - defaultExpanded = false, + defaultExpanded, }: AccordionContextProviderProps) => { - const [expanded, setExpanded] = useState(defaultExpanded); + const [isOpen, setIsOpen] = useState(defaultExpanded); const handleClick = () => { - setExpanded((prev) => !prev); + setIsOpen((prev) => !prev); }; + return ( - + {children} ); diff --git a/apps/client/src/widgets/report/components/accordion/hooks/use-context.ts b/apps/client/src/widgets/report/components/accordion/hooks/use-context.tsx similarity index 95% rename from apps/client/src/widgets/report/components/accordion/hooks/use-context.ts rename to apps/client/src/widgets/report/components/accordion/hooks/use-context.tsx index ba7a9bb9..c267d578 100644 --- a/apps/client/src/widgets/report/components/accordion/hooks/use-context.ts +++ b/apps/client/src/widgets/report/components/accordion/hooks/use-context.tsx @@ -1,7 +1,7 @@ import { createContext, useContext } from 'react'; interface useAccordionContextProps { - expanded: boolean; + isOpen: boolean; handleClick: () => void; } diff --git a/apps/client/src/widgets/report/components/accordion/hooks/use-measure-height.tsx b/apps/client/src/widgets/report/components/accordion/hooks/use-measure-height.tsx new file mode 100644 index 00000000..e957ca60 --- /dev/null +++ b/apps/client/src/widgets/report/components/accordion/hooks/use-measure-height.tsx @@ -0,0 +1,23 @@ +import { useLayoutEffect, useRef, useState } from 'react'; + +export const useMeasureHeight = () => { + const ref = useRef(null); + const [height, setHeight] = useState(0); + + useLayoutEffect(() => { + const element = ref.current; + if (!element) { + return; + } + + const measureHeight = () => setHeight(element.scrollHeight); + + measureHeight(); + const resizeObserver = new ResizeObserver(measureHeight); + resizeObserver.observe(element); + + return () => resizeObserver.disconnect(); + }, []); + + return { ref, height }; +}; diff --git a/apps/client/src/widgets/report/components/ipwon/components/sanghae.tsx b/apps/client/src/widgets/report/components/ipwon/components/sanghae.tsx index 15bf0cb3..ce188d37 100644 --- a/apps/client/src/widgets/report/components/ipwon/components/sanghae.tsx +++ b/apps/client/src/widgets/report/components/ipwon/components/sanghae.tsx @@ -18,6 +18,7 @@ interface SanghaeProps { const Sanghae = ({ target, status, onClick, data }: SanghaeProps) => { const hasCoverage = data?.diseaseDailyHospitalization?.productCoverage == 0; + return ( { const hasCoverage = data?.coverage?.productCoverage == 0; + return ( { const hasCoverage = data?.coverage?.productCoverage == 0; + return ( { {target} - + {data && data?.additionalInfo && ( + + )}
{data?.sections?.map(({ displayName, diagnosis, injury }) => { if (!displayName) { diff --git a/apps/client/src/widgets/report/components/keunbyeong/components/noehyeolgwan.tsx b/apps/client/src/widgets/report/components/keunbyeong/components/noehyeolgwan.tsx index 14d96a20..56706351 100644 --- a/apps/client/src/widgets/report/components/keunbyeong/components/noehyeolgwan.tsx +++ b/apps/client/src/widgets/report/components/keunbyeong/components/noehyeolgwan.tsx @@ -34,7 +34,13 @@ const Noehyeolgwan = ({ onClick, data, target, status }: NoehyeolgwanProps) => { {target} - + {data && data?.additionalInfo && ( + + )}
{data?.sections?.map(({ displayName, diagnosis, injury }) => { if (!displayName) { diff --git a/apps/client/src/widgets/report/components/keunbyeong/components/shimjang.tsx b/apps/client/src/widgets/report/components/keunbyeong/components/shimjang.tsx index 77a31e34..36287670 100644 --- a/apps/client/src/widgets/report/components/keunbyeong/components/shimjang.tsx +++ b/apps/client/src/widgets/report/components/keunbyeong/components/shimjang.tsx @@ -34,7 +34,13 @@ const Shimjang = ({ onClick, data, target, status }: ShimjangProps) => { {target} - + {data && data?.additionalInfo && ( + + )}
{data?.sections?.map(({ displayName, diagnosis, injury }) => { if (!displayName) { diff --git a/apps/client/src/widgets/report/components/samang/components/sanghae.tsx b/apps/client/src/widgets/report/components/samang/components/sanghae.tsx index 1e1297a1..c211471b 100644 --- a/apps/client/src/widgets/report/components/samang/components/sanghae.tsx +++ b/apps/client/src/widgets/report/components/samang/components/sanghae.tsx @@ -18,6 +18,7 @@ interface SanghaeProps { const Sanghae = ({ target, status, onClick, data }: SanghaeProps) => { const hasCoverage = data?.coverage?.productCoverage == 0; + return ( void; data: InsuranceSusulReport['data']; target?: string; status?: StatusType; } -const JilbyeongClass = ({ onClick, data, target, status }: JilbyeongProps) => { +const JilbyeongClass = ({ + onClick, + data, + target, + status, +}: JilbyeongClassProps) => { const surgeryList = Object.values(data?.surgeryType ?? {}); const averageValues = surgeryList.map( @@ -39,21 +44,22 @@ const JilbyeongClass = ({ onClick, data, target, status }: JilbyeongProps) => { {target} - {hasCoverage ? ( - - ) : ( - - )} + {data && + (hasCoverage ? ( + + ) : ( + + ))}
diff --git a/apps/client/src/widgets/report/components/susul/components/jilbyeong.tsx b/apps/client/src/widgets/report/components/susul/components/jilbyeong.tsx index f83a03c0..1b660d23 100644 --- a/apps/client/src/widgets/report/components/susul/components/jilbyeong.tsx +++ b/apps/client/src/widgets/report/components/susul/components/jilbyeong.tsx @@ -9,14 +9,14 @@ import { StatusType } from '@shared/types/type'; import { Accordion } from '../../accordion/accordion'; import Graph from '../../graph/graph'; -interface JilbyeongClassProps { +interface JilbyeongProps { onClick: (category: string) => void; data: InsuranceSusulReport['data']; target?: string; status?: StatusType; } -const Jilbyeong = ({ target, status, onClick, data }: JilbyeongClassProps) => { +const Jilbyeong = ({ target, status, onClick, data }: JilbyeongProps) => { const hasCoverage = data?.surgery?.productCoverage == 0; return ( diff --git a/apps/client/src/widgets/report/components/susul/components/sanghae-class.tsx b/apps/client/src/widgets/report/components/susul/components/sanghae-class.tsx index 19bdc506..88a83e71 100644 --- a/apps/client/src/widgets/report/components/susul/components/sanghae-class.tsx +++ b/apps/client/src/widgets/report/components/susul/components/sanghae-class.tsx @@ -9,14 +9,14 @@ import { StatusType } from '@shared/types/type'; import { Accordion } from '../../accordion/accordion'; import Class from '../../class/class'; -interface SanghaeProps { +interface SanghaeClassProps { onClick: (category: string) => void; data: InsuranceSusulReport['data']; target?: string; status?: StatusType; } -const SanghaeClass = ({ target, status, onClick, data }: SanghaeProps) => { +const SanghaeClass = ({ target, status, onClick, data }: SanghaeClassProps) => { const surgeryList = Object.values(data?.surgeryType ?? {}); const averageValues = surgeryList.map( @@ -39,21 +39,22 @@ const SanghaeClass = ({ target, status, onClick, data }: SanghaeProps) => { {target} - {hasCoverage ? ( - - ) : ( - - )} + {data && + (hasCoverage ? ( + + ) : ( + + ))}
diff --git a/apps/client/src/widgets/report/components/susul/components/sanghae.tsx b/apps/client/src/widgets/report/components/susul/components/sanghae.tsx index eaacc997..3477fe9b 100644 --- a/apps/client/src/widgets/report/components/susul/components/sanghae.tsx +++ b/apps/client/src/widgets/report/components/susul/components/sanghae.tsx @@ -9,15 +9,16 @@ import { StatusType } from '@shared/types/type'; import { Accordion } from '../../accordion/accordion'; import Graph from '../../graph/graph'; -interface SanghaeClassProps { +interface SanghaeProps { onClick: (category: string) => void; data: InsuranceSusulReport['data']; target?: string; status?: StatusType; } -const Sanghae = ({ target, status, data, onClick }: SanghaeClassProps) => { +const Sanghae = ({ target, status, data, onClick }: SanghaeProps) => { const hasCoverage = data?.surgery?.productCoverage == 0; + return (
diff --git a/package.json b/package.json index 5c00a935..61064733 100644 --- a/package.json +++ b/package.json @@ -16,26 +16,16 @@ "version": "changeset version", "release": "pnpm build && changeset publish" }, - "dependencies": { - "react": "^19.1.0", - "react-dom": "^19.1.0" - }, "devDependencies": { + "@changesets/changelog-github": "^0.5.1", "@changesets/cli": "^2.29.5", "@commitlint/cli": "^19.8.1", "@commitlint/config-conventional": "^19.8.1", "@types/react": "^19.1.8", "@types/react-dom": "^19.1.6", - "@vanilla-extract/css": "^1.17.4", - "@vanilla-extract/sprinkles": "^1.6.5", - "@vanilla-extract/vite-plugin": "^5.1.0", - "@vitejs/plugin-react-swc": "^3.10.2", - "@vitejs/plugin-react": "^4.5.2", - "globals": "^16.2.0", "lefthook": "^1.11.14", "prettier": "^3.6.1", "turbo": "^2.5.4", - "typescript": "~5.8.3", - "vite": "^7.0.0" + "typescript": "~5.8.3" } } diff --git a/packages/bds-ui/CHANGELOG.md b/packages/bds-ui/CHANGELOG.md index 9b325191..2bfc53cb 100644 --- a/packages/bds-ui/CHANGELOG.md +++ b/packages/bds-ui/CHANGELOG.md @@ -1,5 +1,11 @@ # @bds/ui +## 1.1.0 + +### Minor Changes + +- [#375](https://github.com/team-bofit/bofit-client/pull/375) [`cc2d41d`](https://github.com/team-bofit/bofit-client/commit/cc2d41de09b3e95c4c5bd015b174c940655d7c8c) Thanks [@minjeoong](https://github.com/minjeoong)! - refactoring 1th + ## 1.0.0 ### Major Changes diff --git a/packages/bds-ui/package.json b/packages/bds-ui/package.json index ee3a6bf1..1a4d83f7 100644 --- a/packages/bds-ui/package.json +++ b/packages/bds-ui/package.json @@ -1,6 +1,6 @@ { "name": "@bds/ui", - "version": "1.0.0", + "version": "1.1.0", "private": true, "exports": { ".": "./src/components/index.ts", @@ -27,22 +27,22 @@ "@storybook/react": "8.6.14", "@storybook/react-vite": "8.6.14", "@turbo/gen": "^1.12.4", - "@types/node": "^20.11.24", - "@types/react": "^19.1.8", - "@types/react-dom": "^19.0.1", - "@vanilla-extract/css": "*", - "@vanilla-extract/recipes": "^0.5.7", - "@vanilla-extract/sprinkles": "*", - "@vanilla-extract/vite-plugin": "*", - "@vitejs/plugin-react": "*", + "@types/node": "catalog:typescript-core", + "@types/react": "catalog:react-core", + "@types/react-dom": "catalog:react-core", + "@vanilla-extract/css": "catalog:vanilla-extract-core", + "@vanilla-extract/recipes": "catalog:vanilla-extract-core", + "@vanilla-extract/sprinkles": "catalog:vanilla-extract-utils", + "@vanilla-extract/vite-plugin": "catalog:vanilla-extract-utils", + "vite": "catalog:vite-core", + "@vitejs/plugin-react": "catalog:vite-plugins", + "typescript": "catalog:typescript-core", "chromatic": "^13.1.2", "storybook": "8.6.14", - "tsx": "^4.20.3", - "typescript": "^5.3.3", - "vite": "*" + "tsx": "^4.20.3" }, "dependencies": { - "react": "^19.1.0", - "react-dom": "^19.0.0" + "react": "catalog:react-core", + "react-dom": "catalog:react-core" } } diff --git a/packages/bds-ui/src/components/alert/alert.css.ts b/packages/bds-ui/src/components/alert/alert.css.ts index 15e37ada..1f6b9e28 100644 --- a/packages/bds-ui/src/components/alert/alert.css.ts +++ b/packages/bds-ui/src/components/alert/alert.css.ts @@ -30,6 +30,7 @@ export const alerIconContainer = recipe({ base: { display: 'flex', alignContent: 'center', + flexShrink: 0, }, variants: { type: { @@ -70,3 +71,7 @@ export const alertContents = recipe({ }, }, }); + +export const iconStyle = style({ + flexShrink: 0, +}); diff --git a/packages/bds-ui/src/components/alert/alert.stories.tsx b/packages/bds-ui/src/components/alert/alert.stories.tsx new file mode 100644 index 00000000..09a34f1c --- /dev/null +++ b/packages/bds-ui/src/components/alert/alert.stories.tsx @@ -0,0 +1,109 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import Alert from './alert'; + +const meta: Meta = { + title: 'Common/Alert', + component: Alert, + parameters: { + layout: 'centered', + docs: { + description: { + component: `\n**Alert** 컴포넌트는 커뮤니티 페이지에서는 주의사항 정보를, 보험 추천 페이지에서는 추가 정보를 사용자에게 알려줄 때 사용합니다.\n\n## Types\n- **info**: 일반 정보 안내.\n- **additional**: 보조/추가 안내. 본문 내 \`highlight\`가 [ 대괄호 ]로 강조됩니다.\n\n## Props 요약\n- **iconName**: 'info' | 'info_warning' 아이콘 중 선택\n- **iconSize**: 아이콘 크기(px 또는 rem 등 단위 포함 문자열)\n- **alertHeader**: 상단 제목 (예: '알려드려요 ', '참고하세요')\n- **alertContents**: 본문 내용\n- **type**: 'info' | 'additional' (info: 알림, additional: 강조)\n- **highlight?**: type이 'additional'일 때만 사용되는 강조 텍스트\n `, + }, + }, + }, + argTypes: { + type: { + control: { type: 'select' }, + options: ['info', 'additional'], + description: '알림의 성격을 선택합니다.', + table: { + type: { summary: 'info | additional' }, + }, + }, + iconName: { + control: { type: 'select' }, + options: ['info', 'info_warning'], + description: '사용할 아이콘을 선택합니다.', + table: { + type: { summary: "'info' | 'info_warning'" }, + }, + }, + iconSize: { + control: { type: 'select' }, + options: ['2.4rem', '2rem'], + description: '아이콘 크기를 지정합니다.', + table: { + type: { summary: "'2.4rem' | '2rem'" }, + }, + }, + alertHeader: { + control: { type: 'text' }, + description: '알림 상단 헤더 문구입니다.', + table: { + type: { summary: 'string' }, + }, + }, + alertContents: { + control: { type: 'text' }, + description: '알림 본문 내용입니다.', + table: { + type: { summary: 'string' }, + }, + }, + highlight: { + control: { type: 'text' }, + description: + "type이 'additional'일 때만 의미가 있는 강조 텍스트입니다. 자동으로 [대괄호]로 감싸집니다.", + table: { + type: { summary: 'string' }, + }, + }, + }, + tags: ['autodocs'], +}; + +export default meta; + +type Story = StoryObj; + +// 정보 안내형 +export const Info: Story = { + args: { + type: 'info', + iconName: 'info', + iconSize: '2.4rem', + alertHeader: '알려드려요', + alertContents: + '이곳은 보험 정보를 자유롭게 나누는 공간이에요. \n전문가의 참여는 환영하지만, 영업이나 광고 목적의 활동은 금지돼요. \n서로의 경험을 나누며 신뢰할 수 있는 정보를 함께 만들어가요!', + }, + parameters: { + docs: { + description: { + story: + '커뮤니티 페이지에 사용되는 커뮤니티에서 주의해야 할 정보를 제공하는 유형입니다.', + }, + }, + }, +}; + +// 추가 안내형 (highlight 사용) +export const Additional: Story = { + args: { + type: 'additional', + iconName: 'info_warning', + iconSize: '2rem', + alertHeader: '참고하세요', + alertContents: ' 은 이 보험에 포함되지 않아요.', + highlight: '부정맥, 심부전', + }, + parameters: { + docs: { + description: { + story: + "보조/추가 안내용입니다. `highlight`가 앞에 '[주의]'처럼 강조되어 표시됩니다.", + }, + }, + }, +}; diff --git a/packages/bds-ui/src/components/alert/alert.tsx b/packages/bds-ui/src/components/alert/alert.tsx index dd1ac804..a34fa307 100644 --- a/packages/bds-ui/src/components/alert/alert.tsx +++ b/packages/bds-ui/src/components/alert/alert.tsx @@ -31,10 +31,11 @@ const Alert = ({

{alertHeader}

diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5131ee57..6f4fe88b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,16 +4,56 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + react-core: + '@types/react': + specifier: ^19.1.8 + version: 19.1.8 + '@types/react-dom': + specifier: ^19.0.1 + version: 19.1.6 + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0 + typescript-core: + '@types/node': + specifier: ^20.11.24 + version: 20.19.9 + typescript: + specifier: ~5.8.3 + version: 5.8.3 + vanilla-extract-core: + '@vanilla-extract/css': + specifier: ^1.17.4 + version: 1.17.4 + '@vanilla-extract/recipes': + specifier: ^0.5.7 + version: 0.5.7 + vanilla-extract-utils: + '@vanilla-extract/sprinkles': + specifier: ^1.6.5 + version: 1.6.5 + '@vanilla-extract/vite-plugin': + specifier: ^5.1.0 + version: 5.1.0 + vite-core: + vite: + specifier: ^7.0.0 + version: 7.0.5 + vite-plugins: + '@vitejs/plugin-react': + specifier: ^4.5.2 + version: 4.7.0 + importers: .: - dependencies: - react: - specifier: ^19.1.0 - version: 19.1.0 - react-dom: - specifier: ^19.1.0 - version: 19.1.0(react@19.1.0) devDependencies: + '@changesets/changelog-github': + specifier: ^0.5.1 + version: 0.5.1 '@changesets/cli': specifier: ^2.29.5 version: 2.29.5 @@ -29,24 +69,6 @@ importers: '@types/react-dom': specifier: ^19.1.6 version: 19.1.6(@types/react@19.1.8) - '@vanilla-extract/css': - specifier: ^1.17.4 - version: 1.17.4 - '@vanilla-extract/sprinkles': - specifier: ^1.6.5 - version: 1.6.5(@vanilla-extract/css@1.17.4) - '@vanilla-extract/vite-plugin': - specifier: ^5.1.0 - version: 5.1.0(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) - '@vitejs/plugin-react': - specifier: ^4.5.2 - version: 4.7.0(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) - '@vitejs/plugin-react-swc': - specifier: ^3.10.2 - version: 3.11.0(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) - globals: - specifier: ^16.2.0 - version: 16.3.0 lefthook: specifier: ^1.11.14 version: 1.12.2 @@ -59,9 +81,6 @@ importers: typescript: specifier: ~5.8.3 version: 5.8.3 - vite: - specifier: ^7.0.0 - version: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) apps/client: dependencies: @@ -78,19 +97,19 @@ importers: specifier: ^1.2.1 version: 1.2.1 '@types/react': - specifier: ^19.1.8 + specifier: catalog:react-core version: 19.1.8 '@types/react-dom': - specifier: ^19.1.6 + specifier: catalog:react-core version: 19.1.6(@types/react@19.1.8) lottie-react: specifier: ^2.4.1 version: 2.4.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: - specifier: ^19.1.0 + specifier: catalog:react-core version: 19.1.0 react-dom: - specifier: ^19.1.0 + specifier: catalog:react-core version: 19.1.0(react@19.1.0) react-error-boundary: specifier: ^6.0.0 @@ -113,7 +132,10 @@ importers: version: link:../../config/typescript '@pivanov/vite-plugin-svg-sprite': specifier: ^3.0.0 - version: 3.1.2(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) + version: 3.1.2(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)) + '@types/node': + specifier: catalog:typescript-core + version: 20.19.9 '@typescript-eslint/eslint-plugin': specifier: ^5.59.0 version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.3))(eslint@8.57.1)(typescript@5.8.3) @@ -121,20 +143,20 @@ importers: specifier: ^5.59.0 version: 5.62.0(eslint@8.57.1)(typescript@5.8.3) '@vanilla-extract/css': - specifier: '*' + specifier: catalog:vanilla-extract-core version: 1.17.4 '@vanilla-extract/recipes': - specifier: ^0.5.7 + specifier: catalog:vanilla-extract-core version: 0.5.7(@vanilla-extract/css@1.17.4) '@vanilla-extract/sprinkles': - specifier: '*' + specifier: catalog:vanilla-extract-utils version: 1.6.5(@vanilla-extract/css@1.17.4) '@vanilla-extract/vite-plugin': - specifier: '*' - version: 5.1.0(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) + specifier: catalog:vanilla-extract-utils + version: 5.1.0(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)) '@vitejs/plugin-react': - specifier: '*' - version: 4.7.0(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) + specifier: catalog:vite-plugins + version: 4.7.0(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)) eslint: specifier: ^8.44.0 version: 8.57.1 @@ -145,14 +167,14 @@ importers: specifier: ^7.8.0 version: 7.8.0(typescript@5.8.3) typescript: - specifier: ~5.8.3 + specifier: catalog:typescript-core version: 5.8.3 vite: - specifier: '*' - version: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) + specifier: catalog:vite-core + version: 7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3) vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.8.3)(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)) + version: 5.1.4(typescript@5.8.3)(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)) config/eslint: devDependencies: @@ -198,10 +220,10 @@ importers: packages/bds-ui: dependencies: react: - specifier: ^19.1.0 + specifier: catalog:react-core version: 19.1.0 react-dom: - specifier: ^19.0.0 + specifier: catalog:react-core version: 19.1.0(react@19.1.0) devDependencies: '@bofit/eslint': @@ -241,28 +263,28 @@ importers: specifier: ^1.12.4 version: 1.13.4(@swc/core@1.13.2)(@types/node@20.19.9)(typescript@5.8.3) '@types/node': - specifier: ^20.11.24 + specifier: catalog:typescript-core version: 20.19.9 '@types/react': - specifier: ^19.1.8 + specifier: catalog:react-core version: 19.1.8 '@types/react-dom': - specifier: ^19.0.1 + specifier: catalog:react-core version: 19.1.6(@types/react@19.1.8) '@vanilla-extract/css': - specifier: '*' + specifier: catalog:vanilla-extract-core version: 1.17.4 '@vanilla-extract/recipes': - specifier: ^0.5.7 + specifier: catalog:vanilla-extract-core version: 0.5.7(@vanilla-extract/css@1.17.4) '@vanilla-extract/sprinkles': - specifier: '*' + specifier: catalog:vanilla-extract-utils version: 1.6.5(@vanilla-extract/css@1.17.4) '@vanilla-extract/vite-plugin': - specifier: '*' + specifier: catalog:vanilla-extract-utils version: 5.1.0(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)) '@vitejs/plugin-react': - specifier: '*' + specifier: catalog:vite-plugins version: 4.7.0(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)) chromatic: specifier: ^13.1.2 @@ -274,10 +296,10 @@ importers: specifier: ^4.20.3 version: 4.20.3 typescript: - specifier: ^5.3.3 + specifier: catalog:typescript-core version: 5.8.3 vite: - specifier: '*' + specifier: catalog:vite-core version: 7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3) packages: @@ -482,6 +504,12 @@ packages: integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==, } + '@changesets/changelog-github@0.5.1': + resolution: + { + integrity: sha512-BVuHtF+hrhUScSoHnJwTELB4/INQxVFc+P/Qdt20BLiBFIHFJDDUaGsZw+8fQeJTRP5hJZrzpt3oZWh0G19rAQ==, + } + '@changesets/cli@2.29.5': resolution: { @@ -507,6 +535,12 @@ packages: integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==, } + '@changesets/get-github-info@0.6.0': + resolution: + { + integrity: sha512-v/TSnFVXI8vzX9/w3DU2Ol+UlTZcu3m0kXTjTT4KlAdwSvwutcByYwyYn9hwerPWfPkT2JfpoX0KgvCEi8Q/SA==, + } + '@changesets/get-release-plan@4.0.13': resolution: { @@ -1368,14 +1402,6 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.44.1': - resolution: - { - integrity: sha512-JAcBr1+fgqx20m7Fwe1DxPUl/hPkee6jA6Pl7n1v2EFiktAHenTaXl5aIFjUIEsfn9w3HE4gK1lEgNGMzBDs1w==, - } - cpu: [arm] - os: [android] - '@rollup/rollup-android-arm-eabi@4.45.1': resolution: { @@ -1384,14 +1410,6 @@ packages: cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.44.1': - resolution: - { - integrity: sha512-RurZetXqTu4p+G0ChbnkwBuAtwAbIwJkycw1n6GvlGlBuS4u5qlr5opix8cBAYFJgaY05TWtM+LaoFggUmbZEQ==, - } - cpu: [arm64] - os: [android] - '@rollup/rollup-android-arm64@4.45.1': resolution: { @@ -1400,14 +1418,6 @@ packages: cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.44.1': - resolution: - { - integrity: sha512-fM/xPesi7g2M7chk37LOnmnSTHLG/v2ggWqKj3CCA1rMA4mm5KVBT1fNoswbo1JhPuNNZrVwpTvlCVggv8A2zg==, - } - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-arm64@4.45.1': resolution: { @@ -1416,14 +1426,6 @@ packages: cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.44.1': - resolution: - { - integrity: sha512-gDnWk57urJrkrHQ2WVx9TSVTH7lSlU7E3AFqiko+bgjlh78aJ88/3nycMax52VIVjIm3ObXnDL2H00e/xzoipw==, - } - cpu: [x64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.45.1': resolution: { @@ -1432,14 +1434,6 @@ packages: cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.44.1': - resolution: - { - integrity: sha512-wnFQmJ/zPThM5zEGcnDcCJeYJgtSLjh1d//WuHzhf6zT3Md1BvvhJnWoy+HECKu2bMxaIcfWiu3bJgx6z4g2XA==, - } - cpu: [arm64] - os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.45.1': resolution: { @@ -1448,14 +1442,6 @@ packages: cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.44.1': - resolution: - { - integrity: sha512-uBmIxoJ4493YATvU2c0upGz87f99e3wop7TJgOA/bXMFd2SvKCI7xkxY/5k50bv7J6dw1SXT4MQBQSLn8Bb/Uw==, - } - cpu: [x64] - os: [freebsd] - '@rollup/rollup-freebsd-x64@4.45.1': resolution: { @@ -1464,14 +1450,6 @@ packages: cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.44.1': - resolution: - { - integrity: sha512-n0edDmSHlXFhrlmTK7XBuwKlG5MbS7yleS1cQ9nn4kIeW+dJH+ExqNgQ0RrFRew8Y+0V/x6C5IjsHrJmiHtkxQ==, - } - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-gnueabihf@4.45.1': resolution: { @@ -1480,14 +1458,6 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.44.1': - resolution: - { - integrity: sha512-8WVUPy3FtAsKSpyk21kV52HCxB+me6YkbkFHATzC2Yd3yuqHwy2lbFL4alJOLXKljoRw08Zk8/xEj89cLQ/4Nw==, - } - cpu: [arm] - os: [linux] - '@rollup/rollup-linux-arm-musleabihf@4.45.1': resolution: { @@ -1496,14 +1466,6 @@ packages: cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.44.1': - resolution: - { - integrity: sha512-yuktAOaeOgorWDeFJggjuCkMGeITfqvPgkIXhDqsfKX8J3jGyxdDZgBV/2kj/2DyPaLiX6bPdjJDTu9RB8lUPQ==, - } - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.45.1': resolution: { @@ -1512,14 +1474,6 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.44.1': - resolution: - { - integrity: sha512-W+GBM4ifET1Plw8pdVaecwUgxmiH23CfAUj32u8knq0JPFyK4weRy6H7ooxYFD19YxBulL0Ktsflg5XS7+7u9g==, - } - cpu: [arm64] - os: [linux] - '@rollup/rollup-linux-arm64-musl@4.45.1': resolution: { @@ -1528,14 +1482,6 @@ packages: cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.44.1': - resolution: - { - integrity: sha512-1zqnUEMWp9WrGVuVak6jWTl4fEtrVKfZY7CvcBmUUpxAJ7WcSowPSAWIKa/0o5mBL/Ij50SIf9tuirGx63Ovew==, - } - cpu: [loong64] - os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.45.1': resolution: { @@ -1544,14 +1490,6 @@ packages: cpu: [loong64] os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': - resolution: - { - integrity: sha512-Rl3JKaRu0LHIx7ExBAAnf0JcOQetQffaw34T8vLlg9b1IhzcBgaIdnvEbbsZq9uZp3uAH+JkHd20Nwn0h9zPjA==, - } - cpu: [ppc64] - os: [linux] - '@rollup/rollup-linux-powerpc64le-gnu@4.45.1': resolution: { @@ -1560,14 +1498,6 @@ packages: cpu: [ppc64] os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.44.1': - resolution: - { - integrity: sha512-j5akelU3snyL6K3N/iX7otLBIl347fGwmd95U5gS/7z6T4ftK288jKq3A5lcFKcx7wwzb5rgNvAg3ZbV4BqUSw==, - } - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-gnu@4.45.1': resolution: { @@ -1576,14 +1506,6 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.44.1': - resolution: - { - integrity: sha512-ppn5llVGgrZw7yxbIm8TTvtj1EoPgYUAbfw0uDjIOzzoqlZlZrLJ/KuiE7uf5EpTpCTrNt1EdtzF0naMm0wGYg==, - } - cpu: [riscv64] - os: [linux] - '@rollup/rollup-linux-riscv64-musl@4.45.1': resolution: { @@ -1592,14 +1514,6 @@ packages: cpu: [riscv64] os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.44.1': - resolution: - { - integrity: sha512-Hu6hEdix0oxtUma99jSP7xbvjkUM/ycke/AQQ4EC5g7jNRLLIwjcNwaUy95ZKBJJwg1ZowsclNnjYqzN4zwkAw==, - } - cpu: [s390x] - os: [linux] - '@rollup/rollup-linux-s390x-gnu@4.45.1': resolution: { @@ -1608,14 +1522,6 @@ packages: cpu: [s390x] os: [linux] - '@rollup/rollup-linux-x64-gnu@4.44.1': - resolution: - { - integrity: sha512-EtnsrmZGomz9WxK1bR5079zee3+7a+AdFlghyd6VbAjgRJDbTANJ9dcPIPAi76uG05micpEL+gPGmAKYTschQw==, - } - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-gnu@4.45.1': resolution: { @@ -1624,14 +1530,6 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.44.1': - resolution: - { - integrity: sha512-iAS4p+J1az6Usn0f8xhgL4PaU878KEtutP4hqw52I4IO6AGoyOkHCxcc4bqufv1tQLdDWFx8lR9YlwxKuv3/3g==, - } - cpu: [x64] - os: [linux] - '@rollup/rollup-linux-x64-musl@4.45.1': resolution: { @@ -1640,14 +1538,6 @@ packages: cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.44.1': - resolution: - { - integrity: sha512-NtSJVKcXwcqozOl+FwI41OH3OApDyLk3kqTJgx8+gp6On9ZEt5mYhIsKNPGuaZr3p9T6NWPKGU/03Vw4CNU9qg==, - } - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.45.1': resolution: { @@ -1656,14 +1546,6 @@ packages: cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.44.1': - resolution: - { - integrity: sha512-JYA3qvCOLXSsnTR3oiyGws1Dm0YTuxAAeaYGVlGpUsHqloPcFjPg+X0Fj2qODGLNwQOAcCiQmHub/V007kiH5A==, - } - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.45.1': resolution: { @@ -1672,14 +1554,6 @@ packages: cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.44.1': - resolution: - { - integrity: sha512-J8o22LuF0kTe7m+8PvW9wk3/bRq5+mRo5Dqo6+vXb7otCm3TPhYOJqOaQtGU9YMWQSL3krMnoOxMr0+9E6F3Ug==, - } - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.45.1': resolution: { @@ -2442,14 +2316,6 @@ packages: peerDependencies: vite: ^5.0.0 || ^6.0.0 - '@vitejs/plugin-react-swc@3.11.0': - resolution: - { - integrity: sha512-YTJCGFdNMHCMfjODYtxRNVAYmTWQ1Lb8PulP/2/f/oEEtglw8oKxKIZmmRkyXrVrHfsKOaVkAc3NT9/dMutO5w==, - } - peerDependencies: - vite: ^4 || ^5 || ^6 || ^7 - '@vitejs/plugin-react@4.7.0': resolution: { @@ -3252,6 +3118,12 @@ packages: } engines: { node: '>= 0.4' } + dataloader@1.4.0: + resolution: + { + integrity: sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==, + } + debug@4.4.1: resolution: { @@ -3448,6 +3320,13 @@ packages: } engines: { node: '>=12' } + dotenv@8.6.0: + resolution: + { + integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==, + } + engines: { node: '>=10' } + dunder-proto@1.0.1: resolution: { @@ -5321,6 +5200,18 @@ packages: integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==, } + node-fetch@2.7.0: + resolution: + { + integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==, + } + engines: { node: 4.x || >=6.0.0 } + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-plop@0.26.3: resolution: { @@ -6049,14 +5940,6 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true - rollup@4.44.1: - resolution: - { - integrity: sha512-x8H8aPvD+xbl0Do8oez5f5o8eMS3trfCghc4HhLAnCkj7Vl0d1JWGs0UF/D886zLW2rOj2QymV/JcSSsw+XDNg==, - } - engines: { node: '>=18.0.0', npm: '>=8.0.0' } - hasBin: true - rollup@4.45.1: resolution: { @@ -6588,6 +6471,12 @@ packages: } engines: { node: '>=8.0' } + tr46@0.0.3: + resolution: + { + integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, + } + ts-dedent@2.2.0: resolution: { @@ -7030,6 +6919,12 @@ packages: integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==, } + webidl-conversions@3.0.1: + resolution: + { + integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, + } + webpack-virtual-modules@0.6.2: resolution: { @@ -7050,6 +6945,12 @@ packages: } engines: { node: '>=18' } + whatwg-url@5.0.0: + resolution: + { + integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, + } + which-boxed-primitive@1.1.1: resolution: { @@ -7222,7 +7123,7 @@ snapshots: '@babel/parser': 7.28.0 '@babel/template': 7.27.2 '@babel/traverse': 7.28.0 - '@babel/types': 7.28.0 + '@babel/types': 7.28.1 convert-source-map: 2.0.0 debug: 4.4.1(supports-color@10.0.0) gensync: 1.0.0-beta.2 @@ -7252,7 +7153,7 @@ snapshots: '@babel/helper-module-imports@7.27.1': dependencies: '@babel/traverse': 7.28.0 - '@babel/types': 7.28.0 + '@babel/types': 7.28.1 transitivePeerDependencies: - supports-color @@ -7276,7 +7177,7 @@ snapshots: '@babel/helpers@7.27.6': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.0 + '@babel/types': 7.28.1 '@babel/parser@7.28.0': dependencies: @@ -7360,6 +7261,14 @@ snapshots: dependencies: '@changesets/types': 6.1.0 + '@changesets/changelog-github@0.5.1': + dependencies: + '@changesets/get-github-info': 0.6.0 + '@changesets/types': 6.1.0 + dotenv: 8.6.0 + transitivePeerDependencies: + - encoding + '@changesets/cli@2.29.5': dependencies: '@changesets/apply-release-plan': 7.0.12 @@ -7412,6 +7321,13 @@ snapshots: picocolors: 1.1.1 semver: 7.7.2 + '@changesets/get-github-info@0.6.0': + dependencies: + dataloader: 1.4.0 + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + '@changesets/get-release-plan@4.0.13': dependencies: '@changesets/assemble-release-plan': 6.0.9 @@ -7855,13 +7771,6 @@ snapshots: svgo: 4.0.0 vite: 7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3) - '@pivanov/vite-plugin-svg-sprite@3.1.2(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3))': - dependencies: - cheerio: 1.1.0 - chokidar: 4.0.3 - svgo: 4.0.0 - vite: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - '@pkgjs/parseargs@0.11.0': optional: true @@ -7900,123 +7809,63 @@ snapshots: optionalDependencies: rollup: 4.45.1 - '@rollup/rollup-android-arm-eabi@4.44.1': - optional: true - '@rollup/rollup-android-arm-eabi@4.45.1': optional: true - '@rollup/rollup-android-arm64@4.44.1': - optional: true - '@rollup/rollup-android-arm64@4.45.1': optional: true - '@rollup/rollup-darwin-arm64@4.44.1': - optional: true - '@rollup/rollup-darwin-arm64@4.45.1': optional: true - '@rollup/rollup-darwin-x64@4.44.1': - optional: true - '@rollup/rollup-darwin-x64@4.45.1': optional: true - '@rollup/rollup-freebsd-arm64@4.44.1': - optional: true - '@rollup/rollup-freebsd-arm64@4.45.1': optional: true - '@rollup/rollup-freebsd-x64@4.44.1': - optional: true - '@rollup/rollup-freebsd-x64@4.45.1': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.44.1': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.45.1': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.44.1': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.45.1': optional: true - '@rollup/rollup-linux-arm64-gnu@4.44.1': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.45.1': optional: true - '@rollup/rollup-linux-arm64-musl@4.44.1': - optional: true - '@rollup/rollup-linux-arm64-musl@4.45.1': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.44.1': - optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.45.1': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.44.1': - optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.45.1': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.44.1': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.45.1': optional: true - '@rollup/rollup-linux-riscv64-musl@4.44.1': - optional: true - '@rollup/rollup-linux-riscv64-musl@4.45.1': optional: true - '@rollup/rollup-linux-s390x-gnu@4.44.1': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.45.1': optional: true - '@rollup/rollup-linux-x64-gnu@4.44.1': - optional: true - '@rollup/rollup-linux-x64-gnu@4.45.1': optional: true - '@rollup/rollup-linux-x64-musl@4.44.1': - optional: true - '@rollup/rollup-linux-x64-musl@4.45.1': optional: true - '@rollup/rollup-win32-arm64-msvc@4.44.1': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.45.1': optional: true - '@rollup/rollup-win32-ia32-msvc@4.44.1': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.45.1': optional: true - '@rollup/rollup-win32-x64-msvc@4.44.1': - optional: true - '@rollup/rollup-win32-x64-msvc@4.45.1': optional: true @@ -8290,12 +8139,15 @@ snapshots: '@swc/core-win32-arm64-msvc': 1.13.2 '@swc/core-win32-ia32-msvc': 1.13.2 '@swc/core-win32-x64-msvc': 1.13.2 + optional: true - '@swc/counter@0.1.3': {} + '@swc/counter@0.1.3': + optional: true '@swc/types@0.1.23': dependencies: '@swc/counter': 0.1.3 + optional: true '@tanstack/query-core@5.83.0': {} @@ -8409,7 +8261,7 @@ snapshots: '@types/conventional-commits-parser@5.0.1': dependencies: - '@types/node': 20.19.9 + '@types/node': 24.1.0 '@types/doctrine@0.0.9': {} @@ -8418,7 +8270,7 @@ snapshots: '@types/glob@7.2.0': dependencies: '@types/minimatch': 6.0.0 - '@types/node': 20.19.9 + '@types/node': 24.1.0 '@types/inquirer@6.5.0': dependencies: @@ -8457,7 +8309,7 @@ snapshots: '@types/through@0.0.33': dependencies: - '@types/node': 20.19.9 + '@types/node': 24.1.0 '@types/tinycolor2@1.4.6': {} @@ -8576,27 +8428,6 @@ snapshots: - tsx - yaml - '@vanilla-extract/compiler@0.3.0(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)': - dependencies: - '@vanilla-extract/css': 1.17.4 - '@vanilla-extract/integration': 8.0.4 - vite: 6.3.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - vite-node: 3.2.4(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - '@vanilla-extract/css@1.17.4': dependencies: '@emotion/hash': 0.9.2 @@ -8621,7 +8452,7 @@ snapshots: '@vanilla-extract/babel-plugin-debug-ids': 1.2.2 '@vanilla-extract/css': 1.17.4 dedent: 1.6.0 - esbuild: 0.25.5 + esbuild: 0.25.8 eval: 0.1.8 find-up: 5.0.0 javascript-stringify: 2.1.0 @@ -8660,34 +8491,6 @@ snapshots: - tsx - yaml - '@vanilla-extract/vite-plugin@5.1.0(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3))': - dependencies: - '@vanilla-extract/compiler': 0.3.0(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - '@vanilla-extract/integration': 8.0.4 - vite: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - '@vitejs/plugin-react-swc@3.11.0(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3))': - dependencies: - '@rolldown/pluginutils': 1.0.0-beta.27 - '@swc/core': 1.13.2 - vite: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - transitivePeerDependencies: - - '@swc/helpers' - '@vitejs/plugin-react@4.7.0(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3))': dependencies: '@babel/core': 7.28.0 @@ -8700,18 +8503,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.7.0(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3))': - dependencies: - '@babel/core': 7.28.0 - '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.0) - '@babel/plugin-transform-react-jsx-source': 7.27.1(@babel/core@7.28.0) - '@rolldown/pluginutils': 1.0.0-beta.27 - '@types/babel__core': 7.20.5 - react-refresh: 0.17.0 - vite: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - transitivePeerDependencies: - - supports-color - '@vitest/expect@2.0.5': dependencies: '@vitest/spy': 2.0.5 @@ -9203,6 +8994,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dataloader@1.4.0: {} + debug@4.4.1(supports-color@10.0.0): dependencies: ms: 2.1.3 @@ -9306,6 +9099,8 @@ snapshots: dotenv@16.0.3: {} + dotenv@8.6.0: {} + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -9667,7 +9462,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 20.19.9 + '@types/node': 24.1.0 require-like: 0.1.2 execa@5.1.1: @@ -10507,6 +10302,10 @@ snapshots: dependencies: lower-case: 1.1.4 + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + node-plop@0.26.3: dependencies: '@babel/runtime-corejs3': 7.28.0 @@ -10980,32 +10779,6 @@ snapshots: dependencies: glob: 7.2.3 - rollup@4.44.1: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.44.1 - '@rollup/rollup-android-arm64': 4.44.1 - '@rollup/rollup-darwin-arm64': 4.44.1 - '@rollup/rollup-darwin-x64': 4.44.1 - '@rollup/rollup-freebsd-arm64': 4.44.1 - '@rollup/rollup-freebsd-x64': 4.44.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.44.1 - '@rollup/rollup-linux-arm-musleabihf': 4.44.1 - '@rollup/rollup-linux-arm64-gnu': 4.44.1 - '@rollup/rollup-linux-arm64-musl': 4.44.1 - '@rollup/rollup-linux-loongarch64-gnu': 4.44.1 - '@rollup/rollup-linux-powerpc64le-gnu': 4.44.1 - '@rollup/rollup-linux-riscv64-gnu': 4.44.1 - '@rollup/rollup-linux-riscv64-musl': 4.44.1 - '@rollup/rollup-linux-s390x-gnu': 4.44.1 - '@rollup/rollup-linux-x64-gnu': 4.44.1 - '@rollup/rollup-linux-x64-musl': 4.44.1 - '@rollup/rollup-win32-arm64-msvc': 4.44.1 - '@rollup/rollup-win32-ia32-msvc': 4.44.1 - '@rollup/rollup-win32-x64-msvc': 4.44.1 - fsevents: 2.3.3 - rollup@4.45.1: dependencies: '@types/estree': 1.0.8 @@ -11031,7 +10804,6 @@ snapshots: '@rollup/rollup-win32-ia32-msvc': 4.45.1 '@rollup/rollup-win32-x64-msvc': 4.45.1 fsevents: 2.3.3 - optional: true run-async@2.4.1: {} @@ -11354,6 +11126,8 @@ snapshots: dependencies: is-number: 7.0.0 + tr46@0.0.3: {} + ts-dedent@2.2.0: {} ts-node@10.9.2(@swc/core@1.13.2)(@types/node@20.19.9)(typescript@5.8.3): @@ -11563,45 +11337,24 @@ snapshots: - tsx - yaml - vite-node@3.2.4(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3): - dependencies: - cac: 6.7.14 - debug: 4.4.1(supports-color@10.0.0) - es-module-lexer: 1.7.0 - pathe: 2.0.3 - vite: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) - transitivePeerDependencies: - - '@types/node' - - jiti - - less - - lightningcss - - sass - - sass-embedded - - stylus - - sugarss - - supports-color - - terser - - tsx - - yaml - - vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3)): + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3)): dependencies: debug: 4.4.1(supports-color@10.0.0) globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.8.3) optionalDependencies: - vite: 7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3) + vite: 7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3) transitivePeerDependencies: - supports-color - typescript vite@6.3.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3): dependencies: - esbuild: 0.25.5 + esbuild: 0.25.8 fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 postcss: 8.5.6 - rollup: 4.44.1 + rollup: 4.45.1 tinyglobby: 0.2.14 optionalDependencies: '@types/node': 20.19.9 @@ -11609,27 +11362,13 @@ snapshots: jiti: 2.4.2 tsx: 4.20.3 - vite@6.3.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3): - dependencies: - esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - postcss: 8.5.6 - rollup: 4.44.1 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 24.1.0 - fsevents: 2.3.3 - jiti: 2.4.2 - tsx: 4.20.3 - vite@7.0.5(@types/node@20.19.9)(jiti@2.4.2)(tsx@4.20.3): dependencies: - esbuild: 0.25.5 + esbuild: 0.25.8 fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 postcss: 8.5.6 - rollup: 4.44.1 + rollup: 4.45.1 tinyglobby: 0.2.14 optionalDependencies: '@types/node': 20.19.9 @@ -11637,24 +11376,12 @@ snapshots: jiti: 2.4.2 tsx: 4.20.3 - vite@7.0.5(@types/node@24.1.0)(jiti@2.4.2)(tsx@4.20.3): - dependencies: - esbuild: 0.25.5 - fdir: 6.4.6(picomatch@4.0.2) - picomatch: 4.0.2 - postcss: 8.5.6 - rollup: 4.44.1 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 24.1.0 - fsevents: 2.3.3 - jiti: 2.4.2 - tsx: 4.20.3 - wcwidth@1.0.1: dependencies: defaults: 1.0.4 + webidl-conversions@3.0.1: {} + webpack-virtual-modules@0.6.2: {} whatwg-encoding@3.1.1: @@ -11663,6 +11390,11 @@ snapshots: whatwg-mimetype@4.0.0: {} + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index bf107a23..cfd97735 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -2,3 +2,28 @@ packages: - 'config/*' - 'apps/*' - 'packages/*' + +catalogs: + vanilla-extract-core: + '@vanilla-extract/css': '^1.17.4' + '@vanilla-extract/recipes': '^0.5.7' + + vanilla-extract-utils: + '@vanilla-extract/sprinkles': '^1.6.5' + '@vanilla-extract/vite-plugin': '^5.1.0' + + vite-core: + 'vite': '^7.0.0' + + vite-plugins: + '@vitejs/plugin-react': '^4.5.2' + + react-core: + 'react': '^19.1.0' + 'react-dom': '^19.1.0' + '@types/react': '^19.1.8' + '@types/react-dom': '^19.0.1' + + typescript-core: + typescript: ~5.8.3 + '@types/node': ^20.11.24