diff --git a/apps/admin/app/components/layout/Header/Header.tsx b/apps/admin/app/components/layout/Header/Header.tsx index f0527638..87a1e20a 100644 --- a/apps/admin/app/components/layout/Header/Header.tsx +++ b/apps/admin/app/components/layout/Header/Header.tsx @@ -1,6 +1,6 @@ import { css } from '_panda/css'; import Nav from './Nav'; -import { Avatar, AvatarImage, AvatarFallback } from '@radix-ui/react-avatar'; +import { Avatar, AvatarImage } from '@radix-ui/react-avatar'; const PROFILE_IMG = 'https://avatars.githubusercontent.com/u/171903401?s=200&v=4'; function Header() { @@ -19,12 +19,12 @@ function Header() { export default Header; const containerStyle = css({ - h: '16', + h: '16px', bg: 'background', shadow: 'md', zIndex: 'sticky', - px: 4, - py: 3, + px: '4px', + py: '3px', display: 'flex', alignItems: 'center', diff --git a/apps/admin/app/components/layout/Header/Nav.tsx b/apps/admin/app/components/layout/Header/Nav.tsx index 726a7b6a..5fe866c9 100644 --- a/apps/admin/app/components/layout/Header/Nav.tsx +++ b/apps/admin/app/components/layout/Header/Nav.tsx @@ -43,8 +43,8 @@ export default function Example() { const listStyle = css({ display: 'flex', flexDirection: 'column', - gap: '3', - p: '6', + gap: '3px', + p: '6px', md: { w: '400px', }, diff --git a/apps/admin/app/components/layout/Main/Main.tsx b/apps/admin/app/components/layout/Main/Main.tsx index 6ce6fc07..16517232 100644 --- a/apps/admin/app/components/layout/Main/Main.tsx +++ b/apps/admin/app/components/layout/Main/Main.tsx @@ -8,5 +8,5 @@ function Main({ children }: PropsWithChildren<{}>) { export default Main; const containerStyle = css({ - p: 8, + p: '8px', }); diff --git a/apps/web/messages/en_US.json b/apps/web/messages/en_US.json index 9281925f..f9e0b36b 100644 --- a/apps/web/messages/en_US.json +++ b/apps/web/messages/en_US.json @@ -87,7 +87,7 @@ "copy-link-success": "Copy success!", "line-set-error": "Cannot set more than 1000.", "apply-button": "Apply", - "customize-size": "Line TypeCustomize Size", + "customize-size": "Customize Size", "extend-button": "Extend", "shrink-button": "Shrink", "change-pet": "Change pet", @@ -102,7 +102,8 @@ "Merge": { "merge": "Merge", "merge-result": "Merge result", - "cancel": "Cancel" + "cancel": "Cancel", + "please-choose-pet": "Please choose a pet to use to merge the level. The pet used disappears." } }, "Event": { diff --git a/apps/web/messages/ko_KR.json b/apps/web/messages/ko_KR.json index d1555a88..d70b79a6 100644 --- a/apps/web/messages/ko_KR.json +++ b/apps/web/messages/ko_KR.json @@ -89,7 +89,7 @@ "copy-link-success": "복사 성공!", "line-set-error": "1000 이상은 설정할 수 없습니다.", "apply-button": "적용하기", - "customize-size": "Line Type 사이즈 조정", + "customize-size": "Customize Size", "extend-button": "확장", "shrink-button": "축소", "change-pet": "펫 변경", @@ -104,7 +104,8 @@ "Merge": { "merge": "합치기", "merge-result": "합치기 결과", - "cancel": "취소" + "cancel": "취소", + "please-choose-pet": "합치기에 사용할 펫을 선택해주세요. 합친 펫은 사라집니다." } }, "Event": { diff --git a/apps/web/package.json b/apps/web/package.json index 80b48af2..ace77c48 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -26,9 +26,11 @@ "@gitanimals/util-common": "workspace:*", "@next/third-parties": "^14.2.5", "@octokit/core": "^6.1.2", + "@shadow-panda/style-context": "^0.7.1", "@suspensive/react": "^2.17.1", "@tanstack/react-query": "*", "axios": "^1.6.8", + "driver.js": "^1.3.1", "framer-motion": "^11.1.7", "google-auth-library": "^9.11.0", "google-spreadsheet": "^4.1.2", @@ -51,6 +53,7 @@ "@gitanimals/util-common": "workspace:*", "@next/bundle-analyzer": "^14.2.5", "@pandacss/dev": "^0.41.0", + "@shadow-panda/preset": "^0.7.1", "@storybook/addon-essentials": "^8.0.9", "@storybook/addon-interactions": "^8.0.9", "@storybook/addon-links": "^8.0.9", diff --git a/apps/web/panda.config.ts b/apps/web/panda.config.ts index e4d4de71..f9b489e7 100644 --- a/apps/web/panda.config.ts +++ b/apps/web/panda.config.ts @@ -124,5 +124,5 @@ export default defineConfig({ outdir: 'styled-system', // delete default presets - presets: [], + presets: ['@shadow-panda/preset'], }); diff --git a/apps/web/src/app/[locale]/dev/page.tsx b/apps/web/src/app/[locale]/dev/page.tsx index 09d5f50d..c215964e 100644 --- a/apps/web/src/app/[locale]/dev/page.tsx +++ b/apps/web/src/app/[locale]/dev/page.tsx @@ -1,5 +1,6 @@ import { css } from '_panda/css'; import { Box } from '_panda/jsx'; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@gitanimals/ui-panda'; import GNB from '@/components/GNB/GNB'; @@ -13,6 +14,22 @@ async function DevPage() {

client

+ + + Is it accessible? + Yes. It adheres to the WAI-ARIA design pattern. + + + Is it styled? + + Yes. It comes with default styles that matches the other components' aesthetic. + + + + Is it animated? + Yes. It's animated by default, but you can disable it if you prefer. + + ); } diff --git a/apps/web/src/app/[locale]/event/[eventCode]/layout.tsx b/apps/web/src/app/[locale]/event/[eventCode]/layout.tsx index 27149801..73c8dd73 100644 --- a/apps/web/src/app/[locale]/event/[eventCode]/layout.tsx +++ b/apps/web/src/app/[locale]/event/[eventCode]/layout.tsx @@ -79,7 +79,7 @@ const imageStyle = css({ zIndex: 1, minHeight: 'calc(100vh - 60px)', pointerEvents: 'none', - top: -60, + top: '-60px', _mobile: { display: 'none', }, diff --git a/apps/web/src/app/[locale]/event/[eventCode]/page.tsx b/apps/web/src/app/[locale]/event/[eventCode]/page.tsx index 15de634b..3c2eadd4 100644 --- a/apps/web/src/app/[locale]/event/[eventCode]/page.tsx +++ b/apps/web/src/app/[locale]/event/[eventCode]/page.tsx @@ -129,16 +129,16 @@ const logoImageStyle = css({ }); const descriptionStyle = css({ - marginTop: 24, - fontSize: 28, - lineHeight: 1.5, + marginTop: '24px', + fontSize: '28px', + lineHeight: '1.5', textAlign: 'center', color: '#fff', - mb: 40, + mb: '40px', whiteSpace: 'pre-line', fontWeight: 600, _mobile: { - fontSize: 24, + fontSize: '24px', }, }); diff --git a/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalCardList.tsx b/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalCardList.tsx index 67021dcc..2bc7b270 100644 --- a/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalCardList.tsx +++ b/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalCardList.tsx @@ -67,7 +67,7 @@ function AnimalCardContainer() { export default AnimalCardContainer; const container = grid({ - gap: 20, + gap: '20px', justifyContent: 'center', gridTemplateColumns: 'repeat(4, 1fr)', width: '1120px', diff --git a/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalSlider.style.ts b/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalSlider.style.ts index c7d3525d..c4ba1d80 100644 --- a/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalSlider.style.ts +++ b/apps/web/src/app/[locale]/landing/AvailablePetSection/AnimalSlider.style.ts @@ -35,7 +35,7 @@ export const showMobile = css({ }); export const cardContainer = grid({ - gap: 20, + gap: '20px', justifyContent: 'center', gridTemplateColumns: 'repeat(4, 1fr)', gridTemplateRows: 'repeat(3, 1fr)', diff --git a/apps/web/src/app/[locale]/landing/Footer/Footer.style.ts b/apps/web/src/app/[locale]/landing/Footer/Footer.style.ts index 23bcaf85..d30be28c 100644 --- a/apps/web/src/app/[locale]/landing/Footer/Footer.style.ts +++ b/apps/web/src/app/[locale]/landing/Footer/Footer.style.ts @@ -12,7 +12,7 @@ export const footer = css({ _mobile: { padding: '80px 16px', - gap: 60, + gap: '60px', }, }); @@ -24,7 +24,7 @@ export const article = css({ _mobile: { flexDir: 'column', - gap: 24, + gap: '24px', }, }); @@ -45,11 +45,11 @@ const defaultContentWrapper: SystemStyleObject = { export const teamContentWrapper = css(defaultContentWrapper, { display: 'flex', - gap: 12, + gap: '12px', _mobile: { flexDir: 'column', - gap: 16, + gap: '16px', }, }); @@ -61,24 +61,24 @@ export const repoContentWrapper = css(defaultContentWrapper, { export const repoLi = css({ display: 'flex', - gap: 8, + gap: '8px', _mobile: { flexDir: 'column', - gap: 1, + gap: '1px', }, }); export const repoLiTitle = css({ display: 'flex', alignItems: 'center', - gap: 8, - width: 226, + gap: '8px', + width: '226px', textStyle: 'glyph18.bold', _mobile: { textStyle: 'glyph15.bold', - gap: 17, + gap: '17px', }, }); @@ -89,6 +89,6 @@ export const repoLiLink = css({ _mobile: { textStyle: 'glyph12.regular', - marginLeft: 37, + marginLeft: '37px', }, }); diff --git a/apps/web/src/app/[locale]/landing/Footer/TeammateProfile.style.ts b/apps/web/src/app/[locale]/landing/Footer/TeammateProfile.style.ts index 32fe4a33..f9c68736 100644 --- a/apps/web/src/app/[locale]/landing/Footer/TeammateProfile.style.ts +++ b/apps/web/src/app/[locale]/landing/Footer/TeammateProfile.style.ts @@ -8,17 +8,17 @@ export const wrapperCss = css({ _mobile: { width: '100%', flexDir: 'row', - gap: 5, + gap: '5px', }, }); export const imageCss = css({ - marginBottom: 8, + marginBottom: '8px', _mobile: { - width: 32, - height: 24, - marginBottom: 0, + width: '32px', + height: '24px', + marginBottom: '0px', objectFit: 'contain', objectPosition: 'left 50%', }, @@ -32,8 +32,8 @@ export const textWrapperCss = css({ export const nicknameWrapperCss = css({ display: 'flex', alignItems: 'center', - gap: 5, - marginBottom: 4, + gap: '5px', + marginBottom: '4px', '& span': { textStyle: 'glyph18.bold', @@ -41,7 +41,7 @@ export const nicknameWrapperCss = css({ }, _mobile: { - marginBottom: 1, + marginBottom: '1px', '& span': { textStyle: 'glyph15.bold', fontWeight: 'bold', diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmBackgroundSelect.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmBackgroundSelect.tsx index 6e1fabbe..4f699f7a 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmBackgroundSelect.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmBackgroundSelect.tsx @@ -80,7 +80,7 @@ const backgroundListStyle = cx( width: 'fit-content', display: 'flex', flexWrap: 'nowrap', - gap: 4, + gap: '4px', }), ); @@ -93,8 +93,8 @@ const backgroundContainerStyle = cx( const backgroundItemStyle = css({ border: '1px solid transparent', - width: 248, - borderRadius: 8, + width: '248px', + borderRadius: '8px', overflow: 'hidden', }); diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmPersonaSelect.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmPersonaSelect.tsx index f5a3f93c..65a4054e 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmPersonaSelect.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmPersonaSelect.tsx @@ -4,7 +4,7 @@ import { css, cx } from '_panda/css'; import { flex } from '_panda/patterns'; import type { Persona } from '@gitanimals/api'; import { userQueries } from '@gitanimals/react-query'; -import { FullModal } from '@gitanimals/ui-panda'; +import { Dialog, dialogContentCva } from '@gitanimals/ui-panda'; import { useQueryClient } from '@tanstack/react-query'; import { ExpandIcon } from 'lucide-react'; @@ -13,6 +13,8 @@ import { customScrollStyle } from '@/styles/scrollStyle'; import { SelectPersonaList } from '../PersonaList'; +import { useFarmTutorial } from './FarmTutorialProvider'; + export function FarmPersonaSelect({ onChangeStatus, }: { @@ -20,6 +22,7 @@ export function FarmPersonaSelect({ }) { const queryClient = useQueryClient(); const t = useTranslations('Mypage'); + const { classes: farmTutorialClasses } = useFarmTutorial(); const [selectPersona, setSelectPersona] = useState([]); const [loadingPersona, setLoadingPersona] = useState([]); @@ -64,7 +67,7 @@ export function FarmPersonaSelect({ }; return ( -
+

{t('change-pet')}

- setIsOpen(false)}> - setIsOpen(false)} /> - - {t('farm-type-select-pet')} + + + {t('farm-type-select-pet')}
-
-
+ +
); } const listStyle = cx( flex({ - gap: 4, + gap: '4px', w: '100%', h: '100%', minH: '0', @@ -112,18 +114,22 @@ const listStyle = cx( customScrollStyle, ); -const flexOverflowStyle = css({ - display: 'flex', - overflowY: 'auto', - overflowX: 'hidden', - width: '100%', - gap: 4, - height: '100%', - minHeight: '0', - flexWrap: 'wrap', - justifyContent: 'center', - maxHeight: 'calc(100% - 100px)', -}); +const flexOverflowStyle = cx( + css({ + display: 'flex', + overflowY: 'auto', + overflowX: 'hidden', + width: '100%', + gap: '4px', + height: '100%', + minHeight: '0', + flexWrap: 'wrap', + justifyContent: 'center', + maxHeight: 'calc(100%)', + marginTop: '24px', + }), + customScrollStyle, +); const selectPetContainerStyle = css({ position: 'relative', diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmTutorialProvider.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmTutorialProvider.tsx new file mode 100644 index 00000000..90e7a9fe --- /dev/null +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmTutorialProvider.tsx @@ -0,0 +1,72 @@ +'use client'; + +import type { PropsWithChildren } from 'react'; +import { createContext, useContext } from 'react'; +import { driver } from 'driver.js'; + +const FARM_TUTORIAL = { + container: 'farm-tutorial-container', + preview: 'preview', + personaSelect: 'persona-select', + copyButton: 'copy-button', +}; + +interface FarmTutorialContextType { + classes: typeof FARM_TUTORIAL; +} + +const FarmTutorialContext = createContext({ + classes: FARM_TUTORIAL, +}); + +export const FarmTutorialProvider = ({ children }: PropsWithChildren) => { + const driverObj = driver({ + steps: [ + { + element: `.${FARM_TUTORIAL.container}`, + popover: { + title: 'Farm Type', + description: 'Farm Mode는 자신이 가지고 있는 펫중 하나를 지정해서, 지정한 범위에서 움직이게 할 수 있어요.', + }, + }, + + { + element: `.${FARM_TUTORIAL.personaSelect}`, + popover: { + title: '펫 선택', + description: '먼저 돌아다닐 펫을 하나를 선택해요.\n우측 버튼으로 펫 선택 리스트를 확장할 수 있어요.', + }, + }, + { + element: `.${FARM_TUTORIAL.preview}`, + popover: { + title: 'Farm 미리보기', + description: '돌아다닐 범위를 설정한 후, 설정한 범위 내에서 펫이 돌아다니는 모습을 미리볼 수 있어요.', + }, + }, + { + element: `.${FARM_TUTORIAL.copyButton}`, + popover: { + title: '이미지 링크 복사', + description: '복사 버튼을 눌러서 펫이 돌아다니는 이미지를 복사할 수 있어요!', + side: 'right', + align: 'start', + }, + }, + ], + }); + + driverObj.drive(); + + return {children}; +}; + +export const useFarmTutorial = () => { + const context = useContext(FarmTutorialContext); + + if (!context) { + throw new Error('useFarmTutorial must be used within a FarmTutorialProvider'); + } + + return context; +}; diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx index 3cbbe3d7..1c58006f 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/FarmType.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { useTranslations } from 'next-intl'; -import { css } from '_panda/css'; +import { css, cx } from '_panda/css'; import { Button } from '@gitanimals/ui-panda'; import { toast } from 'sonner'; @@ -12,9 +12,11 @@ import { copyClipBoard } from '@/utils/copy'; import { FarmBackgroundSelect } from './FarmBackgroundSelect'; import { FarmPersonaSelect } from './FarmPersonaSelect'; +import { useFarmTutorial } from './FarmTutorialProvider'; export function FarmType() { const t = useTranslations('Mypage'); + const { classes: farmTutorialClasses } = useFarmTutorial(); const { name } = useClientUser(); @@ -33,12 +35,12 @@ export function FarmType() { }; return ( -
+
-
+
-
@@ -53,8 +55,8 @@ const farmSectionStyle = css({ flexDirection: 'column', width: '100%', maxHeight: '100%', - py: 40, - gap: 40, + py: '40px', + gap: '40px', _mobile: { background: 'none', @@ -65,4 +67,4 @@ const farmSectionStyle = css({ }, }); -const farmStyle = css({ borderRadius: '12px', overflow: 'hidden', width: 'fit-content', mt: 24 }); +const farmStyle = css({ borderRadius: '12px', overflow: 'hidden', width: 'fit-content', mt: '24px' }); diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/LinePersonaSelect.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/LinePersonaSelect.tsx index 4eba0596..f22f35f2 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/LinePersonaSelect.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/LinePersonaSelect.tsx @@ -4,13 +4,15 @@ import React, { useState } from 'react'; import { useTranslations } from 'next-intl'; import { css, cx } from '_panda/css'; import { flex } from '_panda/patterns'; -import { FullModal } from '@gitanimals/ui-panda'; +import { Dialog, dialogContentCva } from '@gitanimals/ui-panda'; import { ExpandIcon } from 'lucide-react'; import { customScrollStyle } from '@/styles/scrollStyle'; import { SelectPersonaList } from '../PersonaList'; +import { LINE_TUTORIAL } from './useLineTutorial'; + interface Props { selectPersona: string | null; onChangePersona: (personaId: string) => void; @@ -22,10 +24,10 @@ export const LinePersonaSelect = ({ selectPersona, onChangePersona }: Props) => const [isExtend, setIsExtend] = useState(false); return ( -
+

{t('change-pet')}

-
@@ -35,38 +37,41 @@ export const LinePersonaSelect = ({ selectPersona, onChangePersona }: Props) => onSelectPersona={(persona) => onChangePersona(persona.id)} /> - setIsExtend(false)}> - setIsExtend(false)} /> - - {t('line-type-select-pet')} + setIsExtend(false)}> + + {t('line-type-select-pet')}
onChangePersona(persona.id)} />
-
-
+ +
); }; -const flexOverflowStyle = css({ - display: 'flex', - overflowY: 'auto', - overflowX: 'hidden', - width: '100%', - gap: 4, - height: '100%', - minHeight: '0', - flexWrap: 'wrap', - justifyContent: 'center', - maxHeight: 'calc(100% - 100px)', -}); +const flexOverflowStyle = cx( + css({ + display: 'flex', + overflowY: 'auto', + overflowX: 'hidden', + width: '100%', + gap: '4px', + height: '100%', + minHeight: '0', + flexWrap: 'wrap', + justifyContent: 'center', + maxHeight: 'calc(100%)', + marginTop: '24px', + }), + customScrollStyle, +); const listStyle = cx( flex({ - gap: 4, + gap: '4px', w: '100%', h: '100%', minH: '0', diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/LinePreview.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/LinePreview.tsx index b5db907c..01bb3e9c 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/LinePreview.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/LinePreview.tsx @@ -2,8 +2,8 @@ import React, { useState } from 'react'; import { useTranslations } from 'next-intl'; -import { css } from '_panda/css'; -import { flex } from '_panda/patterns'; +import { css, cx } from '_panda/css'; +import { Flex } from '_panda/jsx'; import { Button, TextField } from '@gitanimals/ui-panda'; import { toast } from 'sonner'; @@ -11,6 +11,8 @@ import { getGitanimalsLineString, GitanimalsLine } from '@/components/Gitanimals import { useClientUser } from '@/utils/clientAuth'; import { copyClipBoard } from '@/utils/copy'; +import { LINE_TUTORIAL } from './useLineTutorial'; + const DEFAULT_SIZE = { width: 600, height: 120 }; export function LinePreview({ selectPersona }: { selectPersona: string | null }) { @@ -34,14 +36,14 @@ export function LinePreview({ selectPersona }: { selectPersona: string | null }) }; return ( -
+
{/* TODO: 임시로 모바일에선 input 안보이게 처리 */} setSizes({ width, height })} />
-
@@ -52,7 +54,7 @@ export function LinePreview({ selectPersona }: { selectPersona: string | null }) const sectionContainerStyle = css({ display: 'flex', flexDirection: 'column', - gap: 24, + gap: '24px', }); const lineContainerStyle = css({ @@ -66,6 +68,7 @@ const lineContainerStyle = css({ '& img': { maxWidth: '100%', }, + _mobile: { maxWidth: '100%', }, @@ -78,9 +81,9 @@ function SizeInputList({ onApply }: { onApply: (width: number, height: number) = const [height, setHeight] = useState(DEFAULT_SIZE.height); return ( -
+

{t('customize-size')}

-
+ setWidth(parseInt(e.target.value))} name="width" /> setHeight(parseInt(e.target.value))} name="height" /> -
+
); } const sizeInputStyle = css({ position: 'relative', - mt: 24, '& .heading': { textStyle: 'glyph18.bold', diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/LineType.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/LineType.tsx index a20717f2..f0db12b9 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/LineType.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/LineType.tsx @@ -1,16 +1,17 @@ 'use client'; import React, { useState } from 'react'; -import { css } from '_panda/css'; +import { css, cx } from '_panda/css'; import { LinePersonaSelect } from './LinePersonaSelect'; import { LinePreview } from './LinePreview'; +import { LINE_TUTORIAL, useLineTutorial } from './useLineTutorial'; export function LineType() { const [selectPersona, setSelectPersona] = useState(null); - + useLineTutorial(); return ( -
+
setSelectPersona(personaId)} />
@@ -22,8 +23,8 @@ const sectionContainer = css({ flexDirection: 'column', width: '100%', maxHeight: '100%', - py: 40, - gap: 40, + py: '40px', + gap: '40px', _mobile: { background: 'none', diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx b/apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx index c90e02aa..a50ef944 100644 --- a/apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/page.tsx @@ -5,6 +5,7 @@ import { updateUrlSearchParams } from '@gitanimals/util-common'; import { Link } from '@/i18n/routing'; +import { FarmTutorialProvider } from './FarmTutorialProvider'; import { FarmType } from './FarmType'; import { LineType } from './LineType'; @@ -21,7 +22,11 @@ async function Mypage({ const MYPAGE_TAB_INNER_MAP: Record = { 'line-type': , - 'farm-type': , + 'farm-type': ( + + + + ), }; return ( @@ -46,7 +51,7 @@ const tabItemStyle = css({ }); const tabListStyle = flex({ - gap: 12, + gap: '12px', _mobile: { '& a': { flex: 1, @@ -54,11 +59,11 @@ const tabListStyle = flex({ }, '& .tab-item': { textStyle: 'glyph28.bold', - borderRadius: 12, - padding: 12, + borderRadius: '12px', + padding: '12px', textAlign: 'center', border: '1.5px solid', - height: 58, + height: '58px', color: 'white.white_25', backgroundColor: 'white.white_10', borderColor: 'white.white_10', @@ -77,7 +82,7 @@ const tabListStyle = flex({ borderRadius: '6px', border: '1px solid', textStyle: 'glyph16.bold', - h: 40, + h: '40px', p: '8px 16px', }, }, diff --git a/apps/web/src/app/[locale]/mypage/(github-custom)/useLineTutorial.ts b/apps/web/src/app/[locale]/mypage/(github-custom)/useLineTutorial.ts new file mode 100644 index 00000000..7ded8884 --- /dev/null +++ b/apps/web/src/app/[locale]/mypage/(github-custom)/useLineTutorial.ts @@ -0,0 +1,48 @@ +import { driver } from 'driver.js'; + +export const LINE_TUTORIAL = { + container: 'line-type-tutorial-container', + preview: 'preview', + personaSelect: 'persona-select', + copyButton: 'copy-button', +}; + +export const useLineTutorial = () => { + const driverObj = driver({ + showProgress: true, + steps: [ + { + element: `.${LINE_TUTORIAL.container}`, + popover: { + title: 'Line Type', + description: 'Line Mode는 자신이 가지고 있는 펫중 하나를 지정해서, 지정한 범위에서 움직이게 할 수 있어요.', + }, + }, + { + element: `.${LINE_TUTORIAL.personaSelect}`, + popover: { + title: '펫 선택', + description: '먼저 돌아다닐 펫을 하나를 선택해요.\n우측 버튼으로 펫 선택 리스트를 확장할 수 있어요.', + }, + }, + { + element: `.${LINE_TUTORIAL.preview}`, + popover: { + title: 'Line 미리보기', + description: '돌아다닐 범위를 설정한 후, 설정한 범위 내에서 펫이 돌아다니는 모습을 미리볼 수 있어요.', + }, + }, + { + element: `.${LINE_TUTORIAL.copyButton}`, + popover: { + title: '이미지 링크 복사', + description: '복사 버튼을 눌러서 펫이 돌아다니는 이미지를 복사할 수 있어요!', + side: 'right', + align: 'start', + }, + }, + ], + }); + + driverObj.drive(); +}; diff --git a/apps/web/src/app/[locale]/mypage/ProfileSection.tsx b/apps/web/src/app/[locale]/mypage/ProfileSection.tsx index cdc721c5..c647c65a 100644 --- a/apps/web/src/app/[locale]/mypage/ProfileSection.tsx +++ b/apps/web/src/app/[locale]/mypage/ProfileSection.tsx @@ -92,10 +92,10 @@ const navStyle = css({ }); const navItemStyle = css({ - padding: 4, + padding: '4px', display: 'flex', alignItems: 'center', - gap: 4, + gap: '4px', textStyle: 'glyph18.regular', color: 'white.white_50', '&.selected': { @@ -110,11 +110,11 @@ const navItemStyle = css({ const dividerStyle = css({ background: 'white.white_25', - height: 1, + height: '1px', margin: 0, border: 'none', - marginTop: 48, - marginBottom: 20, + marginTop: '48px', + marginBottom: '20px', _mobile: { display: 'none', }, @@ -144,14 +144,14 @@ const profileNameStyle = css({ _mobile: { textStyle: 'glyph24.bold', margin: 0, - mb: 2, + mb: '2px', }, }); const pointStyle = flex({ color: 'white.white', textStyle: 'glyph24.regular', - gap: '6', + gap: '6px', alignItems: 'center', _mobile: { textStyle: 'glyph14.regular', diff --git a/apps/web/src/app/[locale]/mypage/layout.tsx b/apps/web/src/app/[locale]/mypage/layout.tsx index 93da5048..be5395aa 100644 --- a/apps/web/src/app/[locale]/mypage/layout.tsx +++ b/apps/web/src/app/[locale]/mypage/layout.tsx @@ -20,7 +20,7 @@ async function MypageLayout({ children }: { children: React.ReactNode }) { export default MypageLayout; const mainStyle = grid({ - gap: 80, + gap: '80px', gridTemplateColumns: '222px 1fr', position: 'relative', zIndex: 1, @@ -39,15 +39,13 @@ const mainStyle = grid({ }); const rightSectionStyle = css({ - // height: 'calc(100vh - 240px)', - // overflow: 'hidden', overflowX: 'hidden', width: '100%', - borderRadius: 16, + borderRadius: '16px', background: 'white.white_10', backdropFilter: 'blur(7px)', maxHeight: '1400px', - p: 40, + p: '40px', display: 'flex', flexDirection: 'column', @@ -66,15 +64,3 @@ const containerStyle = css({ height: 'fit-content', backgroundColor: '#019C5A', }); - -const bgStyle = css({ - position: 'absolute', - top: 0, - left: 0, - width: '100%', - height: 'calc(100% - 86px)', - zIndex: 0, - objectFit: 'cover', - marginTop: '86px', - pointerEvents: 'none', -}); diff --git a/apps/web/src/app/[locale]/mypage/my-pet/(merge)/MergePersona.tsx b/apps/web/src/app/[locale]/mypage/my-pet/(merge)/MergePersona.tsx index 6bd1a5c1..5533ab90 100644 --- a/apps/web/src/app/[locale]/mypage/my-pet/(merge)/MergePersona.tsx +++ b/apps/web/src/app/[locale]/mypage/my-pet/(merge)/MergePersona.tsx @@ -3,10 +3,9 @@ import { memo, useState } from 'react'; import { useTranslations } from 'next-intl'; import { css, cx } from '_panda/css'; -import { flex } from '_panda/patterns'; import type { MergePersonaLevelResponse, Persona } from '@gitanimals/api'; import { useMergePersonaLevelByToken, userQueries } from '@gitanimals/react-query'; -import { Button, FullModalBase, LevelBanner } from '@gitanimals/ui-panda'; +import { Button, Dialog, dialogContentCva, LevelBanner } from '@gitanimals/ui-panda'; import { BannerSkeletonList } from '@gitanimals/ui-panda/src/components/Banner/Banner'; import { wrap } from '@suspensive/react'; import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query'; @@ -67,39 +66,35 @@ export function MergePersona({ isOpen, onClose, targetPersona: initTargetPersona }; return ( - -

Merge Persona Level

- - - - -
- - -
- setResultData(null)} - result={resultData as MergePersonaLevelResponse} - /> - {isMerging && } -
+ + + Merge Persona Level + + + + + + + + + setResultData(null)} + result={resultData as MergePersonaLevelResponse} + /> + {isMerging && } + + ); } -const headingStyle = css({ - textStyle: 'glyph48.bold', - color: 'white.white_100', - textAlign: 'center', - marginTop: 40, -}); - -const bottomButtonStyle = css({ display: 'flex', justifyContent: 'center', gap: 12 }); +const headingStyle = css({ marginTop: '40px' }); +const footerStyle = css({ display: 'flex', justifyContent: 'center', gap: '12px' }); interface SelectPersonaListProps { selectPersona: string[]; @@ -114,15 +109,15 @@ const SelectPersonaList = wrap .on(function SelectPersonaList({ selectPersona, onSelectPersona }: SelectPersonaListProps) { const { name } = useClientUser(); const { data } = useSuspenseQuery(userQueries.allPersonasOptions(name)); + const t = useTranslations('Mypage.Merge'); // TODO: 정렬 - return ( -
+
-

Please choose a pet to use to merge the level. The pet used disappears.

+

{t('please-choose-pet')}

-
+
{data.personas.map((persona) => ( + @@ -184,19 +183,19 @@ function SelectedPetTable({ currentPersona, reset }: SelectedPetTableProps) { const tableCss = css({ width: '100%', - marginBottom: 32, + marginBottom: '32px', }); const theadCss = css({ display: 'grid', gridTemplateColumns: '1fr 2.5fr 1fr 1fr 2.2fr 3.5fr', - gap: 16, + gap: '16px', padding: '4px 32px', borderRadius: '12px', backgroundColor: 'white_50', alignItems: 'center', - height: 46, + height: '46px', textStyle: 'glyph18.bold', color: 'white_100', @@ -204,20 +203,20 @@ const theadCss = css({ textAlign: 'center', }, - marginBottom: 4, + marginBottom: '4px', }); const rowStyle = css({ width: '100%', - height: 80, + height: '80px', backgroundColor: 'white_10', - borderRadius: 12, + borderRadius: '12px', display: 'grid', gridTemplateColumns: '1fr 2.5fr 1fr 1fr 2.2fr 3.5fr', alignItems: 'center', padding: '0 32px', - gap: 16, + gap: '16px', textStyle: 'glyph20.regular', color: 'white.white_100', @@ -225,7 +224,7 @@ const rowStyle = css({ '& button': { color: 'black.black', width: '100%', - paddingX: 6, + paddingX: '6px', }, '& *': { diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/Background.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/Background.tsx index ece28e66..d98f7911 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/Background.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/Background.tsx @@ -39,8 +39,8 @@ const floatingBackgroundDivCss = css({ const coinCss = css({ position: 'absolute', width: 'fit-content', - top: 860, - left: 80, + top: '860px', + left: '80px', }); const coinVariants: Variants = { @@ -58,8 +58,8 @@ const coinVariants: Variants = { const carrotCss = css({ position: 'absolute', width: 'fit-content', - top: 300, - right: 86, + top: '300px', + right: '86px', }); const carrotVariants: Variants = { @@ -80,7 +80,7 @@ const backgroundDivCss = css({ bottom: 0, left: 0, w: '100%', - h: 354, + h: '354px', overflow: 'hidden', '& img': { diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/DefaultTabRight.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/DefaultTabRight.tsx index 767c75c3..0851b4b9 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/DefaultTabRight.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/DefaultTabRight.tsx @@ -26,5 +26,5 @@ export function DefaultTabRight() { const divCss = css({ display: 'flex', alignItems: 'center', - gap: 4, + gap: '4px', }); diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/PersonaSearch.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/PersonaSearch.tsx index ee4110db..a4467627 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/PersonaSearch.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/PersonaSearch.tsx @@ -26,10 +26,10 @@ interface PersonaSearchProps { } const buttonWrapperStyle = center({ - w: 36, - h: 36, + w: '36px', + h: '36px', backgroundColor: 'white.white_25', - borderRadius: 10, + borderRadius: '10px', }); export const PersonaSearch = wrap @@ -126,7 +126,7 @@ const headingStyle = css({ textStyle: 'glyph48.bold', color: 'white', textAlign: 'center', - marginBottom: 40, + marginBottom: '40px', '@media (max-width: 1200px)': { textStyle: 'glyph32.bold', @@ -137,19 +137,19 @@ const selectedPersonaWrapperStyle = css({ display: 'flex', justifyContent: 'flex-start', width: '100%', - marginBottom: 16, + marginBottom: '16px', }); const selectedPersonaTagStyle = css({ textStyle: 'glyph16.bold', color: 'white.white_90', - borderRadius: 8, + borderRadius: '8px', background: 'rgba(255, 255, 255, 0.25)', - h: 36, + h: '36px', display: 'flex', - gap: 2, + gap: '2px', alignItems: 'center', - px: 8, + px: '8px', }); const contentStyle = css({ @@ -173,7 +173,7 @@ const personaListHeadingStyle = css({ textStyle: 'glyph18.bold', color: 'white', textAlign: 'left', - my: 12, + my: '12px', }); const personaListStyle = css({ diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/PetList.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/PetList.tsx index dfa8bf5f..f17400fd 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/PetList.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/PetList.tsx @@ -44,5 +44,5 @@ const listContainerStyle = css({ flexWrap: 'wrap', maxHeight: '582px', overflowY: 'scroll', - gap: 4, + gap: '4px', }); diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellInputRow.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellInputRow.tsx index e6ea9055..d159c881 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellInputRow.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellInputRow.tsx @@ -4,6 +4,7 @@ import React, { useState } from 'react'; import { useTranslations } from 'next-intl'; import { css, cx } from '_panda/css'; import type { Persona } from '@gitanimals/api'; +import { auctionQueries, userQueries } from '@gitanimals/react-query'; import { Button } from '@gitanimals/ui-panda'; import { snakeToTitleCase } from '@gitanimals/util-common'; import { useQueryClient } from '@tanstack/react-query'; @@ -16,7 +17,6 @@ import { ANIMAL_TIER_TEXT_MAP, getAnimalTierInfo } from '@/utils/animals'; import { getPersonaImage } from '@/utils/image'; import { tableCss, theadCss } from '../table.styles'; -import { auctionQueries, userQueries } from '@gitanimals/react-query'; const MAX_PRICE = 100_000_000; @@ -102,11 +102,6 @@ function SellInputRow({ item, initPersona }: Props) { export default SellInputRow; -const containerStyle = css({ - height: '84px', - marginBottom: 32, -}); - const inputStyle = css({ textStyle: 'glyph20.regular', diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellSection.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellSection.tsx index 9d754b2d..9bd0071a 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellSection.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/SellSection/SellSection.tsx @@ -23,6 +23,6 @@ export default SellSection; const petHeadingStyle = css({ textStyle: 'glyph18.bold', - marginBottom: 16, + marginBottom: '16px', color: 'white.white_100', }); diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/Tab.tsx b/apps/web/src/app/[locale]/shop/AuctionSection/Tab.tsx index 1bef910f..986b08ce 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/Tab.tsx +++ b/apps/web/src/app/[locale]/shop/AuctionSection/Tab.tsx @@ -59,7 +59,7 @@ const tabContainerStyle = css({ display: 'flex', alignItems: 'center', justifyContent: 'space-between', - marginBottom: 32, + marginBottom: '32px', }); function TabItem({ isSelected, label, path }: { isSelected?: boolean } & TabItemType) { diff --git a/apps/web/src/app/[locale]/shop/AuctionSection/table.styles.ts b/apps/web/src/app/[locale]/shop/AuctionSection/table.styles.ts index 3ffd78e0..4d6a2e07 100644 --- a/apps/web/src/app/[locale]/shop/AuctionSection/table.styles.ts +++ b/apps/web/src/app/[locale]/shop/AuctionSection/table.styles.ts @@ -2,19 +2,19 @@ import { css } from '_panda/css'; export const tableCss = css({ width: '100%', - marginBottom: 32, + marginBottom: '32px', }); export const theadCss = css({ display: 'grid', gridTemplateColumns: '1fr 2.5fr 1fr 1fr 4.2fr 1.5fr', - gap: 16, + gap: '16px', padding: '4px 32px', borderRadius: '12px', backgroundColor: 'white_50', alignItems: 'center', - height: 46, + height: '46px', textStyle: 'glyph18.bold', color: 'white_100', @@ -22,11 +22,11 @@ export const theadCss = css({ textAlign: 'center', }, - marginBottom: 4, + marginBottom: '4px', }); export const tbodyCss = css({ display: 'flex', flexDir: 'column', - gap: 4, + gap: '4px', }); diff --git a/apps/web/src/app/[locale]/shop/BackgroundSection/BackgroundSection.tsx b/apps/web/src/app/[locale]/shop/BackgroundSection/BackgroundSection.tsx index 907b2335..5875b467 100644 --- a/apps/web/src/app/[locale]/shop/BackgroundSection/BackgroundSection.tsx +++ b/apps/web/src/app/[locale]/shop/BackgroundSection/BackgroundSection.tsx @@ -110,8 +110,8 @@ function BackgroundItem({ const eventLabelCss = css({ position: 'absolute', - top: 12, - left: 12, + top: '12px', + left: '12px', zIndex: 10, display: 'inline-flex', padding: '6px 12px', @@ -174,7 +174,7 @@ const cardPointStyle = css({ border: '1px solid #3FB458', background: '#56CA6F', mt: '4px', - mb: 24, + mb: '24px', p: '4px 25px', w: '100%', }); diff --git a/apps/web/src/app/[locale]/shop/FloatingPointSection/FloatingPointSection.tsx b/apps/web/src/app/[locale]/shop/FloatingPointSection/FloatingPointSection.tsx index 236b43d0..ceb5b2ec 100644 --- a/apps/web/src/app/[locale]/shop/FloatingPointSection/FloatingPointSection.tsx +++ b/apps/web/src/app/[locale]/shop/FloatingPointSection/FloatingPointSection.tsx @@ -30,8 +30,8 @@ export const FloatingPointSection = memo( const divCss = css({ position: 'fixed', - top: 88, - left: 20, + top: '88px', + left: '20px', w: 'fit-content', padding: '12px 16px', borderRadius: '12px', @@ -40,7 +40,7 @@ const divCss = css({ display: 'flex', flexDir: 'column', - gap: 4, + gap: '4px', color: 'white_100', backdropFilter: 'blur(7px)', }); @@ -52,6 +52,6 @@ const titleCss = css({ const pointCss = css({ display: 'flex', alignItems: 'center', - gap: 6, + gap: '6px', textStyle: 'glyph32.bold', }); diff --git a/apps/web/src/app/[locale]/shop/PetGotcha/TenPet.tsx b/apps/web/src/app/[locale]/shop/PetGotcha/TenPet.tsx index eda366e6..bcca12b4 100644 --- a/apps/web/src/app/[locale]/shop/PetGotcha/TenPet.tsx +++ b/apps/web/src/app/[locale]/shop/PetGotcha/TenPet.tsx @@ -114,7 +114,7 @@ const noticeMessageStyle = css({ textStyle: 'glyph28.bold', color: 'white', textAlign: 'center', - mt: 12, + mt: '12px', }); const headingStyle = css({ diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index 92305688..ce3cd2b5 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -1,12 +1,5 @@ @layer reset, base, tokens, recipes, utilities; @layer reset { - @font-face { - font-family: 'DNFBitBitv2'; - font-style: normal; - font-weight: 700; - src: url('//cdn.df.nexon.com/img/common/font/DNFBitBitv2.otf') format('opentype'); - } - *, *::before, *::after { @@ -14,11 +7,6 @@ } body { - font-family: 'DNFBitBitv2'; - font-style: normal; - font-weight: 400; - line-height: 140%; /* 107.8px */ - /* background-color: #2a7442; */ position: relative; } @@ -26,21 +14,8 @@ cursor: pointer; border: transparent; background-color: transparent; - font-family: 'DNFBitBitv2'; - line-height: 1.5; - font-style: normal; - font-weight: 400; - line-height: 140%; padding: 0; - } - - input { - font-family: 'DNFBitBitv2'; - } - - input::placeholder { - color: #b5b5b5; - font-family: 'DNFBitBitv2'; + outline: none; } .mobile { @@ -92,3 +67,46 @@ width: fit-content; gap: 12px; } + +.driver-popover-footer { + flex-direction: column; + align-items: flex-start; + gap: 4px; +} + +.driver-popover-navigation-btns { + width: 100%; +} + +.driver-popover-footer button.driver-popover-prev-btn, +.driver-popover-footer button.driver-popover-next-btn { + display: flex; + height: 32px; + padding: 0 20px; + justify-content: center; + align-items: center; + gap: 4px; + text-align: center; + color: var(--black, #000); + text-align: center; + font-family: 'Product Sans'; + font-size: 14px; +} +.driver-popover-footer button.driver-popover-prev-btn { + border-radius: 6px; + border: 1px solid var(--black, #000); + background: var(--white, #fff); + box-shadow: + 0px 4px 4px 0px rgba(0, 0, 0, 0.25), + 0px -3px 0px 0px #a1a1b1 inset, + 0px 3px 0px 0px #d2dcfe inset; +} +.driver-popover-footer button.driver-popover-next-btn { + border-radius: 6px; + border: 1px solid var(--black, #000); + background: var(--brand-color-canary, #fcfd9c); + box-shadow: + 0px 4px 4px 0px rgba(0, 0, 0, 0.25), + 0px -3px 0px 0px #c4c382 inset, + 0px 3px 0px 0px #fdfed2 inset; +} diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index 73bbccfa..6fafded8 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -7,8 +7,9 @@ import { interceptorResponseRejected, } from '@/apis/interceptor'; -import './globals.css'; import '@gitanimals/asset-font/product-sans/index.css'; +import 'driver.js/dist/driver.css'; +import './globals.css'; export const metadata: Metadata = { metadataBase: new URL('https://www.gitanimals.org/'), diff --git a/apps/web/src/components/Error/ErrorPage.tsx b/apps/web/src/components/Error/ErrorPage.tsx index 71b55964..d951e3bc 100644 --- a/apps/web/src/components/Error/ErrorPage.tsx +++ b/apps/web/src/components/Error/ErrorPage.tsx @@ -37,11 +37,11 @@ const mainCss = css({ const h1Css = css({ textStyle: 'glyph40.bold', - marginBottom: 12, + marginBottom: '12px', }); const pCss = css({ - marginBottom: 32, + marginBottom: '32px', '& a': { textDecoration: 'underline', color: 'blue', diff --git a/apps/web/src/components/GNB/DesktopGNB.tsx b/apps/web/src/components/GNB/DesktopGNB.tsx index 2c62ad49..8138a37b 100644 --- a/apps/web/src/components/GNB/DesktopGNB.tsx +++ b/apps/web/src/components/GNB/DesktopGNB.tsx @@ -80,7 +80,7 @@ const headerBaseStyle = flex({ position: 'fixed', padding: '0 20px', top: 0, - height: 60, + height: '60px', width: '100%', backgroundColor: 'white', }); @@ -120,7 +120,7 @@ const headerStyle = flex({ }); const headerBlockStyle = css({ - height: 60, + height: '60px', }); const navStyle = flex({ diff --git a/apps/web/src/components/GNB/MobileGNB.tsx b/apps/web/src/components/GNB/MobileGNB.tsx index 71ce9a78..5e95df7c 100644 --- a/apps/web/src/components/GNB/MobileGNB.tsx +++ b/apps/web/src/components/GNB/MobileGNB.tsx @@ -119,11 +119,11 @@ const mobileHeaderContentStyle = css({ justifyContent: 'space-between', position: 'relative', width: '100%', - height: 44, + height: '44px', '& .center-title': { width: 'fit-content', position: 'absolute', left: '50%', transform: 'translateX(-50%)' }, '& .profile-image': { - width: 28, - height: 28, + width: '28px', + height: '28px', borderRadius: '50%', overflow: 'hidden', }, @@ -137,7 +137,7 @@ const mobileHeaderStyle = css({ position: 'fixed', padding: '0 20px', top: 0, - height: 60, + height: '60px', backgroundColor: 'white', // mobile diff --git a/apps/web/src/components/ProductTable/ShopTableRowView.tsx b/apps/web/src/components/ProductTable/ShopTableRowView.tsx index 9b9c38aa..f5ef7bfe 100644 --- a/apps/web/src/components/ProductTable/ShopTableRowView.tsx +++ b/apps/web/src/components/ProductTable/ShopTableRowView.tsx @@ -59,15 +59,15 @@ const skeletonStyle = css({ export const rowStyle = css({ width: '100%', - height: 80, + height: '80px', backgroundColor: 'white_10', - borderRadius: 12, + borderRadius: '12px', display: 'grid', gridTemplateColumns: '1fr 2.5fr 1fr 1fr 4.2fr 1.5fr', alignItems: 'center', padding: '0 32px', - gap: 16, + gap: '16px', textStyle: 'glyph20.regular', color: 'white.white_100', @@ -75,7 +75,7 @@ export const rowStyle = css({ '& button': { color: 'black.black', width: '100%', - paddingX: 6, + paddingX: '6px', }, '& *': { diff --git a/packages/ui/panda/package.json b/packages/ui/panda/package.json index b133c045..c862b76b 100644 --- a/packages/ui/panda/package.json +++ b/packages/ui/panda/package.json @@ -9,18 +9,22 @@ "generate:component": "turbo gen react-component" }, "dependencies": { - "lucide-react": "^0.408.0", - "@gitanimals/react": "workspace:*" + "@gitanimals/react": "workspace:*", + "@radix-ui/react-accordion": "^1.2.1", + "@radix-ui/react-dialog": "^1.1.2", + "@shadow-panda/style-context": "^0.7.1", + "lucide-react": "^0.408.0" }, "devDependencies": { - "@pandacss/dev": "^0.41.0", "@gitanimals/eslint-config": "workspace:*", "@gitanimals/typescript-config": "workspace:*", "@gitanimals/ui-token": "workspace:*", "@gitanimals/util-typescript": "workspace:*", + "@pandacss/dev": "^0.41.0", + "@shadow-panda/preset": "^0.7.1", "@turbo/gen": "^1.12.4", - "@types/node": "^20.11.24", "@types/eslint": "^8.56.5", + "@types/node": "^20.11.24", "@types/react": "*", "@types/react-dom": "^18.2.19", "eslint": "^8.57.0", diff --git a/packages/ui/panda/panda.config.ts b/packages/ui/panda/panda.config.ts index 07d20f09..176d6fe1 100644 --- a/packages/ui/panda/panda.config.ts +++ b/packages/ui/panda/panda.config.ts @@ -35,5 +35,5 @@ export default defineConfig({ outdir: 'styled-system', // delete default presets - presets: [], + presets: ['@shadow-panda/preset'], }); diff --git a/packages/ui/panda/src/components/Accordion/Accordion.tsx b/packages/ui/panda/src/components/Accordion/Accordion.tsx new file mode 100644 index 00000000..2e13ec6b --- /dev/null +++ b/packages/ui/panda/src/components/Accordion/Accordion.tsx @@ -0,0 +1,40 @@ +'use client'; + +import * as React from 'react'; +import * as AccordionPrimitive from '@radix-ui/react-accordion'; +import { ChevronDown } from 'lucide-react'; +import { createStyleContext } from '@shadow-panda/style-context'; +import { styled } from '_panda/jsx'; +import { accordion } from '_panda/recipes'; + +const { withProvider, withContext } = createStyleContext(accordion); + +const Header = withContext(styled(AccordionPrimitive.Header), 'header'); + +const Trigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ children, ...props }, ref) => ( +
+ + {children} + + +
+)); +Trigger.displayName = AccordionPrimitive.Trigger.displayName; + +const Content = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ children, ...props }, ref) => ( + +
{children}
+
+)); +Content.displayName = AccordionPrimitive.Content.displayName; + +export const Accordion = withProvider(styled(AccordionPrimitive.Root), 'root'); +export const AccordionItem = withContext(styled(AccordionPrimitive.Item), 'item'); +export const AccordionTrigger = withContext(styled(Trigger), 'trigger'); +export const AccordionContent = withContext(styled(Content), 'content'); diff --git a/packages/ui/panda/src/components/Accordion/index.ts b/packages/ui/panda/src/components/Accordion/index.ts new file mode 100644 index 00000000..63f62bc6 --- /dev/null +++ b/packages/ui/panda/src/components/Accordion/index.ts @@ -0,0 +1 @@ +export * from './Accordion'; diff --git a/packages/ui/panda/src/components/Banner/LevelBanner.tsx b/packages/ui/panda/src/components/Banner/LevelBanner.tsx index 14e96884..23a9dd65 100644 --- a/packages/ui/panda/src/components/Banner/LevelBanner.tsx +++ b/packages/ui/panda/src/components/Banner/LevelBanner.tsx @@ -17,12 +17,12 @@ export function LevelBanner({ image, level, ...styleProps }: Props) { } const levelTagStyle = css({ - borderRadius: 12, + borderRadius: '12px', background: 'black.black_25', padding: '0 8px', color: 'white.white_75', textStyle: 'glyph12.regular', - fontSize: 10, + fontSize: '10px', lineHeight: '20px', position: 'absolute', bottom: '3px', diff --git a/packages/ui/panda/src/components/Banner/cva.ts b/packages/ui/panda/src/components/Banner/cva.ts index f28a6ae6..0a3a8054 100644 --- a/packages/ui/panda/src/components/Banner/cva.ts +++ b/packages/ui/panda/src/components/Banner/cva.ts @@ -6,7 +6,7 @@ export const bannerStyle = cva({ flexDirection: 'column', alignItems: 'center', justifyContent: 'center', - borderRadius: 12, + borderRadius: '12px', backgroundColor: 'white.white_10', transition: 'border 0.3s, background-color 0.3s', position: 'relative', diff --git a/packages/ui/panda/src/components/Button/cva.ts b/packages/ui/panda/src/components/Button/cva.ts index 8ac06f25..35f9fee4 100644 --- a/packages/ui/panda/src/components/Button/cva.ts +++ b/packages/ui/panda/src/components/Button/cva.ts @@ -31,6 +31,7 @@ export const buttonStyle = cva({ padding: '0 30px', fontSize: '16px', minHeight: '40px', + height: '40px', }, l: { padding: '25px 76px', diff --git a/packages/ui/panda/src/components/Dialog/Dialog.styles.ts.tsx b/packages/ui/panda/src/components/Dialog/Dialog.styles.ts.tsx new file mode 100644 index 00000000..52fe0f9e --- /dev/null +++ b/packages/ui/panda/src/components/Dialog/Dialog.styles.ts.tsx @@ -0,0 +1,30 @@ +import { cva } from '_panda/css'; + +export const dialogContentCva = cva({ + base: {}, + variants: { + size: { + large: { + borderRadius: '16px', + backgroundColor: 'gray.gray_150', + padding: '60px 40px', + + maxWidth: 'calc(100% - 400px)', + maxHeight: 'calc(100% - 240px)', + width: '100%', + height: '100%', + + '@media (max-width: 1200px)': { + padding: '48px 24px', + maxWidth: 'calc(100vw - 240px)', + maxHeight: 'calc(100vh - 120px)', + }, + _mobile: { + maxWidth: '100vw', + maxHeight: '100vh', + borderRadius: '0px', + }, + }, + }, + }, +}); diff --git a/packages/ui/panda/src/components/Dialog/Dialog.tsx b/packages/ui/panda/src/components/Dialog/Dialog.tsx new file mode 100644 index 00000000..d309d5a4 --- /dev/null +++ b/packages/ui/panda/src/components/Dialog/Dialog.tsx @@ -0,0 +1,87 @@ +'use client'; + +import * as React from 'react'; +import * as DialogPrimitive from '@radix-ui/react-dialog'; +import { X } from 'lucide-react'; +import { createStyleContext } from '@shadow-panda/style-context'; +import { styled } from '_panda/jsx'; +import { css, cx } from '_panda/css'; +import { dialog, icon } from '_panda/recipes'; + +const { withProvider, withContext } = createStyleContext(dialog); + +const DialogPortal = withContext(styled(DialogPrimitive.Portal), 'portal'); +const DialogOverlay = withContext(styled(DialogPrimitive.Overlay), 'overlay'); +const DialogClose = withContext(styled(DialogPrimitive.Close), 'close'); + +const Content = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)); + +Content.displayName = DialogPrimitive.Content.displayName; + +const overlayStyle = css({ background: 'black.black_75', zIndex: 3000 }); +const contentStyle = css({ + background: 'gray.gray_150', + borderRadius: '16px', + border: '1px solid', + borderColor: 'gray.gray_150', + zIndex: 3001, + color: 'white.white_100', +}); +const closeStyle = css({ background: 'transparent', outline: 'none', padding: '0' }); + +const Title = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ children, ...props }, ref) => ( + + {children} + +)); + +const titleStyle = css({ + textStyle: 'glyph48.bold', + color: 'white.white_100', + textAlign: 'center', + '@media (max-width: 1200px)': { + textStyle: 'glyph32.bold', + }, + _mobile: { + textStyle: 'glyph24.bold', + }, +}); + +Title.displayName = DialogPrimitive.Title.displayName; + +const DialogRoot = withProvider(styled(DialogPrimitive.Root), 'root'); +const DialogTrigger = withContext(styled(DialogPrimitive.Trigger), 'trigger'); +const DialogContent = withContext(styled(Content), 'content'); +const DialogHeader = withContext(styled('div'), 'header'); +const DialogFooter = withContext(styled('div'), 'footer'); +const DialogTitle = withContext(styled(Title), 'title'); +const DialogDescription = withContext(styled(DialogPrimitive.Description), 'description'); + +const Dialog = Object.assign(DialogRoot, { + Root: DialogRoot, + Trigger: DialogTrigger, + Content: DialogContent, + Header: DialogHeader, + Footer: DialogFooter, + Title: DialogTitle, + Description: DialogDescription, +}); + +export { Dialog }; diff --git a/packages/ui/panda/src/components/Dialog/index.ts b/packages/ui/panda/src/components/Dialog/index.ts new file mode 100644 index 00000000..3cd3685e --- /dev/null +++ b/packages/ui/panda/src/components/Dialog/index.ts @@ -0,0 +1,2 @@ +export * from './Dialog'; +export * from './Dialog.styles.ts'; diff --git a/packages/ui/panda/src/components/Modal/FullModal.tsx b/packages/ui/panda/src/components/Modal/FullModal.tsx deleted file mode 100644 index 798d1db0..00000000 --- a/packages/ui/panda/src/components/Modal/FullModal.tsx +++ /dev/null @@ -1,105 +0,0 @@ -'use client'; - -import { useBodyLock } from '@gitanimals/react'; -import { css } from '_panda/css'; -import { XIcon } from 'lucide-react'; -import { PropsWithChildren } from 'react'; -import { flex } from '_panda/patterns'; -import { useDialog } from './useDialog'; - -interface FullModalProps { - isOpen: boolean; - onClose?: () => void; -} - -function FullModalRoot({ isOpen, onClose, children }: PropsWithChildren) { - const { dialogRef } = useDialog({ isOpen, onClose }); - - useBodyLock(isOpen); - - return ( - - {children} - - ); -} - -const dialogStyle = css({ - margin: 'auto', - borderRadius: '16px', - backgroundColor: 'gray.gray_150', - padding: '24px', - - width: 'calc(100vw - 400px)', - height: 'calc(100vh - 240px)', - - '&::backdrop': { - background: 'black.black_75', - }, - - '@media (max-width: 1200px)': { - width: 'calc(100vw - 240px)', - height: 'calc(100vh - 120px)', - }, - _mobile: { - width: '100vw', - height: '100vh', - }, -}); - -function FullModalCloseButton({ onClose }: { onClose: () => void }) { - return ( - - ); -} - -const closeButtonStyle = css({ - position: 'absolute', - top: 24, - right: 24, -}); - -function FullModalHeading({ children }: { children: React.ReactNode }) { - return

{children}

; -} - -const headingStyle = css({ - textStyle: 'glyph48.bold', - color: 'white', - textAlign: 'center', - - '@media (max-width: 1200px)': { - textStyle: 'glyph32.bold', - }, -}); - -function FullModalContent({ children }: { children: React.ReactNode }) { - return
{children}
; -} - -const contentStyle = flex({ - width: '100%', - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - gap: '28px', - color: 'white', - height: '100%', -}); - -export const FullModal = Object.assign(FullModalRoot, { - CloseButton: FullModalCloseButton, - Heading: FullModalHeading, - Content: FullModalContent, -}); - -export function FullModalBase({ isOpen, onClose, children }: PropsWithChildren) { - return ( - - {onClose && } - {children} - - ); -} diff --git a/packages/ui/panda/src/components/Modal/Modal.tsx b/packages/ui/panda/src/components/Modal/Modal.tsx index f9b9ab55..04bf1fd0 100644 --- a/packages/ui/panda/src/components/Modal/Modal.tsx +++ b/packages/ui/panda/src/components/Modal/Modal.tsx @@ -11,7 +11,7 @@ interface Props { isOpen: boolean; onClose?: () => void; } - +/** @deprecated */ export function Modal({ isOpen, onClose, children }: PropsWithChildren) { const { dialogRef } = useDialog({ isOpen, onClose }); @@ -40,8 +40,8 @@ const dialogStyle = css({ const closeButtonStyle = css({ position: 'absolute', - top: 24, - right: 24, + top: '24px', + right: '24px', }); const contentStyle = flex({ diff --git a/packages/ui/panda/src/components/Modal/ScreenModal.tsx b/packages/ui/panda/src/components/Modal/ScreenModal.tsx index 313f988f..e2b591bf 100644 --- a/packages/ui/panda/src/components/Modal/ScreenModal.tsx +++ b/packages/ui/panda/src/components/Modal/ScreenModal.tsx @@ -14,6 +14,7 @@ interface ScreenModalProps { /** * 화면 전체를 덮는 모달 컴포넌트 + * @deprecated */ function ScreenModalRoot({ isOpen, onClose, children }: PropsWithChildren) { const { dialogRef } = useDialog({ isOpen, onClose }); @@ -55,8 +56,8 @@ function ScreenModalCloseButton({ onClose }: { onClose: () => void }) { const closeButtonStyle = css({ position: 'absolute', - top: 24, - right: 24, + top: '24px', + right: '24px', }); function ScreenModalHeading({ children }: { children: React.ReactNode }) { diff --git a/packages/ui/panda/src/components/Modal/index.ts b/packages/ui/panda/src/components/Modal/index.ts index 80f4fb8a..3bacd5c6 100644 --- a/packages/ui/panda/src/components/Modal/index.ts +++ b/packages/ui/panda/src/components/Modal/index.ts @@ -1,3 +1,2 @@ export * from './Modal'; -export * from './FullModal'; export * from './ScreenModal'; diff --git a/packages/ui/panda/src/components/Textfield/TextField.tsx b/packages/ui/panda/src/components/Textfield/TextField.tsx index 75225e4f..64b847cc 100644 --- a/packages/ui/panda/src/components/Textfield/TextField.tsx +++ b/packages/ui/panda/src/components/Textfield/TextField.tsx @@ -6,11 +6,11 @@ export const TextField = (props: ComponentProps<'input'>) => { }; const textFieldStyle = css({ - height: 55, + height: '55px', padding: '14px 20px', alignItems: 'flex-start', - gap: 8, - borderRadius: 8, + gap: '8px', + borderRadius: '8px', border: '1px solid', borderColor: 'white.white_25', color: 'white.white_50', diff --git a/packages/ui/panda/src/components/index.ts b/packages/ui/panda/src/components/index.ts index 915fb975..8e3b84c7 100644 --- a/packages/ui/panda/src/components/index.ts +++ b/packages/ui/panda/src/components/index.ts @@ -4,3 +4,5 @@ export * from './Modal'; export * from './Skeleton'; export * from './Banner'; export * from './Textfield'; +export * from './Accordion'; +export * from './Dialog'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bacb78cc..754ef7e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -183,6 +183,9 @@ importers: '@octokit/core': specifier: ^6.1.2 version: 6.1.2 + '@shadow-panda/style-context': + specifier: ^0.7.1 + version: 0.7.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) '@suspensive/react': specifier: ^2.17.1 version: 2.17.1(react@18.2.0) @@ -192,6 +195,9 @@ importers: axios: specifier: ^1.6.8 version: 1.7.2 + driver.js: + specifier: ^1.3.1 + version: 1.3.1 framer-motion: specifier: ^11.1.7 version: 11.2.10(@emotion/is-prop-valid@1.2.2)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) @@ -250,6 +256,9 @@ importers: '@pandacss/dev': specifier: ^0.41.0 version: 0.41.0(typescript@5.4.5) + '@shadow-panda/preset': + specifier: ^0.7.1 + version: 0.7.1(@pandacss/dev@0.41.0(typescript@5.4.5)) '@storybook/addon-essentials': specifier: ^8.0.9 version: 8.1.9(@types/react-dom@18.2.19)(@types/react@18.2.61)(prettier@3.2.5)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) @@ -368,7 +377,7 @@ importers: version: 2.0.0(eslint@8.57.0) eslint-plugin-import: specifier: ^2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: specifier: ^6.8.0 version: 6.8.0(eslint@8.57.0) @@ -479,6 +488,15 @@ importers: '@gitanimals/react': specifier: workspace:* version: link:../../lib/react + '@radix-ui/react-accordion': + specifier: ^1.2.1 + version: 1.2.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-dialog': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@shadow-panda/style-context': + specifier: ^0.7.1 + version: 0.7.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) lucide-react: specifier: ^0.408.0 version: 0.408.0(react@18.2.0) @@ -498,6 +516,9 @@ importers: '@pandacss/dev': specifier: ^0.41.0 version: 0.41.0(typescript@5.4.5) + '@shadow-panda/preset': + specifier: ^0.7.1 + version: 0.7.1(@pandacss/dev@0.41.0(typescript@5.4.5)) '@turbo/gen': specifier: ^1.12.4 version: 1.12.4(@types/node@20.11.24)(typescript@5.4.5) @@ -1884,6 +1905,7 @@ packages: '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} @@ -1891,6 +1913,7 @@ packages: '@humanwhocodes/object-schema@2.0.2': resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + deprecated: Use @eslint/object-schema instead '@img/sharp-darwin-arm64@0.33.4': resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==} @@ -2290,6 +2313,19 @@ packages: '@radix-ui/primitive@1.1.0': resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + '@radix-ui/react-accordion@1.2.1': + resolution: {integrity: sha512-bg/l7l5QzUjgsh8kjwDFommzAshnUsuVMV5NM56QVCm+7ZckYdd9P/ExR8xG/Oup0OajVxNLaHJ1tb8mXk+nzQ==} + peerDependencies: + '@types/react': ^18 + '@types/react-dom': '*' + react: ^18 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-arrow@1.1.0': resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==} peerDependencies: @@ -2329,6 +2365,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-collapsible@1.1.1': + resolution: {integrity: sha512-1///SnrfQHJEofLokyczERxQbWfCGQlQ2XsCZMucVs6it+lq9iw4vXy+uDn1edlb58cOZOWSldnfPAYcT4O/Yg==} + peerDependencies: + '@types/react': ^18 + '@types/react-dom': '*' + react: ^18 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-collection@1.1.0': resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} peerDependencies: @@ -2378,6 +2427,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-context@1.1.1': + resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==} + peerDependencies: + '@types/react': ^18 + react: ^18 + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-dialog@1.0.5': resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: @@ -2391,6 +2449,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-dialog@1.1.2': + resolution: {integrity: sha512-Yj4dZtqa2o+kG61fzB0H2qUvmwBA2oyQroGLyNtBj1beo1khoQ3q1a2AO8rrQYjd8256CO9+N8L9tvsS+bnIyA==} + peerDependencies: + '@types/react': ^18 + '@types/react-dom': '*' + react: ^18 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-direction@1.1.0': resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==} peerDependencies: @@ -2426,6 +2497,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-dismissable-layer@1.1.1': + resolution: {integrity: sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==} + peerDependencies: + '@types/react': ^18 + '@types/react-dom': '*' + react: ^18 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-dropdown-menu@2.1.1': resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==} peerDependencies: @@ -2457,6 +2541,15 @@ packages: '@types/react': optional: true + '@radix-ui/react-focus-guards@1.1.1': + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} + peerDependencies: + '@types/react': ^18 + react: ^18 + peerDependenciesMeta: + '@types/react': + optional: true + '@radix-ui/react-focus-scope@1.0.4': resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: @@ -2566,6 +2659,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-portal@1.1.2': + resolution: {integrity: sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==} + peerDependencies: + '@types/react': ^18 + '@types/react-dom': '*' + react: ^18 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-presence@1.0.1': resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: @@ -2592,6 +2698,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-presence@1.1.1': + resolution: {integrity: sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==} + peerDependencies: + '@types/react': ^18 + '@types/react-dom': '*' + react: ^18 + react-dom: ^18.3.1 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-primitive@1.0.3': resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: @@ -4890,6 +5009,9 @@ packages: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} + driver.js@1.3.1: + resolution: {integrity: sha512-MvUdXbqSgEsgS/H9KyWb5Rxy0aE6BhOVT4cssi2x2XjmXea6qQfgdx32XKVLLSqTaIw7q/uxU5Xl3NV7+cN6FQ==} + duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} @@ -5251,6 +5373,7 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -5663,6 +5786,7 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -5911,6 +6035,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -7702,6 +7827,16 @@ packages: '@types/react': optional: true + react-remove-scroll@2.6.0: + resolution: {integrity: sha512-I2U4JVEsQenxDAKaVa3VZ/JeJZe0/2DxPWL8Tj8yLKctQJQiZM52pn/GWFpSp8dftjM3pSAHVJZscAnC/y+ySQ==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^18 + react: ^18 + peerDependenciesMeta: + '@types/react': + optional: true + react-router-dom@6.25.0: resolution: {integrity: sha512-BhcczgDWWgvGZxjDDGuGHrA8HrsSudilqTaRSBYLWDayvo1ClchNIDVt5rldqp6e7Dro5dEFx9Mzc+r292lN0w==} engines: {node: '>=14.0.0'} @@ -7903,6 +8038,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true ripemd160@2.0.2: @@ -10986,6 +11122,23 @@ snapshots: '@radix-ui/primitive@1.1.0': {} + '@radix-ui/react-accordion@1.2.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collapsible': 1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-context': 1.1.1(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.61)(react@18.2.0) + react: 18.2.0 + react-dom: 18.3.1(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + '@types/react-dom': 18.2.19 + '@radix-ui/react-arrow@1.1.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) @@ -11023,6 +11176,22 @@ snapshots: '@types/react': 18.2.61 '@types/react-dom': 18.2.19 + '@radix-ui/react-collapsible@1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-context': 1.1.1(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.61)(react@18.2.0) + react: 18.2.0 + react-dom: 18.3.1(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + '@types/react-dom': 18.2.19 + '@radix-ui/react-collection@1.1.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.61)(react@18.2.0) @@ -11061,6 +11230,12 @@ snapshots: optionalDependencies: '@types/react': 18.2.61 + '@radix-ui/react-context@1.1.1(@types/react@18.2.61)(react@18.2.0)': + dependencies: + react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.61 + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.7 @@ -11084,6 +11259,28 @@ snapshots: '@types/react': 18.2.61 '@types/react-dom': 18.2.19 + '@radix-ui/react-dialog@1.1.2(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-context': 1.1.1(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-portal': 1.1.2(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-presence': 1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.61)(react@18.2.0) + aria-hidden: 1.2.4 + react: 18.2.0 + react-dom: 18.3.1(react@18.2.0) + react-remove-scroll: 2.6.0(@types/react@18.2.61)(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + '@types/react-dom': 18.2.19 + '@radix-ui/react-direction@1.1.0(@types/react@18.2.61)(react@18.2.0)': dependencies: react: 18.2.0 @@ -11117,6 +11314,19 @@ snapshots: '@types/react': 18.2.61 '@types/react-dom': 18.2.19 + '@radix-ui/react-dismissable-layer@1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.2.61)(react@18.2.0) + react: 18.2.0 + react-dom: 18.3.1(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + '@types/react-dom': 18.2.19 + '@radix-ui/react-dropdown-menu@2.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@radix-ui/primitive': 1.1.0 @@ -11145,6 +11355,12 @@ snapshots: optionalDependencies: '@types/react': 18.2.61 + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.2.61)(react@18.2.0)': + dependencies: + react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.61 + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.7 @@ -11269,6 +11485,16 @@ snapshots: '@types/react': 18.2.61 '@types/react-dom': 18.2.19 + '@radix-ui/react-portal@1.1.2(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.61)(react@18.2.0) + react: 18.2.0 + react-dom: 18.3.1(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + '@types/react-dom': 18.2.19 + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.7 @@ -11290,6 +11516,16 @@ snapshots: '@types/react': 18.2.61 '@types/react-dom': 18.2.19 + '@radix-ui/react-presence@1.1.1(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.61)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.61)(react@18.2.0) + react: 18.2.0 + react-dom: 18.3.1(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + '@types/react-dom': 18.2.19 + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.19)(@types/react@18.2.61)(react-dom@18.3.1(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.7 @@ -13168,10 +13404,10 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.17.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': 6.17.0(eslint@8.57.0)(typescript@5.4.5) eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)) - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-import-resolver-alias: 1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jest: 27.6.0(@typescript-eslint/eslint-plugin@7.1.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-playwright: 0.16.0(eslint-plugin-jest@27.6.0(@typescript-eslint/eslint-plugin@6.17.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) @@ -14441,6 +14677,8 @@ snapshots: dotenv@16.0.3: {} + driver.js@1.3.1: {} + duplexer@0.1.2: {} duplexify@3.7.1: @@ -14732,8 +14970,8 @@ snapshots: '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.33.2(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) @@ -14752,9 +14990,9 @@ snapshots: eslint: 8.57.0 eslint-plugin-turbo: 2.0.0(eslint@8.57.0) - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)): dependencies: - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-import-resolver-node@0.3.9: dependencies: @@ -14764,29 +15002,12 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): - dependencies: - debug: 4.3.4 - enhanced-resolve: 5.17.0 - eslint: 8.57.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) - fast-glob: 3.3.2 - get-tsconfig: 4.7.2 - is-core-module: 2.13.1 - is-glob: 4.0.3 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.17.0 eslint: 8.57.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 @@ -14798,13 +15019,13 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.17.0 eslint: 8.57.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -14815,18 +15036,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 6.17.0(eslint@8.57.0)(typescript@5.4.5) - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -14837,14 +15047,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) transitivePeerDependencies: - supports-color @@ -14854,33 +15064,6 @@ snapshots: eslint: 8.57.0 ignore: 5.3.1 - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): - dependencies: - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - hasown: 2.0.0 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.1 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 6.17.0(eslint@8.57.0)(typescript@5.4.5) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: array-includes: 3.1.7 @@ -14891,7 +15074,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.17.0(eslint@8.57.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -14908,7 +15091,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 @@ -14918,34 +15101,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) - hasown: 2.0.0 - is-core-module: 2.13.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.7 - object.groupby: 1.0.1 - object.values: 1.1.7 - semver: 6.3.1 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 7.1.0(eslint@8.57.0)(typescript@5.4.5) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0): - dependencies: - array-includes: 3.1.7 - array.prototype.findlastindex: 1.2.3 - array.prototype.flat: 1.3.2 - array.prototype.flatmap: 1.3.2 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.57.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0))(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.1.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) hasown: 2.0.0 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -17984,6 +18140,17 @@ snapshots: optionalDependencies: '@types/react': 18.2.61 + react-remove-scroll@2.6.0(@types/react@18.2.61)(react@18.2.0): + dependencies: + react: 18.2.0 + react-remove-scroll-bar: 2.3.6(@types/react@18.2.61)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.61)(react@18.2.0) + tslib: 2.6.2 + use-callback-ref: 1.3.2(@types/react@18.2.61)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.61)(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.61 + react-router-dom@6.25.0(react-dom@18.3.1(react@18.2.0))(react@18.2.0): dependencies: '@remix-run/router': 1.18.0